diff -u --recursive --new-file v2.4.10/linux/COPYING linux/COPYING
--- v2.4.10/linux/COPYING	Fri Sep  8 11:15:58 2000
+++ linux/COPYING	Tue Oct  9 15:00:06 2001
@@ -7,8 +7,8 @@
  kernel) is copyrighted by me and others who actually wrote it.
 
  Also note that the only valid version of the GPL as far as the kernel
- is concerned is _this_ license (ie v2), unless explicitly otherwise
- stated.
+ is concerned is _this_ particular version of the license (ie v2, not
+ v2.2 or v3.x or whatever), unless explicitly otherwise stated.
 
 			Linus Torvalds
 
diff -u --recursive --new-file v2.4.10/linux/CREDITS linux/CREDITS
--- v2.4.10/linux/CREDITS	Sun Sep 23 11:40:54 2001
+++ linux/CREDITS	Fri Oct  5 12:04:50 2001
@@ -603,6 +603,13 @@
 S: Guildford, GU1 3DA
 S: United Kingdom
 
+N: Cristian Mihail Craciunescu
+W: http://www.dnt.ro/~cristi/
+E: cristi@dnt.ro
+D: Support for Xircom PGSDB9 (firmware and host driver)
+S: Bucharest
+S: Romania
+
 N: Laurence Culhane
 E: loz@holmes.demon.co.uk
 D: Wrote the initial alpha SLIP code
@@ -837,7 +844,6 @@
 S: USA
 
 N: Johannes Erdfelt
-E: jerdfelt@valinux.com
 E: johannes@erdfelt.com
 D: Linux/IA-64 bootloader and kernel goop, USB
 S: 6350 Stoneridge Mall Road
diff -u --recursive --new-file v2.4.10/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.4.10/linux/Documentation/Configure.help	Sun Sep 23 11:40:54 2001
+++ linux/Documentation/Configure.help	Tue Oct  9 15:13:03 2001
@@ -119,18 +119,39 @@
   SMP-FAQ on the WWW at http://www.irisa.fr/prive/mentre/smp-faq/ .
   
   If you don't know what to do here, say N.
+
+Multiquad support for NUMA systems
+CONFIG_MULTIQUAD
+  This option is used for getting Linux to run on a (IBM/Sequent) NUMA 
+  multiquad box. This changes the way that processors are bootstrapped,
+  and uses Clustered Logical APIC addressing mode instead of Flat Logical.
+  You will need a new lynxer.elf file to flash your firmware with - send
+  email to Martin.Bligh@us.ibm.com
   
-APIC and IO-APIC Support on Uniprocessors
+IO-APIC Support on Uniprocessors
 CONFIG_X86_UP_IOAPIC
-  APIC (Advanced Programmable Interrupt Controller) is a scheme for
-  delivering hardware interrupt requests to the CPU. It is commonly
-  used on systems with several CPU's. If you have a single-CPU system
-  which uses APIC, you can say Y here to use it. If you say Y here
-  even though your machine doesn't have APIC, then the kernel will
-  still run with no slowdown at all.
+  An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
+  SMP-capable replacement for PC-style interrupt controllers. Most
+  SMP systems and a small number of uniprocessor systems have one.
+  If you have a single-CPU system with an IO-APIC, you can say Y here
+  to use it. If you say Y here even though your machine doesn't have
+  an IO-APIC, then the kernel will still run with no slowdown at all.
+
+  If you have a system with several CPUs, you do not need to say Y
+  here: the IO-APIC will be used automatically.
+
+Local APIC Support on Uniprocessors
+CONFIG_X86_UP_APIC
+  A local APIC (Advanced Programmable Interrupt Controller) is an
+  integrated interrupt controller in the CPU. If you have a single-CPU
+  system which has a processor with a local APIC, you can say Y here to
+  enable and use it. If you say Y here even though your machine doesn't
+  have a local APIC, then the kernel will still run with no slowdown at
+  all. The local APIC supports CPU-generated self-interrupts (timer,
+  performance counters), and the NMI watchdog which detects hard lockups.
 
-  If you have system with several CPU's, you do not need to say Y
-  here: APIC will be used automatically.
+  If you have a system with several CPUs, you do not need to say Y
+  here: the local APIC will be used automatically.
 
 Kernel math emulation
 CONFIG_MATH_EMULATION
@@ -1143,6 +1164,29 @@
   devices (hard disks, CD-ROM drives, etc.) that are connected to the
   builtin IDE interface.
 
+MPC8xx IDE support
+CONFIG_BLK_DEV_MPC8xx_IDE
+  This option provides support for IDE on Motorola MPC8xx Systems.
+  Please see 'Type of MPC8xx IDE interface' for details.
+
+  If unsure, say N.
+
+Type of MPC8xx IDE interface
+CONFIG_IDE_8xx_PCCARD
+  Select how the IDE devices are connected to the MPC8xx system:
+
+  8xx_PCCARD uses the 8xx internal PCMCIA interface in combination
+             with a PC Card (e.g. ARGOSY portable Hard Disk Adapter),
+             ATA PC Card HDDs or ATA PC Flash Cards (example: TQM8xxL
+             systems)
+
+  8xx_DIRECT is used for directly connected IDE devices using the 8xx
+             internal PCMCIA interface (example: IVMS8 systems)
+
+  EXT_DIRECT is used for IDE devices directly connected to the 8xx
+             bus using some glue logic, but _not_ the 8xx internal
+             PCMCIA interface (example: IDIF860 systems)
+
 ICS IDE interface support
 CONFIG_BLK_DEV_IDE_ICSIDE
   On Acorn systems, say Y here if you wish to use the ICS IDE
@@ -2554,10 +2598,10 @@
   module, say M here and read Documentation/modules.txt. The module
   will be called agpgart.o.
 
-Intel 440LX/BX/GX/815/840/850 support
+Intel 440LX/BX/GX/815/830M/840/850 support
 CONFIG_AGP_INTEL
   This option gives you AGP support for the GLX component of the
-  XFree86 4.x on Intel 440LX/BX/GX, 815, 840 and 850 chipsets.
+  XFree86 4.x on Intel 440LX/BX/GX, 815, 830M, 840 and 850 chipsets.
 
   For the moment, you should probably say N, unless you want to test
   the GLX component for XFree86 3.3.6, which can be downloaded from
@@ -2565,9 +2609,9 @@
 
 Intel I810/I810 DC100/I810e support
 CONFIG_AGP_I810
-  This option gives you AGP support for the Xserver on the Intel 810
-  and 815 chipset boards for their on-board integrated graphics. This
-  is required to do any useful video modes with these boards.
+  This option gives you AGP support for the Xserver on the Intel 810,
+  830M and 815 chipset boards for their on-board integrated graphics.
+  This is required to do any useful video modes with these boards.
 
 VIA chipset support
 CONFIG_AGP_VIA
@@ -7593,6 +7637,53 @@
   location). You also want to check out the PCMCIA-HOWTO, available
   from http://www.linuxdoc.org/docs.html#howto .
 
+Hermes chipset 802.11b support (Orinoco/Prism2/Symbol cards)
+CONFIG_HERMES
+  A driver for 802.11b wireless cards based based on the "Hermes" or
+  Intersil HFA384x (Prism 2) MAC controller.  This includes the vast
+  majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
+  - except for the Cisco/Aironet cards.  Cards supported include the
+  Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
+  Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
+  IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
+  MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
+  PRO/Wireless, and Symbol Spectrum24 High Rate amongst others.
+
+  This option includes the guts of the driver, but in order to
+  actually use a card you will also need to enable support for PCMCIA
+  Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
+
+  You will also very likely also need the Wireless Tools in order to
+  configure your card and that /etc/pcmcia/wireless.opts works :
+    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
+
+Apple Airport support (built-in)
+CONFIG_APPLE_AIRPORT
+  Enable support for the Apple Airport card (which is essentially a
+  Lucent Orinoco card with a non-standard interface) built into some
+  newer Apple Macintosh machines.
+
+Hermes 802.11b in PLX9052 based PCI adaptor support
+CONFIG_PLX_HERMES
+  Enable support for PCMCIA cards supported by the "Hermes" (aka
+  orinoco_cs) driver when used in PLX9052 based PCI adaptors.  These
+  adaptors are not a full PCMCIA controller but act as a more limited
+  PCI <-> PCMCIA bridge.  Several vendors sell such adaptors so that
+  802.11b PCMCIA cards can be used in desktop machines.  The Netgear
+  MA301 is such an adaptor.
+
+  Support for these adaptors is so far still incomplete and buggy.
+  You have been warned.
+
+Hermes PCMCIA card support
+CONFIG_PCMCIA_HERMES
+  Enable support for PCMCIA 802.11b cards using the Hermes or Intersil
+  HFA384x (Prism 2) chipset.  To use your PC-cards, you will need
+  supporting software from David Hinds' pcmcia-cs package (see the
+  file Documentation/Changes for location). You also want to check out
+  the PCMCIA-HOWTO, available from
+  http://www.linuxdoc.org/docs.html#howto .
+
 Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)
 CONFIG_PCMCIA_HERMES
   A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
@@ -15708,25 +15799,18 @@
 Creative EMU10K1 based PCI sound cards
 CONFIG_SOUND_EMU10K1
   Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
-  such as the Creative SBLive!, SB PCI512 or Emu-APS.
+  such as the various Creative SBLive!, SB PCI512 or Emu-APS.
 
-  For more information about the degree of support for the different
-  card models please check:
-
-       http://opensource.creative.com
+  For more information on this driver and the degree of support for the
+  different card models please check <http://opensource.creative.com>.
 
   It is now possible to load dsp microcode patches into the EMU10K1
   chip.  These patches are used to implement real time sound processing
-  effects which include for example: signal routing, bass/treble control,
-  AC3 passthrough, ...
-  Userspace tools to create new patches and load/unload them can be found
-  at the above link. You need to get the source snapshot and then type:
-
-	% make tools
-	% make install-tools
-
-  in the top directory.
-
+  effects which include for example: signal routing, bass/treble
+  control, AC3 passthrough, ...
+  Userspace tools to create new patches and load/unload them can be
+  found at <http://opensource.creative.com/dist.html>.
+ 
 Creative EMU10K1 MIDI
 CONFIG_MIDI_EMU10K1
   Say Y if you want to be able to use the OSS /dev/sequencer interface.
@@ -18481,6 +18565,16 @@
   and Sony PCG-505TX. If you want to compile it as a module, say M
   here and read Documentation/modules.txt. The module will be called
   smc-ircc.o.
+
+VLSI 82C147 PCI-IrDA Controller Driver
+CONFIG_VLSI_FIR
+  Say Y here if you want to build support for the VLSI 82C147
+  PCI-IrDA Controller. This controller is used by the HP OmniBook 800
+  and 5500 notebooks. The driver provides support for SIR, MIR and
+  FIR (4Mbps) speeds.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called vlsi_ir.o.
 
 Serial dongle support
 CONFIG_DONGLE
diff -u --recursive --new-file v2.4.10/linux/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile
--- v2.4.10/linux/Documentation/DocBook/Makefile	Sun Sep 23 11:40:54 2001
+++ linux/Documentation/DocBook/Makefile	Fri Oct  5 12:06:51 2001
@@ -141,17 +141,18 @@
 OUT	:=	$(patsubst %.sgml, %.out, $(BOOKS))
 
 clean:
-	-$(RM) core *~
-	-$(RM) $(BOOKS)
-	-$(RM) $(DVI) $(AUX) $(TEX) $(LOG) $(OUT)
-	-$(RM) $(JPG-parportbook) $(EPS-parportbook)
-	-$(RM) $(C-procfs-example)
+	rm -f core *~
+	rm -f $(BOOKS)
+	rm -f $(DVI) $(AUX) $(TEX) $(LOG) $(OUT)
+	rm -f $(JPG-parportbook) $(EPS-parportbook)
+	rm -f $(C-procfs-example)
 
 mrproper: clean
-	-$(RM) $(PS) $(PDF)
-	-$(RM) -r $(HTML)
-	-$(RM) .depend
-	-$(RM) $(TOPDIR)/scripts/mkdep-docbook
+	rm -f $(PS) $(PDF)
+	rm -f -r $(HTML)
+	rm -f .depend
+	rm -f $(TOPDIR)/scripts/mkdep-docbook
+	rm -rf DBTOHTML_OUTPUT*
 
 %.ps : %.sgml
 	@(which db2ps > /dev/null 2>&1) || \
@@ -169,7 +170,7 @@
 	@(which db2html > /dev/null 2>&1) || \
 	 (echo "*** You need to install DocBook stylesheets ***"; \
 	  exit 1)
-	-$(RM) -r $@
+	rm -rf $@
 	db2html $<
 	if [ ! -z "$(JPG-$@)" ]; then cp $(JPG-$@) $@; fi
 
diff -u --recursive --new-file v2.4.10/linux/Documentation/DocBook/kernel-api.tmpl linux/Documentation/DocBook/kernel-api.tmpl
--- v2.4.10/linux/Documentation/DocBook/kernel-api.tmpl	Sun Sep 23 11:40:54 2001
+++ linux/Documentation/DocBook/kernel-api.tmpl	Fri Oct  5 12:06:51 2001
@@ -187,11 +187,6 @@
 !Edrivers/block/ll_rw_blk.c
   </chapter>
 
-  <chapter id="part">
-     <title>Partition Handling</title>
-!Edrivers/block/genhd.c
-  </chapter>
-
   <chapter id="miscdev">
      <title>Miscellaneous Devices</title>
 !Edrivers/char/misc.c
diff -u --recursive --new-file v2.4.10/linux/Documentation/DocBook/kernel-hacking.tmpl linux/Documentation/DocBook/kernel-hacking.tmpl
--- v2.4.10/linux/Documentation/DocBook/kernel-hacking.tmpl	Sat May 19 17:43:05 2001
+++ linux/Documentation/DocBook/kernel-hacking.tmpl	Fri Oct  5 12:06:51 2001
@@ -976,17 +976,35 @@
    </para>
   </sect1>
 
-  <sect1 id="sym-exportsymtab">
-   <title><function>EXPORT_SYMTAB</function></title>
+  <sect1 id="sym-exportnosymbols">
+   <title><symbol>EXPORT_NO_SYMBOLS</symbol>
+    <filename class=headerfile>include/linux/module.h</filename></title>
+
+   <para>
+    If a module exports no symbols then you can specify
+    <programlisting>
+EXPORT_NO_SYMBOLS;
+    </programlisting>
+    anywhere in the module.
+    In kernel 2.4 and earlier, if a module contains neither
+    <function>EXPORT_SYMBOL()</function> nor
+    <symbol>EXPORT_NO_SYMBOLS</symbol> then the module defaults to
+    exporting all non-static global symbols.
+    In kernel 2.5 onwards you must explicitly specify whether a module
+    exports symbols or not.
+   </para>
+  </sect1>
 
-   <para>
-    For convenience, a module usually exports all non-file-scope
-    symbols (ie. all those not declared <type>static</type>).  If this
-    is defined before
+  <sect1 id="sym-exportsymbols-gpl">
+   <title><function>EXPORT_SYMBOL_GPL()</function>
+    <filename class=headerfile>include/linux/module.h</filename></title>
 
-    <filename class=headerfile>include/linux/module.h</filename> is
-    included, then only symbols explicit exported with
-    <function>EXPORT_SYMBOL()</function> will be exported.
+   <para>
+    Similar to <function>EXPORT_SYMBOL()</function> except that the
+    symbols exported by <function>EXPORT_SYMBOL_GPL()</function> can
+    only be seen by modules with a
+    <function>MODULE_LICENCE()</function> that specifies a GPL
+    compatible license.
    </para>
   </sect1>
  </chapter>
@@ -1241,9 +1259,19 @@
      Edit the <filename>Makefile</filename>: the CONFIG variables are
      exported here so you can conditionalize compilation with `ifeq'.
      If your file exports symbols then add the names to
-     <varname>MX_OBJS</varname> or <varname>OX_OBJS</varname> instead
-     of <varname>M_OBJS</varname> or <varname>O_OBJS</varname>, so
-     that genksyms will find them.
+     <varname>export-objs</varname> so that genksyms will find them.
+     <caution>
+      <para>
+       There is a restriction on the kernel build system that objects
+       which export symbols must have globally unique names.
+       If your object does not have a globally unique name then the
+       standard fix is to move the
+       <function>EXPORT_SYMBOL()</function> statements to their own
+       object with a unique name.
+       This is why several systems have separate exporting objects,
+       usually suffixed with ksyms.
+      </para>
+     </caution>
     </para>
    </listitem>
 
diff -u --recursive --new-file v2.4.10/linux/Documentation/DocBook/mousedrivers.tmpl linux/Documentation/DocBook/mousedrivers.tmpl
--- v2.4.10/linux/Documentation/DocBook/mousedrivers.tmpl	Thu Jan  4 12:50:12 2001
+++ linux/Documentation/DocBook/mousedrivers.tmpl	Sun Sep 30 12:26:05 2001
@@ -241,16 +241,12 @@
 
   <programlisting>
 struct file_operations our_mouse_fops = {
-        NULL,                   /* Mice don't seek */
-        read_mouse,             /* You can read a mouse */
-        write_mouse,            /* This won't do a lot */
-        NULL,                   /* No readdir - not a directory */
-        poll_mouse,             /* Poll */
-        NULL,                   /* No ioctl calls */
-        NULL,                   /* No mmap */
-        open_mouse,             /* Called on open */
-        NULL,                   /* Flush - 2.2+ only */
-        close_mouse,            /* Called on close */
+        owner: THIS_MODULE,            /* Automatic usage management */
+        read:  read_mouse,             /* You can read a mouse */
+        write: write_mouse,            /* This won't do a lot */
+        poll:  poll_mouse,             /* Poll */
+        open:  open_mouse,             /* Called on open */
+        release: close_mouse,          /* Called on close */
 };
   </programlisting>
 
@@ -262,6 +258,18 @@
     configuration interfaces via ioctl calls.
   </para>
   <para>
+    The syntax we use is not standard C as such. GCC provides the ability
+    to initialise fields by name, and this generally makes the method table
+    much easier to read than counting through NULL pointers and remembering
+    the order by hand.
+  </para>
+  <para>
+    The owner field is used to manage the locking of module load an
+    unloading. It is obviously important that a module is not unloaded while
+    in use. When your device is opened the module specified by "owner" is 
+    locked. When it is finally released the module is unlocked.
+  </para>
+  <para>
     The open and close routines need to manage enabling and disabling the 
     interrupts for the mouse as well as stopping the mouse being unloaded
     when it is no longer required. 
@@ -278,12 +286,9 @@
         if(mouse_users++)
                 return 0;
 
-	MOD_INC_USE_COUNT;
-
         if(request_irq(mouse_intr, OURMOUSE_IRQ, 0, "ourmouse", NULL))
         {
                 mouse_users--;
-	        MOD_DEC_USE_COUNT;
                 return -EBUSY;
         }
         mouse_dx = 0;
@@ -301,11 +306,6 @@
     <returnvalue>0</returnvalue> for success.
   </para>
   <para>
-    Firstly we use <function>MOD_INC_USE_COUNT</function> to ensure that 
-    while the mouse is open nobody will unload it and cause a nasty crash.
-    We must do this before we sleep - and grabbing the interrupt might sleep.
-  </para>
-  <para>
     We grab the interrupt and thus start mouse interrupts. If the interrupt 
     has been borrowed by some other driver then <function>request_irq</function>
     will fail and we will return an error. If we were capable of sharing an 
@@ -328,7 +328,6 @@
         if(--mouse_users)
                 return 0;
         free_irq(OURMOUSE_IRQ, NULL);
-        MOD_DEC_USE_COUNT;
         return 0;
 }
   </programlisting>
@@ -336,8 +335,7 @@
     We count off a user and provided that there are still other users need 
     take no further action. The last person closing the mouse causes us to 
     free up the interrupt. This stops interrupts from the mouse from using 
-    our CPU time, and lets us use <function>MOD_DEC_USE_COUNT</function> so 
-    that the mouse can now be unloaded.
+    our CPU time, and ensures that the mouse can now be unloaded.
   </para>
   <para>
     We can fill in the write handler at this point as the write function for 
@@ -718,14 +716,14 @@
         struct wait_queue wait = { current, NULL };
 
         add_wait_queue(&amp;mouse_wait, &amp;wait);
-        current-&gt;state = TASK_INTERRUPTIBLE;
+        set_current_state(TASK_INTERRUPTIBLE);
         
         while(!mouse_event)
         {
                 if(file-&gt;f_flags&amp;O_NDELAY)
                 {
                         remove_wait_queue(&amp;mouse_wait, &amp;wait);
-                        current-&gt;state = TASK_RUNNING;
+                        set_current_state(TASK_RUNNING);
                         return -EWOULDBLOCK;
                 }
                 if(signal_pending(current))
@@ -735,11 +733,11 @@
                         return -ERESTARTSYS;
                 }
                 schedule();
-                current-&gt;state = TASK_INTERRUPTIBLE;
+                set_current_state(TASK_INTERRUPTIBLE);
         }
         
         remove_wait_wait(&amp;mouse_wait, &amp;wait);
-        current-&gt;state = TASK_RUNNING;
+        set_current_state(TASK_RUNNING);
   </programlisting>
 
   <para>
@@ -889,18 +887,13 @@
 
   <programlisting>
 struct file_operations our_mouse_fops = {
-        NULL,                   /* Mice don't seek */
-        read_mouse,             /* You can read a mouse */
-        write_mouse,            /* This won't do a lot */
-        NULL,                   /* No readdir - not a directory */
-        poll_mouse,             /* Poll */
-        NULL,                   /* No ioctl calls */
-        NULL,                   /* No mmap */
-        open_mouse,             /* Called on open */
-        NULL,                   /* Flush */
-        close_mouse,            /* Called on close */
-        NULL,                   /* No fsync on a mouse */
-        fasync_mouse,           /* Asynchronous I/O */
+        owner: THIS_MODULE
+        read:  read_mouse,      /* You can read a mouse */
+        write: write_mouse,     /* This won't do a lot */
+        poll:  poll_mouse,      /* Poll */
+        open:  open_mouse,      /* Called on open */
+        release: close_mouse,   /* Called on close */
+        fasync: fasync_mouse,   /* Asynchronous I/O */
 };
   </programlisting>
 
diff -u --recursive --new-file v2.4.10/linux/Documentation/DocBook/tulip-user.tmpl linux/Documentation/DocBook/tulip-user.tmpl
--- v2.4.10/linux/Documentation/DocBook/tulip-user.tmpl	Wed Apr 18 14:40:06 2001
+++ linux/Documentation/DocBook/tulip-user.tmpl	Fri Oct  5 12:06:51 2001
@@ -90,7 +90,7 @@
 
   </chapter>
 
-  <chapter id="drvr_compat">
+  <chapter id="drvr-compat">
     <title>Driver Compatibility</title>
 
 <para>
@@ -111,7 +111,7 @@
 </para>
   </chapter>
 
-  <chapter id="board_settings">
+  <chapter id="board-settings">
     <title>Board-specific Settings</title>
 
 <para>
@@ -129,7 +129,7 @@
 </para>
   </chapter>
 
-  <chapter id="driver_operation">
+  <chapter id="driver-operation">
     <title>Driver Operation</title>
 
 <sect1><title>Ring buffers</title>
diff -u --recursive --new-file v2.4.10/linux/Documentation/arm/SA1100/Assabet linux/Documentation/arm/SA1100/Assabet
--- v2.4.10/linux/Documentation/arm/SA1100/Assabet	Sun Sep 23 11:40:54 2001
+++ linux/Documentation/arm/SA1100/Assabet	Thu Oct  4 15:13:18 2001
@@ -126,7 +126,7 @@
 Using JFFS2
 -----------
 
-Using JFFS2 (the Second Journaling Flash File System) is probably the most
+Using JFFS2 (the Second Journalling Flash File System) is probably the most
 convenient way to store a writable filesystem into flash.  JFFS2 is used in
 conjunction with the MTD layer which is responsible for low-level flash
 management.  More information on the Linux MTD can be found on-line at:
diff -u --recursive --new-file v2.4.10/linux/Documentation/fb/matroxfb.txt linux/Documentation/fb/matroxfb.txt
--- v2.4.10/linux/Documentation/fb/matroxfb.txt	Tue Jul  3 17:08:18 2001
+++ linux/Documentation/fb/matroxfb.txt	Sun Sep 30 12:26:08 2001
@@ -216,6 +216,13 @@
            secondary (TV) output - if DFP is active, TV output must be
 	   inactive and vice versa. DFP always uses same timing as primary
 	   (monitor) output.
+dfp:X    - use settings X for digital flat panel interface. X is number from
+           0 to 0xFF, and meaning of each individual bit is described in
+	   G400 manual, in description of DAC register 0x1F. For normal operation
+	   you should set all bits to zero, except lowest bit. This lowest bit
+	   selects who is source of display clocks, whether G400, or panel.
+	   Default value is now read back from hardware - so you should specify
+	   this value only if you are also using `init' parameter.
 vesa:X   - selects startup videomode. X is number from 0 to 0x1FF, see table
            above for detailed explanation. Default is 640x480x8bpp if driver
 	   has 8bpp support. Otherwise first available of 640x350x4bpp,
@@ -280,6 +287,8 @@
  + interlaced text mode is not supported; it looks like hardware limitation,
    but I'm not sure.
  + Gxx0 SGRAM/SDRAM is not autodetected.
+ + If you are using more than one framebuffer device, you must boot kernel
+   with 'video=scrollback:0'.
  + maybe more...
 And following misfeatures:
  + SVGALib does not restore screen on exit.
diff -u --recursive --new-file v2.4.10/linux/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- v2.4.10/linux/Documentation/filesystems/devfs/ChangeLog	Sun Sep 23 11:40:54 2001
+++ linux/Documentation/filesystems/devfs/ChangeLog	Mon Oct  8 11:38:51 2001
@@ -1755,3 +1755,7 @@
 - Ported to kernel 2.4.10-pre11
 
 - Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>
+===============================================================================
+Changes for patch v193
+
+- Went back to global rwsem for symlinks (refcount scheme no good)
diff -u --recursive --new-file v2.4.10/linux/Documentation/filesystems/fat_cvf.txt linux/Documentation/filesystems/fat_cvf.txt
--- v2.4.10/linux/Documentation/filesystems/fat_cvf.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/filesystems/fat_cvf.txt	Mon Oct  1 13:45:42 2001
@@ -112,7 +112,7 @@
   int (*mount_cvf) (struct super_block*sb,char*options);
   int (*unmount_cvf) (struct super_block*sb);
   [...]
-  void (*cvf_zero_cluster) (struct inode*inode,int clusternr);
+  void (*zero_out_cluster) (struct inode*, int clusternr);
 }
 
 This structure defines the capabilities of a CVF module. It must be filled
@@ -161,8 +161,8 @@
       functions. NULL means use the original FAT driver functions instead.
       If you really want "no action", write a function that does nothing and 
       hang it in instead.
-  - cvf_zero_cluster:
-      The cvf_zero_cluster function is called when the fat driver wants to
+  - zero_out_cluster:
+      The zero_out_cluster function is called when the fat driver wants to
       zero out a (new) cluster. This is important for directories (mkdir).
       If it is NULL, the FAT driver defaults to overwriting the whole
       cluster with zeros. Note that clusternr is absolute, not relative
diff -u --recursive --new-file v2.4.10/linux/Documentation/filesystems/ntfs.txt linux/Documentation/filesystems/ntfs.txt
--- v2.4.10/linux/Documentation/filesystems/ntfs.txt	Sun Sep 23 11:40:54 2001
+++ linux/Documentation/filesystems/ntfs.txt	Sun Sep 30 11:42:44 2001
@@ -98,6 +98,14 @@
 ChangeLog
 =========
 
+NTFS 1.1.20:
+	- Fixed two bugs in ntfs_readwrite_attr(). Thanks to Jan Kara for
+	  spotting the out of bounds one.
+	- Check return value of set_blocksize() in ntfs_read_super() and make
+	  use of get_hardsect_size() to determine the minimum block size.
+	- Fix return values of ntfs_vcn_to_lcn(). This should stop
+	  peoples start of partition being overwritten at random.
+
 NTFS 1.1.19:
 	- Fixed ntfs_getdir_unsorted(), ntfs_readdir() and ntfs_printcb() to
 	  cope with arbitrary cluster sizes. Very important for Win2k+. Also,
diff -u --recursive --new-file v2.4.10/linux/Documentation/networking/8139too.txt linux/Documentation/networking/8139too.txt
--- v2.4.10/linux/Documentation/networking/8139too.txt	Wed Jul 25 17:10:17 2001
+++ linux/Documentation/networking/8139too.txt	Tue Oct  9 15:13:02 2001
@@ -164,7 +164,7 @@
 
 1) Work with Donald to merge fixes and updates into his driver.
 
-2) ethtool support
+2) ETHTOOL_SSET support
 
 3) PPC platform has stability problems. (XXX: verify this is still true)
 
@@ -175,8 +175,6 @@
 
 9) Better documentation.  (patches welcome)
 
-11) RTL8139C support untested.
-
 12) 10base-T support flaky or slow (todo: verify this is still true)
 
 
@@ -184,6 +182,14 @@
 
 Change History
 --------------
+
+Version 0.9.19 - October 9, 2001
+
+* Eliminate buffer copy for unaligned Tx's (manfred)
+* Better RX error recovery (manfred)
+* Wake-On-LAN and ETHTOOL_GSET support (Kalle Niemitalo)
+* Fix assertion in PIO mode (various)
+
 
 Version 0.9.18 - July 6, 2001
 
diff -u --recursive --new-file v2.4.10/linux/Documentation/oops-tracing.txt linux/Documentation/oops-tracing.txt
--- v2.4.10/linux/Documentation/oops-tracing.txt	Tue Oct  3 09:24:41 2000
+++ linux/Documentation/oops-tracing.txt	Sun Sep 30 12:26:08 2001
@@ -201,3 +201,26 @@
 820 4th St. N.
 Fargo, ND  58122
 Phone: 701-234-7556
+
+
+---------------------------------------------------------------------------
+Tainted kernels:
+
+Some oops reports contain the string 'Tainted: ' after the program
+counter, this indicates that the kernel has been tainted by some
+mechanism.  The string is followed by a series of position sensitive
+characters, each representing a particular tainted value.
+
+  1: 'G' if all modules loaded have a GPL or compatible license, 'P' if
+     any proprietary module has been loaded.  Modules without a
+     MODULE_LICENSE or with a MODULE_LICENSE that is not recognised by
+     insmod as GPL compatible are assumed to be proprietary.
+
+  2: 'F' if any module was force loaded by insmod -f, ' ' if all
+     modules were loaded normally.
+
+The primary reason for the 'Tainted: ' string is to tell kernel
+debuggers if this is a clean kernel or if anything unusual has
+occurred.  Tainting is permanent, even if an offending module is
+unloading the tainted value remains to indicate that the kernel is not
+trustworthy.
diff -u --recursive --new-file v2.4.10/linux/Documentation/sysctl/kernel.txt linux/Documentation/sysctl/kernel.txt
--- v2.4.10/linux/Documentation/sysctl/kernel.txt	Mon Jan 10 18:15:58 2000
+++ linux/Documentation/sysctl/kernel.txt	Sun Sep 30 12:26:08 2001
@@ -39,6 +39,7 @@
 - rtsig-max
 - sg-big-buff                 [ generic SCSI device (sg) ]
 - shmmax                      [ sysv ipc ]
+- tainted
 - version
 - zero-paged                  [ PPC only ]
 
@@ -217,6 +218,19 @@
 on the maximum shared memory segment size that can be created.
 Shared memory segments up to 1Gb are now supported in the 
 kernel.  This value defaults to SHMMAX.
+
+==============================================================
+
+tainted: 
+
+Non-zero if the kernel has been tainted.  Numeric values, which
+can be ORed together:
+
+  1 - A module with a non-GPL license has been loaded, this
+      includes modules with no license.
+      Set by modutils >= 2.4.9.
+  2 - A module was force loaded by insmod -f.
+      Set by modutils >= 2.4.9.
 
 ==============================================================
 
diff -u --recursive --new-file v2.4.10/linux/Documentation/usb/CREDITS linux/Documentation/usb/CREDITS
--- v2.4.10/linux/Documentation/usb/CREDITS	Mon Oct  2 12:02:16 2000
+++ linux/Documentation/usb/CREDITS	Fri Oct  5 12:04:50 2001
@@ -8,7 +8,7 @@
   David Brownell <dbrownell@users.sourceforge.net>
   Alan Cox <alan@lxorguk.ukuu.org.uk>
   Randy Dunlap <randy.dunlap@intel.com>
-  Johannes Erdfelt <jerdfelt@sventech.com>
+  Johannes Erdfelt <johannes@erdfelt.com>
   Deti Fliegl <deti@fliegl.de>
   ham <ham@unsuave.com>
   Bradley M Keryan <keryan@andrew.cmu.edu>
diff -u --recursive --new-file v2.4.10/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.10/linux/MAINTAINERS	Sun Sep 23 11:40:54 2001
+++ linux/MAINTAINERS	Fri Oct  5 12:29:28 2001
@@ -132,6 +132,14 @@
 W:	http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
 S:	Maintained
 
+ACP/MWAVE MODEM
+P:	Paul B Schroeder
+M:	paulsch@us.ibm.com
+P:	Mike Sullivan
+M:	sullivam@us.ibm.com
+W:	http://www.ibm.com/linux/ltc/
+S:	Supported
+
 ACPI
 P:	Andy Grover
 M:	andrew.grover@intel.com
@@ -329,6 +337,12 @@
 M:	hpa@zytor.com
 S:	Maintained
 
+CRAMFS FILESYSTEM
+P:	Daniel Quinlan
+M:	quinlan@transmeta.com
+W:	http://sourceforge.net/projects/cramfs/
+S:	Maintained
+
 CREDITS FILE
 P:	John A. Martin
 M:	jam@acm.org
@@ -1473,7 +1487,6 @@
 
 USB HUB
 P:	Johannes Erdfelt
-M:	jerdfelt@valinux.com
 M:	johannes@erdfelt.com
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
@@ -1578,7 +1591,6 @@
 
 USB SUBSYSTEM
 P:	Johannes Erdfelt
-M:	jerdfelt@valinux.com
 M:	johannes@erdfelt.com
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
diff -u --recursive --new-file v2.4.10/linux/Makefile linux/Makefile
--- v2.4.10/linux/Makefile	Sun Sep 23 11:40:54 2001
+++ linux/Makefile	Tue Oct  9 16:43:18 2001
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 10
+SUBLEVEL = 11
 EXTRAVERSION =
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff -u --recursive --new-file v2.4.10/linux/README linux/README
--- v2.4.10/linux/README	Sun Mar 25 18:24:31 2001
+++ linux/README	Fri Oct  5 12:10:00 2001
@@ -192,11 +192,7 @@
    to the place where your regular bootable kernel is found. 
 
    For some, this is on a floppy disk, in which case you can copy the
-   kernel bzImage file to /dev/fd0 to make a bootable floppy. Please note
-   that you can not boot a kernel by directly dumping it to a 720k
-   double-density 3.5" floppy.  In this case, it is highly recommended
-   that you install LILO on your double-density boot floppy or switch to
-   high-density floppies.
+   kernel bzImage file to /dev/fd0 to make a bootable floppy.
 
    If you boot Linux from the hard drive, chances are you use LILO which
    uses the kernel image as specified in the file /etc/lilo.conf.  The
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile
--- v2.4.10/linux/arch/alpha/boot/Makefile	Mon Sep 25 12:36:09 2000
+++ linux/arch/alpha/boot/Makefile	Thu Oct  4 18:47:08 2001
@@ -59,7 +59,7 @@
 	echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T
 ifdef INITRD
 	[ -f $(INITRD) ] || exit 1
-	echo "#define INITRD_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
+	echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
 endif
 	cmp -s $@T $@ || mv -f $@T $@
 	rm -f $@T
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/boot/bootp.c linux/arch/alpha/boot/bootp.c
--- v2.4.10/linux/arch/alpha/boot/bootp.c	Mon Jun 19 17:59:32 2000
+++ linux/arch/alpha/boot/bootp.c	Thu Oct  4 18:47:08 2001
@@ -147,7 +147,7 @@
 	 */
 	static long nbytes;
 	static char envval[256] __attribute__((aligned(8)));
-#ifdef INITRD_SIZE
+#ifdef INITRD_IMAGE_SIZE
 	static unsigned long initrd_start;
 #endif
 
@@ -164,7 +164,7 @@
 	}
 	pal_init();
 
-#ifdef INITRD_SIZE
+#ifdef INITRD_IMAGE_SIZE
 	/* The initrd must be page-aligned.  See below for the 
 	   cause of the magic number 5.  */
 	initrd_start = ((START_ADDR + 5*KERNEL_SIZE) | (PAGE_SIZE-1)) + 1;
@@ -192,17 +192,17 @@
 	 *
 	 * Sigh...  */
 
-#ifdef INITRD_SIZE
-	load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_SIZE);
+#ifdef INITRD_IMAGE_SIZE
+	load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_IMAGE_SIZE);
 #endif
         load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
         load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
 
 	memset((char*)ZERO_PGE, 0, PAGE_SIZE);
 	strcpy((char*)ZERO_PGE, envval);
-#ifdef INITRD_SIZE
+#ifdef INITRD_IMAGE_SIZE
 	((long *)(ZERO_PGE+256))[0] = initrd_start;
-	((long *)(ZERO_PGE+256))[1] = INITRD_SIZE;
+	((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE;
 #endif
 
 	runkernel();
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.4.10/linux/arch/alpha/config.in	Mon Aug 27 12:41:37 2001
+++ linux/arch/alpha/config.in	Thu Oct  4 18:47:08 2001
@@ -142,15 +142,18 @@
 then
 	define_bool CONFIG_ALPHA_EV6 y
 	define_bool CONFIG_ALPHA_TSUNAMI y
+	bool 'EV67 (or later) CPU (speed > 600MHz)?' CONFIG_ALPHA_EV67
 fi
 if [ "$CONFIG_ALPHA_SHARK" = "y" ]
 then
+	define_bool CONFIG_ALPHA_EV6 y
 	define_bool CONFIG_ALPHA_EV67 y
 	define_bool CONFIG_ALPHA_TSUNAMI y
 fi
 if [ "$CONFIG_ALPHA_WILDFIRE" = "y" -o "$CONFIG_ALPHA_TITAN" = "y" ]
 then
-        define_bool CONFIG_ALPHA_EV6 y
+	define_bool CONFIG_ALPHA_EV6 y
+	define_bool CONFIG_ALPHA_EV67 y
 fi
 if [ "$CONFIG_ALPHA_RAWHIDE" = "y" ]
 then
@@ -170,6 +173,7 @@
 then
 	define_bool CONFIG_ALPHA_IRONGATE y
 	define_bool CONFIG_ALPHA_EV6 y
+	define_bool CONFIG_ALPHA_EV67 y
 fi
 
 if [ "$CONFIG_ALPHA_JENSEN" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/kernel/irq_alpha.c linux/arch/alpha/kernel/irq_alpha.c
--- v2.4.10/linux/arch/alpha/kernel/irq_alpha.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/irq_alpha.c	Thu Oct  4 18:47:08 2001
@@ -108,11 +108,6 @@
 	wrent(entInt, 0);
 
 	alpha_mv.init_irq();
-
-	/* If we had wanted SRM console printk echoing early, undo it now. */
-	if (alpha_using_srm && srmcons_output) {
-		unregister_srm_console();
-	}
 }
 
 /*
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v2.4.10/linux/arch/alpha/kernel/process.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -214,7 +214,8 @@
 {
 	printk("\n");
 	printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
-	printk("ps: %04lx pc: [<%016lx>] CPU %d\n", regs->ps, regs->pc, smp_processor_id());
+	printk("ps: %04lx pc: [<%016lx>] CPU %d    %s\n",
+	       regs->ps, regs->pc, smp_processor_id(), print_tainted());
 	printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
 	printk(" r0: %016lx  r1: %016lx  r2: %016lx  r3: %016lx\n",
 	       regs->r0, regs->r1, regs->r2, regs->r3);
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v2.4.10/linux/arch/alpha/kernel/setup.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/alpha/kernel/setup.c	Thu Oct  4 18:47:08 2001
@@ -63,12 +63,20 @@
 /* Which processor we booted from.  */
 int boot_cpuid;
 
-/* Using SRM callbacks for initial console output. This works from
-   setup_arch() time through the end of init_IRQ(), as those places
-   are under our control.
-
-   By default, OFF; set it with a bootcommand arg of "srmcons".
-*/
+/*
+ * Using SRM callbacks for initial console output. This works from
+ * setup_arch() time through the end of time_init(), as those places
+ * are under our (Alpha) control.
+
+ * "srmcons" specified in the boot command arguments allows us to
+ * see kernel messages during the period of time before the true
+ * console device is "registered" during console_init(). As of this
+ * version (2.4.10), time_init() is the last Alpha-specific code
+ * called before console_init(), so we put "unregister" code
+ * there to prevent schizophrenic console behavior later... ;-}
+ *
+ * By default, OFF; set it with a bootcommand arg of "srmcons".
+ */
 int srmcons_output = 0;
 
 /* Enforce a memory size limit; useful for testing. By default, none. */
@@ -85,7 +93,7 @@
 
 static struct alpha_machine_vector *get_sysvec(long, long, long);
 static struct alpha_machine_vector *get_sysvec_byname(const char *);
-static void get_sysnames(long, long, char **, char **);
+static void get_sysnames(long, long, long, char **, char **);
 
 static char command_line[COMMAND_LINE_SIZE];
 char saved_command_line[COMMAND_LINE_SIZE];
@@ -537,14 +545,14 @@
 	/*
 	 * Indentify and reconfigure for the current system.
 	 */
+	cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
+
 	get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
-		     &type_name, &var_name);
+		     cpu->type, &type_name, &var_name);
 	if (*var_name == '0')
 		var_name = "";
 
 	if (!vec) {
-		cpu = (struct percpu_struct*)
-			((char*)hwrpb + hwrpb->processor_offset);
 		vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation,
 				 cpu->type);
 	}
@@ -801,6 +809,8 @@
 		/* Member ID is a bit-field. */
 		long member = (variation >> 10) & 0x3f;
 
+		cpu &= 0xffffffff; /* make it usable */
+
 		switch (type) {
 		case ST_DEC_ALCOR:
 			if (member < N(alcor_indices))
@@ -809,6 +819,10 @@
 		case ST_DEC_EB164:
 			if (member < N(eb164_indices))
 				vec = eb164_vecs[eb164_indices[member]];
+			/* PC164 may show as EB164 variation with EV56 CPU,
+			   but, since no true EB164 had anything but EV5... */
+			if (vec == &eb164_mv && cpu == EV56_CPU)
+				vec = &pc164_mv;
 			break;
 		case ST_DEC_EB64P:
 			if (member < N(eb64p_indices))
@@ -827,21 +841,18 @@
 				vec = tsunami_vecs[tsunami_indices[member]];
 			break;
 		case ST_DEC_1000:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &mikasa_primo_mv;
 			else
 				vec = &mikasa_mv;
 			break;
 		case ST_DEC_NORITAKE:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &noritake_primo_mv;
 			else
 				vec = &noritake_mv;
 			break;
 		case ST_DEC_2100_A500:
-			cpu &= 0xffffffff;
 			if (cpu == EV5_CPU || cpu == EV56_CPU)
 				vec = &sable_gamma_mv;
 			else
@@ -905,7 +916,7 @@
 }
 
 static void
-get_sysnames(long type, long variation,
+get_sysnames(long type, long variation, long cpu,
 	     char **type_name, char **variation_name)
 {
 	long member;
@@ -938,12 +949,18 @@
 
 	member = (variation >> 10) & 0x3f; /* member ID is a bit-field */
 
+	cpu &= 0xffffffff; /* make it usable */
+
 	switch (type) { /* select by family */
 	default: /* default to variation "0" for now */
 		break;
 	case ST_DEC_EB164:
 		if (member < N(eb164_indices))
 			*variation_name = eb164_names[eb164_indices[member]];
+		/* PC164 may show as EB164 variation, but with EV56 CPU,
+		   so, since no true EB164 had anything but EV5... */
+		if (eb164_indices[member] == 0 && cpu == EV56_CPU)
+			*variation_name = eb164_names[1]; /* make it PC164 */
 		break;
 	case ST_DEC_ALCOR:
 		if (member < N(alcor_indices))
@@ -1054,7 +1071,7 @@
 		cpu_name = cpu_names[cpu_index];
 
 	get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
-		     &systype_name, &sysvariation_name);
+		     cpu->type, &systype_name, &sysvariation_name);
 
 	nr_processors = get_nr_processors(cpu, hwrpb->nr_processors);
 
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.4.10/linux/arch/alpha/kernel/smp.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/smp.c	Mon Oct  8 12:37:11 2001
@@ -171,13 +171,6 @@
 	/* Set interrupt vector.  */
 	wrent(entInt, 0);
 
-	/* Setup the scheduler for this processor.  */
-	init_idle();
-
-	/* ??? This should be in init_idle.  */
-	atomic_inc(&init_mm.mm_count);
-	current->active_mm = &init_mm;
-
 	/* Get our local ticker going. */
 	smp_setup_percpu_timer(cpuid);
 
@@ -207,6 +200,12 @@
 	DBGS(("smp_callin: commencing CPU %d current %p\n",
 	      cpuid, current));
 
+	/* Setup the scheduler for this processor.  */
+	init_idle();
+
+	/* ??? This should be in init_idle.  */
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
 	/* Do nothing.  */
 	cpu_idle();
 }
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c
--- v2.4.10/linux/arch/alpha/kernel/sys_cabriolet.c	Wed Jan 24 15:16:23 2001
+++ linux/arch/alpha/kernel/sys_cabriolet.c	Thu Oct  4 18:47:08 2001
@@ -106,12 +106,12 @@
 }
 
 static void __init
-cabriolet_init_irq(void)
+common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r))
 {
 	init_i8259a_irqs();
 
 	if (alpha_using_srm) {
-		alpha_mv.device_interrupt = srm_device_interrupt;
+		alpha_mv.device_interrupt = srm_dev_int;
 		init_srm_irqs(35, 0);
 	}
 	else {
@@ -131,29 +131,47 @@
 	setup_irq(16+4, &isa_cascade_irqaction);
 }
 
+static void __init
+cabriolet_init_irq(void)
+{
+	common_init_irq(srm_device_interrupt);
+}
+
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PC164)
+/* In theory, the PC164 has the same interrupt hardware as the other
+   Cabriolet based systems.  However, something got screwed up late
+   in the development cycle which broke the interrupt masking hardware.
+   Repeat, it is not possible to mask and ack interrupts.  At all.
+
+   In an attempt to work around this, while processing interrupts,
+   we do not allow the IPL to drop below what it is currently.  This
+   prevents the possibility of recursion.  
+
+   ??? Another option might be to force all PCI devices to use edge
+   triggered rather than level triggered interrupts.  That might be
+   too invasive though.  */
+
 static void
-pc164_device_interrupt(unsigned long v, struct pt_regs *r)
+pc164_srm_device_interrupt(unsigned long v, struct pt_regs *r)
 {
-	/* In theory, the PC164 has the same interrupt hardware as
-	   the other Cabriolet based systems.  However, something 
-	   got screwed up late in the development cycle which broke
-	   the interrupt masking hardware.  Repeat, it is not 
-	   possible to mask and ack interrupts.  At all.
-
-	   In an attempt to work around this, while processing 
-	   interrupts, we do not allow the IPL to drop below what
-	   it is currently.  This prevents the possibility of
-	   recursion.  
-
-	   ??? Another option might be to force all PCI devices
-	   to use edge triggered rather than level triggered
-	   interrupts.  That might be too invasive though.  */
+	__min_ipl = getipl();
+	srm_device_interrupt(v, r);
+	__min_ipl = 0;
+}
 
+static void
+pc164_device_interrupt(unsigned long v, struct pt_regs *r)
+{
 	__min_ipl = getipl();
 	cabriolet_device_interrupt(v, r);
 	__min_ipl = 0;
 }
+
+static void __init
+pc164_init_irq(void)
+{
+	common_init_irq(pc164_srm_device_interrupt);
+}
 #endif
 
 /*
@@ -419,7 +437,7 @@
 	device_interrupt:	pc164_device_interrupt,
 
 	init_arch:		cia_init_arch,
-	init_irq:		cabriolet_init_irq,
+	init_irq:		pc164_init_irq,
 	init_rtc:		common_init_rtc,
 	init_pci:		alphapc164_init_pci,
 	pci_map_irq:		alphapc164_map_irq,
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.4.10/linux/arch/alpha/kernel/time.c	Mon Aug 27 12:41:38 2001
+++ linux/arch/alpha/kernel/time.c	Thu Oct  4 18:47:08 2001
@@ -332,6 +332,21 @@
 	alpha_mv.init_rtc();
 
 	do_get_fast_time = do_gettimeofday;
+
+	/*
+	 * If we had wanted SRM console printk echoing early, undo it now.
+	 *
+	 * "srmcons" specified in the boot command arguments allows us to
+	 * see kernel messages during the period of time before the true
+	 * console device is "registered" during console_init(). As of this
+	 * version (2.4.10), time_init() is the last Alpha-specific code
+	 * called before console_init(), so we put this "unregister" code
+	 * here to prevent schizophrenic console behavior later... ;-}
+	 */
+	if (alpha_using_srm && srmcons_output) {
+		unregister_srm_console();
+		srmcons_output = 0;
+	}
 }
 
 /*
diff -u --recursive --new-file v2.4.10/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.4.10/linux/arch/alpha/kernel/traps.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/alpha/kernel/traps.c	Sun Sep 30 12:26:08 2001
@@ -53,8 +53,8 @@
 void
 dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
 {
-	printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx\n",
-	       regs->pc, regs->r26, regs->ps);
+	printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx    %s\n",
+	       regs->pc, regs->r26, regs->ps, print_tainted());
 	printk("v0 = %016lx  t0 = %016lx  t1 = %016lx\n",
 	       regs->r0, regs->r1, regs->r2);
 	printk("t2 = %016lx  t3 = %016lx  t4 = %016lx\n",
diff -u --recursive --new-file v2.4.10/linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- v2.4.10/linux/arch/arm/kernel/process.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/arm/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -158,10 +158,10 @@
 
 	flags = condition_codes(regs);
 
-	printk("pc : [<%08lx>]    lr : [<%08lx>]\n"
+	printk("pc : [<%08lx>]    lr : [<%08lx>]    %s\n"
 	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
 		instruction_pointer(regs),
-		regs->ARM_lr, regs->ARM_sp,
+		regs->ARM_lr, print_tainted(), regs->ARM_sp,
 		regs->ARM_ip, regs->ARM_fp);
 	printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
 		regs->ARM_r10, regs->ARM_r9,
diff -u --recursive --new-file v2.4.10/linux/arch/cris/Makefile linux/arch/cris/Makefile
--- v2.4.10/linux/arch/cris/Makefile	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/Makefile	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.20 2001/07/05 10:07:58 jonashg Exp $
+# $Id: Makefile,v 1.22 2001/10/01 14:42:38 bjornw Exp $
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -29,23 +29,25 @@
               -e s/@CONFIG_ETRAX_DRAM_SIZE_M@/$(CONFIG_ETRAX_DRAM_SIZE)/ \
               < $(LD_SCRIPT) > $(LD_SCRIPT).tmp; \
      else true; \
-     fi && $(CROSS_COMPILE)ld -mcriself
+     fi && $(CROSS_COMPILE)gcc -mlinux -nostdlib
 
-LINKFLAGS =-qmagic -mcriself -T $(LD_SCRIPT).tmp
+LINKFLAGS = -mlinux -T $(LD_SCRIPT).tmp
 
 # objcopy is used to make binary images from the resulting linked file
 
 OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
 
 # normally, gcc on a linux box adds __linux__ but we do it "manually"
-# gcc-cris defaults to a.out, we need ELF, so -melf
+# -mlinux enables -march=v10, -fno-underscores among others
 
-CFLAGS := $(CFLAGS) -march=v10 -fno-strict-aliasing -pipe -D__linux__
+CFLAGS := $(CFLAGS) -mlinux -fno-strict-aliasing -pipe -D__linux__
 
 ifdef CONFIG_ETRAX_KGDB
 CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g
 CFLAGS += -fno-omit-frame-pointer
 endif
+
+AFLAGS += -mlinux
 
 HEAD := arch/cris/kernel/head.o
 
diff -u --recursive --new-file v2.4.10/linux/arch/cris/boot/rescue/Makefile linux/arch/cris/boot/rescue/Makefile
--- v2.4.10/linux/arch/cris/boot/rescue/Makefile	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/rescue/Makefile	Mon Oct  8 11:43:54 2001
@@ -4,9 +4,9 @@
 ifndef TOPDIR
 TOPDIR = ../../../..
 endif
-CC = gcc-cris -I $(TOPDIR)/include
+CC = gcc-cris -mlinux -I $(TOPDIR)/include
 CFLAGS = -O2
-LD = ld-cris
+LD = gcc-cris -mlinux -nostdlib
 OBJCOPY = objcopy-cris
 
 all: rescue.bin testrescue.bin kimagerescue.bin
@@ -48,3 +48,7 @@
 	rm -f *.o *.bin
 
 fastdep:
+
+modules:
+
+modules-install:
diff -u --recursive --new-file v2.4.10/linux/arch/cris/boot/rescue/head.S linux/arch/cris/boot/rescue/head.S
--- v2.4.10/linux/arch/cris/boot/rescue/head.S	Tue May  1 16:04:56 2001
+++ linux/arch/cris/boot/rescue/head.S	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.7 2001/04/18 12:05:07 bjornw Exp $
+/* $Id: head.S,v 1.8 2001/10/03 17:15:15 bjornw Exp $
  * 
  * Rescue code, made to reside at the beginning of the
  * flash-memory. when it starts, it checks a partition
@@ -134,12 +134,12 @@
 	;; change 1's to 0's without erasing the sector, it is possible to add new
 	;; code after this and altering the jumptarget in an upgrade.
 
-jtcd:	move.d	[jumptarget], r0
-	cmp.d	0xffffffff, r0
+jtcd:	move.d	[jumptarget], $r0
+	cmp.d	0xffffffff, $r0
 	beq	no_newjump
 	nop
 	
-	jump	[r0]
+	jump	[$r0]
 
 jumptarget:	
 	.dword	0xffffffff	; can be overwritten later to insert new code
@@ -151,69 +151,69 @@
 	;; we now should go through the checksum-table and check the listed
 	;; partitions for errors.
 	
-	move.d	PTABLE_START, r3
-	move.d	[r3], r0
-	cmp.d	NOP_DI, r0	; make sure the nop/di is there...
+	move.d	PTABLE_START, $r3
+	move.d	[$r3], $r0
+	cmp.d	NOP_DI, $r0	; make sure the nop/di is there...
 	bne	do_rescue
 	nop
 	
 	;; skip the code transparency block (10 bytes).
 
-	addq	10, r3
+	addq	10, $r3
 	
 	;; check for correct magic
 	
-	move.w	[r3+], r0
-	cmp.w	PTABLE_MAGIC, r0
+	move.w	[$r3+], $r0
+	cmp.w	PTABLE_MAGIC, $r0
 	bne	do_rescue	; didn't recognize - trig rescue
 	nop
 
 	;; check for correct ptable checksum
 
-	movu.w	[r3+], r2	; ptable length
-	move.d	r2, r8		; save for later, length of total ptable
-	addq	28, r8		; account for the rest
-	move.d	[r3+], r4	; ptable checksum
-	move.d	r3, r1
+	movu.w	[$r3+], $r2	; ptable length
+	move.d	$r2, $r8	; save for later, length of total ptable
+	addq	28, $r8		; account for the rest
+	move.d	[$r3+], $r4	; ptable checksum
+	move.d	$r3, $r1
 	jsr	checksum	; r1 source, r2 length, returns in r0
 
-	cmp.d	r0, r4
+	cmp.d	$r0, $r4
 	bne	do_rescue	; didn't match - trig rescue
 	nop
 	
 	;; ptable is ok. validate each entry.
 
-	moveq	-1, r7
+	moveq	-1, $r7
 	
-ploop:	move.d	[r3+], r1	; partition offset (from ptable start)
+ploop:	move.d	[$r3+], $r1	; partition offset (from ptable start)
 	bne	notfirst	; check if its the partition containing ptable
 	nop			; yes..
-	move.d	r8, r1		; for its checksum check, skip the ptable
-	move.d	[r3+], r2	; partition length
-	sub.d	r8, r2		; minus the ptable length
+	move.d	$r8, $r1	; for its checksum check, skip the ptable
+	move.d	[$r3+], $r2	; partition length
+	sub.d	$r8, $r2	; minus the ptable length
 	ba	bosse
 	nop
 notfirst:	
-	cmp.d	-1, r1		; the end of the ptable ?
+	cmp.d	-1, $r1		; the end of the ptable ?
 	beq	flash_ok	;   if so, the flash is validated
-	move.d	[r3+], r2	; partition length
-bosse:	move.d	[r3+], r5	; checksum
-	move.d	[r3+], r4	; type and flags
-	addq	16, r3		; skip the reserved bytes
-	btstq	16, r4		; check ro flag
+	move.d	[$r3+], $r2	; partition length
+bosse:	move.d	[$r3+], $r5	; checksum
+	move.d	[$r3+], $r4	; type and flags
+	addq	16, $r3		; skip the reserved bytes
+	btstq	16, $r4		; check ro flag
 	bpl	ploop		;   rw partition, skip validation
 	nop
-	btstq	17, r4		; check bootable flag
+	btstq	17, $r4		; check bootable flag
 	bpl	1f
 	nop
-	move.d	r1, r7		; remember boot partition offset
+	move.d	$r1, $r7	; remember boot partition offset
 1:	
 
-	add.d	PTABLE_START, r1
+	add.d	PTABLE_START, $r1
 	
 	jsr	checksum	; checksum the partition
 	
-	cmp.d	r0, r5
+	cmp.d	$r0, $r5
 	beq	ploop		; checksums matched, go to next entry
 	nop
 
@@ -223,92 +223,92 @@
 	;; setup port PA and PB default initial directions and data
 	;; (so we can flash LEDs, and so that DTR and others are set)
 	
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
-	move.b	r0, [R_PORT_PA_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
-	move.b	r0, [R_PORT_PA_DATA]
-	
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
-	move.b	r0, [R_PORT_PB_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
-	move.b	r0, [R_PORT_PB_DATA]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
+	move.b	$r0, [R_PORT_PA_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
+	move.b	$r0, [R_PORT_PA_DATA]
+	
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
+	move.b	$r0, [R_PORT_PB_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
+	move.b	$r0, [R_PORT_PB_DATA]
 
 	;; setup the serial port at 115200 baud
 	
-	moveq	0, r0
-	move.d	r0, [SERXOFF] 
+	moveq	0, $r0
+	move.d	$r0, [SERXOFF] 
 
-	move.b	0x99, r0
-	move.b	r0, [SERBAUD]		; 115.2kbaud for both transmit and receive
+	move.b	0x99, $r0
+	move.b	$r0, [SERBAUD]		; 115.2kbaud for both transmit and receive
 
-	move.b	0x40, r0		; rec enable
-	move.b	r0, [SERRECC] 
+	move.b	0x40, $r0		; rec enable
+	move.b	$r0, [SERRECC] 
 
-	moveq	0, r1		; "timer" to clock out a LED red flash
-	move.d	CODE_START, r3	; destination counter
-	movu.w	CODE_LENGTH, r4	; length
+	moveq	0, $r1		; "timer" to clock out a LED red flash
+	move.d	CODE_START, $r3	; destination counter
+	movu.w	CODE_LENGTH, $r4; length
 	
 wait_ser:
-	addq	1, r1
+	addq	1, $r1
 #ifndef CONFIG_ETRAX_NO_LEDS
 #ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
 #endif
 #ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
 #endif
-	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), r0
-	btstq	16, r1
+	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
+	btstq	16, $r1
 	bpl	1f
 	nop
-	or.d	r0, r2		; set bit
+	or.d	$r0, $r2	; set bit
 	ba	2f
 	nop
-1:	not	r0		; clear bit
-	and.d	r0, r2
+1:	not	$r0		; clear bit
+	and.d	$r0, $r2
 2:	
 #ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	r2, [R_PORT_PA_DATA]	
+	move.b	$r2, [R_PORT_PA_DATA]	
 #endif	
 #ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	r2, [R_PORT_PB_DATA]	
+	move.b	$r2, [R_PORT_PB_DATA]	
 #endif
 #ifdef CONFIG_ETRAX_90000000_LEDS
-	move.b	r2, [0x90000000]
+	move.b	$r2, [0x90000000]
 #endif
 #endif
 	
 	;; check if we got something on the serial port
 	
-	move.b	[SERSTAT], r0
-	btstq	0, r0		; data_avail
+	move.b	[SERSTAT], $r0
+	btstq	0, $r0		; data_avail
 	bpl	wait_ser
 	nop
 
 	;; got something - copy the byte and loop
 
-	move.b	[SERRDAT], r0
-	move.b	r0, [r3+]
+	move.b	[SERRDAT], $r0
+	move.b	$r0, [$r3+]
 	
-	subq	1, r4		; decrease length
+	subq	1, $r4		; decrease length
 	bne	wait_ser
 	nop
 
 	;; jump into downloaded code
 
-	move.d	RAM_INIT_MAGIC, r8	; Tell next product that DRAM is initialized
+	move.d	RAM_INIT_MAGIC, $r8	; Tell next product that DRAM is initialized
 	jump	CODE_START
 
 flash_ok:
 	;; check r7, which contains either -1 or the partition to boot from
 
-	cmp.d	-1, r7
+	cmp.d	-1, $r7
 	bne	1f
 	nop
-	move.d	PTABLE_START, r7; otherwise use the ptable start
+	move.d	PTABLE_START, $r7; otherwise use the ptable start
 1:
-	move.d	RAM_INIT_MAGIC, r8	; Tell next product that DRAM is initialized
-	jump	r7		; boot!
+	move.d	RAM_INIT_MAGIC, $r8	; Tell next product that DRAM is initialized
+	jump	$r7		; boot!
 
 
 	;; Helper subroutines
@@ -318,9 +318,9 @@
 	;; r2 - length in bytes
 	;; result will be in r0
 checksum:
-	moveq	0, r0
-1:	addu.b	[r1+], r0
-	subq	1, r2
+	moveq	0, $r0
+1:	addu.b	[$r1+], $r0
+	subq	1, $r2
 	bne	1b
 	nop
 	ret
diff -u --recursive --new-file v2.4.10/linux/arch/cris/boot/rescue/kimagerescue.S linux/arch/cris/boot/rescue/kimagerescue.S
--- v2.4.10/linux/arch/cris/boot/rescue/kimagerescue.S	Tue May  1 16:04:56 2001
+++ linux/arch/cris/boot/rescue/kimagerescue.S	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: kimagerescue.S,v 1.4 2001/04/18 12:04:46 bjornw Exp $
+/* $Id: kimagerescue.S,v 1.5 2001/10/03 17:15:15 bjornw Exp $
  * 
  * Rescue code to be prepended on a kimage and copied to the
  * rescue serial port.
@@ -56,15 +56,15 @@
 	;; setup port PA and PB default initial directions and data
 	;; (so we can flash LEDs, and so that DTR and others are set)
 	
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
-	move.b	r0, [R_PORT_PA_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
-	move.b	r0, [R_PORT_PA_DATA]
-	
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
-	move.b	r0, [R_PORT_PB_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
-	move.b	r0, [R_PORT_PB_DATA]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
+	move.b	$r0, [R_PORT_PA_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
+	move.b	$r0, [R_PORT_PA_DATA]
+	
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
+	move.b	$r0, [R_PORT_PB_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
+	move.b	$r0, [R_PORT_PB_DATA]
 	
 	;; We need to setup the bus registers before we start using the DRAM
 #include "../../lib/dram_init.S"
@@ -74,68 +74,68 @@
 	;; We assume 8 MB is the minimum DRAM in an eLinux
 	;; product and put the sp at the top for now.
 
-	move.d	0x40800000, sp
+	move.d	0x40800000, $sp
 	
 	;; setup the serial port at 115200 baud
 	
-	moveq	0, r0
-	move.d	r0, [SERXOFF] 
+	moveq	0, $r0
+	move.d	$r0, [SERXOFF] 
 
-	move.b	0x99, r0
-	move.b	r0, [SERBAUD]		; 115.2kbaud for both transmit and receive
+	move.b	0x99, $r0
+	move.b	$r0, [SERBAUD]		; 115.2kbaud for both transmit and receive
 
-	move.b	0x40, r0		; rec enable
-	move.b	r0, [SERRECC] 
+	move.b	0x40, $r0		; rec enable
+	move.b	$r0, [SERRECC] 
 
 
-	moveq	0, r1		; "timer" to clock out a LED red flash
-	move.d	CODE_START, r3	; destination counter
-	move.d	CODE_LENGTH, r4	; length
-	move.d	TIMEOUT_VALUE, r5	; "timeout" until jump
+	moveq	0, $r1		; "timer" to clock out a LED red flash
+	move.d	CODE_START, $r3	; destination counter
+	move.d	CODE_LENGTH, $r4	; length
+	move.d	TIMEOUT_VALUE, $r5	; "timeout" until jump
 
 wait_ser:
-	addq	1, r1
-	subq	1, r5		; decrease timeout
+	addq	1, $r1
+	subq	1, $r5		; decrease timeout
 	beq	jump_start	; timed out
 	nop
 #ifndef CONFIG_ETRAX_NO_LEDS
 #ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
 #endif
 #ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
 #endif
-	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), r0
-	btstq	16, r1
+	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
+	btstq	16, $r1
 	bpl	1f
 	nop
-	or.d	r0, r2		; set bit
+	or.d	$r0, $r2		; set bit
 	ba	2f
 	nop
-1:	not	r0		; clear bit
-	and.d	r0, r2
+1:	not	$r0		; clear bit
+	and.d	$r0, $r2
 2:	
 #ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	r2, [R_PORT_PA_DATA]
+	move.b	$r2, [R_PORT_PA_DATA]
 #endif	
 #ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	r2, [R_PORT_PB_DATA]
+	move.b	$r2, [R_PORT_PB_DATA]
 #endif
 #endif
 		
 	;; check if we got something on the serial port
 	
-	move.b	[SERSTAT], r0
-	btstq	0, r0		; data_avail
+	move.b	[SERSTAT], $r0
+	btstq	0, $r0		; data_avail
 	bpl	wait_ser
 	nop
 
 	;; got something - copy the byte and loop
 
-	move.b	[SERRDAT], r0
-	move.b	r0, [r3+]
-	move.d	TIMEOUT_VALUE, r5	; reset "timeout"
-	subq	1, r4		; decrease length
+	move.b	[SERRDAT], $r0
+	move.b	$r0, [$r3+]
+	move.d	TIMEOUT_VALUE, $r5	; reset "timeout"
+	subq	1, $r4		; decrease length
 	bne	wait_ser
 	nop
 jump_start:
diff -u --recursive --new-file v2.4.10/linux/arch/cris/boot/rescue/rescue.ld linux/arch/cris/boot/rescue/rescue.ld
--- v2.4.10/linux/arch/cris/boot/rescue/rescue.ld	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/rescue/rescue.ld	Mon Oct  8 11:43:54 2001
@@ -8,13 +8,13 @@
 {
 	.text :
 	{
-		_stext = . ;
+		stext = . ;
 		*(.text)
-		_etext = . ;
+		etext = . ;
 	} > flash
 	.data :
 	{
 		*(.data)
-		_edata = . ;
+		edata = . ;
 	} > flash
 }
diff -u --recursive --new-file v2.4.10/linux/arch/cris/boot/rescue/testrescue.S linux/arch/cris/boot/rescue/testrescue.S
--- v2.4.10/linux/arch/cris/boot/rescue/testrescue.S	Tue May  1 16:04:56 2001
+++ linux/arch/cris/boot/rescue/testrescue.S	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: testrescue.S,v 1.2 2001/04/18 12:05:07 bjornw Exp $
+/* $Id: testrescue.S,v 1.3 2001/10/03 17:15:15 bjornw Exp $
  *
  * Simple testcode to download by the rescue block.
  * Just lits some LEDs to show it was downloaded correctly.
@@ -13,10 +13,10 @@
 
 	nop
 	nop
-	moveq	-1, r2
-	move.b	r2, [R_PORT_PA_DIR]
-	moveq	0, r2
-	move.b	r2, [R_PORT_PA_DATA]	
+	moveq	-1, $r2
+	move.b	$r2, [R_PORT_PA_DIR]
+	moveq	0, $r2
+	move.b	$r2, [R_PORT_PA_DATA]	
 
 endless:
 	nop
diff -u --recursive --new-file v2.4.10/linux/arch/cris/config.in linux/arch/cris/config.in
--- v2.4.10/linux/arch/cris/config.in	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/config.in	Mon Oct  8 11:43:54 2001
@@ -14,6 +14,15 @@
 endmenu
 
 mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
 comment 'General setup'
 
 bool 'Networking support' CONFIG_NET
@@ -49,10 +58,8 @@
 int 'DRAM size (dec, in MB)' CONFIG_ETRAX_DRAM_SIZE 8
 
 int 'Buswidth of flash in bytes' CONFIG_ETRAX_FLASH_BUSWIDTH 2
-bool 'Use flash mirroring (for cramfs)' CONFIG_ETRAX_FLASH_MIRRORING_FOR_CRAMFS
-if [ "$CONFIG_ETRAX_FLASH_MIRRORING_FOR_CRAMFS" = "y" ]; then
-	int '  Individual flash chip size (in MB)' CONFIG_ETRAX_FLASH_SIZE 2
-fi
+
+string 'Root device name' CONFIG_ETRAX_ROOT_DEVICE "/dev/mtdblock3"
 
 choice 'Product LED port' \
 	"Port-PA-LEDs	CONFIG_ETRAX_PA_LEDS	\
diff -u --recursive --new-file v2.4.10/linux/arch/cris/cris.ld linux/arch/cris/cris.ld
--- v2.4.10/linux/arch/cris/cris.ld	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/cris.ld	Mon Oct  8 11:43:54 2001
@@ -11,32 +11,37 @@
 SECTIONS
 {
 	. = @CONFIG_ETRAX_DRAM_VIRTUAL_BASE@;
-	_dram_start = .;
-	_ibr_start = .;
+	dram_start = .;
+	ibr_start = .;
 	. = . + 0x4000; /* see head.S and pages reserved at the start */
 
 	_text = .;                    /* Text and read-only data */
-	_text_start = .;              /* lots of aliases */
+	text_start = .;              /* lots of aliases */
 	_stext = .;
 	__stext = .;
 	.text : {
 		*(.text)
 		*(.fixup)
 		*(.text.__*)
-		*(.rodata)
-		*(.rodata.__*)
 	}
+  	.text.lock : { *(.text.lock) }        /* out-of-line lock text */
+
+	_etext = . ;                  /* End of text section */ 
+	__etext = .;
+
+	.rodata : { *(.rodata) *(.rodata.__*) }
+	.kstrtab : { *(.kstrtab) }
 
 	. = ALIGN(4);                /* Exception table */
   	__start___ex_table = .;
   	__ex_table : { *(__ex_table) }
   	__stop___ex_table = .;
 
-	_etext = . ;                  /* End of text section */ 
-	__etext = .;
+  	__start___ksymtab = .;        /* Kernel symbol table */
+  	__ksymtab : { *(__ksymtab) }
+  	__stop___ksymtab = .;
 
 	. = ALIGN (4);
-	___data_rom_start = . ;
 	___data_start = . ;
 	__Sdata = . ;
 	.data : {                     /* Data */
@@ -49,17 +54,17 @@
   	.data.init_task : { *(.data.init_task) }
 
   	. = ALIGN(8192);              /* Init code and data */
-  	___init_begin = .;
+  	__init_begin = .;
   	.text.init : { *(.text.init) }
   	.data.init : { *(.data.init) }
   	. = ALIGN(16);
-  	___setup_start = .;
+  	__setup_start = .;
   	.setup.init : { *(.setup.init) }
-  	___setup_end = .;
+  	__setup_end = .;
   	.initcall.init : {
-		___initcall_start = .;
+		__initcall_start = .;
 		*(.initcall.init);
-		___initcall_end = .;
+		__initcall_end = .;
 
 		/* We fill to the next page, so we can discard all init
 		   pages without needing to consider what payload might be
@@ -68,7 +73,7 @@
 		. = ALIGN (8192);
 	}
 	__vmlinux_end = .;            /* last address of the physical file */
-  	___init_end = .;
+  	__init_end = .;
 
 	__data_end = . ;              /* Move to _edata ? */
 	__bss_start = .;              /* BSS */
@@ -88,5 +93,5 @@
 		*(.exitcall.exit)
         }
 
-	_dram_end = _dram_start + @CONFIG_ETRAX_DRAM_SIZE_M@*1024*1024;
+	dram_end = dram_start + @CONFIG_ETRAX_DRAM_SIZE_M@*1024*1024;
 }
diff -u --recursive --new-file v2.4.10/linux/arch/cris/defconfig linux/arch/cris/defconfig
--- v2.4.10/linux/arch/cris/defconfig	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/defconfig	Mon Oct  8 11:43:54 2001
@@ -31,6 +31,7 @@
 CONFIG_ETRAX_DRAM_VIRTUAL_BASE=60000000
 CONFIG_ETRAX_DRAM_SIZE=8
 CONFIG_ETRAX_FLASH_BUSWIDTH=2
+CONFIG_ETRAX_ROOT_DEVICE="/dev/mtdblock3"
 CONFIG_ETRAX_PA_LEDS=y
 # CONFIG_ETRAX_PB_LEDS is not set
 # CONFIG_ETRAX_CSP0_LEDS is not set
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/Config.in linux/arch/cris/drivers/Config.in
--- v2.4.10/linux/arch/cris/drivers/Config.in	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/drivers/Config.in	Mon Oct  8 11:43:54 2001
@@ -23,15 +23,17 @@
 
 bool 'Serial-port support' CONFIG_ETRAX_SERIAL
 if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
-  comment '  Port 0 is always enabled'
-  bool '  Ser0 DTR, RI, DSR, CD on PB' CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB
-  if [ "$CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB" = "y" ]; then
-    int '    Ser0 DTR on PB bit' CONFIG_ETRAX_SER0_DTR_ON_PB_BIT 4
-    int '    Ser0 RI  on PB bit' CONFIG_ETRAX_SER0_RI_ON_PB_BIT 5
-    int '    Ser0 DSR on PB bit' CONFIG_ETRAX_SER0_DSR_ON_PB_BIT 6
-    int '    Ser0 CD  on PB bit' CONFIG_ETRAX_SER0_CD_ON_PB_BIT 7
+  bool '  Serial port 0 enabled' CONFIG_ETRAX_SERIAL_PORT0
+  if [ "$CONFIG_ETRAX_SERIAL_PORT0" = "y" ]; then
+    bool '  Ser0 DTR, RI, DSR, CD on PB' CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB
+    if [ "$CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB" = "y" ]; then
+      int '    Ser0 DTR on PB bit' CONFIG_ETRAX_SER0_DTR_ON_PB_BIT 4
+      int '    Ser0 RI  on PB bit' CONFIG_ETRAX_SER0_RI_ON_PB_BIT 5
+      int '    Ser0 DSR on PB bit' CONFIG_ETRAX_SER0_DSR_ON_PB_BIT 6
+      int '    Ser0 CD  on PB bit' CONFIG_ETRAX_SER0_CD_ON_PB_BIT 7
+    fi
   fi
- 
+
   bool '  Serial port 1 enabled' CONFIG_ETRAX_SERIAL_PORT1
   if [ "$CONFIG_ETRAX_SERIAL_PORT1" = "y" ]; then
     bool '  Ser1 DTR, RI, DSR, CD on PB' CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB
@@ -137,6 +139,7 @@
 
 	define_bool CONFIG_MTD_CHAR y
 	define_bool CONFIG_MTD_BLOCK y
+	define_bool CONFIG_MTD_PARTITIONS y
 fi
 
 bool 'I2C support' CONFIG_ETRAX_I2C
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/axisflashmap.c linux/arch/cris/drivers/axisflashmap.c
--- v2.4.10/linux/arch/cris/drivers/axisflashmap.c	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/drivers/axisflashmap.c	Mon Oct  8 11:43:54 2001
@@ -11,6 +11,12 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.14  2001/09/21 07:14:10  jonashg
+ * Made root filesystem (cramfs) use mtdblock driver when booting from flash.
+ *
+ * Revision 1.13  2001/08/15 13:57:35  jonashg
+ * Entire MTD updated to the linux 2.4.7 version.
+ *
  * Revision 1.12  2001/06/11 09:50:30  jonashg
  * Oops, 2MB is 0x200000 bytes.
  *
@@ -84,6 +90,8 @@
 
 #define WINDOW_SIZE  (128 * 1024 * 1024)
 
+extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* From head.S */
+
 /* 
  * Map driver
  *
@@ -229,11 +237,11 @@
 	printk(KERN_NOTICE "Axis flash mapping: %x at %x\n",
 	       WINDOW_SIZE, FLASH_CACHED_ADDR);
 
-	mymtd = (struct mtd_info *)do_cfi_probe(&axis_map);
+	mymtd = (struct mtd_info *)do_map_probe("cfi", &axis_map);
 
 #ifdef CONFIG_MTD_AMDSTD
 	if (!mymtd) {
-		mymtd = (struct mtd_info *)do_amd_flash_probe(&axis_map);
+		mymtd = (struct mtd_info *)do_map_probe("amd_flash", &axis_map);
 	}
 #endif
 
@@ -310,11 +318,23 @@
 		use_default_ptable = !ptable_ok;
 	}
 
-	if(use_default_ptable) {
+	if (use_default_ptable) {
 		printk(" Using default partition table\n");
 		return add_mtd_partitions(mymtd, axis_default_partitions,
 					  NUM_DEFAULT_PARTITIONS);
 	} else {
+		if (romfs_in_flash) {
+			axis_partitions[pidx].name = "romfs";
+			axis_partitions[pidx].size = romfs_length;
+			axis_partitions[pidx].offset = romfs_start -
+						       FLASH_CACHED_ADDR;
+			axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
+
+			printk(" Adding readonly partition for romfs image:\n");
+			printk(pmsg, pidx, axis_partitions[pidx].offset,
+			       axis_partitions[pidx].size);
+			pidx++;
+		}
 		return add_mtd_partitions(mymtd, axis_partitions, pidx);
 	}		
 }
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/ethernet.c linux/arch/cris/drivers/ethernet.c
--- v2.4.10/linux/arch/cris/drivers/ethernet.c	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/drivers/ethernet.c	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: ethernet.c,v 1.17 2001/06/11 12:43:46 olof Exp $
+/* $Id: ethernet.c,v 1.18 2001/10/03 14:40:43 jonashg Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
@@ -7,6 +7,9 @@
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: ethernet.c,v $
+ * Revision 1.18  2001/10/03 14:40:43  jonashg
+ * Update rx_bytes counter.
+ *
  * Revision 1.17  2001/06/11 12:43:46  olof
  * Modified defines for network LED behavior
  *
@@ -833,6 +836,7 @@
 	}
 
 	length += myNextRxDesc->hw_len; /* use hw_len for the last descr */
+	((struct net_local *)dev->priv)->stats.rx_bytes += length;
 
 #ifdef ETHDEBUG
 	printk("Got a packet of length %d:\n", length);
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/lpslave/bintocarr.pl linux/arch/cris/drivers/lpslave/bintocarr.pl
--- v2.4.10/linux/arch/cris/drivers/lpslave/bintocarr.pl	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/drivers/lpslave/bintocarr.pl	Mon Oct  8 11:43:54 2001
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# $Id: bintocarr.pl,v 1.3 2001/06/08 08:46:50 olof Exp $
+# $Id: bintocarr.pl,v 1.4 2001/08/08 08:18:13 bjarne Exp $
 # Copy of mkjulbin.pl made by Olof
 # convert a binary stdin to a C-file containing a char array of the input
 # first argument is the symbol name
@@ -7,7 +7,8 @@
 $symbol = shift @ARGV;
 
 print "#include <linux/init.h>\n\n";
-print "unsigned char $symbol", "[] __initdata = {\n";
+#print "unsigned char $symbol", "[] __initdata = {\n";
+print "unsigned char $symbol", "[]  = {\n";
 
 my $char;
 
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/parport.c linux/arch/cris/drivers/parport.c
--- v2.4.10/linux/arch/cris/drivers/parport.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/cris/drivers/parport.c	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: parport.c,v 1.7 2001/06/25 16:17:30 jonashg Exp $
+/* $Id: parport.c,v 1.8 2001/09/26 11:51:52 bjornw Exp $
  * 
  * Elinux parallel port driver
  * NOTE!
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/serial.c linux/arch/cris/drivers/serial.c
--- v2.4.10/linux/arch/cris/drivers/serial.c	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/drivers/serial.c	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: serial.c,v 1.13 2001/05/09 12:40:31 johana Exp $
+/* $Id: serial.c,v 1.18 2001/09/24 09:27:22 pkj Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
@@ -7,6 +7,30 @@
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.18  2001/09/24 09:27:22  pkj
+ * Completed ext_baud_table[] in cflag_to_baud() and cflag_to_etrax_baud().
+ *
+ * Revision 1.17  2001/08/24 11:32:49  ronny
+ * More fixes for the CONFIG_ETRAX_SERIAL_PORT0 define.
+ *
+ * Revision 1.16  2001/08/24 07:56:22  ronny
+ * Added config ifdefs around ser0 irq requests.
+ *
+ * Revision 1.15  2001/08/16 09:10:31  bjarne
+ * serial.c - corrected the initialization of rs_table, the wrong defines
+ *            where used.
+ *            Corrected a test in timed_flush_handler.
+ *            Changed configured to enabled.
+ * serial.h - Changed configured to enabled.
+ *
+ * Revision 1.14  2001/08/15 07:31:23  bjarne
+ * Introduced two new members to the e100_serial struct.
+ * configured - Will be set to 1 if the port has been configured in .config
+ * uses_dma   - Should be set to 1 if the port uses DMA. Currently it is set to 1
+ *              when a port is opened. This is used to limit the DMA interrupt
+ *              routines to only manipulate DMA channels actually used by the
+ *              serial driver.
+ *
  * Revision 1.13  2001/05/09 12:40:31  johana
  * Use DMA_NBR and IRQ_NBR defines from dma.h and irq.h
  *
@@ -202,7 +226,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.13 $";
+static char *serial_version = "$Revision: 1.18 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -333,28 +357,52 @@
 	  R_DMA_CH6_STATUS, R_DMA_CH6_HWSW,
 	  R_DMA_CH7_CLR_INTR, R_DMA_CH7_FIRST, R_DMA_CH7_CMD,
 	  R_DMA_CH7_STATUS, R_DMA_CH7_HWSW,
-	  STD_FLAGS, DEF_RX, DEF_TX, 2 },  /* ttyS0 */
+	  STD_FLAGS, DEF_RX, DEF_TX, 2,
+#ifdef CONFIG_ETRAX_SERIAL_PORT0
+          1
+#else
+          0
+#endif
+},  /* ttyS0 */
 #ifndef CONFIG_SVINTO_SIM
 	{ DEF_BAUD, (unsigned char *)R_SERIAL1_CTRL, 1U << 16, /* uses DMA 8 and 9 */
 	  R_DMA_CH8_CLR_INTR, R_DMA_CH8_FIRST, R_DMA_CH8_CMD,
 	  R_DMA_CH8_STATUS, R_DMA_CH8_HWSW,
 	  R_DMA_CH9_CLR_INTR, R_DMA_CH9_FIRST, R_DMA_CH9_CMD,
 	  R_DMA_CH9_STATUS, R_DMA_CH9_HWSW,
-	  STD_FLAGS, DEF_RX, DEF_TX, 3 },  /* ttyS1 */
+	  STD_FLAGS, DEF_RX, DEF_TX, 3 ,
+#ifdef CONFIG_ETRAX_SERIAL_PORT1
+          1
+#else
+          0
+#endif
+},  /* ttyS1 */
 
 	{ DEF_BAUD, (unsigned char *)R_SERIAL2_CTRL, 1U << 4,  /* uses DMA 2 and 3 */
 	  R_DMA_CH2_CLR_INTR, R_DMA_CH2_FIRST, R_DMA_CH2_CMD,
 	  R_DMA_CH2_STATUS, R_DMA_CH2_HWSW,
 	  R_DMA_CH3_CLR_INTR, R_DMA_CH3_FIRST, R_DMA_CH3_CMD,
 	  R_DMA_CH3_STATUS, R_DMA_CH3_HWSW,
-	  STD_FLAGS, DEF_RX, DEF_TX, 0 },  /* ttyS2 */
+	  STD_FLAGS, DEF_RX, DEF_TX, 0,
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
+          1
+#else
+          0
+#endif
+ },  /* ttyS2 */
 
 	{ DEF_BAUD, (unsigned char *)R_SERIAL3_CTRL, 1U << 8,  /* uses DMA 4 and 5 */
 	  R_DMA_CH4_CLR_INTR, R_DMA_CH4_FIRST, R_DMA_CH4_CMD,
 	  R_DMA_CH4_STATUS, R_DMA_CH4_HWSW,
 	  R_DMA_CH5_CLR_INTR, R_DMA_CH5_FIRST, R_DMA_CH5_CMD,
 	  R_DMA_CH5_STATUS, R_DMA_CH5_HWSW,
-	  STD_FLAGS, DEF_RX, DEF_TX, 1 }   /* ttyS3 */
+	  STD_FLAGS, DEF_RX, DEF_TX, 1,
+#ifdef CONFIG_ETRAX_SERIAL_PORT3
+          1
+#else
+          0
+#endif
+ }   /* ttyS3 */
 #endif
 };
 
@@ -544,11 +592,12 @@
 	static int baud_table[] = {
 		0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
 		4800, 9600, 19200, 38400 };
-	
+
 	static int ext_baud_table[] = {
-		0, 57600, 115200, 230400, 460800, 921600, 1843200, 6250000 };
-	
-	if(cflag & CBAUDEX)
+		0, 57600, 115200, 230400, 460800, 921600, 1843200, 6250000,
+                0, 0, 0, 0, 0, 0, 0, 0 };
+
+	if (cflag & CBAUDEX)
 		return ext_baud_table[(cflag & CBAUD) & ~CBAUDEX];
 	else 
 		return baud_table[cflag & CBAUD];
@@ -560,19 +609,19 @@
 cflag_to_etrax_baud(unsigned int cflag)
 {
 	char retval;
-	
+
 	static char baud_table[] = {
 		-1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, 3, 4, 5, 6, 7 };
-	
+
 	static char ext_baud_table[] = {
-		-1, 8, 9, 10, 11, 12, 13, 14 };
-	
-	if(cflag & CBAUDEX)
+		-1, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 };
+
+	if (cflag & CBAUDEX)
 		retval = ext_baud_table[(cflag & CBAUD) & ~CBAUDEX];
 	else 
 		retval = baud_table[cflag & CBAUD];
-	
-	if(retval < 0) {
+
+	if (retval < 0) {
 		printk("serdriver tried setting invalid baud rate, flags %x.\n", cflag);
 		retval = 5; /* choose default 9600 instead */
 	}
@@ -1266,6 +1315,8 @@
 	
 	for(i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
+		if (!info->uses_dma) 
+			continue; 
 		/* check for dma_descr (dont need to check for dma_eop in output dma for serial */
 		if(ireg & info->irq) {  
 			/* we can send a new dma bunch. make it so. */
@@ -1303,6 +1354,8 @@
 	
 	for(i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
+		if (!info->uses_dma) 
+			continue; 
 		/* check for both dma_eop and dma_descr for the input dma channel */
 		if(ireg & ((info->irq << 2) | (info->irq << 3))) {
 			/* we have received something */
@@ -1340,7 +1393,7 @@
 	
 	for(i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
-		if(!(info->flags & ASYNC_INITIALIZED))
+		if(!info->enabled || !(info->flags & ASYNC_INITIALIZED))
 			continue;
 
 		/* istatusadr (bit 6-0) hold number of bytes in fifo 
@@ -1394,8 +1447,9 @@
 	unsigned char rstat;
 
 	for(i = 0; i < NR_PORTS; i++) {
-
 		info = rs_table + i;
+		if (!info->uses_dma) 
+			continue; 
 		rstat = info->port[REG_STATUS];
 		
 		if(*R_IRQ_MASK1_RD & (1U << (8+2*info->line))) { /* This line caused the irq */
@@ -1553,6 +1607,7 @@
 	 * Reset the DMA channels and make sure their interrupts are cleared
 	 */
 	
+	info->uses_dma = 1;
 	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 	*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 
@@ -2753,23 +2808,11 @@
 	if (line < 0 || line >= NR_PORTS)
 		return -ENODEV;
 
-	/* dont allow opening ports that are not enabled in the HW config */
-#ifndef CONFIG_ETRAX_SERIAL_PORT1
-	if (line == 1)
-		return -ENODEV;
-#endif
-#ifndef CONFIG_ETRAX_SERIAL_PORT2
-	if (line == 2)
-		return -ENODEV;
-#endif
-#ifndef CONFIG_ETRAX_SERIAL_PORT3
-	if (line == 3)
-		return -ENODEV;
-#endif
-
 	/* find the corresponding e100_serial struct in the table */
 
 	info = rs_table + line;
+	/* dont allow the opening of ports that are not enabled in the HW config */
+	if (!info->enabled) return -ENODEV; 
   
 #ifdef SERIAL_DEBUG_OPEN
 	printk("[%d] rs_open %s%d, count = %d\n", current->pid,
@@ -2911,6 +2954,8 @@
 	len += sprintf(page, "serinfo:1.0 driver:%s\n",
 		       serial_version);
 	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		if (!rs_table[i].enabled) 
+			continue; 
 		l = line_info(page + len, &rs_table[i]);
 		len += l;
 		if (len+begin > off+count)
@@ -3022,6 +3067,7 @@
 	/* do some initializing for the separate ports */
   
 	for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
+		info->uses_dma = 0;   
 		info->line = i;
 		info->tty = 0;
 		info->type = PORT_ETRAX;
@@ -3043,18 +3089,21 @@
 		init_waitqueue_head(&info->close_wait);
 		info->xmit.buf = 0;
 		info->xmit.tail = info->xmit.head = 0;
-
-		printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
-		       serial_driver.name, info->line, (unsigned int)info->port);
+		if (info->enabled) {
+			printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n",
+			       serial_driver.name, info->line, (unsigned int)info->port);
+		}
 	}
 
 #ifndef CONFIG_SVINTO_SIM
 	/* Not needed in simulator.  May only complicate stuff. */
 	/* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
+#ifdef CONFIG_ETRAX_SERIAL_PORT0
 	if(request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL))
 		panic("irq22");
 	if(request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL))
 		panic("irq23");
+#endif
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
 	if(request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
 		panic("irq8");
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/serial.h linux/arch/cris/drivers/serial.h
--- v2.4.10/linux/arch/cris/drivers/serial.h	Tue May  1 16:04:56 2001
+++ linux/arch/cris/drivers/serial.h	Mon Oct  8 11:43:54 2001
@@ -45,7 +45,11 @@
 	u8           rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */
 	u8           tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */
 	u8           iseteop; /* bit number for R_SET_EOP for the input dma */
+	int          enabled;    /* Set to 1 if the port is enabled in HW config */
+  
+  
 /* end of fields defined in rs_table[] in .c-file */
+	int          uses_dma; /* Set to 1 if DMA should be used */
 	unsigned char           fifo_didmagic; /* a fifo eop has been forced */
 
 	struct etrax_dma_descr tr_descr, rec_descr;
diff -u --recursive --new-file v2.4.10/linux/arch/cris/drivers/usb-host.c linux/arch/cris/drivers/usb-host.c
--- v2.4.10/linux/arch/cris/drivers/usb-host.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/cris/drivers/usb-host.c	Mon Oct  8 11:43:54 2001
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2001 Axis Communications AB.
  *
- * $Id: usb-host.c,v 1.9 2001/05/09 12:54:12 johana Exp $
+ * $Id: usb-host.c,v 1.11 2001/09/26 11:52:16 bjornw Exp $
  *
  */
 
@@ -34,7 +34,7 @@
 #define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR
 #define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR
 
-static const char *usb_hcd_version = "$Revision: 1.9 $";
+static const char *usb_hcd_version = "$Revision: 1.11 $";
 
 #undef KERN_DEBUG
 #define KERN_DEBUG ""
@@ -792,6 +792,8 @@
 	cli();
 	
 	if (test_bit(epid, (void *)&ep_usage_bitmask)) {
+		restore_flags(flags);
+
 		warn("Trying to setup used epid %d", epid);
 		DBFEXIT;
 		return;
@@ -828,12 +830,16 @@
 
 	save_flags(flags);
 	cli();
+
 	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
 	nop();
-	while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold))printk("+");
+	while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold))
+		printk("+");
 	*R_USB_EPT_DATA = 0;
 	clear_bit(epid, (void *)&ep_usage_bitmask);
+
 	restore_flags(flags);
+
 	dbg_ep("epid: %d freed", epid);
 	
 	DBFEXIT;
@@ -861,6 +867,8 @@
 			    (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) &&
 			    (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) &&
 			    (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxp)) {
+				restore_flags(flags);
+	
 				dbg_ep("Found ep_id %d for devnum %d, endpoint %d",
 				       i, devnum, endpoint);
 				DBFEXIT;
@@ -1337,6 +1345,7 @@
 	TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_1);
 	TxCtrlEPList[epid].hw_len = 0;
 	TxCtrlEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
+
 	restore_flags(flags);
 
 	dump_ep_desc(&TxCtrlEPList[epid]);
@@ -1775,8 +1784,10 @@
 
 		save_flags(flags);
 		cli();
+
 		*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
 		r_usb_ept_data = *R_USB_EPT_DATA;
+
 		restore_flags(flags);
 
 		if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) {
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/Makefile linux/arch/cris/kernel/Makefile
--- v2.4.10/linux/arch/cris/kernel/Makefile	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/kernel/Makefile	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7 2001/07/05 01:11:48 hp Exp $
+# $Id: Makefile,v 1.8 2001/10/01 14:44:07 bjornw Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -20,6 +20,7 @@
            ptrace.o setup.o time.o sys_cris.o shadows.o \
 	   debugport.o semaphore.o
 
+obj-$(CONFIG_MODULES)    += ksyms.o
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
 
 # This dependency isn't caught by mkdep.  See entry.S.
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- v2.4.10/linux/arch/cris/kernel/entry.S	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/kernel/entry.S	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.31 2001/07/25 16:07:42 bjornw Exp $
+/* $Id: entry.S,v 1.34 2001/10/01 14:45:03 bjornw Exp $
  *
  *  linux/arch/cris/entry.S
  *
@@ -7,6 +7,15 @@
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.34  2001/10/01 14:45:03  bjornw
+ *  Removed underscores and added register prefixes
+ *
+ *  Revision 1.33  2001/08/21 13:48:01  jonashg
+ *  Added fix by HP to avoid oops when doing a hard_reset_now.
+ *
+ *  Revision 1.32  2001/08/14 04:32:02  hp
+ *  In _resume, add comment why R9 is saved; don't sound like it's call-saved.
+ *
  *  Revision 1.31  2001/07/25 16:07:42  bjornw
  *  softirq_active/mask -> softirq_pending only
  *
@@ -166,22 +175,22 @@
 	
 	;; functions exported from this file
 	
-	.globl _system_call
-	.globl _ret_from_intr
-	.globl _ret_from_sys_call
-	.globl _resume
-	.globl _multiple_interrupt
-	.globl _hwbreakpoint
-	.globl _IRQ1_interrupt
-	.globl _timer_interrupt
-	.globl _timer_shortcut
-	.globl _spurious_interrupt
-	.globl _hw_bp_trigs
-	.globl _mmu_bus_fault
-	.globl _do_sigtrap
-	.globl _gdb_handle_breakpoint
+	.globl system_call
+	.globl ret_from_intr
+	.globl ret_from_sys_call
+	.globl resume
+	.globl multiple_interrupt
+	.globl hwbreakpoint
+	.globl IRQ1_interrupt
+	.globl timer_interrupt
+	.globl timer_shortcut
+	.globl spurious_interrupt
+	.globl hw_bp_trigs
+	.globl mmu_bus_fault
+	.globl do_sigtrap
+	.globl gdb_handle_breakpoint
 			
-	.globl _sys_call_table
+	.globl sys_call_table
 	
 	;; Get values and offsets into various structs.  The file isn't
 	;; suitable for consumption by the preprocessor, so don't use
@@ -196,38 +205,38 @@
 	
 	;; handle software irqs
 				
-handle_softirq:
-	move.d	r9,r1
-	jsr	_do_softirq		; call the C routine for softirq handling
-	move.d	r1,r9
+_handle_softirq:
+	move.d	$r9, $r1
+	jsr	do_softirq	; call the C routine for softirq handling
+	move.d	$r1, $r9
 
 	;; fall-through
 	
-_ret_from_intr:
+ret_from_intr:
 	;; check for resched only if we're going back to user-mode
 
-	move	ccr, r0
-	btstq	8, r0		; U-flag
-	bpl	Rexit		; go back directly
+	move	$ccr, $r0
+	btstq	8, $r0		; U-flag
+	bpl	_Rexit		; go back directly
 	nop
-	ba	ret_with_reschedule  ; go back but check schedule and signals first 
+	ba	_ret_with_reschedule  ; go back but check schedule and signals first 
 	nop
 
-reschedule:
+_reschedule:
 	;; keep r9 intact
-	move.d	r9,r1
-	jsr	_schedule
-	ba	_ret_from_sys_call
-	move.d	r1,r9
+	move.d	$r9, $r1
+	jsr	schedule
+	ba	ret_from_sys_call
+	move.d	$r1, $r9
 
 	;; return but call do_signal first
-signal_return:
+_signal_return:
 	ei			; we can get here from an interrupt
-	move.d	r9,r10		; do_signals syscall/irq param
-	moveq	0,r11		; oldset param - 0 in this case
-	move.d	sp,r12		; another argument to do_signal (the regs param)
-	jsr	_do_signal	; arch/cris/kernel/signal.c
-	ba	Rexit
+	move.d	$r9, $r10	; do_signals syscall/irq param
+	moveq	0, $r11		; oldset param - 0 in this case
+	move.d	$sp, $r12	; another argument to do_signal (the regs param)
+	jsr	do_signal	; arch/cris/kernel/signal.c
+	ba	_Rexit
 	nop
 	
 	;; The system_call is called by a BREAK instruction, which works like
@@ -246,112 +255,114 @@
 	;; really designed so that the fast-path does not force cache-loading of non-used
 	;; instructions. Only the non-common cases cause the outlined code to run..
 
-_system_call:
+system_call:
 	;; stack-frame similar to the irq heads, which is reversed in ret_from_sys_call
-	move	brp,[sp=sp-16]	; instruction pointer and room for a fake SBFS frame
-	push	srp
-	push	dccr
-	push	mof
-	subq	14*4,sp		; make room for r0-r13
-	movem	r13,[sp]	; push r0-r13
-	push	r10		; push orig_r10
-	clear.d [sp=sp-4]	; frametype == 0, normal stackframe
+	move	$brp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame
+	push	$srp
+	push	$dccr
+	push	$mof
+	subq	14*4, $sp		; make room for r0-r13
+	movem	$r13, [$sp]	; push r0-r13
+	push	$r10		; push orig_r10
+	clear.d [$sp=$sp-4]	; frametype == 0, normal stackframe
 	
-	movs.w	-ENOSYS,r0
-	move.d	r0,[sp+LR10]	; put the default return value in r10 in the frame
+	movs.w	-ENOSYS, $r0
+	move.d	$r0, [$sp+LR10]	; put the default return value in r10 in the frame
 
 	;; check if this process is syscall-traced
 
-	movs.w	-8192,r0	; THREAD_SIZE == 8192
-	and.d	sp,r0
+	movs.w	-8192, $r0	; THREAD_SIZE == 8192
+	and.d	$sp, $r0
 	
-	move.d	[r0+LTASK_PTRACE],r0
-	btstq	PT_TRACESYS_BIT, r0
-	bmi	tracesys
+	move.d	[$r0+LTASK_PTRACE], $r0
+	btstq	PT_TRACESYS_BIT, $r0
+	bmi	_tracesys
 	nop	
 
 	;; check for sanity in the requested syscall number
 	
-	cmpu.w	NR_syscalls,r9	
-	bcc	_ret_from_sys_call
-	lslq	2,r9		;  multiply by 4, in the delay slot
+	cmpu.w	NR_syscalls, $r9	
+	bcc	ret_from_sys_call
+	lslq	2, $r9		;  multiply by 4, in the delay slot
 
 	;; as a bonus 7th parameter, we give the location on the stack
 	;; of the register structure itself. some syscalls need this.
 
-	push	sp
+	push	$sp
 	
 	;; the parameter carrying registers r10, r11, r12 and 13 are intact.
 	;; the fifth and sixth parameters (if any) was in mof and srp 
 	;; respectively, and we need to put them on the stack.
 
-	push	srp
-	push	mof
+	push	$srp
+	push	$mof
 	
-	jsr	[r9+_sys_call_table]	; actually do the system call
-	addq	3*4,sp			; pop the mof, srp and regs parameters
-	move.d	r10,[sp+LR10]		; save the return value
+	jsr	[$r9+sys_call_table]	; actually do the system call
+	addq	3*4, $sp		; pop the mof, srp and regs parameters
+	move.d	$r10, [$sp+LR10]	; save the return value
 
-	moveq	1,r9		; "parameter" to ret_from_sys_call to show it was a sys call
+	moveq	1, $r9		; "parameter" to ret_from_sys_call to show it was a sys call
 	
 	;; fall through into ret_from_sys_call to return
 	
-_ret_from_sys_call:
+ret_from_sys_call:
 	;; r9 is a parameter - if 1, we came from a syscall, if 0, from an irq
 		
 	;; check if any bottom halves need service
 	
-	test.d	[_irq_stat]	       ; softirq_pending
-	bne	handle_softirq
+	test.d	[irq_stat]	       ; softirq_pending
+	bne	_handle_softirq
 	nop
 
-ret_with_reschedule:
+_ret_with_reschedule:
 	;; first get the current task-struct pointer (see top for defs)
 
-	move.d	sp, r0
-	and.d	-8192, r0	; THREAD_SIZE == 8192
+	move.d	$sp, $r0
+	and.d	-8192, $r0	; THREAD_SIZE == 8192
 	
 	;; see if we want to reschedule into another process
 	
-	test.d	[r0+LTASK_NEEDRESCHED]
-	bne	reschedule
+	test.d	[$r0+LTASK_NEEDRESCHED]
+	bne	_reschedule
 	nop
 
 	;; see if we need to run signal checks (important that r9 is intact here)
 
-	test.d	[r0+LTASK_SIGPENDING]
-	bne	signal_return
+	test.d	[$r0+LTASK_SIGPENDING]
+	bne	_signal_return
 	nop
 	
-Rexit:
+_Rexit:
 	;; this epilogue MUST match the prologues in multiple_interrupt, irq.h and ptregs.h
-	pop	r10		; frametype
-	bne	RBFexit		; was not CRIS_FRAME_NORMAL, handle otherwise
-	addq	4,sp		; skip orig_r10, in delayslot
-	movem	[sp+],r13	; registers r0-r13
-	pop	mof		; multiply overflow register 
-	pop	dccr		; condition codes
-	pop	srp		; subroutine return pointer
+	pop	$r10		; frametype
+	bne	_RBFexit	; was not CRIS_FRAME_NORMAL, handle otherwise
+	addq	4, $sp		; skip orig_r10, in delayslot
+	movem	[$sp+], $r13	; registers r0-r13
+	pop	$mof		; multiply overflow register 
+	pop	$dccr		; condition codes
+	pop	$srp		; subroutine return pointer
 	;; now we have a 4-word SBFS frame which we do not want to restore
 	;; using RBF since it was not stacked with SBFS. instead we would like to
 	;; just get the PC value to restart it with, and skip the rest of
 	;; the frame.
-	move	[sp=sp+16], p8	; pop the SBFS frame from the sp
-	jmpu	[sp-16]		; return through the irp field in the sbfs frame
+	;; Also notice that it's important to use instructions here that
+	;; keep the interrupts disabled (since we've already popped DCCR)
+	move	[$sp=$sp+16], $p8; pop the SBFS frame from the sp
+	jmpu	[$sp-16]	; return through the irp field in the sbfs frame
+
+_RBFexit:
+	movem	[$sp+], $r13	; registers r0-r13, in delay slot
+	pop	$mof		; multiply overflow register 
+	pop	$dccr		; condition codes
+	pop	$srp		; subroutine return pointer
+	rbf	[$sp+]		; return by popping the CPU status
 
-RBFexit:
-	movem	[sp+],r13	; registers r0-r13, in delay slot
-	pop	mof		; multiply overflow register 
-	pop	dccr		; condition codes
-	pop	srp		; subroutine return pointer
-	rbf	[sp+]		; return by popping the CPU status
-
-tracesys:
+_tracesys:
 	;; this first invocation of syscall_trace _requires_ that
 	;; LR10 in the frame contains -ENOSYS (as is set in the beginning
 	;; of system_call).
 
-	jsr	_syscall_trace
+	jsr	syscall_trace
 
 	;; now we should more or less do the same things as in the system_call
 	;; but since our argument regs got clobbered during syscall_trace and
@@ -360,177 +371,188 @@
 
 	;; check for sanity in the requested syscall number
 
-	move.d	[sp+LR9], r9
-	movs.w	-ENOSYS, r10
-	cmpu.w	NR_syscalls,r9	
+	move.d	[$sp+LR9], $r9
+	movs.w	-ENOSYS, $r10
+	cmpu.w	NR_syscalls, $r9	
 	bcc	1f
-	lslq	2,r9		;  multiply by 4, in the delay slot
+	lslq	2, $r9		;  multiply by 4, in the delay slot
 
 	;; read the system call vector entry into r9
 	
-	move.d	[r9+_sys_call_table],r9
+	move.d	[$r9+sys_call_table], $r9
 
 	;; restore r10, r11, r12, r13, mof and srp into the needed registers
 
-	move.d	[sp+LORIG_R10], r10  ; LR10 is already filled with -ENOSYS.
-	move.d	[sp+LR11],      r11
-	move.d	[sp+LR12],      r12
-	move.d	[sp+LR13],      r13
-	move	[sp+LMOF],      mof
-	move	[sp+LSRP],      srp
+	move.d	[$sp+LORIG_R10], $r10  ; LR10 is already filled with -ENOSYS.
+	move.d	[$sp+LR11],      $r11
+	move.d	[$sp+LR12],      $r12
+	move.d	[$sp+LR13],      $r13
+	move	[$sp+LMOF],      $mof
+	move	[$sp+LSRP],      $srp
 
 	;; as a bonus 7th parameter, we give the location on the stack
 	;; of the register structure itself. some syscalls need this.
 
-	push	sp
+	push	$sp
 	
 	;; the fifth and sixth parameters needs to be put on the stack for
 	;; the system call to find them
 
-	push	srp
-	push	mof
+	push	$srp
+	push	$mof
 
-	jsr	r9		; actually call the system-call
-	addq	3*4,sp		; pop the srp, mof and regs parameters
+	jsr	$r9		; actually call the system-call
+	addq	3*4, $sp	; pop the srp, mof and regs parameters
 
-1:	move.d	r10,[sp+LR10]	; save the return value
+1:	move.d	$r10, [$sp+LR10]; save the return value
 
 	;; second call of syscall_trace, to let it grab the results
 		
-	jsr	_syscall_trace
+	jsr	syscall_trace
 
-	moveq	1,r9		; "parameter" to ret_from_sys_call to show it was a sys call
-	ba	_ret_from_sys_call
+	moveq	1, $r9		; "parameter" to ret_from_sys_call to show it was a sys call
+	ba	ret_from_sys_call
 	nop
 		
-	;; _resume performs the actual task-switching, by switching stack pointers
+	;; resume performs the actual task-switching, by switching stack pointers
 	;; input arguments: r10 = prev, r11 = next, r12 = thread offset in task struct
 	;; returns old current in r10
 	;;
 	;; TODO:  see the i386 version. The switch_to which calls resume in our version
 	;;        could really be an inline asm of this.
 
-_resume:	
-	push	srp		         ; we keep the old/new PC on the stack 
-	add.d	r12, r10		 ; r10 = current tasks tss
-	move	dccr, [r10+LTHREAD_DCCR] ; save irq enable state
+resume:	
+	push	$srp		         ; we keep the old/new PC on the stack 
+	add.d	$r12, $r10		 ; r10 = current tasks tss
+	move	$dccr, [$r10+LTHREAD_DCCR] ; save irq enable state
 	di
 
-	move	usp, [r10+LTHREAD_USP]	 ; save user-mode stackpointer
+	move	$usp, [$r10+LTHREAD_USP] ; save user-mode stackpointer
 	
-	subq	10*4, sp
-	movem	r9, [sp]		 ; save non-scratch registers
+	;; See copy_thread for the reason why register R9 is saved.
+	subq	10*4, $sp
+	movem	$r9, [$sp]		 ; save non-scratch registers and R9.
 	
-	move.d	sp, [r10+LTHREAD_KSP]	 ; save the kernel stack pointer for the old task
-	move.d	sp, r10			 ; return last running task in r10
-	and.d   -8192, r10	         ; get task ptr from stackpointer
-	add.d	r12, r11		 ; find the new tasks tss
-	move.d	[r11+LTHREAD_KSP], sp	 ; switch into the new stackframe by restoring kernel sp
+	move.d	$sp, [$r10+LTHREAD_KSP]	 ; save the kernel stack pointer for the old task
+	move.d	$sp, $r10		 ; return last running task in r10
+	and.d   -8192, $r10	         ; get task ptr from stackpointer
+	add.d	$r12, $r11		 ; find the new tasks tss
+	move.d	[$r11+LTHREAD_KSP], $sp	 ; switch into the new stackframe by restoring kernel sp
 
-	movem	[sp+], r9		 ; restore non-scratch registers
+	movem	[$sp+], $r9		 ; restore non-scratch registers and R9.
 
-	move	[r11+LTHREAD_USP], usp	 ; restore user-mode stackpointer
+	move	[$r11+LTHREAD_USP], $usp ; restore user-mode stackpointer
 	
-	move	[r11+LTHREAD_DCCR], dccr ; restore irq enable status
-	jump	[sp+]		         ; restore PC
+	move	[$r11+LTHREAD_DCCR], $dccr ; restore irq enable status
+	jump	[$sp+]		         ; restore PC
 
 	;; This is the MMU bus fault handler.
 	;; It needs to stack the CPU status and overall is different
 	;; from the other interrupt handlers.
 
-_mmu_bus_fault:	
-	sbfs	[sp=sp-16]	; push the internal CPU status
+mmu_bus_fault:	
+	sbfs	[$sp=$sp-16]	; push the internal CPU status
 	;; the first longword in the sbfs frame was the interrupted PC
 	;; which fits nicely with the "IRP" slot in pt_regs normally used to
 	;; contain the return address. used by Oops to print kernel errors..
-	push	srp		; make a stackframe similar to pt_regs
-	push	dccr
-	push	mof
+	push	$srp		; make a stackframe similar to pt_regs
+	push	$dccr
+	push	$mof
 	di
-	subq	14*4, sp
-	movem	r13, [sp]
-	push	r10		; dummy orig_r10
-	moveq	1, r10
-	push	r10		; frametype == 1, BUSFAULT frame type
+	subq	14*4, $sp
+	movem	$r13, [$sp]
+	push	$r10		; dummy orig_r10
+	moveq	1, $r10
+	push	$r10		; frametype == 1, BUSFAULT frame type
 
-	moveq	0, r9		; busfault is equivalent to an irq
+	moveq	0, $r9		; busfault is equivalent to an irq
 		
-	move.d	sp, r10		; pt_regs argument to handle_mmu_bus_fault
+	move.d	$sp, $r10	; pt_regs argument to handle_mmu_bus_fault
 		
-	jsr	_handle_mmu_bus_fault  ; in arch/cris/mm/fault.c
+	jsr	handle_mmu_bus_fault  ; in arch/cris/mm/fault.c
 
 	;; now we need to return through the normal path, we cannot just
 	;; do the RBFexit since we might have killed off the running
 	;; process due to a SEGV, scheduled due to a page blocking or
 	;; whatever.
 
-	ba	_ret_from_intr
+	ba	ret_from_intr
 	nop
 		
 	;; special handlers for breakpoint and NMI
 #if 0			
-_hwbreakpoint:
-	push	dccr
+hwbreakpoint:
+	push	$dccr
 	di
-	push	r10
-	push	r11
-	push	r12
-	push	r13
+	push	$r10
+	push	$r11
+	push	$r12
+	push	$r13
 	clearf	b
-	move	brp,r11
-	move.d	[_hw_bp_msg],r10
-	jsr	_printk
+	move	$brp,$r11
+	move.d	[hw_bp_msg],$r10
+	jsr	printk
 	setf	b
-	pop	r13
-	pop	r12
-	pop	r11
-	pop	r10
-	pop	dccr
+	pop	$r13
+	pop	$r12
+	pop	$r11
+	pop	$r10
+	pop	$dccr
 	retb
 	nop
 #else
-_hwbreakpoint:
-	push	dccr
+hwbreakpoint:
+	push	$dccr
 	di
 #if 1
-	push	r10
-	push	r11
-	move.d	[_hw_bp_trig_ptr],r10
-	move.d	[r10],r11
-	cmp.d	42,r11
-	beq	nobp
-	nop
-	move	brp,r11
-	move.d	r11,[r10+]
-	move.d	r10,[_hw_bp_trig_ptr]
-nobp:	pop	r11
-	pop	r10
+	push	$r10
+	push	$r11
+	move.d	[hw_bp_trig_ptr],$r10
+	move.d	[$r10],$r11
+	cmp.d	42,$r11
+	beq	1f
+	nop
+	move	$brp,$r11
+	move.d	$r11,[$r10+]
+	move.d	$r10,[hw_bp_trig_ptr]
+1:	pop	$r11
+	pop	$r10
 #endif
-	pop	dccr
+	pop	$dccr
 	retb
 	nop
 #endif
 	
-_IRQ1_interrupt:
+IRQ1_interrupt:
 
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
 ;; If we receive a watchdog interrupt while it is not expected, then set
 ;; up a canonical frame and dump register contents before dying.
 
 	;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!!
-	move	brp,[sp=sp-16]	; instruction pointer and room for a fake SBFS frame
-	push	srp
-	push	dccr
-	push	mof
+	move	$brp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame
+	push	$srp
+	push	$dccr
+	push	$mof
 	di
-	subq	14*4,sp
-	movem	r13,[sp]
-	push	r10		; push orig_r10
-	clear.d [sp=sp-4]	; frametype == 0, normal frame
+	subq	14*4, $sp
+	movem	$r13, [$sp]
+	push	$r10		; push orig_r10
+	clear.d [$sp=$sp-4]	; frametype == 0, normal frame
 
 ;; We don't check that we actually were bit by the watchdog as opposed to
 ;; an external NMI, since there is currently no handler for external NMI.
 
+;; Check if we're waiting for reset to happen, as signalled by
+;; hard_reset_now setting cause_of_death to a magic value.  If so, just
+;; get stuck until reset happens.
+	.comm	cause_of_death, 4	;; Don't declare this anywhere.
+	move.d	[cause_of_death], $r10
+	cmp.d	0xbedead, $r10
+_killed_by_death:
+	beq	_killed_by_death
+	nop
+
 ;; We'll see this in ksymoops dumps.
 Watchdog_bite:
 
@@ -540,134 +562,134 @@
 ;; Change the watchdog key to an arbitrary 3-bit value and restart the
 ;; watchdog.
 #define WD_INIT 2
-	moveq	  IO_FIELD (R_WATCHDOG, key, WD_INIT), r10
-	move.d	R_WATCHDOG, r11
+	moveq	  IO_FIELD (R_WATCHDOG, key, WD_INIT), $r10
+	move.d	R_WATCHDOG, $r11
 
-	move.d	r10,[r11]
+	move.d	$r10, [$r11]
 	moveq	  IO_FIELD (R_WATCHDOG, key,				\
 			    IO_EXTRACT (R_WATCHDOG, key,		\
 					IO_MASK (R_WATCHDOG, key))	\
 			    ^ WD_INIT)					\
-		| IO_STATE (R_WATCHDOG, enable, start),r10
-	move.d	r10,[r11]
+		| IO_STATE (R_WATCHDOG, enable, start), $r10
+	move.d	$r10, [$r11]
 
 ;; Note that we don't do "setf m" here (or after two necessary NOPs),
 ;; since *not* doing that saves us from re-entrancy checks.  We don't want
 ;; to get here again due to possible subsequent NMIs; we want the watchdog
 ;; to reset us.
 
-	move.d	watchdogmsg,r10
-	jsr	_printk
+	move.d	_watchdogmsg,$r10
+	jsr	printk
 
-	move.d	sp,r10
-	jsr	_show_registers
+	move.d	$sp, $r10
+	jsr	show_registers
 
 ;; This nop is here so we see the "Watchdog_bite" label in ksymoops dumps
-;; rather than "_spurious_interrupt".
+;; rather than "spurious_interrupt".
 	nop
-;; At this point we drop down into _spurious_interrupt, which will do a
+;; At this point we drop down into spurious_interrupt, which will do a
 ;; hard reset.
 
 	.section .rodata,"a"
-watchdogmsg:
+_watchdogmsg:
 	.ascii	"Oops: bitten by watchdog\n\0"
 	.previous
 
 #endif /* CONFIG_ETRAX_WATCHDOG and not CONFIG_SVINTO_SIM */
 
-_spurious_interrupt:	
+spurious_interrupt:	
 	di
-	jump _hard_reset_now
+	jump hard_reset_now
 
 	;; this handles the case when multiple interrupts arrive at the same time
 	;; we jump to the first set interrupt bit in a priority fashion
 	;; the hardware will call the unserved interrupts after the handler finishes
 	
-_multiple_interrupt:
+multiple_interrupt:
 	;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!!
-	move	irp,[sp=sp-16]	; instruction pointer and room for a fake SBFS frame
-	push	srp
-	push	dccr
-	push	mof
+	move	$irp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame
+	push	$srp
+	push	$dccr
+	push	$mof
 	di
-	subq	14*4,sp
-	movem	r13,[sp]
-	push	r10		; push orig_r10
-	clear.d [sp=sp-4]	; frametype == 0, normal frame
-	
-	move.d	_irq_shortcuts + 8,r1
-	moveq	2,r2		; first bit we care about is the timer0 irq
-	move.d	[R_VECT_MASK_RD],r0	; read the irq bits that triggered the multiple irq
-multloop:	
-	btst	r2,r0		; check for the irq given by bit r2
-	bmi	do_shortcut	; actually do the shortcut
-	nop
-	addq	1,r2		; next vector bit
-	addq	4,r1		; next vector
-	cmp.b	32,r2
-	bne	multloop	; process all irq's up to and including number 31
+	subq	14*4, $sp
+	movem	$r13, [$sp]
+	push	$r10		; push orig_r10
+	clear.d [$sp=$sp-4]	; frametype == 0, normal frame
+	
+	move.d	irq_shortcuts + 8, $r1
+	moveq	2, $r2		; first bit we care about is the timer0 irq
+	move.d	[R_VECT_MASK_RD], $r0; read the irq bits that triggered the multiple irq
+1:	
+	btst	$r2, $r0	; check for the irq given by bit r2
+	bmi	_do_shortcut	; actually do the shortcut
+	nop
+	addq	1, $r2		; next vector bit
+	addq	4, $r1		; next vector
+	cmp.b	32, $r2
+	bne	1b	; process all irq's up to and including number 31
 	nop
 	
 	;; strange, we didn't get any set vector bits.. oh well, just return
 	
-	ba	Rexit
+	ba	_Rexit
 	nop
 
-do_shortcut:
-	test.d	[r1]
-	beq	Rexit
+_do_shortcut:
+	test.d	[$r1]
+	beq	_Rexit
 	nop
-	jump	[r1]		; jump to the irq handlers shortcut
+	jump	[$r1]		; jump to the irq handlers shortcut
 
-_do_sigtrap:
+do_sigtrap:
 	;; 
 	;; SIGTRAP the process that executed the break instruction.
 	;; Make a frame that Rexit in entry.S expects.
 	;;
-	move	brp,[sp=sp-16]		; Push BRP while faking a cpu status record.
-	push	srp			; Push subroutine return pointer.
-	push	dccr			; Push condition codes.
-	push	mof			; Push multiply overflow reg.
+	move	$brp, [$sp=$sp-16]	; Push BRP while faking a cpu status record.
+	push	$srp			; Push subroutine return pointer.
+	push	$dccr			; Push condition codes.
+	push	$mof			; Push multiply overflow reg.
 	di				; Need to disable irq's at this point.
-	subq	14*4,sp			; Make room for r0-r13.
-	movem	r13,[sp]		; Push the r0-r13 registers.
-	push	r10			; Push orig_r10.
-	clear.d	[sp=sp-4]		; Frametype - this is a normal stackframe.
-
-	movs.w	-8192,r9		; THREAD_SIZE == 8192
-	and.d	sp,r9
-	move.d	[r9+LTASK_PID],r10	; current->pid as arg1.
-	moveq	5,r11			; SIGTRAP as arg2.
-	jsr	_sys_kill       
-	jump	_ret_from_intr		; Use the return routine for interrupts.
-
-_gdb_handle_breakpoint:	
-	push	dccr
-	push	r0
+	subq	14*4, $sp		; Make room for r0-r13.
+	movem	$r13, [$sp]		; Push the r0-r13 registers.
+	push	$r10			; Push orig_r10.
+	clear.d	[$sp=$sp-4]		; Frametype - this is a normal stackframe.
+
+	movs.w	-8192,$r9		; THREAD_SIZE == 8192
+	and.d	$sp, $r9
+	move.d	[$r9+LTASK_PID], $r10	; current->pid as arg1.
+	moveq	5, $r11			; SIGTRAP as arg2.
+	jsr	sys_kill       
+	jump	ret_from_intr		; Use the return routine for interrupts.
+
+gdb_handle_breakpoint:	
+	push	$dccr
+	push	$r0
 #ifdef CONFIG_ETRAX_KGDB
-	move	dccr,r0			; U-flag not affected by previous insns. 
-	btstq	8,r0			; Test the U-flag.
+	move	$dccr, $r0		; U-flag not affected by previous insns. 
+	btstq	8, $r0			; Test the U-flag.
 	bmi	_ugdb_handle_breakpoint	; Go to user mode debugging. 
 	nop				; Empty delay slot (cannot pop r0 here). 
-	pop	r0			; Restore r0.
-	ba	_kgdb_handle_breakpoint	; Go to kernel debugging. 
-	pop	dccr			; Restore dccr in delay slot.
+	pop	$r0			; Restore r0.
+	ba	kgdb_handle_breakpoint	; Go to kernel debugging. 
+	pop	$dccr			; Restore dccr in delay slot.
 #endif
 	
 _ugdb_handle_breakpoint:	
-	move	brp,r0			; Use r0 temporarily for calculation.
-	subq	2,r0			; Set to address of previous instruction.
-	move	r0,brp
-	pop	r0			; Restore r0. 
-	ba	_do_sigtrap		; SIGTRAP the offending process. 
-	pop	dccr			; Restore dccr in delay slot.
+	move	$brp, $r0		; Use r0 temporarily for calculation.
+	subq	2, $r0			; Set to address of previous instruction.
+	move	$r0, $brp
+	pop	$r0			; Restore r0. 
+	ba	do_sigtrap		; SIGTRAP the offending process. 
+	pop	$dccr			; Restore dccr in delay slot.
 	
 	.data
 
-_hw_bp_trigs:
+hw_bp_trigs:
 	.space 64*4
-_hw_bp_trig_ptr:
-	.dword _hw_bp_trigs
+hw_bp_trig_ptr:
+	.dword hw_bp_trigs
 
 /*
  * This is the mechanism for creating a new kernel thread.
@@ -686,47 +708,47 @@
 /*                   r10                r11         r12  */
 
 	.text
-	.global _kernel_thread
-_kernel_thread:
+	.global kernel_thread
+kernel_thread:
 
 	/* Save ARG for later.  */
-	move.d r11,r13
+	move.d $r11, $r13
 
 	/* r11 is argument 2 to clone, the flags */
-	move.d r12,r11
-	or.w	LCLONE_VM,r11
+	move.d  $r12, $r11
+	or.w	LCLONE_VM, $r11
 
 	/* Save FN for later.  */
-	move.d	r10,r12
+	move.d	$r10, $r12
 
 	/* r9 contains syscall number, to sys_clone */
-	movu.w	__NR_clone,r9
+	movu.w	__NR_clone, $r9
 
 	/* r10 is argument 1 to clone */
-	clear.d	r10
+	clear.d	$r10
 	
 	/* call sys_clone, this will fork */
 	break	13
 
 	/* parent or child? child returns 0 here. */
-	test.d	r10
+	test.d	$r10
 
 	/* jump if parent */
 	bne	1f
 	nop              /* delay slot */
 
 	/* set argument to function to call */
-	move.d	r13,r10
+	move.d	$r13, $r10
 
 	/* call specified function */
-	jsr	r12
+	jsr	$r12
 	/* If we ever return from the function, something bad has happened.  */
 
 	/* r9 is sys_exit syscall number */
-	movu.w	__NR_exit,r9
+	movu.w	__NR_exit, $r9
 
 	/* Give a really bad exit-value */
-	moveq	-1,r10
+	moveq	-1, $r10
 
 	/* call sys_exit, killing the child */
 	break	13
@@ -734,16 +756,8 @@
 	ret
 	nop              /* delay slot */
 
-
-/* The file include/linux/linkage.h is wrong for compiling the
-   Linux/CRIS kernel.  We currently have C symbols in the kernel (only
-   the kernel) prefixed with _, hence, we need to redefine SYMBOL_NAME.  */
-
-#undef SYMBOL_NAME
-#define SYMBOL_NAME(X) _##X
-
 	.section .rodata,"a"
-_sys_call_table:	
+sys_call_table:	
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
 	.long SYMBOL_NAME(sys_exit)
 	.long SYMBOL_NAME(sys_fork)
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S
--- v2.4.10/linux/arch/cris/kernel/head.S	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/kernel/head.S	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.36 2001/06/29 12:39:31 pkj Exp $
+/* $Id: head.S,v 1.40 2001/10/03 14:59:57 pkj Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,18 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.40  2001/10/03 14:59:57  pkj
+ * Added support for resetting the Bluetooth hardware.
+ *
+ * Revision 1.39  2001/10/01 14:45:03  bjornw
+ * Removed underscores and added register prefixes
+ *
+ * Revision 1.38  2001/09/21 07:14:11  jonashg
+ * Made root filesystem (cramfs) use mtdblock driver when booting from flash.
+ *
+ * Revision 1.37  2001/09/11 13:44:29  orjanf
+ * Decouple usage of serial ports for debug and kgdb.
+ *
  * Revision 1.36  2001/06/29 12:39:31  pkj
  * Added support for mirroring the first flash to just below the
  * second one, to make them look consecutive to cramfs.
@@ -144,11 +156,11 @@
 		
 	;; exported symbols
 		
-	.globl	_etrax_irv
-	.globl	_romfs_start
-	.globl	_romfs_length
-	.globl	_romfs_in_flash
-	.globl  _swapper_pg_dir
+	.globl	etrax_irv
+	.globl	romfs_start
+	.globl	romfs_length
+	.globl	romfs_in_flash
+	.globl  swapper_pg_dir
 					
 	.text
 
@@ -184,13 +196,13 @@
  	move.d	  IO_FIELD (R_MMU_KBASE_HI, base_c, 4)		\
 		| IO_FIELD (R_MMU_KBASE_HI, base_b, 0xb)	\
 		| IO_FIELD (R_MMU_KBASE_HI, base_9, 9)		\
-		| IO_FIELD (R_MMU_KBASE_HI, base_8, 8), r0
-	move.d	r0, [R_MMU_KBASE_HI]
+		| IO_FIELD (R_MMU_KBASE_HI, base_8, 8), $r0
+	move.d	$r0, [R_MMU_KBASE_HI]
 
 	; temporary map of 0x40->0x40 and 0x60->0x40 
  	move.d	  IO_FIELD (R_MMU_KBASE_LO, base_6, 4)		\
-		| IO_FIELD (R_MMU_KBASE_LO, base_4, 4), r0
-	move.d	r0, [R_MMU_KBASE_LO]
+		| IO_FIELD (R_MMU_KBASE_LO, base_4, 4), $r0
+	move.d	$r0, [R_MMU_KBASE_LO]
 
 	; mmu enable, segs e,c,b,a,6,5,4,0 segment mapped
  	move.d	  IO_STATE (R_MMU_CONFIG, mmu_enable, enable)	\
@@ -212,18 +224,18 @@
 		| IO_STATE (R_MMU_CONFIG, seg_3, page)		\
 		| IO_STATE (R_MMU_CONFIG, seg_2, page)		\
 		| IO_STATE (R_MMU_CONFIG, seg_1, page)		\
-		| IO_STATE (R_MMU_CONFIG, seg_0, seg), r0
-	move.d	r0, [R_MMU_CONFIG]
+		| IO_STATE (R_MMU_CONFIG, seg_0, seg), $r0
+	move.d	$r0, [R_MMU_CONFIG]
 #else
 	; kseg mappings
  	move.d	  IO_FIELD (R_MMU_KBASE_HI, base_e, 8)		\
 		| IO_FIELD (R_MMU_KBASE_HI, base_c, 4)		\
-		| IO_FIELD (R_MMU_KBASE_HI, base_b, 0xb), r0
-	move.d	r0, [R_MMU_KBASE_HI]
+		| IO_FIELD (R_MMU_KBASE_HI, base_b, 0xb), $r0
+	move.d	$r0, [R_MMU_KBASE_HI]
 
 	; temporary map of 0x40->0x40 and 0x00->0x00 
-	move.d	  IO_FIELD (R_MMU_KBASE_LO, base_4, 4), r0
-	move.d	r0, [R_MMU_KBASE_LO]
+	move.d	  IO_FIELD (R_MMU_KBASE_LO, base_4, 4), $r0
+	move.d	$r0, [R_MMU_KBASE_LO]
 
 	; mmu enable, segs f,e,c,b,4,0 segment mapped
  	move.d	  IO_STATE (R_MMU_CONFIG, mmu_enable, enable)	\
@@ -245,8 +257,8 @@
 		| IO_STATE (R_MMU_CONFIG, seg_3, page)		\
 		| IO_STATE (R_MMU_CONFIG, seg_2, page)		\
 		| IO_STATE (R_MMU_CONFIG, seg_1, page)		\
-		| IO_STATE (R_MMU_CONFIG, seg_0, seg), r0
-	move.d	r0, [R_MMU_CONFIG]
+		| IO_STATE (R_MMU_CONFIG, seg_0, seg), $r0
+	move.d	$r0, [R_MMU_CONFIG]
 #endif
 
 	;; Now we need to sort out the segments and their locations in RAM or
@@ -270,31 +282,31 @@
 	
 	;; Check if we start from DRAM or FLASH by testing PC
 	
-	move.d	pc,r0
-	and.d	0x7fffffff,r0	; get rid of the non-cache bit
-	cmp.d	0x10000,r0	; arbitrary... just something above this code
-	blo	inflash0
+	move.d	$pc,$r0
+	and.d	0x7fffffff,$r0	; get rid of the non-cache bit
+	cmp.d	0x10000,$r0	; arbitrary... just something above this code
+	blo	_inflash0
 	nop
 
-	jump	inram		; enter cached ram
+	jump	_inram		; enter cached ram
 
 	;; Jumpgate for branches.
-inflash0:
-	jump	inflash
+_inflash0:
+	jump	_inflash
 
 	;; Put this in a suitable section where we can reclaim storage
 	;; after init.
 	.section ".text.init"
-inflash:
+_inflash:
 	;; We need to initialze DRAM registers before we start using the DRAM
 
-	cmp.d	RAM_INIT_MAGIC, r8	; Already initialized?
-	beq	dram_init_finished
+	cmp.d	RAM_INIT_MAGIC, $r8	; Already initialized?
+	beq	_dram_init_finished
 	nop
 	
 #include "../lib/dram_init.S"
 
-dram_init_finished:		
+_dram_init_finished:		
 	;; Copy text+data to DRAM
 	;; This is fragile - the calculation of r4 as the image size depends
 	;; on that the labels below actually are the first and last positions
@@ -307,14 +319,14 @@
 	;; and when run with compression, the kernel is actually unpacked to
 	;; DRAM and we never get here in the first place :))
 	
-	moveq	0, r0			; source
-	move.d	_text_start, r1		; destination
-	move.d	__vmlinux_end, r2	; end destination
-	move.d	r2, r4
-	sub.d	r1, r4			; r4=__vmlinux_end in flash, used below
-1:	move.w	[r0+], r3
-	move.w	r3, [r1+]
-	cmp.d	r2, r1
+	moveq	0, $r0			; source
+	move.d	text_start, $r1		; destination
+	move.d	__vmlinux_end, $r2	; end destination
+	move.d	$r2, $r4
+	sub.d	$r1, $r4		; r4=__vmlinux_end in flash, used below
+1:	move.w	[$r0+], $r3
+	move.w	$r3, [$r1+]
+	cmp.d	$r2, $r1
 	blo	1b
 	nop
 
@@ -322,33 +334,33 @@
 	;; There might be none, but that does not matter because
 	;; we don't do anything than read some bytes here.
 
-	moveq	0, r0
-	move.d	r0, [_romfs_length] ; default if there is no cramfs
+	moveq	0, $r0
+	move.d	$r0, [romfs_length] ; default if there is no cramfs
 
-	move.d  [r4], r0	; cramfs_super.magic
-	cmp.d	CRAMFS_MAGIC, r0
+	move.d  [$r4], $r0	; cramfs_super.magic
+	cmp.d	CRAMFS_MAGIC, $r0
 	bne	1f
 	nop
-	move.d	[r4 + 4], r0	; cramfs_super.size
-	move.d	r0, [_romfs_length]
+	move.d	[$r4 + 4], $r0	; cramfs_super.size
+	move.d	$r0, [romfs_length]
 #ifdef CONFIG_CRIS_LOW_MAP
-	add.d   0x50000000, r4	; add flash start in virtual memory (cached)
+	add.d   0x50000000, $r4	; add flash start in virtual memory (cached)
 #else
-	add.d   0xf0000000, r4	; add flash start in virtual memory (cached)
+	add.d   0xf0000000, $r4	; add flash start in virtual memory (cached)
 #endif
-	move.d	r4, [_romfs_start]
+	move.d	$r4, [romfs_start]
 1:	
-	moveq	1, r0
-	move.d	r0, [_romfs_in_flash]
+	moveq	1, $r0
+	move.d	$r0, [romfs_in_flash]
 		
-	jump	start_it	; enter code, cached this time
+	jump	_start_it	; enter code, cached this time
 
-inram:
+_inram:
 	;; Move the ROM fs to after BSS end. This assumes that the cramfs
 	;; second longword contains the length of the cramfs
 	
-	moveq	0, r0
-	move.d	r0, [_romfs_length] ; default if there is no cramfs
+	moveq	0, $r0
+	move.d	$r0, [romfs_length] ; default if there is no cramfs
 	
 	;; The kernel could have been unpacked to DRAM by the loader, but
 	;; the cramfs image could still be in the Flash directly after the
@@ -360,120 +372,117 @@
 	;;  garbage but we do sanity checks on it, the chance that it points
 	;;  to a cramfs magic is small.. )
 	
-	cmp.d	0x0ffffff8, r9
-	bhs	no_romfs_in_flash	; r9 points outside the flash area
+	cmp.d	0x0ffffff8, $r9
+	bhs	_no_romfs_in_flash	; r9 points outside the flash area
 	nop
-	move.d	[r9], r0	; cramfs_super.magic
-	cmp.d	CRAMFS_MAGIC, r0
-	bne	no_romfs_in_flash
+	move.d	[$r9], $r0	; cramfs_super.magic
+	cmp.d	CRAMFS_MAGIC, $r0
+	bne	_no_romfs_in_flash
 	nop
-	move.d	[r9+4], r0	; cramfs_super.length
-	move.d	r0, [_romfs_length]
+	move.d	[$r9+4], $r0	; cramfs_super.length
+	move.d	$r0, [romfs_length]
 #ifdef CONFIG_CRIS_LOW_MAP
-	add.d   0x50000000, r9	; add flash start in virtual memory (cached)
+	add.d   0x50000000, $r9	; add flash start in virtual memory (cached)
 #else
-	add.d   0xf0000000, r9	; add flash start in virtual memory (cached)
+	add.d   0xf0000000, $r9	; add flash start in virtual memory (cached)
 #endif
-#ifdef CONFIG_ETRAX_FLASH_MIRRORING_FOR_CRAMFS
-	add.d   MEM_CSE1_START-CONFIG_ETRAX_FLASH_SIZE*0x100000, r9   ; move flash start to upper mirror
-#endif
-	move.d	r9, [_romfs_start]
+	move.d	$r9, [romfs_start]
 
-	moveq	1, r0
-	move.d	r0, [_romfs_in_flash]
+	moveq	1, $r0
+	move.d	$r0, [romfs_in_flash]
 	
-	jump	start_it	; enter code, cached this time
+	jump	_start_it	; enter code, cached this time
 
-no_romfs_in_flash:
+_no_romfs_in_flash:
 	;; Check if there is a cramfs (magic value).
 	;; Notice that we check for cramfs magic value - which is
 	;; the "rom fs" we'll possibly use in 2.4 if not JFFS (which does
 	;; not need this mechanism anyway)
 	
-	move.d	__vmlinux_end, r0 ; the image will be after the vmlinux end address
-	move.d	[r0], r1	; cramfs assumes same endian on host/target
-	cmp.d	CRAMFS_MAGIC, r1; magic value in cramfs superblock
+	move.d	__vmlinux_end, $r0; the image will be after the vmlinux end address
+	move.d	[$r0], $r1	; cramfs assumes same endian on host/target
+	cmp.d	CRAMFS_MAGIC, $r1; magic value in cramfs superblock
 	bne	1f
 	nop
 
 	;; Ok. What is its size ? 
 	
-	move.d	[r0 + 4], r2	; cramfs_super.size (again, no need to swapwb)
+	move.d	[$r0 + 4], $r2	; cramfs_super.size (again, no need to swapwb)
 
 	;; We want to copy it to the end of the BSS
 
-	move.d	_end, r1
+	move.d	_end, $r1
 
 	;; Remember values so cramfs and setup can find this info
 
-	move.d	r1, [_romfs_start]	; new romfs location
-	move.d	r2, [_romfs_length]
+	move.d	$r1, [romfs_start]	; new romfs location
+	move.d	$r2, [romfs_length]
 
 	;; We need to copy it backwards, since they can be overlapping
 
-	add.d	r2, r0
-	add.d	r2, r1
+	add.d	$r2, $r0
+	add.d	$r2, $r1
 		
 	;; Go ahead. Make my loop.
 
-	lsrq	1, r2		; size is in bytes, we copy words
+	lsrq	1, $r2		; size is in bytes, we copy words
 
-1:	move.w	[r0=r0-2],r3
-	move.w	r3,[r1=r1-2]
-	subq	1, r2
+1:	move.w	[$r0=$r0-2],$r3
+	move.w	$r3,[$r1=$r1-2]
+	subq	1, $r2
 	bne	1b
 	nop
 	
 	;; Dont worry that the BSS is tainted. It will be cleared later.
 
-	moveq	0, r0
-	move.d	r0, [_romfs_in_flash]
+	moveq	0, $r0
+	move.d	$r0, [romfs_in_flash]
 
-	jump	start_it	; better skip the additional cramfs check below
+	jump	_start_it	; better skip the additional cramfs check below
 	
-start_it:
+_start_it:
 	;; the kernel stack is overlayed with the task structure for each
 	;; task. thus the initial kernel stack is in the same page as the
 	;; init_task (but starts in the top of the page, size 8192)
-	move.d	_init_task_union + 8192,sp
-	move.d	_ibr_start,r0	; this symbol is set by the linker script 
-	move	r0,ibr
-	move.d	r0,[_etrax_irv]	; set the interrupt base register and pointer
+	move.d	init_task_union + 8192, $sp
+	move.d	ibr_start,$r0	; this symbol is set by the linker script 
+	move	$r0,$ibr
+	move.d	$r0,[etrax_irv]	; set the interrupt base register and pointer
 
 	;; Clear BSS region, from _bss_start to _end
 
-	move.d	__bss_start, r0
-	move.d	_end, r1
-1:	clear.d	[r0+]
-	cmp.d	r1, r0
+	move.d	__bss_start, $r0
+	move.d	_end, $r1
+1:	clear.d	[$r0+]
+	cmp.d	$r1, $r0
 	blo	1b
 	nop
 	
 #ifdef CONFIG_BLK_DEV_ETRAXIDE
 	;; disable ATA before enabling it in genconfig below
-	moveq	0,r0
-	move.d	r0,[R_ATA_CTRL_DATA]
-	move.d	r0,[R_ATA_TRANSFER_CNT]
-	move.d	r0,[R_ATA_CONFIG]
+	moveq	0,$r0
+	move.d	$r0,[R_ATA_CTRL_DATA]
+	move.d	$r0,[R_ATA_TRANSFER_CNT]
+	move.d	$r0,[R_ATA_CONFIG]
 #if 0
-	move.d	R_PORT_G_DATA,r1
-	move.d	r0,[r1]; assert ATA bus-reset
+	move.d	R_PORT_G_DATA, $r1
+	move.d	$r0, [$r1]; assert ATA bus-reset
 	nop
 	nop
 	nop
 	nop
 	nop
 	nop
-	move.d	0x08000000,r0
-	move.d	r0,[r1]
+	move.d	0x08000000,$r0
+	move.d	$r0,[$r1]
 #endif
 #endif
 
 #ifdef CONFIG_JULIETTE
 	;; configure external DMA channel 0 before enabling it in genconfig
 	
-	moveq	0,r0
-	move.d	r0,[R_EXT_DMA_0_ADDR]
+	moveq	0,$r0
+	move.d	$r0,[R_EXT_DMA_0_ADDR]
 	; cnt enable, word size, output, stop, size 0
 	move.d	  IO_STATE (R_EXT_DMA_0_CMD, cnt, enable)	\
 		| IO_STATE (R_EXT_DMA_0_CMD, rqpol, ahigh)	\
@@ -482,168 +491,216 @@
 		| IO_STATE (R_EXT_DMA_0_CMD, wid, word)		\
 		| IO_STATE (R_EXT_DMA_0_CMD, dir, output)	\
 		| IO_STATE (R_EXT_DMA_0_CMD, run, stop)		\
-		| IO_FIELD (R_EXT_DMA_0_CMD, trf_count, 0),r0
-	move.d	r0,[R_EXT_DMA_0_CMD]
+		| IO_FIELD (R_EXT_DMA_0_CMD, trf_count, 0),$r0
+	move.d	$r0,[R_EXT_DMA_0_CMD]
 
 	;; reset dma4 and wait for completion
 	
-	moveq	IO_STATE (R_DMA_CH4_CMD, cmd, reset),r0
-	move.b	r0,[R_DMA_CH4_CMD]
-w4u:	move.b	[R_DMA_CH4_CMD],r0
-	and.b	IO_MASK (R_DMA_CH4_CMD, cmd),r0
-	cmp.b	IO_STATE (R_DMA_CH4_CMD, cmd, reset),r0
-	beq	w4u
+	moveq	IO_STATE (R_DMA_CH4_CMD, cmd, reset),$r0
+	move.b	$r0,[R_DMA_CH4_CMD]
+1:	move.b	[R_DMA_CH4_CMD],$r0
+	and.b	IO_MASK (R_DMA_CH4_CMD, cmd),$r0
+	cmp.b	IO_STATE (R_DMA_CH4_CMD, cmd, reset),$r0
+	beq	1b
 	nop
 
 	;; reset dma5 and wait for completion
 	
-	moveq	IO_STATE (R_DMA_CH5_CMD, cmd, reset),r0
-	move.b	r0,[R_DMA_CH5_CMD]
-w5u:	move.b	[R_DMA_CH5_CMD],r0
-	and.b	IO_MASK (R_DMA_CH5_CMD, cmd),r0
-	cmp.b	IO_STATE (R_DMA_CH5_CMD, cmd, reset),r0
-	beq	w5u
+	moveq	IO_STATE (R_DMA_CH5_CMD, cmd, reset),$r0
+	move.b	$r0,[R_DMA_CH5_CMD]
+1:	move.b	[R_DMA_CH5_CMD],$r0
+	and.b	IO_MASK (R_DMA_CH5_CMD, cmd),$r0
+	cmp.b	IO_STATE (R_DMA_CH5_CMD, cmd, reset),$r0
+	beq	1b
 	nop
 #endif	
 			
 	;; Etrax product HW genconfig setup
 
-	moveq	0,r0
-#if !defined(CONFIG_ETRAX_KGDB) && !defined(CONFIG_DMA_MEMCPY)
-	; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA
+	moveq	0,$r0
+#if (!defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT0)) \
+	&& !defined(CONFIG_DMA_MEMCPY)
+	; DMA channels 6 and 7 to se$r0, kgdb doesnt want DMA
 	or.d	  IO_STATE (R_GEN_CONFIG, dma7, serial0)	\
-		| IO_STATE (R_GEN_CONFIG, dma6, serial0),r0
+		| IO_STATE (R_GEN_CONFIG, dma6, serial0),$r0
 #endif
-#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1)	
+#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1)
+	; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA
 	or.d	  IO_STATE (R_GEN_CONFIG, dma9, serial1)	\
-		| IO_STATE (R_GEN_CONFIG, dma8, serial1),r0
+		| IO_STATE (R_GEN_CONFIG, dma8, serial1),$r0
 #endif	
 #ifdef CONFIG_DMA_MEMCPY
 	; 6/7 memory-memory DMA
 	or.d	  IO_STATE (R_GEN_CONFIG, dma7, intdma6)	\
-		| IO_STATE (R_GEN_CONFIG, dma6, intdma7),r0
+		| IO_STATE (R_GEN_CONFIG, dma6, intdma7),$r0
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
-	; DMA channels 2 and 3 to serport 2, port 2 enabled
+	; Enable serial port 2
+	or.w	IO_STATE (R_GEN_CONFIG, ser2, select),$r0
+#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT2)
+	; DMA channels 2 and 3 to ser2, kgdb doesnt want DMA
 	or.d	  IO_STATE (R_GEN_CONFIG, dma3, serial2)	\
-		| IO_STATE (R_GEN_CONFIG, dma2, serial2)	\
-		| IO_STATE (R_GEN_CONFIG, ser2, select),r0
+		| IO_STATE (R_GEN_CONFIG, dma2, serial2),$r0
+#endif
 #endif
 #if defined(CONFIG_ETRAX_SERIAL_PORT3) || defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
-	; DMA channels 4 and 5 to serport 3, port 3 enabled
+	; Enable serial port 3
+	or.w	IO_STATE (R_GEN_CONFIG, ser3, select),$r0
+#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT3)
+	; DMA channels 4 and 5 to ser3, kgdb doesnt want DMA
 	or.d	  IO_STATE (R_GEN_CONFIG, dma5, serial3)	\
-		| IO_STATE (R_GEN_CONFIG, dma4, serial3)	\
-		| IO_STATE (R_GEN_CONFIG, ser3, select),r0
-#endif	
+		| IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0
+#endif
+#endif
 #if defined(CONFIG_ETRAX_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
 	; parport 0 enabled using DMA 2/3
-	or.w	IO_STATE (R_GEN_CONFIG, par0, select),r0
+	or.w	IO_STATE (R_GEN_CONFIG, pa$r0, select),$r0
 #endif
 #if defined(CONFIG_ETRAX_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
 	; parport 1 enabled using DMA 4/5
-	or.w	IO_STATE (R_GEN_CONFIG, par1, select),r0
+	or.w	IO_STATE (R_GEN_CONFIG, par1, select),$r0
 #endif
 #ifdef CONFIG_ETRAX_IDE
 	; DMA channels 2 and 3 to ATA, ATA enabled
 	or.d	  IO_STATE (R_GEN_CONFIG, dma3, ata)	\
 		| IO_STATE (R_GEN_CONFIG, dma2, ata)	\
-		| IO_STATE (R_GEN_CONFIG, ata, select),r0
+		| IO_STATE (R_GEN_CONFIG, ata, select),$r0
 #endif
 	
 #ifdef CONFIG_ETRAX_USB_HOST_PORT1
 	; Set the USB port 1 enable bit
-	or.d	IO_STATE (R_GEN_CONFIG, usb1, select),r0
+	or.d	IO_STATE (R_GEN_CONFIG, usb1, select),$r0
 #endif
 #ifdef CONFIG_ETRAX_USB_HOST_PORT2
 	; Set the USB port 2 enable bit
-	or.d	IO_STATE (R_GEN_CONFIG, usb2, select),r0
+	or.d	IO_STATE (R_GEN_CONFIG, usb2, select),$r0
 #endif
 #ifdef CONFIG_ETRAX_USB_HOST
 	; Connect DMA channels 8 and 9 to USB
 	and.d	(~(IO_MASK (R_GEN_CONFIG, dma9)		\
 		   | IO_MASK (R_GEN_CONFIG, dma8)))	\
 		| IO_STATE (R_GEN_CONFIG, dma9, usb)	\
-		| IO_STATE (R_GEN_CONFIG, dma8, usb),r0
+		| IO_STATE (R_GEN_CONFIG, dma8, usb),$r0
 #endif
 	
 #ifdef CONFIG_JULIETTE
 	; DMA channels 4 and 5 to EXTDMA0, for Juliette
 	or.d	  IO_STATE (R_GEN_CONFIG, dma5, extdma0)	\
-		| IO_STATE (R_GEN_CONFIG, dma4, extdma0),r0
+		| IO_STATE (R_GEN_CONFIG, dma4, extdma0),$r0
+#endif
+
+#if defined(CONFIG_BLUETOOTH) && (defined(CONFIG_BLUETOOTH_RESET_G10) || defined(CONFIG_BLUETOOTH_RESET_G11))
+	or.d	  IO_STATE (R_GEN_CONFIG, g8_15dir, out),$r0
 #endif
-	move.d	r0,[_genconfig_shadow] ; init a shadow register of R_GEN_CONFIG
+
+	move.d	$r0,[genconfig_shadow] ; init a shadow register of R_GEN_CONFIG
 
 #ifndef CONFIG_SVINTO_SIM
-	move.d	r0,[R_GEN_CONFIG]
+	move.d	$r0,[R_GEN_CONFIG]
 
 #if 0
-	moveq	4,r0
-	move.b	r0,[R_DMA_CH6_CMD]	; reset (ser0 dma out)
-	move.b	r0,[R_DMA_CH7_CMD]	; reset (ser0 dma in)
-w61:	move.b	[R_DMA_CH6_CMD],r0	; wait for reset cycle to finish
-	and.b	7,r0
-	cmp.b	4,r0
-	beq	w61
-	nop
-w71:	move.b	[R_DMA_CH7_CMD],r0	; wait for reset cycle to finish
-	and.b	7,r0
-	cmp.b	4,r0
-	beq	w71
+	moveq	4,$r0
+	move.b	$r0,[R_DMA_CH6_CMD]	; reset (ser0 dma out)
+	move.b	$r0,[R_DMA_CH7_CMD]	; reset (ser0 dma in)
+1:	move.b	[R_DMA_CH6_CMD],$r0	; wait for reset cycle to finish
+	and.b	7,$r0
+	cmp.b	4,$r0
+	beq	1b
+	nop
+1:	move.b	[R_DMA_CH7_CMD],$r0	; wait for reset cycle to finish
+	and.b	7,$r0
+	cmp.b	4,$r0
+	beq	1b
 	nop
 #endif
 	
-	moveq	IO_STATE (R_DMA_CH8_CMD, cmd, reset),r0
-	move.b	r0,[R_DMA_CH8_CMD]	; reset (ser1 dma out)
-	move.b	r0,[R_DMA_CH9_CMD]	; reset (ser1 dma in)
-w81:	move.b	[R_DMA_CH8_CMD],r0	; wait for reset cycle to finish
-	and.b	IO_MASK (R_DMA_CH8_CMD, cmd),r0
-	cmp.b	IO_STATE (R_DMA_CH8_CMD, cmd, reset),r0
-	beq	w81
-	nop
-w91:	move.b	[R_DMA_CH9_CMD],r0	; wait for reset cycle to finish
-	and.b	IO_MASK (R_DMA_CH9_CMD, cmd),r0
-	cmp.b	IO_STATE (R_DMA_CH9_CMD, cmd, reset),r0
-	beq	w91
+	moveq	IO_STATE (R_DMA_CH8_CMD, cmd, reset),$r0
+	move.b	$r0,[R_DMA_CH8_CMD]	; reset (ser1 dma out)
+	move.b	$r0,[R_DMA_CH9_CMD]	; reset (ser1 dma in)
+1:	move.b	[R_DMA_CH8_CMD],$r0	; wait for reset cycle to finish
+	andq	IO_MASK (R_DMA_CH8_CMD, cmd),$r0
+	cmpq	IO_STATE (R_DMA_CH8_CMD, cmd, reset),$r0
+	beq	1b
+	nop
+1:	move.b	[R_DMA_CH9_CMD],$r0	; wait for reset cycle to finish
+	andq	IO_MASK (R_DMA_CH9_CMD, cmd),$r0
+	cmpq	IO_STATE (R_DMA_CH9_CMD, cmd, reset),$r0
+	beq	1b
 	nop
 
 	;; setup port PA and PB default initial directions and data
 	;; including their shadow registers
 		
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR,r0
-	move.b	r0,[_port_pa_dir_shadow]
-	move.b	r0,[R_PORT_PA_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA,r0
-	move.b	r0,[_port_pa_data_shadow]
-	move.b	r0,[R_PORT_PA_DATA]
-	
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG,r0
-	move.b	r0,[_port_pb_config_shadow]
-	move.b	r0,[R_PORT_PB_CONFIG]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR,r0
-	move.b	r0,[_port_pb_dir_shadow]
-	move.b	r0,[R_PORT_PB_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA,r0
-	move.b	r0,[_port_pb_data_shadow]
-	move.b	r0,[R_PORT_PB_DATA]
-	move.d  0, r0
-	move.d  r0,[_port_pb_i2c_shadow]
-	move.d  r0, [R_PORT_PB_I2C]
-
-	moveq	0,r0
-	move.d	r0,[_port_g_data_shadow]
-	move.d	r0,[R_PORT_G_DATA]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR,$r0
+#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PA7)
+	or.b	IO_STATE (R_PORT_PA_DIR, dir7, output),$r0
+#endif
+	move.b	$r0,[port_pa_dir_shadow]
+	move.b	$r0,[R_PORT_PA_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA,$r0
+#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PA7)
+#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
+	and.b	~(1 << 7),$r0
+#else
+	or.b	(1 << 7),$r0
+#endif
+#endif
+	move.b	$r0,[port_pa_data_shadow]
+	move.b	$r0,[R_PORT_PA_DATA]
+	
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG,$r0
+	move.b	$r0,[port_pb_config_shadow]
+	move.b	$r0,[R_PORT_PB_CONFIG]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR,$r0
+#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PB5)
+	or.b	IO_STATE (R_PORT_PB_DIR, dir5, output),$r0
+#endif
+	move.b	$r0,[port_pb_dir_shadow]
+	move.b	$r0,[R_PORT_PB_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA,$r0
+#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_PB5)
+#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
+	and.b	~(1 << 5),$r0
+#else
+	or.b	(1 << 5),$r0
+#endif
+#endif
+	move.b	$r0,[port_pb_data_shadow]
+	move.b	$r0,[R_PORT_PB_DATA]
+
+	moveq   0, $r0
+	move.d  $r0,[port_pb_i2c_shadow]
+	move.d  $r0, [R_PORT_PB_I2C]
+
+	moveq	0,$r0
+#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_G10)
+#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
+	and.d	~(1 << 10),$r0
+#else
+	or.d	(1 << 10),$r0
+#endif
+#endif
+#if defined(CONFIG_BLUETOOTH) && defined(CONFIG_BLUETOOTH_RESET_G11)
+#if defined(CONFIG_BLUETOOTH_RESET_ACTIVE_HIGH)
+	and.d	~(1 << 11),$r0
+#else
+	or.d	(1 << 11),$r0
+#endif
+#endif
+	move.d	$r0,[port_g_data_shadow]
+	move.d	$r0,[R_PORT_G_DATA]
 	
 	;; setup the serial port 0 at 115200 baud for debug purposes
 	
 	moveq	  IO_STATE (R_SERIAL0_XOFF, tx_stop, enable)		\
 		| IO_STATE (R_SERIAL0_XOFF, auto_xoff, disable)		\
-		| IO_FIELD (R_SERIAL0_XOFF, xoff_char, 0),r0
-	move.d	r0,[R_SERIAL0_XOFF] 
+		| IO_FIELD (R_SERIAL0_XOFF, xoff_char, 0),$r0
+	move.d	$r0,[R_SERIAL0_XOFF] 
 
 	; 115.2kbaud for both transmit and receive
 	move.b	  IO_STATE (R_SERIAL0_BAUD, tr_baud, c115k2Hz)		\
-		| IO_STATE (R_SERIAL0_BAUD, rec_baud, c115k2Hz),r0
-	move.b	r0,[R_SERIAL0_BAUD]
+		| IO_STATE (R_SERIAL0_BAUD, rec_baud, c115k2Hz),$r0
+	move.b	$r0,[R_SERIAL0_BAUD]
 
 	; Set up and enable the serial0 receiver.
 	move.b	  IO_STATE (R_SERIAL0_REC_CTRL, dma_err, stop)		\
@@ -653,8 +710,8 @@
 		| IO_STATE (R_SERIAL0_REC_CTRL, rec_stick_par, normal)	\
 		| IO_STATE (R_SERIAL0_REC_CTRL, rec_par, even)		\
 		| IO_STATE (R_SERIAL0_REC_CTRL, rec_par_en, disable)	\
-		| IO_STATE (R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit),r0
-	move.b	r0,[R_SERIAL0_REC_CTRL] 
+		| IO_STATE (R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit),$r0
+	move.b	$r0,[R_SERIAL0_REC_CTRL] 
 	
 	; Set up and enable the serial0 transmitter.
 	move.b	  IO_FIELD (R_SERIAL0_TR_CTRL, txd, 0)			\
@@ -664,20 +721,20 @@
 		| IO_STATE (R_SERIAL0_TR_CTRL, tr_stick_par, normal)	\
 		| IO_STATE (R_SERIAL0_TR_CTRL, tr_par, even)		\
 		| IO_STATE (R_SERIAL0_TR_CTRL, tr_par_en, disable)	\
-		| IO_STATE (R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit),r0
-	move.b	r0,[R_SERIAL0_TR_CTRL]
+		| IO_STATE (R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit),$r0
+	move.b	$r0,[R_SERIAL0_TR_CTRL]
 
 	;; setup the serial port 1 at 115200 baud for debug purposes
 	
 	moveq	  IO_STATE (R_SERIAL1_XOFF, tx_stop, enable)		\
 		| IO_STATE (R_SERIAL1_XOFF, auto_xoff, disable)		\
-		| IO_FIELD (R_SERIAL1_XOFF, xoff_char, 0),r0
-	move.d	r0,[R_SERIAL1_XOFF] 
+		| IO_FIELD (R_SERIAL1_XOFF, xoff_char, 0),$r0
+	move.d	$r0,[R_SERIAL1_XOFF] 
 
 	; 115.2kbaud for both transmit and receive
 	move.b	  IO_STATE (R_SERIAL1_BAUD, tr_baud, c115k2Hz)		\
-		| IO_STATE (R_SERIAL1_BAUD, rec_baud, c115k2Hz),r0
-	move.b	r0,[R_SERIAL1_BAUD]
+		| IO_STATE (R_SERIAL1_BAUD, rec_baud, c115k2Hz),$r0
+	move.b	$r0,[R_SERIAL1_BAUD]
 
 	; Set up and enable the serial1 receiver.
 	move.b	  IO_STATE (R_SERIAL1_REC_CTRL, dma_err, stop)		\
@@ -687,8 +744,8 @@
 		| IO_STATE (R_SERIAL1_REC_CTRL, rec_stick_par, normal)	\
 		| IO_STATE (R_SERIAL1_REC_CTRL, rec_par, even)		\
 		| IO_STATE (R_SERIAL1_REC_CTRL, rec_par_en, disable)	\
-		| IO_STATE (R_SERIAL1_REC_CTRL, rec_bitnr, rec_8bit),r0
-	move.b	r0,[R_SERIAL1_REC_CTRL] 
+		| IO_STATE (R_SERIAL1_REC_CTRL, rec_bitnr, rec_8bit),$r0
+	move.b	$r0,[R_SERIAL1_REC_CTRL] 
 	
 	; Set up and enable the serial1 transmitter.
 	move.b	  IO_FIELD (R_SERIAL1_TR_CTRL, txd, 0)			\
@@ -698,8 +755,8 @@
 		| IO_STATE (R_SERIAL1_TR_CTRL, tr_stick_par, normal)	\
 		| IO_STATE (R_SERIAL1_TR_CTRL, tr_par, even)		\
 		| IO_STATE (R_SERIAL1_TR_CTRL, tr_par_en, disable)	\
-		| IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),r0
-	move.b	r0,[R_SERIAL1_TR_CTRL]
+		| IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),$r0
+	move.b	$r0,[R_SERIAL1_TR_CTRL]
 
 	
 #ifdef CONFIG_ETRAX_SERIAL_PORT3	
@@ -707,13 +764,13 @@
 	
 	moveq	  IO_STATE (R_SERIAL3_XOFF, tx_stop, enable)		\
 		| IO_STATE (R_SERIAL3_XOFF, auto_xoff, disable)		\
-		| IO_FIELD (R_SERIAL3_XOFF, xoff_char, 0),r0
-	move.d	r0,[R_SERIAL3_XOFF] 
+		| IO_FIELD (R_SERIAL3_XOFF, xoff_char, 0),$r0
+	move.d	$r0,[R_SERIAL3_XOFF] 
 
 	; 115.2kbaud for both transmit and receive
 	move.b	  IO_STATE (R_SERIAL3_BAUD, tr_baud, c115k2Hz)		\
-		| IO_STATE (R_SERIAL3_BAUD, rec_baud, c115k2Hz),r0
-	move.b	r0,[R_SERIAL3_BAUD]
+		| IO_STATE (R_SERIAL3_BAUD, rec_baud, c115k2Hz),$r0
+	move.b	$r0,[R_SERIAL3_BAUD]
 
 	; Set up and enable the serial3 receiver.
 	move.b	  IO_STATE (R_SERIAL3_REC_CTRL, dma_err, stop)		\
@@ -723,8 +780,8 @@
 		| IO_STATE (R_SERIAL3_REC_CTRL, rec_stick_par, normal)	\
 		| IO_STATE (R_SERIAL3_REC_CTRL, rec_par, even)		\
 		| IO_STATE (R_SERIAL3_REC_CTRL, rec_par_en, disable)	\
-		| IO_STATE (R_SERIAL3_REC_CTRL, rec_bitnr, rec_8bit),r0
-	move.b	r0,[R_SERIAL3_REC_CTRL] 
+		| IO_STATE (R_SERIAL3_REC_CTRL, rec_bitnr, rec_8bit),$r0
+	move.b	$r0,[R_SERIAL3_REC_CTRL] 
 	
 	; Set up and enable the serial3 transmitter.
 	move.b	  IO_FIELD (R_SERIAL3_TR_CTRL, txd, 0)			\
@@ -734,31 +791,31 @@
 		| IO_STATE (R_SERIAL3_TR_CTRL, tr_stick_par, normal)	\
 		| IO_STATE (R_SERIAL3_TR_CTRL, tr_par, even)		\
 		| IO_STATE (R_SERIAL3_TR_CTRL, tr_par_en, disable)	\
-		| IO_STATE (R_SERIAL3_TR_CTRL, tr_bitnr, tr_8bit),r0
-	move.b	r0,[R_SERIAL3_TR_CTRL]
+		| IO_STATE (R_SERIAL3_TR_CTRL, tr_bitnr, tr_8bit),$r0
+	move.b	$r0,[R_SERIAL3_TR_CTRL]
 #endif
 	
 #endif /* CONFIG_SVINTO_SIM */
 
-	jump	_start_kernel	; jump into the C-function _start_kernel in init/main.c
+	jump	start_kernel	; jump into the C-function start_kernel in init/main.c
 		
 	.data
-_etrax_irv:	
+etrax_irv:	
 	.dword	0
-_romfs_start:
+romfs_start:
 	.dword	0
-_romfs_length:
+romfs_length:
 	.dword	0
-_romfs_in_flash:
+romfs_in_flash:
 	.dword	0
 	
 	;; put some special pages at the beginning of the kernel aligned
 	;; to page boundaries - the kernel cannot start until after this
 
 #ifdef CONFIG_CRIS_LOW_MAP
-_swapper_pg_dir = 0x60002000
+swapper_pg_dir = 0x60002000
 #else	
-_swapper_pg_dir = 0xc0002000
+swapper_pg_dir = 0xc0002000
 #endif
 
 	.section ".data.init"
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/ksyms.c linux/arch/cris/kernel/ksyms.c
--- v2.4.10/linux/arch/cris/kernel/ksyms.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/ksyms.c	Mon Oct  8 11:43:54 2001
@@ -1,2 +1,65 @@
-/* no kernel support yet */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/sched.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include <linux/pm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+ 
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/checksum.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern unsigned long get_cmos_time(void);
+extern void __ashrdi3(void);
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(get_cmos_time);
+
+EXPORT_SYMBOL(strtok);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(simple_strtol);
+EXPORT_SYMBOL(strstr);
+
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(__ashrdi3);
+
+/* other stuff */
+
+EXPORT_SYMBOL(strncpy_from_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+EXPORT_SYMBOL(__generic_copy_from_user);
+EXPORT_SYMBOL(__generic_copy_to_user);
+EXPORT_SYMBOL(strnlen_user);
+EXPORT_SYMBOL(__copy_user_zeroing);
+EXPORT_SYMBOL(__copy_user);
+
+#undef memcpy
+#undef memset
+extern void * memset(void *,int,__kernel_size_t);
+extern void * memcpy(void *,const void *,__kernel_size_t);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+
 
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/process.c linux/arch/cris/kernel/process.c
--- v2.4.10/linux/arch/cris/kernel/process.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/cris/kernel/process.c	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.16 2001/06/21 02:00:40 hp Exp $
+/* $Id: process.c,v 1.20 2001/10/03 08:21:39 jonashg Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
@@ -8,6 +8,18 @@
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: process.c,v $
+ *  Revision 1.20  2001/10/03 08:21:39  jonashg
+ *  cause_of_death does not exist if CONFIG_SVINTO_SIM is defined.
+ *
+ *  Revision 1.19  2001/09/26 11:52:54  bjornw
+ *  INIT_MMAP is gone in 2.4.10
+ *
+ *  Revision 1.18  2001/08/21 21:43:51  hp
+ *  Move last watchdog fix inside #ifdef CONFIG_ETRAX_WATCHDOG
+ *
+ *  Revision 1.17  2001/08/21 13:48:01  jonashg
+ *  Added fix by HP to avoid oops when doing a hard_reset_now.
+ *
  *  Revision 1.16  2001/06/21 02:00:40  hp
  *  	* entry.S: Include asm/unistd.h.
  *  	(_sys_call_table): Use section .rodata, not .data.
@@ -118,10 +130,20 @@
 
 void hard_reset_now (void)
 {
+	/*
+	 * Don't declare this variable elsewhere.  We don't want any other
+	 * code to know about it than the watchdog handler in entry.S and
+	 * this code, implementing hard reset through the watchdog.
+	 */
+	extern int cause_of_death;
+
 	printk("*** HARD RESET ***\n");
 	cli();
 
-#ifndef CONFIG_ETRAX_WATCHDOG
+#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
+	cause_of_death = 0xbedead;
+
+#else
 	/* Since we dont plan to keep on reseting the watchdog,
 	   the key can be arbitrary hence three */
 	*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/ptrace.c linux/arch/cris/kernel/ptrace.c
--- v2.4.10/linux/arch/cris/kernel/ptrace.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/cris/kernel/ptrace.c	Mon Oct  8 11:43:54 2001
@@ -8,6 +8,9 @@
  * Authors:   Bjorn Wesen
  *
  * $Log: ptrace.c,v $
+ * Revision 1.7  2001/09/26 11:53:49  bjornw
+ * PTRACE_DETACH works more simple in 2.4.10
+ *
  * Revision 1.6  2001/07/25 16:08:47  bjornw
  * PTRACE_ATTACH bulk moved into arch-independant code in 2.4.7
  *
@@ -89,7 +92,7 @@
  */
 void ptrace_disable(struct task_struct *child)
 {
-	/* Todo - pending singlesteps? */
+       /* Todo - pending singlesteps? */
 }
 
 /* Note that this implementation of ptrace behaves differently from vanilla
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/setup.c linux/arch/cris/kernel/setup.c
--- v2.4.10/linux/arch/cris/kernel/setup.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/kernel/setup.c	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.18 2001/06/28 04:47:16 hp Exp $
+/* $Id: setup.c,v 1.21 2001/10/01 14:45:35 bjornw Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
@@ -166,7 +166,17 @@
 	   saving anything that might be there.  */
 
 	*cmdline_p = command_line;
-	strcpy(command_line, "root=/dev/rom"); /* use the appended romdisk as root */
+
+	if (romfs_in_flash) {
+		strncpy(command_line, "root=", COMMAND_LINE_SIZE);
+		strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
+			COMMAND_LINE_SIZE-5);
+
+		/* Save command line copy for /proc/cmdline */
+
+		memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+		saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+	}
 
 	/* give credit for the CRIS port */
 
@@ -213,15 +223,10 @@
 int get_cpuinfo(char *buffer)
 {
 	int revision;
-#ifndef CONFIG_SVINTO_SIM
-	unsigned char tmp;
 
-	__asm__ volatile ("move vr,%0" : "=rm" (tmp));
-	revision = tmp;
-#else
-        /* Fake a revision for the simulator */
-	revision = 7;
-#endif
+	/* read the version register in the CPU and print some stuff */
+
+	revision = rdvr();
 
 	return sprintf(buffer,
 		       "cpu\t\t: CRIS\n"
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- v2.4.10/linux/arch/cris/kernel/signal.c	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/kernel/signal.c	Mon Oct  8 11:43:54 2001
@@ -64,6 +64,7 @@
 		err |= __put_user(from->si_pid, &to->si_pid);
 		switch (from->si_code >> 16) {
 		case __SI_FAULT >> 16:
+                        err |= __put_user(from->si_addr, &to->si_addr);
 			break;
 		case __SI_CHLD >> 16:
 			err |= __put_user(from->si_utime, &to->si_utime);
@@ -347,6 +348,11 @@
 
 	err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
 
+        /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
+           the signal handler. The frametype will be restored to its previous
+           value in restore_sigcontext. */
+        regs->frametype = CRIS_FRAME_NORMAL;
+
 	/* then some other stuff */
 
 	err |= __put_user(mask, &sc->oldmask);
@@ -476,10 +482,10 @@
 	} else {
 		/* trampoline - the desired return ip is the retcode itself */
 		return_ip = (unsigned long)&frame->retcode;
-		/* This is movu.w __NR_sigreturn, r9; break 13; */
-		err |= __put_user(0x9c5f,         (short *)(frame->retcode+0));
-		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
-		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
+		/* This is movu.w __NR_rt_sigreturn, r9; break 13; */
+		err |= __put_user(0x9c5f,            (short *)(frame->retcode+0));
+		err |= __put_user(__NR_rt_sigreturn, (short *)(frame->retcode+2));
+		err |= __put_user(0xe93d,            (short *)(frame->retcode+4));
 	}
 
 	if (err)
@@ -492,6 +498,8 @@
 	regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
 	regs->srp = return_ip;                          /* what we enter LATER */
 	regs->r10 = sig;                                /* first argument is signo */
+        regs->r11 = (unsigned long) &frame->info;       /* second argument is (siginfo_t *) */
+        regs->r12 = 0;                                  /* third argument is unused */
 
 	/* actually move the usp to reflect the stacked frame */
 
diff -u --recursive --new-file v2.4.10/linux/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
--- v2.4.10/linux/arch/cris/kernel/traps.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/kernel/traps.c	Sun Sep 30 12:26:08 2001
@@ -138,8 +138,8 @@
 	   register.  */
 	unsigned long usp = rdusp();
 
-	printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
-	       regs->irp, regs->srp, regs->dccr, usp, regs->mof );
+	printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx    %s\n",
+	       regs->irp, regs->srp, regs->dccr, usp, regs->mof, print_tainted());
 	printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
 	       regs->r0, regs->r1, regs->r2, regs->r3);
 	printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
diff -u --recursive --new-file v2.4.10/linux/arch/cris/lib/checksum.S linux/arch/cris/lib/checksum.S
--- v2.4.10/linux/arch/cris/lib/checksum.S	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/lib/checksum.S	Mon Oct  8 11:43:54 2001
@@ -1,12 +1,12 @@
-/* $Id: checksum.S,v 1.5 2001/05/29 11:40:14 markusl Exp $
+/* $Id: checksum.S,v 1.6 2001/10/01 14:47:35 bjornw Exp $
  * A fast checksum routine using movem
  * Copyright (c) 1998-2001 Axis Communications AB
  *
  * csum_partial(const unsigned char * buff, int len, unsigned int sum)
  */
 
-	.globl	_csum_partial
-_csum_partial:
+	.globl	csum_partial
+csum_partial:
 	
 	;; r10 - src
 	;; r11 - length
@@ -16,8 +16,8 @@
 	;; we also do _NOT_ want to compute a checksum over more than the 
 	;; actual length when length < 40
 	
-	cmpu.w	80,r11
-	blo	word_loop
+	cmpu.w	80,$r11
+	blo	_word_loop
 	nop
 
 	;; need to save the registers we use below in the movem loop
@@ -25,100 +25,100 @@
 	;; only r0 - r8 have to be saved, the other ones are clobber-able
 	;; according to the ABI
 	
-	subq	9*4,sp
-	movem	r8,[sp]
+	subq	9*4,$sp
+	movem	$r8,[$sp]
 	
 	;; do a movem checksum
 
-	subq	10*4,r11	; update length for the first loop
+	subq	10*4,$r11	; update length for the first loop
 	
-mloop:	movem	[r10+],r9	; read 10 longwords
+_mloop:	movem	[$r10+],$r9	; read 10 longwords
 
 	;; perform dword checksumming on the 10 longwords
 	
-	add.d	r0,r12
+	add.d	$r0,$r12
 	ax
-	add.d	r1,r12
+	add.d	$r1,$r12
 	ax
-	add.d	r2,r12
+	add.d	$r2,$r12
 	ax
-	add.d	r3,r12
+	add.d	$r3,$r12
 	ax
-	add.d	r4,r12
+	add.d	$r4,$r12
 	ax
-	add.d	r5,r12
+	add.d	$r5,$r12
 	ax
-	add.d	r6,r12
+	add.d	$r6,$r12
 	ax
-	add.d	r7,r12
+	add.d	$r7,$r12
 	ax
-	add.d	r8,r12
+	add.d	$r8,$r12
 	ax
-	add.d	r9,r12
+	add.d	$r9,$r12
 
 	;; fold the carry into the checksum, to avoid having to loop the carry
 	;; back into the top
 	
 	ax
-	addq	0,r12
+	addq	0,$r12
 	ax			; do it again, since we might have generated a carry
-	addq	0,r12
+	addq	0,$r12
 
-	subq	10*4,r11
-	bge	mloop
+	subq	10*4,$r11
+	bge	_mloop
 	nop
 
-	addq	10*4,r11	; compensate for last loop underflowing length
+	addq	10*4,$r11	; compensate for last loop underflowing length
 
-	movem	[sp+],r8	; restore regs
+	movem	[$sp+],$r8	; restore regs
 
-word_loop:
+_word_loop:
 	;; only fold if there is anything to fold.
 
-	cmpq	0,r12
-	beq	no_fold
+	cmpq	0,$r12
+	beq	_no_fold
 
 	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below.
 	;; r9 and r13 can be used as temporaries.
 	
-	moveq	-1,r9		; put 0xffff in r9, faster than move.d 0xffff,r9
-	lsrq	16,r9
+	moveq	-1,$r9		; put 0xffff in r9, faster than move.d 0xffff,r9
+	lsrq	16,$r9
 	
-	move.d	r12,r13
-	lsrq	16,r13		; r13 = checksum >> 16
-	and.d	r9,r12		; checksum = checksum & 0xffff
-	add.d	r13,r12		; checksum += r13
-	move.d	r12,r13		; do the same again, maybe we got a carry last add
-	lsrq	16,r13
-	and.d	r9,r12
-	add.d	r13,r12
-
-no_fold:
-	cmpq	2,r11
-	blt	no_words
+	move.d	$r12,$r13
+	lsrq	16,$r13		; r13 = checksum >> 16
+	and.d	$r9,$r12		; checksum = checksum & 0xffff
+	add.d	$r13,$r12		; checksum += r13
+	move.d	$r12,$r13		; do the same again, maybe we got a carry last add
+	lsrq	16,$r13
+	and.d	$r9,$r12
+	add.d	$r13,$r12
+
+_no_fold:
+	cmpq	2,$r11
+	blt	_no_words
 	nop
 	
 	;; checksum the rest of the words
 	
-	subq	2,r11
+	subq	2,$r11
 	
-wloop:	subq	2,r11
-	bge	wloop
-	addu.w	[r10+],r12
+_wloop:	subq	2,$r11
+	bge	_wloop
+	addu.w	[$r10+],$r12
 	
-	addq	2,r11
+	addq	2,$r11
 		
-no_words:
+_no_words:
 	;; see if we have one odd byte more
-	cmpq	1,r11
-	beq	do_byte
+	cmpq	1,$r11
+	beq	_do_byte
 	nop
 	ret
-	move.d	r12, r10
+	move.d	$r12, $r10
 
-do_byte:	
+_do_byte:	
 	;; copy and checksum the last byte
-	addu.b	[r10],r12
+	addu.b	[$r10],$r12
 	ret
-	move.d	r12, r10
+	move.d	$r12, $r10
 		
diff -u --recursive --new-file v2.4.10/linux/arch/cris/lib/checksumcopy.S linux/arch/cris/lib/checksumcopy.S
--- v2.4.10/linux/arch/cris/lib/checksumcopy.S	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/lib/checksumcopy.S	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: checksumcopy.S,v 1.6 2001/06/28 03:57:16 hp Exp $
+/* $Id: checksumcopy.S,v 1.7 2001/10/01 14:47:35 bjornw Exp $
  * A fast checksum+copy routine using movem
  * Copyright (c) 1998, 2001 Axis Communications AB
  *
@@ -8,8 +8,8 @@
  *		             int len, unsigned int sum)
  */
 
-	.globl	_csum_partial_copy_nocheck
-_csum_partial_copy_nocheck:	
+	.globl	csum_partial_copy_nocheck
+csum_partial_copy_nocheck:	
 	
 	;; r10 - src
 	;; r11 - dst
@@ -20,8 +20,8 @@
 	;; we also do _NOT_ want to compute a checksum over more than the 
 	;; actual length when length < 40
 	
-	cmpu.w	80,r12
-	blo	word_loop
+	cmpu.w	80, $r12
+	blo	_word_loop
 	nop
 
 	;; need to save the registers we use below in the movem loop
@@ -29,104 +29,104 @@
 	;; only r0 - r8 have to be saved, the other ones are clobber-able
 	;; according to the ABI
 	
-	subq	9*4,sp
-	movem	r8,[sp]
+	subq	9*4, $sp
+	movem	$r8, [$sp]
 	
 	;; do a movem copy and checksum
 
-	subq	10*4,r12	; update length for the first loop
+	subq	10*4, $r12	; update length for the first loop
 	
-mloop:	movem	[r10+],r9	; read 10 longwords
+_mloop:	movem	[$r10+],$r9	; read 10 longwords
 1:	;; A failing userspace access will have this as PC.
-	movem	r9,[r11+]	; write 10 longwords
+	movem	$r9,[$r11+]	; write 10 longwords
 
 	;; perform dword checksumming on the 10 longwords
 	
-	add.d	r0,r13
+	add.d	$r0,$r13
 	ax
-	add.d	r1,r13
+	add.d	$r1,$r13
 	ax
-	add.d	r2,r13
+	add.d	$r2,$r13
 	ax
-	add.d	r3,r13
+	add.d	$r3,$r13
 	ax
-	add.d	r4,r13
+	add.d	$r4,$r13
 	ax
-	add.d	r5,r13
+	add.d	$r5,$r13
 	ax
-	add.d	r6,r13
+	add.d	$r6,$r13
 	ax
-	add.d	r7,r13
+	add.d	$r7,$r13
 	ax
-	add.d	r8,r13
+	add.d	$r8,$r13
 	ax
-	add.d	r9,r13
+	add.d	$r9,$r13
 
 	;; fold the carry into the checksum, to avoid having to loop the carry
 	;; back into the top
 	
 	ax
-	addq	0,r13
+	addq	0,$r13
 	ax			; do it again, since we might have generated a carry
-	addq	0,r13
+	addq	0,$r13
 
-	subq	10*4,r12
-	bge	mloop
+	subq	10*4,$r12
+	bge	_mloop
 	nop
 
-	addq	10*4,r12	; compensate for last loop underflowing length
+	addq	10*4,$r12	; compensate for last loop underflowing length
 
-	movem	[sp+],r8	; restore regs
+	movem	[$sp+],$r8	; restore regs
 
-word_loop:
+_word_loop:
 	;; only fold if there is anything to fold.
 
-	cmpq	0,r13
-	beq	no_fold
+	cmpq	0,$r13
+	beq	_no_fold
 
 	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
 	;; r9 can be used as temporary.
 	
-	move.d	r13,r9
-	lsrq	16,r9		; r0 = checksum >> 16
-	and.d	0xffff,r13	; checksum = checksum & 0xffff
-	add.d	r9,r13		; checksum += r0
-	move.d	r13,r9		; do the same again, maybe we got a carry last add
-	lsrq	16,r9
-	and.d	0xffff,r13
-	add.d	r9,r13
-	
-no_fold:
-	cmpq	2,r12
-	blt	no_words
+	move.d	$r13,$r9
+	lsrq	16,$r9		; r0 = checksum >> 16
+	and.d	0xffff,$r13	; checksum = checksum & 0xffff
+	add.d	$r9,$r13	; checksum += r0
+	move.d	$r13,$r9	; do the same again, maybe we got a carry last add
+	lsrq	16,$r9
+	and.d	0xffff,$r13
+	add.d	$r9,$r13
+	
+_no_fold:
+	cmpq	2,$r12
+	blt	_no_words
 	nop
 	
 	;; copy and checksum the rest of the words
 	
-	subq	2,r12
+	subq	2,$r12
 	
-wloop:	move.w	[r10+],r9
+_wloop:	move.w	[$r10+],$r9
 2:	;; A failing userspace access will have this as PC.
-	addu.w	r9,r13
-	subq	2,r12
-	bge	wloop
-	move.w	r9,[r11+]
+	addu.w	$r9,$r13
+	subq	2,$r12
+	bge	_wloop
+	move.w	$r9,[$r11+]
 	
-	addq	2,r12
+	addq	2,$r12
 		
-no_words:
+_no_words:
 	;; see if we have one odd byte more
-	cmpq	1,r12
-	beq	do_byte
+	cmpq	1,$r12
+	beq	_do_byte
 	nop
 	ret
-	move.d	r13, r10
+	move.d	$r13, $r10
 
-do_byte:	
+_do_byte:	
 	;; copy and checksum the last byte
-	move.b	[r10],r9
+	move.b	[$r10],$r9
 3:	;; A failing userspace access will have this as PC.
-	addu.b	r9,r13
-	move.b	r9,[r11]
+	addu.b	$r9,$r13
+	move.b	$r9,[$r11]
 	ret
-	move.d	r13, r10
+	move.d	$r13, $r10
diff -u --recursive --new-file v2.4.10/linux/arch/cris/lib/csumcpfruser.S linux/arch/cris/lib/csumcpfruser.S
--- v2.4.10/linux/arch/cris/lib/csumcpfruser.S	Sun Aug 12 13:27:58 2001
+++ linux/arch/cris/lib/csumcpfruser.S	Mon Oct  8 11:43:54 2001
@@ -21,7 +21,7 @@
    It is conveniently located on the stack, so the normal function body
    does not have to handle it.  */
 
-#define _csum_partial_copy_nocheck _csum_partial_copy_from_user
+#define csum_partial_copy_nocheck csum_partial_copy_from_user
 
 /* There are local labels numbered 1, 2 and 3 present to mark the
    different from-user accesses.  */
@@ -31,30 +31,30 @@
 
 ;; Here from the movem loop; restore stack.
 4:
-	movem	[sp+],r8
+	movem	[$sp+],$r8
 ;; r12 is already decremented.  Add back chunk_size-2.
-	addq	40-2,r12
+	addq	40-2,$r12
 
 ;; Here from the word loop; r12 is off by 2; add it back.
 5:
-	addq	2,r12
+	addq	2,$r12
 
 ;; Here from a failing single byte.
 6:
 
 ;; Signal in *errptr that we had a failing access.
-	moveq	-EFAULT,r9
-	move.d	r9,[[sp]]
+	moveq	-EFAULT,$r9
+	move.d	$r9,[[$sp]]
 
 ;; Clear the rest of the destination area using memset.  Preserve the
 ;; checksum for the readable bytes.
-	push	srp
-	push	r13
-	move.d	r11,r10
-	clear.d	r11
-	jsr	_memset
-	pop	r10
-	jump	[sp+]
+	push	$srp
+	push	$r13
+	move.d	$r11,$r10
+	clear.d	$r11
+	jsr	memset
+	pop	$r10
+	jump	[$sp+]
 
 	.previous
 	.section __ex_table,"a"
diff -u --recursive --new-file v2.4.10/linux/arch/cris/lib/dram_init.S linux/arch/cris/lib/dram_init.S
--- v2.4.10/linux/arch/cris/lib/dram_init.S	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/lib/dram_init.S	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,4 @@
-/* $Id: dram_init.S,v 1.8 2001/05/15 07:12:45 hp Exp $
+/* $Id: dram_init.S,v 1.10 2001/10/04 12:00:21 martinnn Exp $
  * 
  * DRAM/SDRAM initialization - alter with care
  * This file is intended to be included from other assembler files
@@ -11,6 +11,12 @@
  * Authors:  Mikael Starvik (starvik@axis.com)	
  * 
  * $Log: dram_init.S,v $
+ * Revision 1.10  2001/10/04 12:00:21  martinnn
+ * Added missing underscores.
+ *
+ * Revision 1.9  2001/10/01 14:47:35  bjornw
+ * Added register prefixes and removed underscores
+ *
  * Revision 1.8  2001/05/15 07:12:45  hp
  * Copy warning from head.S about r8 and r9
  *
@@ -52,24 +58,24 @@
 	;; They should not be used in the code below.
 
 #ifndef CONFIG_SVINTO_SIM	
-	move.d   CONFIG_ETRAX_DEF_R_WAITSTATES, r0
-	move.d   r0, [R_WAITSTATES]
+	move.d   CONFIG_ETRAX_DEF_R_WAITSTATES, $r0
+	move.d   $r0, [R_WAITSTATES]
 
-	move.d   CONFIG_ETRAX_DEF_R_BUS_CONFIG, r0
-	move.d   r0, [R_BUS_CONFIG]
+	move.d   CONFIG_ETRAX_DEF_R_BUS_CONFIG, $r0
+	move.d   $r0, [R_BUS_CONFIG]
 	
 #ifndef CONFIG_ETRAX_SDRAM
-	move.d   CONFIG_ETRAX_DEF_R_DRAM_CONFIG, r0
-	move.d   r0, [R_DRAM_CONFIG]
+	move.d   CONFIG_ETRAX_DEF_R_DRAM_CONFIG, $r0
+	move.d   $r0, [R_DRAM_CONFIG]
 
-	move.d   CONFIG_ETRAX_DEF_R_DRAM_TIMING, r0
-	move.d   r0, [R_DRAM_TIMING]
+	move.d   CONFIG_ETRAX_DEF_R_DRAM_TIMING, $r0
+	move.d   $r0, [R_DRAM_TIMING]
 #else	
 	; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
 	
 	; Bank configuration
-	move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, r0
-	move.d   r0, [R_SDRAM_CONFIG]
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r0
+	move.d   $r0, [R_SDRAM_CONFIG]
 
 	; Calculate value of mrs_data 
 	; CAS latency = 2 && bus_width = 32 => 0x40
@@ -77,71 +83,69 @@
 	; CAS latency = 2 && bus_width = 16 => 0x20
 	; CAS latency = 3 && bus_width = 16 => 0x30
 	
-	move.d   0x40, r2       ; Assume 32 bits and CAS latency = 2
-	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, r1
-	move.d   r1, r3
- 	and.d    0x03, r1       ; Get CAS latency
-	and.d    0x1000, r3     ; 50 or 100 MHz?
-	beq      speed_50
-	nop
-speed_100:		
-	cmp.d    0x00, r1	; CAS latency = 2?
-	beq      bw_check
-	nop
-	or.d     0x20, r2	; CAS latency = 3 
-	ba       bw_check
-	nop
-speed_50:			
-	cmp.d    0x01, r1	; CAS latency = 2?
-	beq      bw_check
-	nop
-	or.d     0x20, r2       ; CAS latency = 3
-bw_check:
-	move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, r1
-	and.d    0x800000, r1	; DRAM width is bit 23
-	bne      set_timing
+	move.d   0x40, $r2       ; Assume 32 bits and CAS latency = 2
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
+	move.d   $r1, $r3
+ 	and.d    0x03, $r1       ; Get CAS latency
+	and.d    0x1000, $r3     ; 50 or 100 MHz?
+	beq      _speed_50
+	nop
+_speed_100:		
+	cmp.d    0x00, $r1	; CAS latency = 2?
+	beq      _bw_check
+	nop
+	or.d     0x20, $r2	; CAS latency = 3 
+	ba       _bw_check
+	nop
+_speed_50:			
+	cmp.d    0x01, $r1	; CAS latency = 2?
+	beq      _bw_check
+	nop
+	or.d     0x20, $r2       ; CAS latency = 3
+_bw_check:
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r1
+	and.d    0x800000, $r1	; DRAM width is bit 23
+	bne      _set_timing
 	nop
-	lsrq     1, r2		;  16 bits. Shift down value.
+	lsrq     1, $r2		;  16 bits. Shift down value.
 
 	; Set timing parameters. Starts master clock
-set_timing:
-	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, r1
-	and.d    0x8000f9ff, r1 ; Make sure mrs data and command is 0 
-	or.d     0x80000000, r1	; Make sure sdram enable bit is set
-	move.d   r1, r5
-	or.d     0x0000c000, r1 ; ref = disable
-	lslq     16, r2		; mrs data starts at bit 16
-	or.d     r2, r1 
-	move.d   r1, [R_SDRAM_TIMING]	
+_set_timing:
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
+	and.d    0x8000f9ff, $r1 ; Make sure mrs data and command is 0 
+	or.d     0x80000000, $r1	; Make sure sdram enable bit is set
+	move.d   $r1, $r5
+	or.d     0x0000c000, $r1 ; ref = disable
+	lslq     16, $r2		; mrs data starts at bit 16
+	or.d     $r2, $r1 
+	move.d   $r1, [R_SDRAM_TIMING]	
 		
 	; Wait 200us
-	move.d   10000, r2
-sdram_loop:
-	bne      sdram_loop
-	subq     1, r2
+	move.d   10000, $r2
+1:	bne      1b
+	subq     1, $r2
 	
 	; Issue initialization command sequence
-	move.d   sdram_commands_start, r2
-	move.d   sdram_commands_end,  r3
-command_loop:
-	clear.d  r4
-	move.b   [r2+], r4
-	lslq     9, r4	; Command starts at bit 9
-	or.d     r1, r4
-	move.d   r4, [R_SDRAM_TIMING]
+	move.d   _sdram_commands_start, $r2
+	move.d   _sdram_commands_end,  $r3
+1:	clear.d  $r4
+	move.b   [$r2+], $r4
+	lslq     9, $r4	; Command starts at bit 9
+	or.d     $r1, $r4
+	move.d   $r4, [R_SDRAM_TIMING]
 	nop		; Wait five nop cycles between each command
 	nop
 	nop
 	nop
 	nop
-	cmp.d    r2, r3
-	bne      command_loop
+	cmp.d    $r2, $r3
+	bne      1b
 	nop
-	move.d   r5, [R_SDRAM_TIMING]
-	ba       sdram_commands_end
+	move.d   $r5, [R_SDRAM_TIMING]
+	ba       _sdram_commands_end
 	nop
 
-sdram_commands_start:
+_sdram_commands_start:
 	.byte   3	; Precharge
 	.byte   0       ; nop
 	.byte   2	; refresh
@@ -162,6 +166,6 @@
 	.byte   0	; nop
 	.byte   1	; mrs
 	.byte   0	; nop 
-sdram_commands_end:		
+_sdram_commands_end:		
 #endif
 #endif
diff -u --recursive --new-file v2.4.10/linux/arch/cris/lib/memset.c linux/arch/cris/lib/memset.c
--- v2.4.10/linux/arch/cris/lib/memset.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/lib/memset.c	Mon Oct  8 11:43:54 2001
@@ -56,12 +56,12 @@
 
   /* Ugh.  This is fragile at best.  Check with newer GCC releases, if
      they compile cascaded "x |= x << 8" sanely! */
-  __asm__("movu.b %0,r13\n\t"
-          "lslq 8,r13\n\t"
-	  "move.b %0,r13\n\t"
-	  "move.d r13,%0\n\t"
-	  "lslq 16,r13\n\t"
-	  "or.d r13,%0"
+  __asm__("movu.b %0,$r13\n\t"
+          "lslq 8,$r13\n\t"
+	  "move.b %0,$r13\n\t"
+	  "move.d $r13,%0\n\t"
+	  "lslq 16,$r13\n\t"
+	  "or.d $r13,%0"
           : "=r" (lc) : "0" (lc) : "r13");
 
   {
@@ -118,36 +118,36 @@
 	;; Save the registers we'll clobber in the movem process
 	;; on the stack.  Don't mention them to gcc, it will only be
 	;; upset.
-	subq 	11*4,sp
-        movem   r10,[sp]
+	subq 	11*4,$sp
+        movem   $r10,[$sp]
 
-        move.d  r11,r0
-        move.d  r11,r1
-        move.d  r11,r2
-        move.d  r11,r3
-        move.d  r11,r4
-        move.d  r11,r5
-        move.d  r11,r6
-        move.d  r11,r7
-        move.d  r11,r8
-        move.d  r11,r9
-        move.d  r11,r10
+        move.d  $r11,$r0
+        move.d  $r11,$r1
+        move.d  $r11,$r2
+        move.d  $r11,$r3
+        move.d  $r11,$r4
+        move.d  $r11,$r5
+        move.d  $r11,$r6
+        move.d  $r11,$r7
+        move.d  $r11,$r8
+        move.d  $r11,$r9
+        move.d  $r11,$r10
 
         ;; Now we've got this:
 	;; r13 - dst
 	;; r12 - n
 	
         ;; Update n for the first loop
-        subq    12*4,r12
+        subq    12*4,$r12
 0:
-        subq   12*4,r12
+        subq   12*4,$r12
         bge     0b
-	movem	r11,[r13+]
+	movem	$r11,[$r13+]
 
-        addq   12*4,r12  ;; compensate for last loop underflowing n
+        addq   12*4,$r12  ;; compensate for last loop underflowing n
 
 	;; Restore registers from stack
-        movem [sp+],r10" 
+        movem [$sp+],$r10" 
 
      /* Outputs */ : "=r" (dst), "=r" (n)
      /* Inputs */ : "0" (dst), "1" (n), "r" (lc));
diff -u --recursive --new-file v2.4.10/linux/arch/cris/lib/string.c linux/arch/cris/lib/string.c
--- v2.4.10/linux/arch/cris/lib/string.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/lib/string.c	Mon Oct  8 11:43:54 2001
@@ -102,8 +102,8 @@
         ;;
 	;; Save the registers we'll use in the movem process
 	;; on the stack.
-	subq 	11*4,sp
-	movem	r10,[sp]
+	subq 	11*4,$sp
+	movem	$r10,[$sp]
 
         ;; Now we've got this:
 	;; r11 - src
@@ -111,17 +111,17 @@
 	;; r12 - n
 	
         ;; Update n for the first loop
-        subq    44,r12
+        subq    44,$r12
 0:
-	movem	[r11+],r10
-        subq   44,r12
+	movem	[$r11+],$r10
+        subq   44,$r12
         bge     0b
-	movem	r10,[r13+]
+	movem	$r10,[$r13+]
 
-        addq   44,r12  ;; compensate for last loop underflowing n
+        addq   44,$r12  ;; compensate for last loop underflowing n
 
 	;; Restore registers from stack
-        movem [sp+],r10" 
+        movem [$sp+],$r10" 
 
      /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) 
      /* Inputs */ : "0" (dst), "1" (src), "2" (n));
diff -u --recursive --new-file v2.4.10/linux/arch/cris/lib/usercopy.c linux/arch/cris/lib/usercopy.c
--- v2.4.10/linux/arch/cris/lib/usercopy.c	Wed Jul 25 17:10:17 2001
+++ linux/arch/cris/lib/usercopy.c	Mon Oct  8 11:43:54 2001
@@ -95,8 +95,8 @@
 	;;
 	;; Save the registers we'll use in the movem process
 	;; on the stack.
-	subq	11*4,sp
-	movem	r10,[sp]
+	subq	11*4,$sp
+	movem	$r10,[$sp]
 
 	;; Now we've got this:
 	;; r11 - src
@@ -104,7 +104,7 @@
 	;; r12 - n
 
 	;; Update n for the first loop
-	subq	44,r12
+	subq	44,$r12
 
 ; Since the noted PC of a faulting instruction in a delay-slot of a taken
 ; branch, is that of the branch target, we actually point at the from-movem
@@ -113,15 +113,15 @@
 ; after *that* movem.
 
 0:
-	movem	[r11+],r10
-	subq   44,r12
+	movem	[$r11+],$r10
+	subq   44,$r12
 	bge	0b
-	movem	r10,[r13+]
+	movem	$r10,[$r13+]
 1:
-	addq   44,r12  ;; compensate for last loop underflowing n
+	addq   44,$r12  ;; compensate for last loop underflowing n
 
 	;; Restore registers from stack
-	movem [sp+],r10
+	movem [$sp+],$r10
 2:
 	.section .fixup,\"ax\"
 
@@ -130,14 +130,14 @@
 ; performance penalty for sany use; the program will segfault soon enough.
 
 3:
-	move.d [sp],r10
-	addq 44,r10
-	move.d r10,[sp]
+	move.d [$sp],$r10
+	addq 44,$r10
+	move.d $r10,[$sp]
 	jump 0b
 4:
-	movem [sp+],r10
-	addq 44,r10
-	addq 44,r12
+	movem [$sp+],$r10
+	addq 44,$r10
+	addq 44,$r12
 	jump 2b
 
 	.previous
@@ -255,8 +255,8 @@
 	;;
 	;; Save the registers we'll use in the movem process
 	;; on the stack.
-	subq	11*4,sp
-	movem	r10,[sp]
+	subq	11*4,$sp
+	movem	$r10,[$sp]
 
 	;; Now we've got this:
 	;; r11 - src
@@ -264,18 +264,18 @@
 	;; r12 - n
 
 	;; Update n for the first loop
-	subq	44,r12
+	subq	44,$r12
 0:
-	movem	[r11+],r10
+	movem	[$r11+],$r10
 1:
-	subq   44,r12
+	subq   44,$r12
 	bge	0b
-	movem	r10,[r13+]
+	movem	$r10,[$r13+]
 
-	addq   44,r12  ;; compensate for last loop underflowing n
+	addq   44,$r12  ;; compensate for last loop underflowing n
 8:
 	;; Restore registers from stack
-	movem [sp+],r10
+	movem [$sp+],$r10
 
 	.section .fixup,\"ax\"
 
@@ -287,57 +287,57 @@
 ;; the SIZE bytes at PAGE after the first fault.
 
 3:
-	move.d [sp],r10
+	move.d [$sp],$r10
 
 ;; Number of remaining bytes, cleared but not copied, is r12 + 44.
 
-	add.d r12,r10
-	addq 44,r10
+	add.d $r12,$r10
+	addq 44,$r10
 
-	move.d r10,[sp]
-	clear.d r0
-	clear.d r1
-	clear.d r2
-	clear.d r3
-	clear.d r4
-	clear.d r5
-	clear.d r6
-	clear.d r7
-	clear.d r8
-	clear.d r9
-	clear.d r10
+	move.d $r10,[$sp]
+	clear.d $r0
+	clear.d $r1
+	clear.d $r2
+	clear.d $r3
+	clear.d $r4
+	clear.d $r5
+	clear.d $r6
+	clear.d $r7
+	clear.d $r8
+	clear.d $r9
+	clear.d $r10
 
 ;; Perform clear similar to the copy-loop.
 
 4:
-	subq 44,r12
+	subq 44,$r12
 	bge 4b
-	movem r10,[r13+]
+	movem $r10,[$r13+]
 
 ;; Clear by four for the remaining multiples.
 
-	addq 40,r12
+	addq 40,$r12
 	bmi 6f
 	nop
 5:
-	subq 4,r12
+	subq 4,$r12
 	bpl 5b
-	clear.d [r13+]
+	clear.d [$r13+]
 6:
-	addq 4,r12
+	addq 4,$r12
 	beq 7f
 	nop
 
-	subq 1,r12
+	subq 1,$r12
 	beq 7f
-	clear.b [r13+]
+	clear.b [$r13+]
 
-	subq 1,r12
+	subq 1,$r12
 	beq 7f
-	clear.b [r13+]
+	clear.b [$r13+]
 
-	clear.d r12
-	clear.b [r13+]
+	clear.d $r12
+	clear.b [$r13+]
 7:
 	jump 8b
 
@@ -451,50 +451,50 @@
 	;; Save the registers we'll clobber in the movem process
 	;; on the stack.  Don't mention them to gcc, it will only be
 	;; upset.
-	subq	11*4,sp
-	movem	r10,[sp]
+	subq	11*4,$sp
+	movem	$r10,[$sp]
 
-	clear.d r0
-	clear.d r1
-	clear.d r2
-	clear.d r3
-	clear.d r4
-	clear.d r5
-	clear.d r6
-	clear.d r7
-	clear.d r8
-	clear.d r9
-	clear.d r10
-	clear.d r11
+	clear.d $r0
+	clear.d $r1
+	clear.d $r2
+	clear.d $r3
+	clear.d $r4
+	clear.d $r5
+	clear.d $r6
+	clear.d $r7
+	clear.d $r8
+	clear.d $r9
+	clear.d $r10
+	clear.d $r11
 
 	;; Now we've got this:
 	;; r13 - dst
 	;; r12 - n
 
 	;; Update n for the first loop
-	subq	12*4,r12
+	subq	12*4,$r12
 0:
-	subq   12*4,r12
+	subq   12*4,$r12
 	bge	0b
-	movem	r11,[r13+]
+	movem	$r11,[$r13+]
 1:
-	addq   12*4,r12	 ;; compensate for last loop underflowing n
+	addq   12*4,$r12        ;; compensate for last loop underflowing n
 
 	;; Restore registers from stack
-	movem [sp+],r10
+	movem [$sp+],$r10
 2:
 	.section .fixup,\"ax\"
 3:
-	move.d [sp],r10
-	addq 12*4,r10
-	move.d r10,[sp]
-	clear.d r10
+	move.d [$sp],$r10
+	addq 12*4,$r10
+	move.d $r10,[$sp]
+	clear.d $r10
 	jump 0b
 
 4:
-	movem [sp+],r10
-	addq 12*4,r10
-	addq 12*4,r12
+	movem [$sp+],$r10
+	addq 12*4,$r10
+	addq 12*4,$r12
 	jump 2b
 
 	.previous
diff -u --recursive --new-file v2.4.10/linux/arch/cris/mm/extable.c linux/arch/cris/mm/extable.c
--- v2.4.10/linux/arch/cris/mm/extable.c	Tue May  1 16:04:56 2001
+++ linux/arch/cris/mm/extable.c	Mon Oct  8 11:43:54 2001
@@ -1,13 +1,19 @@
 /*
  * linux/arch/cris/mm/extable.c
+ *
+ * $Log: extable.c,v $
+ * Revision 1.3  2001/09/27 13:52:40  bjornw
+ * Harmonize underscore-ness with other parts
+ *
+ *
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
-extern const struct exception_table_entry _start___ex_table[];
-extern const struct exception_table_entry _stop___ex_table[];
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
 
 static inline unsigned long
 search_one_table(const struct exception_table_entry *first,
@@ -37,7 +43,7 @@
 
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
-	return search_one_table(_start___ex_table, _stop___ex_table-1, addr);
+	return search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
diff -u --recursive --new-file v2.4.10/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c
--- v2.4.10/linux/arch/i386/boot/compressed/misc.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/boot/compressed/misc.c	Thu Oct  4 18:42:54 2001
@@ -123,6 +123,10 @@
 static int vidport;
 static int lines, cols;
 
+#ifdef CONFIG_MULTIQUAD
+static void *xquad_portio = NULL;
+#endif
+
 #include "../../../../lib/inflate.c"
 
 static void *malloc(int size)
diff -u --recursive --new-file v2.4.10/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.4.10/linux/arch/i386/config.in	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/config.in	Thu Oct  4 18:42:54 2001
@@ -170,11 +170,16 @@
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
 if [ "$CONFIG_SMP" != "y" ]; then
-   bool 'APIC and IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC
+   bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
+   dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
+   if [ "$CONFIG_X86_UP_APIC" = "y" ]; then
+      define_bool CONFIG_X86_LOCAL_APIC y
+   fi
    if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then
       define_bool CONFIG_X86_IO_APIC y
-      define_bool CONFIG_X86_LOCAL_APIC y
    fi
+else
+   bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
 fi
 
 if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
diff -u --recursive --new-file v2.4.10/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.4.10/linux/arch/i386/defconfig	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/defconfig	Mon Oct  8 13:29:26 2001
@@ -59,6 +59,7 @@
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_MTRR is not set
 CONFIG_SMP=y
+# CONFIG_MULTIQUAD is not set
 CONFIG_HAVE_DEC_LOCK=y
 
 #
@@ -311,7 +312,6 @@
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_NCR53C8XX is not set
 CONFIG_SCSI_SYM53C8XX=y
@@ -604,6 +604,7 @@
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
@@ -737,6 +738,7 @@
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
 # CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -753,6 +755,7 @@
 #
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_USBNET is not set
 
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/apic.c linux/arch/i386/kernel/apic.c
--- v2.4.10/linux/arch/i386/kernel/apic.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/apic.c	Thu Oct  4 18:42:54 2001
@@ -48,7 +48,7 @@
 	return maxlvt;
 }
 
-static void clear_local_APIC(void)
+void clear_local_APIC(void)
 {
 	int maxlvt;
 	unsigned long v;
@@ -254,6 +254,14 @@
 {
 	unsigned long value, ver, maxlvt;
 
+	/* Pound the ESR really hard over the head with a big hammer - mbligh */
+	if (esr_disable) {
+		apic_write(APIC_ESR, 0);
+		apic_write(APIC_ESR, 0);
+		apic_write(APIC_ESR, 0);
+		apic_write(APIC_ESR, 0);
+	}
+
 	value = apic_read(APIC_LVR);
 	ver = GET_APIC_VERSION(value);
 
@@ -262,8 +270,10 @@
 
 	/*
 	 * Double-check wether this APIC is really registered.
+	 * This is meaningless in clustered apic mode, so we skip it.
 	 */
-	if (!test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
+	if (!clustered_apic_mode && 
+	    !test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
 		BUG();
 
 	/*
@@ -272,19 +282,22 @@
 	 * document number 292116).  So here it goes...
 	 */
 
-	/*
-	 * Put the APIC into flat delivery mode.
-	 * Must be "all ones" explicitly for 82489DX.
-	 */
-	apic_write_around(APIC_DFR, 0xffffffff);
+	if (!clustered_apic_mode) {
+		/*
+		 * In clustered apic mode, the firmware does this for us 
+		 * Put the APIC into flat delivery mode.
+		 * Must be "all ones" explicitly for 82489DX.
+		 */
+		apic_write_around(APIC_DFR, 0xffffffff);
 
-	/*
-	 * Set up the logical destination ID.
-	 */
-	value = apic_read(APIC_LDR);
-	value &= ~APIC_LDR_MASK;
-	value |= (1<<(smp_processor_id()+24));
-	apic_write_around(APIC_LDR, value);
+		/*
+		 * Set up the logical destination ID.
+		 */
+		value = apic_read(APIC_LDR);
+		value &= ~APIC_LDR_MASK;
+		value |= (1<<(smp_processor_id()+24));
+		apic_write_around(APIC_LDR, value);
+	}
 
 	/*
 	 * Set Task Priority to 'accept all'. We never change this
@@ -367,7 +380,7 @@
 		value |= APIC_LVT_LEVEL_TRIGGER;
 	apic_write_around(APIC_LVT1, value);
 
-	if (APIC_INTEGRATED(ver)) {		/* !82489DX */
+	if (APIC_INTEGRATED(ver) && !esr_disable) {		/* !82489DX */
 		maxlvt = get_maxlvt();
 		if (maxlvt > 3)		/* Due to the Pentium erratum 3AP. */
 			apic_write(APIC_ESR, 0);
@@ -383,8 +396,18 @@
 			apic_write(APIC_ESR, 0);
 		value = apic_read(APIC_ESR);
 		printk("ESR value after enabling vector: %08lx\n", value);
-	} else
-		printk("No ESR for 82489DX.\n");
+	} else {
+		if (esr_disable)	
+			/* 
+			 * Something untraceble is creating bad interrupts on 
+			 * secondary quads ... for the moment, just leave the
+			 * ESR disabled - we can't do anything useful with the
+			 * errors anyway - mbligh
+			 */
+			printk("Leaving ESR disabled.\n");
+		else 
+			printk("No ESR for 82489DX.\n");
+	}
 
 	if (nmi_watchdog == NMI_LOCAL_APIC)
 		setup_apic_nmi_watchdog();
@@ -598,7 +621,7 @@
 	}
 	set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability);
 	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-	boot_cpu_id = 0;
+	boot_cpu_physical_apicid = 0;
 	if (nmi_watchdog != NMI_NONE)
 		nmi_watchdog = NMI_LOCAL_APIC;
 
@@ -636,8 +659,8 @@
 	 * Fetch the APIC ID of the BSP in case we have a
 	 * default configuration (or the MP table is broken).
 	 */
-	if (boot_cpu_id == -1U)
-		boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
+	if (boot_cpu_physical_apicid == -1U)
+		boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
 
 #ifdef CONFIG_X86_IO_APIC
 	{
@@ -1077,9 +1100,9 @@
 	/*
 	 * Complain if the BIOS pretends there is one.
 	 */
-	if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_id])) {
+	if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
 		printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
-			boot_cpu_id);
+			boot_cpu_physical_apicid);
 		return -1;
 	}
 
@@ -1088,7 +1111,7 @@
 	connect_bsp_APIC();
 
 	phys_cpu_present_map = 1;
-	apic_write_around(APIC_ID, boot_cpu_id);
+	apic_write_around(APIC_ID, boot_cpu_physical_apicid);
 
 	apic_pm_init2();
 
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- v2.4.10/linux/arch/i386/kernel/apm.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/apm.c	Sun Sep 30 12:26:42 2001
@@ -689,7 +689,6 @@
 		(void) apm_set_power_state(APM_STATE_OFF);
 }
 
-#ifdef CONFIG_MAGIC_SYSRQ
 /*
  * Magic sysrq key and handler for the power off function
  */
@@ -703,7 +702,6 @@
 	help_msg:       "Off",
 	action_msg:     "Power Off\n"
 };
-#endif
 
 
 #ifdef CONFIG_APM_DO_ENABLE
@@ -1672,7 +1670,7 @@
 		apm_info.realmode_power_off = 1;
 	/* User can override, but default is to trust DMI */
 	if (apm_disabled != -1)
-		apm_info.disabled = 1;
+		apm_info.disabled = apm_disabled;
 
 	/*
 	 * Fix for the Compaq Contura 3/25c which reports BIOS version 0.1
@@ -1699,8 +1697,7 @@
 	}
 
 	if (apm_info.disabled) {
-		if(apm_disabled == 1)
-			printk(KERN_NOTICE "apm: disabled on user request.\n");
+		printk(KERN_NOTICE "apm: disabled on user request.\n");
 		return -ENODEV;
 	}
 	if ((smp_num_cpus > 1) && !power_off) {
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.4.10/linux/arch/i386/kernel/entry.S	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/entry.S	Mon Oct  8 10:39:58 2001
@@ -44,7 +44,6 @@
 #include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#define ASSEMBLY
 #include <asm/smp.h>
 
 EBX		= 0x00
@@ -620,6 +619,8 @@
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
 	.long SYMBOL_NAME(sys_fcntl64)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* Reserved for Security */
+	.long SYMBOL_NAME(sys_gettid)
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.4.10/linux/arch/i386/kernel/io_apic.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/io_apic.c	Thu Oct  4 18:42:54 2001
@@ -44,11 +44,6 @@
  */
 int nr_ioapic_registers[MAX_IO_APICS];
 
-#if CONFIG_SMP
-# define TARGET_CPUS cpu_online_map
-#else
-# define TARGET_CPUS 0x01
-#endif
 /*
  * Rough estimation of how many shared IRQs there are, can
  * be changed anytime.
@@ -603,7 +598,7 @@
 		memset(&entry,0,sizeof(entry));
 
 		entry.delivery_mode = dest_LowestPrio;
-		entry.dest_mode = 1;			/* logical delivery */
+		entry.dest_mode = INT_DELIVERY_MODE;
 		entry.mask = 0;				/* enable IRQ */
 		entry.dest.logical.logical_dest = TARGET_CPUS;
 
@@ -677,7 +672,7 @@
 	 * We use logical delivery to get the timer IRQ
 	 * to the first CPU.
 	 */
-	entry.dest_mode = 1;				/* logical delivery */
+	entry.dest_mode = INT_DELIVERY_MODE;
 	entry.mask = 0;					/* unmask IRQ now */
 	entry.dest.logical.logical_dest = TARGET_CPUS;
 	entry.delivery_mode = dest_LowestPrio;
@@ -1016,6 +1011,9 @@
 	unsigned char old_id;
 	unsigned long flags;
 
+	if (clustered_apic_mode)
+		/* We don't have a good way to do this yet - hack */
+		phys_id_present_map = (u_long) 0xf;
 	/*
 	 * Set the IOAPIC ID to the value stored in the MPC table.
 	 */
@@ -1053,7 +1051,11 @@
 				i);
 			phys_id_present_map |= 1 << i;
 			mp_ioapics[apic].mpc_apicid = i;
+		} else {
+			printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid);
+			phys_id_present_map |= 1 << mp_ioapics[apic].mpc_apicid;
 		}
+
 
 		/*
 		 * We need to adjust the IRQ routing table
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/mpparse.c linux/arch/i386/kernel/mpparse.c
--- v2.4.10/linux/arch/i386/kernel/mpparse.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/mpparse.c	Thu Oct  4 18:42:54 2001
@@ -54,7 +54,7 @@
 unsigned long mp_lapic_addr;
 
 /* Processor that is doing the boot up */
-unsigned int boot_cpu_id = -1U;
+unsigned int boot_cpu_physical_apicid = -1U;
 /* Internal processor count */
 static unsigned int num_processors;
 
@@ -180,8 +180,9 @@
 
 	if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
 		Dprintk("    Bootup CPU\n");
-		boot_cpu_id = m->mpc_apicid;
+		boot_cpu_physical_apicid = m->mpc_apicid;
 	}
+
 	num_processors++;
 
 	if (m->mpc_apicid > MAX_APICS) {
@@ -191,7 +192,12 @@
 	}
 	ver = m->mpc_apicver;
 
-	phys_cpu_present_map |= 1 << m->mpc_apicid;
+	if (clustered_apic_mode)
+		/* Crude temporary hack. Assumes processors are sequential */
+		phys_cpu_present_map |= 1 << (num_processors-1);
+	else
+		phys_cpu_present_map |= 1 << m->mpc_apicid;
+
 	/*
 	 * Validate version
 	 */
@@ -376,6 +382,10 @@
 				break;
 			}
 		}
+	}
+	if (clustered_apic_mode && nr_ioapics > 2) {
+		/* don't initialise IO apics on secondary quads */
+		nr_ioapics = 2;
 	}
 	if (!num_processors)
 		printk(KERN_ERR "SMP mptable: no processors registered!\n");
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c
--- v2.4.10/linux/arch/i386/kernel/pci-pc.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/pci-pc.c	Tue Oct  9 16:17:38 2001
@@ -261,18 +261,14 @@
 	u32 data;
 	result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 2, &data);
-	*value = (u8)data;
+	*value = (u16)data;
 	return result;
 }
 
 static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-	int result; 
-	u32 data;
-	result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
-		PCI_FUNC(dev->devfn), where, 4, &data);
-	*value = (u8)data;
-	return result;
+	return pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
 }
 
 static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value)
@@ -1154,6 +1150,26 @@
 	d->irq = 9;
 }
 
+/*
+ * Nobody seems to know what this does. Damn.
+ *
+ * But it does seem to fix some unspecified problem
+ * with 'movntq' copies on Athlons.
+ *
+ * VIA 8363 chipset:
+ *  - bit 7 at offset 0x55: Debug (RW)
+ */
+static void __init pci_fixup_via_athlon_bug(struct pci_dev *d)
+{
+	u8 v;
+	pci_read_config_byte(d, 0x55, &v);
+	if (v & 0x80) {
+		printk("Trying to stomp on Athlon bug...\n");
+		v &= 0x7f; /* clear bit 55.7 */
+		pci_write_config_byte(d, 0x55, v);
+	}
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82451NX,	pci_fixup_i450nx },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454GX,	pci_fixup_i450gx },
@@ -1173,6 +1189,7 @@
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5597,		pci_fixup_latency },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5598,		pci_fixup_latency },
  	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371AB_3,	pci_fixup_piix4_acpi },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	pci_fixup_via_athlon_bug },
 	{ 0 }
 };
 
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.4.10/linux/arch/i386/kernel/process.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/process.c	Thu Oct  4 18:42:54 2001
@@ -376,7 +376,7 @@
 		if ((reboot_cpu == -1) ||  
 		      (reboot_cpu > (NR_CPUS -1))  || 
 		      !(phys_cpu_present_map & (1<<cpuid))) 
-			reboot_cpu = boot_cpu_id;
+			reboot_cpu = boot_cpu_physical_apicid;
 
 		reboot_smp = 0;  /* use this as a flag to only go through this once*/
 		/* re-run this function on the other CPUs
@@ -442,7 +442,7 @@
 	printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, smp_processor_id());
 	if (regs->xcs & 3)
 		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
-	printk(" EFLAGS: %08lx\n",regs->eflags);
+	printk(" EFLAGS: %08lx    %s\n",regs->eflags, print_tainted());
 	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
 		regs->eax,regs->ebx,regs->ecx,regs->edx);
 	printk("ESI: %08lx EDI: %08lx EBP: %08lx",
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.4.10/linux/arch/i386/kernel/setup.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/setup.c	Fri Oct  5 14:45:00 2001
@@ -2422,6 +2422,10 @@
 		if (!(cpu_online_map & (1<<n)))
 			continue;
 #endif
+		/* Stupid hack */
+		if (p - buffer > (3*PAGE_SIZE)/4)
+			break;
+
 		p += sprintf(p,"processor\t: %d\n"
 			"vendor_id\t: %s\n"
 			"cpu family\t: %d\n"
@@ -2479,7 +2483,7 @@
 	return p - buffer;
 }
 
-static unsigned long cpu_initialized __initdata = 0;
+unsigned long cpu_initialized __initdata = 0;
 
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.4.10/linux/arch/i386/kernel/smp.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/smp.c	Thu Oct  4 18:42:54 2001
@@ -20,6 +20,7 @@
 
 #include <asm/mtrr.h>
 #include <asm/pgalloc.h>
+#include <asm/smpboot.h>
 
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
@@ -148,28 +149,12 @@
 	apic_write_around(APIC_ICR, cfg);
 }
 
-static inline void send_IPI_allbutself(int vector)
-{
-	/*
-	 * if there are no other CPUs in the system then
-	 * we get an APIC send error if we try to broadcast.
-	 * thus we have to avoid sending IPIs in this case.
-	 */
-	if (smp_num_cpus > 1)
-		__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
-}
-
-static inline void send_IPI_all(int vector)
-{
-	__send_IPI_shortcut(APIC_DEST_ALLINC, vector);
-}
-
 void send_IPI_self(int vector)
 {
 	__send_IPI_shortcut(APIC_DEST_SELF, vector);
 }
 
-static inline void send_IPI_mask(int mask, int vector)
+static inline void send_IPI_mask_bitmask(int mask, int vector)
 {
 	unsigned long cfg;
 	unsigned long flags;
@@ -177,27 +162,120 @@
 	__save_flags(flags);
 	__cli();
 
+		
 	/*
 	 * Wait for idle.
 	 */
 	apic_wait_icr_idle();
-
+		
 	/*
 	 * prepare target chip field
 	 */
 	cfg = __prepare_ICR2(mask);
 	apic_write_around(APIC_ICR2, cfg);
-
+		
 	/*
 	 * program the ICR 
 	 */
 	cfg = __prepare_ICR(0, vector);
-	
+			
 	/*
 	 * Send the IPI. The write to APIC_ICR fires this off.
 	 */
 	apic_write_around(APIC_ICR, cfg);
+
 	__restore_flags(flags);
+}
+
+static inline void send_IPI_mask_sequence(int mask, int vector)
+{
+	unsigned long cfg, flags;
+	unsigned int query_cpu, query_mask;
+
+	/*
+	 * Hack. The clustered APIC addressing mode doesn't allow us to send 
+	 * to an arbitrary mask, so I do a unicasts to each CPU instead. This 
+	 * should be modified to do 1 message per cluster ID - mbligh
+	 */ 
+
+	__save_flags(flags);
+	__cli();
+
+	for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
+		query_mask = 1 << query_cpu;
+		if (query_mask & mask) {
+		
+			/*
+			 * Wait for idle.
+			 */
+			apic_wait_icr_idle();
+		
+			/*
+			 * prepare target chip field
+			 */
+			cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu));
+			apic_write_around(APIC_ICR2, cfg);
+		
+			/*
+			 * program the ICR 
+			 */
+			cfg = __prepare_ICR(0, vector);
+			
+			/*
+			 * Send the IPI. The write to APIC_ICR fires this off.
+			 */
+			apic_write_around(APIC_ICR, cfg);
+		}
+	}
+	__restore_flags(flags);
+}
+
+static inline void send_IPI_mask(int mask, int vector)
+{
+	if (clustered_apic_mode) 
+		send_IPI_mask_sequence(mask, vector);
+	else
+		send_IPI_mask_bitmask(mask, vector);
+}
+
+static inline void send_IPI_allbutself(int vector)
+{
+	/*
+	 * if there are no other CPUs in the system then
+	 * we get an APIC send error if we try to broadcast.
+	 * thus we have to avoid sending IPIs in this case.
+	 */
+	if (!(smp_num_cpus > 1))
+		return;
+
+	if (clustered_apic_mode) {
+		// Pointless. Use send_IPI_mask to do this instead
+		int cpu;
+
+		if (smp_num_cpus > 1) {
+			for (cpu = 0; cpu < smp_num_cpus; ++cpu) {
+				if (cpu != smp_processor_id())
+					send_IPI_mask(1 << cpu, vector);
+			}
+		}
+	} else {
+		__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
+		return;
+	}
+}
+
+static inline void send_IPI_all(int vector)
+{
+	if (clustered_apic_mode) {
+		// Pointless. Use send_IPI_mask to do this instead
+		int cpu;
+
+		for (cpu = 0; cpu < smp_num_cpus; ++cpu) {
+			send_IPI_mask(1 << cpu, vector);
+		}
+	} else {
+		__send_IPI_shortcut(APIC_DEST_ALLINC, vector);
+	}
 }
 
 /*
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
--- v2.4.10/linux/arch/i386/kernel/smpboot.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/smpboot.c	Thu Oct  4 18:42:54 2001
@@ -29,6 +29,7 @@
  *		Ingo Molnar	:	various cleanups and rewrites
  *		Tigran Aivazian	:	fixed "0.00 in /proc/uptime on SMP" bug.
  *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs
+ *		Martin J. Bligh	: 	Added support for multi-quad systems
  */
 
 #include <linux/config.h>
@@ -44,6 +45,7 @@
 #include <linux/mc146818rtc.h>
 #include <asm/mtrr.h>
 #include <asm/pgalloc.h>
+#include <asm/smpboot.h>
 
 /* Set if we find a B stepping CPU			*/
 static int smp_b_stepping;
@@ -57,11 +59,6 @@
 /* Bitmask of currently online CPUs */
 unsigned long cpu_online_map;
 
-/* which CPU (physical APIC ID) maps to which logical CPU number */
-volatile int x86_apicid_to_cpu[NR_CPUS];
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-volatile int x86_cpu_to_apicid[NR_CPUS];
-
 static volatile unsigned long cpu_callin_map;
 static volatile unsigned long cpu_callout_map;
 
@@ -357,7 +354,8 @@
 	 * our local APIC.  We have to wait for the IPI or we'll
 	 * lock up on an APIC access.
 	 */
-	while (!atomic_read(&init_deasserted));
+	if (!clustered_apic_mode) 
+		while (!atomic_read(&init_deasserted));
 
 	/*
 	 * (This works even if the APIC is not enabled.)
@@ -406,9 +404,15 @@
 	 */
 
 	Dprintk("CALLIN, before setup_local_APIC().\n");
+	/*
+	 * Because we use NMIs rather than the INIT-STARTUP sequence to
+	 * bootstrap the CPUs, the APIC may be in a wierd state. Kick it.
+	 */
+	if (clustered_apic_mode)
+		clear_local_APIC();
 	setup_local_APIC();
 
-	sti();
+	__sti();
 
 #ifdef CONFIG_MTRR
 	/*
@@ -501,6 +505,61 @@
 	return do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
 }
 
+/* which physical APIC ID maps to which logical CPU number */
+volatile int physical_apicid_2_cpu[MAX_APICID];
+/* which logical CPU number maps to which physical APIC ID */
+volatile int cpu_2_physical_apicid[NR_CPUS];
+
+/* which logical APIC ID maps to which logical CPU number */
+volatile int logical_apicid_2_cpu[MAX_APICID];
+/* which logical CPU number maps to which logical APIC ID */
+volatile int cpu_2_logical_apicid[NR_CPUS];
+
+static inline void init_cpu_to_apicid(void)
+/* Initialize all maps between cpu number and apicids */
+{
+	int apicid, cpu;
+
+	for (apicid = 0; apicid < MAX_APICID; apicid++) {
+		physical_apicid_2_cpu[apicid] = -1;
+		logical_apicid_2_cpu[apicid] = -1;
+	}
+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
+		cpu_2_physical_apicid[cpu] = -1;
+		cpu_2_logical_apicid[cpu] = -1;
+	}
+}
+
+static inline void map_cpu_to_boot_apicid(int cpu, int apicid)
+/* 
+ * set up a mapping between cpu and apicid. Uses logical apicids for multiquad,
+ * else physical apic ids
+ */
+{
+	if (clustered_apic_mode) {
+		logical_apicid_2_cpu[apicid] = cpu;	
+		cpu_2_logical_apicid[cpu] = apicid;
+	} else {
+		physical_apicid_2_cpu[apicid] = cpu;	
+		cpu_2_physical_apicid[cpu] = apicid;
+	}
+}
+
+static inline void unmap_cpu_to_boot_apicid(int cpu, int apicid)
+/* 
+ * undo a mapping between cpu and apicid. Uses logical apicids for multiquad,
+ * else physical apic ids
+ */
+{
+	if (clustered_apic_mode) {
+		logical_apicid_2_cpu[apicid] = -1;	
+		cpu_2_logical_apicid[cpu] = -1;
+	} else {
+		physical_apicid_2_cpu[apicid] = -1;	
+		cpu_2_physical_apicid[cpu] = -1;
+	}
+}
+
 #if APIC_DEBUG
 static inline void inquire_remote_apic(int apicid)
 {
@@ -539,89 +598,65 @@
 }
 #endif
 
-static void __init do_boot_cpu (int apicid)
+static int wakeup_secondary_via_NMI(int logical_apicid)
+/* 
+ * Poke the other CPU in the eye to wake it up. Remember that the normal
+ * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
+ * won't ... remember to clear down the APIC, etc later.
+ */
 {
-	struct task_struct *idle;
-	unsigned long send_status, accept_status, boot_status, maxlvt;
-	int timeout, num_starts, j, cpu;
-	unsigned long start_eip;
-
-	cpu = ++cpucount;
-	/*
-	 * We can't use kernel_thread since we must avoid to
-	 * reschedule the child.
-	 */
-	if (fork_by_hand() < 0)
-		panic("failed fork for CPU %d", cpu);
-
-	/*
-	 * We remove it from the pidhash and the runqueue
-	 * once we got the process:
-	 */
-	idle = init_task.prev_task;
-	if (!idle)
-		panic("No idle process for CPU %d", cpu);
-
-	idle->processor = cpu;
-	x86_cpu_to_apicid[cpu] = apicid;
-	x86_apicid_to_cpu[apicid] = cpu;
-	idle->has_cpu = 1; /* we schedule the first task manually */
-	idle->thread.eip = (unsigned long) start_secondary;
+	unsigned long send_status = 0, accept_status = 0;
+	int timeout, maxlvt;
 
-	del_from_runqueue(idle);
-	unhash_process(idle);
-	init_tasks[cpu] = idle;
+	/* Target chip */
+	apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid));
 
-	/* start_eip had better be page-aligned! */
-	start_eip = setup_trampoline();
+	/* Boot on the stack */
+	/* Kick the second */
+	apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL);
 
-	/* So we see what's up   */
-	printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
-	stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle);
+	Dprintk("Waiting for send to finish...\n");
+	timeout = 0;
+	do {
+		Dprintk("+");
+		udelay(100);
+		send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
+	} while (send_status && (timeout++ < 1000));
 
 	/*
-	 * This grunge runs the startup process for
-	 * the targeted processor.
+	 * Give the other CPU some time to accept the IPI.
 	 */
-
-	atomic_set(&init_deasserted, 0);
-
-	Dprintk("Setting warm reset code and vector.\n");
-
-	CMOS_WRITE(0xa, 0xf);
-	local_flush_tlb();
-	Dprintk("1.\n");
-	*((volatile unsigned short *) phys_to_virt(0x469)) = start_eip >> 4;
-	Dprintk("2.\n");
-	*((volatile unsigned short *) phys_to_virt(0x467)) = start_eip & 0xf;
-	Dprintk("3.\n");
-
+	udelay(200);
 	/*
-	 * Be paranoid about clearing APIC errors.
+	 * Due to the Pentium erratum 3AP.
 	 */
-	if (APIC_INTEGRATED(apic_version[apicid])) {
+	maxlvt = get_maxlvt();
+	if (maxlvt > 3) {
 		apic_read_around(APIC_SPIV);
 		apic_write(APIC_ESR, 0);
-		apic_read(APIC_ESR);
 	}
+	accept_status = (apic_read(APIC_ESR) & 0xEF);
+	Dprintk("NMI sent.\n");
 
-	/*
-	 * Status is now clean
-	 */
-	send_status = 0;
-	accept_status = 0;
-	boot_status = 0;
+	if (send_status)
+		printk("APIC never delivered???\n");
+	if (accept_status)
+		printk("APIC delivery error (%lx).\n", accept_status);
 
-	/*
-	 * Starting actual IPI sequence...
-	 */
+	return (send_status | accept_status);
+}
+
+static int wakeup_secondary_via_INIT(int phys_apicid, unsigned long start_eip)
+{
+	unsigned long send_status = 0, accept_status = 0;
+	int maxlvt, timeout, num_starts, j;
 
 	Dprintk("Asserting INIT.\n");
 
 	/*
 	 * Turn INIT on target chip
 	 */
-	apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+	apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
 	/*
 	 * Send IPI
@@ -642,7 +677,7 @@
 	Dprintk("Deasserting INIT.\n");
 
 	/* Target chip */
-	apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+	apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
 	/* Send IPI */
 	apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
@@ -661,10 +696,9 @@
 	 * Should we send STARTUP IPIs ?
 	 *
 	 * Determine this based on the APIC version.
-	 * If we don't have an integrated APIC, don't
-	 * send the STARTUP IPIs.
+	 * If we don't have an integrated APIC, don't send the STARTUP IPIs.
 	 */
-	if (APIC_INTEGRATED(apic_version[apicid]))
+	if (APIC_INTEGRATED(apic_version[phys_apicid]))
 		num_starts = 2;
 	else
 		num_starts = 0;
@@ -688,7 +722,7 @@
 		 */
 
 		/* Target chip */
-		apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+		apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
 		/* Boot on the stack */
 		/* Kick the second */
@@ -732,7 +766,104 @@
 	if (accept_status)
 		printk("APIC delivery error (%lx).\n", accept_status);
 
-	if (!send_status && !accept_status) {
+	return (send_status | accept_status);
+}
+
+extern unsigned long cpu_initialized;
+
+static void __init do_boot_cpu (int apicid) 
+/*
+ * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
+ * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
+ */
+{
+	struct task_struct *idle;
+	unsigned long boot_error = 0;
+	int timeout, cpu;
+	unsigned long start_eip;
+	unsigned short nmi_high, nmi_low;
+
+	cpu = ++cpucount;
+	/*
+	 * We can't use kernel_thread since we must avoid to
+	 * reschedule the child.
+	 */
+	if (fork_by_hand() < 0)
+		panic("failed fork for CPU %d", cpu);
+
+	/*
+	 * We remove it from the pidhash and the runqueue
+	 * once we got the process:
+	 */
+	idle = init_task.prev_task;
+	if (!idle)
+		panic("No idle process for CPU %d", cpu);
+
+	idle->processor = cpu;
+
+	map_cpu_to_boot_apicid(cpu, apicid);
+
+	idle->has_cpu = 1; /* we schedule the first task manually */
+	idle->thread.eip = (unsigned long) start_secondary;
+
+	del_from_runqueue(idle);
+	unhash_process(idle);
+	init_tasks[cpu] = idle;
+
+	/* start_eip had better be page-aligned! */
+	start_eip = setup_trampoline();
+
+	/* So we see what's up   */
+	printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
+	stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle);
+
+	/*
+	 * This grunge runs the startup process for
+	 * the targeted processor.
+	 */
+
+	atomic_set(&init_deasserted, 0);
+
+	Dprintk("Setting warm reset code and vector.\n");
+
+	if (clustered_apic_mode) {
+		/* stash the current NMI vector, so we can put things back */
+		nmi_high = *((volatile unsigned short *) TRAMPOLINE_HIGH);
+		nmi_low = *((volatile unsigned short *) TRAMPOLINE_LOW);
+	} 
+
+	CMOS_WRITE(0xa, 0xf);
+	local_flush_tlb();
+	Dprintk("1.\n");
+	*((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4;
+	Dprintk("2.\n");
+	*((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf;
+	Dprintk("3.\n");
+
+	/*
+	 * Be paranoid about clearing APIC errors.
+	 */
+	if (!clustered_apic_mode && APIC_INTEGRATED(apic_version[apicid])) {
+		apic_read_around(APIC_SPIV);
+		apic_write(APIC_ESR, 0);
+		apic_read(APIC_ESR);
+	}
+
+	/*
+	 * Status is now clean
+	 */
+	boot_error = 0;
+
+	/*
+	 * Starting actual IPI sequence...
+	 */
+
+	if (clustered_apic_mode)
+		boot_error = wakeup_secondary_via_NMI(apicid);
+	else 
+		boot_error = wakeup_secondary_via_INIT(apicid, start_eip);
+
+	if (!boot_error) {
 		/*
 		 * allow APs to start initializing.
 		 */
@@ -756,7 +887,7 @@
 			print_cpu_info(&cpu_data[cpu]);
 			Dprintk("CPU has booted.\n");
 		} else {
-			boot_status = 1;
+			boot_error= 1;
 			if (*((volatile unsigned char *)phys_to_virt(8192))
 					== 0xA5)
 				/* trampoline started but...? */
@@ -765,18 +896,28 @@
 				/* trampoline code not run */
 				printk("Not responding.\n");
 #if APIC_DEBUG
-			inquire_remote_apic(apicid);
+			if (!clustered_apic_mode)
+				inquire_remote_apic(apicid);
 #endif
 		}
 	}
-	if (send_status || accept_status || boot_status) {
-		x86_cpu_to_apicid[cpu] = -1;
-		x86_apicid_to_cpu[apicid] = -1;
+	if (boot_error) {
+		/* Try to put things back the way they were before ... */
+		unmap_cpu_to_boot_apicid(cpu, apicid);
+		clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */
+		clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+		clear_bit(cpu, &cpu_online_map);  /* was set in smp_callin() */
 		cpucount--;
 	}
 
 	/* mark "stuck" area as not stuck */
 	*((volatile unsigned long *)phys_to_virt(8192)) = 0;
+
+	if(clustered_apic_mode) {
+		printk("Restoring NMI vector\n");
+		*((volatile unsigned short *) TRAMPOLINE_HIGH) = nmi_high;
+		*((volatile unsigned short *) TRAMPOLINE_LOW) = nmi_low;
+	}
 }
 
 cycles_t cacheflush_time;
@@ -826,9 +967,20 @@
 extern int prof_old_multiplier[NR_CPUS];
 extern int prof_counter[NR_CPUS];
 
+static int boot_cpu_logical_apicid;
+/* Where the IO area was mapped on multiquad, always 0 otherwise */
+void *xquad_portio = NULL;
+
 void __init smp_boot_cpus(void)
 {
-	int apicid, cpu;
+	int apicid, cpu, bit;
+
+        if (clustered_apic_mode) {
+                /* remap the 1st quad's 256k range for cross-quad I/O */
+                xquad_portio = ioremap (XQUAD_PORTIO_BASE, XQUAD_PORTIO_LEN);
+                printk("Cross quad port I/O vaddr 0x%08lx, len %08lx\n",
+                        (u_long) xquad_portio, (u_long) XQUAD_PORTIO_LEN);
+        }
 
 #ifdef CONFIG_MTRR
 	/*  Must be done before other processors booted  */
@@ -839,13 +991,14 @@
 	 * and the per-CPU profiling counter/multiplier
 	 */
 
-	for (apicid = 0; apicid < NR_CPUS; apicid++) {
-		x86_apicid_to_cpu[apicid] = -1;
-		prof_counter[apicid] = 1;
-		prof_old_multiplier[apicid] = 1;
-		prof_multiplier[apicid] = 1;
+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
+		prof_counter[cpu] = 1;
+		prof_old_multiplier[cpu] = 1;
+		prof_multiplier[cpu] = 1;
 	}
 
+	init_cpu_to_apicid();
+
 	/*
 	 * Setup boot CPU information
 	 */
@@ -857,8 +1010,9 @@
 	 * We have the boot CPU online for sure.
 	 */
 	set_bit(0, &cpu_online_map);
-	x86_apicid_to_cpu[boot_cpu_id] = 0;
-	x86_cpu_to_apicid[0] = boot_cpu_id;
+	boot_cpu_logical_apicid = logical_smp_processor_id();
+	map_cpu_to_boot_apicid(0, boot_cpu_apicid);
+
 	global_irq_holder = 0;
 	current->processor = 0;
 	init_idle();
@@ -884,20 +1038,22 @@
 	/*
 	 * Should not be necessary because the MP table should list the boot
 	 * CPU too, but we do it for the sake of robustness anyway.
+	 * Makes no sense to do this check in clustered apic mode, so skip it
 	 */
-	if (!test_bit(boot_cpu_id, &phys_cpu_present_map)) {
+	if (!clustered_apic_mode && 
+	    !test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map)) {
 		printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
-								 boot_cpu_id);
+							boot_cpu_physical_apicid);
 		phys_cpu_present_map |= (1 << hard_smp_processor_id());
 	}
 
 	/*
 	 * If we couldn't find a local APIC, then get out of here now!
 	 */
-	if (APIC_INTEGRATED(apic_version[boot_cpu_id]) &&
+	if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) &&
 	    !test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability)) {
 		printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
-			boot_cpu_id);
+			boot_cpu_physical_apicid);
 		printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
 #ifndef CONFIG_VISWS
 		io_apic_irqs = 0;
@@ -926,22 +1082,27 @@
 	connect_bsp_APIC();
 	setup_local_APIC();
 
-	if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id)
+	if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid)
 		BUG();
 
 	/*
-	 * Now scan the CPU present map and fire up the other CPUs.
+	 * Scan the CPU present map and fire up the other CPUs via do_boot_cpu
+	 *
+	 * In clustered apic mode, phys_cpu_present_map is a constructed thus:
+	 * bits 0-3 are quad0, 4-7 are quad1, etc. A perverse twist on the 
+	 * clustered apic ID.
 	 */
 	Dprintk("CPU present map: %lx\n", phys_cpu_present_map);
 
-	for (apicid = 0; apicid < NR_CPUS; apicid++) {
+	for (bit = 0; bit < NR_CPUS; bit++) {
+		apicid = cpu_present_to_apicid(bit);
 		/*
 		 * Don't even attempt to start the boot CPU!
 		 */
-		if (apicid == boot_cpu_id)
+		if (apicid == boot_cpu_apicid)
 			continue;
 
-		if (!(phys_cpu_present_map & (1 << apicid)))
+		if (!(phys_cpu_present_map & (1 << bit)))
 			continue;
 		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
 			continue;
@@ -951,9 +1112,10 @@
 		/*
 		 * Make sure we unmap all failed CPUs
 		 */
-		if ((x86_apicid_to_cpu[apicid] == -1) &&
-				(phys_cpu_present_map & (1 << apicid)))
-			printk("phys CPU #%d not responding - cannot use it.\n",apicid);
+		if ((boot_apicid_to_cpu(apicid) == -1) &&
+				(phys_cpu_present_map & (1 << bit)))
+			printk("CPU #%d not responding - cannot use it.\n",
+								apicid);
 	}
 
 	/*
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/trampoline.S linux/arch/i386/kernel/trampoline.S
--- v2.4.10/linux/arch/i386/kernel/trampoline.S	Mon Feb  7 19:59:39 2000
+++ linux/arch/i386/kernel/trampoline.S	Thu Oct  4 18:42:54 2001
@@ -36,7 +36,9 @@
 
 ENTRY(trampoline_data)
 r_base = .
-
+#ifdef CONFIG_MULTIQUAD
+	wbinvd
+#endif /* CONFIG_MULTIQUAD */
 	mov	%cs, %ax	# Code and data in the same place
 	mov	%ax, %ds
 
diff -u --recursive --new-file v2.4.10/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v2.4.10/linux/arch/i386/kernel/traps.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/kernel/traps.c	Sun Sep 30 12:26:08 2001
@@ -200,8 +200,8 @@
 		esp = regs->esp;
 		ss = regs->xss & 0xffff;
 	}
-	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]\nEFLAGS: %08lx\n",
-		smp_processor_id(), 0xffff & regs->xcs, regs->eip, regs->eflags);
+	printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
+		smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
 	printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
 		regs->eax, regs->ebx, regs->ecx, regs->edx);
 	printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
diff -u --recursive --new-file v2.4.10/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- v2.4.10/linux/arch/i386/mm/fault.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/i386/mm/fault.c	Tue Oct  9 15:13:03 2001
@@ -17,6 +17,7 @@
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/tty.h>
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 
 #include <asm/system.h>
diff -u --recursive --new-file v2.4.10/linux/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
--- v2.4.10/linux/arch/ia64/kernel/process.c	Sun Aug 12 13:27:58 2001
+++ linux/arch/ia64/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -63,8 +63,8 @@
 {
 	unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
 
-	printk("\npsr : %016lx ifs : %016lx ip  : [<%016lx>]\n",
-	       regs->cr_ipsr, regs->cr_ifs, ip);
+	printk("\npsr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
+	       regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
 	printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
 	       regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
 	printk("rnat: %016lx bsps: %016lx pr  : %016lx\n",
diff -u --recursive --new-file v2.4.10/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- v2.4.10/linux/arch/m68k/kernel/process.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/m68k/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -109,8 +109,8 @@
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
-	printk("Format %02x  Vector: %04x  PC: %08lx  Status: %04x\n",
-	       regs->format, regs->vector, regs->pc, regs->sr);
+	printk("Format %02x  Vector: %04x  PC: %08lx  Status: %04x    %s\n",
+	       regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
 	printk("ORIG_D0: %08lx  D0: %08lx  A2: %08lx  A1: %08lx\n",
 	       regs->orig_d0, regs->d0, regs->a2, regs->a1);
 	printk("A0: %08lx  D5: %08lx  D4: %08lx\n",
diff -u --recursive --new-file v2.4.10/linux/arch/mips/au1000/common/serial.c linux/arch/mips/au1000/common/serial.c
--- v2.4.10/linux/arch/mips/au1000/common/serial.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/mips/au1000/common/serial.c	Fri Oct  5 12:06:51 2001
@@ -68,9 +68,6 @@
  * End of serial driver configuration section.
  */
 
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
 #include <linux/module.h>
 
 #include <linux/types.h>
diff -u --recursive --new-file v2.4.10/linux/arch/mips/dec/wbflush.c linux/arch/mips/dec/wbflush.c
--- v2.4.10/linux/arch/mips/dec/wbflush.c	Thu Feb 24 22:52:30 2000
+++ linux/arch/mips/dec/wbflush.c	Fri Oct  5 12:06:51 2001
@@ -103,8 +103,6 @@
 {
 }
 
-#ifdef EXPORT_SYMTAB
 #include <linux/module.h>
 
 EXPORT_SYMBOL(__wbflush);
-#endif
diff -u --recursive --new-file v2.4.10/linux/arch/mips/mm/mips32.c linux/arch/mips/mm/mips32.c
--- v2.4.10/linux/arch/mips/mm/mips32.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/mips/mm/mips32.c	Sun Sep 30 12:26:08 2001
@@ -739,8 +739,8 @@
 	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
 
 	/* Saved cp0 registers. */
-	printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+	printk("epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
 }
 			
 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
diff -u --recursive --new-file v2.4.10/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- v2.4.10/linux/arch/mips/mm/r2300.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/mips/mm/r2300.c	Sun Sep 30 12:26:08 2001
@@ -665,8 +665,10 @@
 	/*
 	 * Saved cp0 registers
 	 */
-	printk("epc  : %08lx\nStatus: %08x\nCause : %08x\n",
-	       (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status,
+	printk("epc  : %08lx    %s\nStatus: %08x\nCause : %08x\n",
+	       (unsigned long) regs->cp0_epc,
+	       print_tainted(),
+	       (unsigned int) regs->cp0_status,
 	       (unsigned int) regs->cp0_cause);
 }
 
diff -u --recursive --new-file v2.4.10/linux/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- v2.4.10/linux/arch/mips/mm/r4xx0.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/mips/mm/r4xx0.c	Sun Sep 30 12:26:08 2001
@@ -2364,8 +2364,8 @@
 	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
 
 	/* Saved cp0 registers. */
-	printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+	printk("epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
 }
 			
 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
diff -u --recursive --new-file v2.4.10/linux/arch/mips/mm/r5432.c linux/arch/mips/mm/r5432.c
--- v2.4.10/linux/arch/mips/mm/r5432.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/mips/mm/r5432.c	Sun Sep 30 12:26:08 2001
@@ -765,8 +765,8 @@
 	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
 
 	/* Saved cp0 registers. */
-	printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+	printk("epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
 }
 			
 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
diff -u --recursive --new-file v2.4.10/linux/arch/mips/mm/rm7k.c linux/arch/mips/mm/rm7k.c
--- v2.4.10/linux/arch/mips/mm/rm7k.c	Wed Jul 25 17:10:18 2001
+++ linux/arch/mips/mm/rm7k.c	Sun Sep 30 12:26:08 2001
@@ -507,8 +507,8 @@
 	       regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
 
 	/* Saved cp0 registers. */
-	printk(KERN_INFO "epc   : %08lx\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+	printk(KERN_INFO "epc   : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
 }
 
 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
diff -u --recursive --new-file v2.4.10/linux/arch/mips64/mm/andes.c linux/arch/mips64/mm/andes.c
--- v2.4.10/linux/arch/mips64/mm/andes.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/mips64/mm/andes.c	Sun Sep 30 12:26:08 2001
@@ -326,8 +326,8 @@
 	printk("Lo      : %016lx\n", regs->lo);
 
 	/* Saved cp0 registers. */
-	printk("epc     : %016lx\nbadvaddr: %016lx\n",
-	       regs->cp0_epc, regs->cp0_badvaddr);
+	printk("epc     : %016lx    %s\nbadvaddr: %016lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_badvaddr);
 	printk("Status  : %08x\nCause   : %08x\n",
 	       (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
 }
diff -u --recursive --new-file v2.4.10/linux/arch/mips64/mm/r4xx0.c linux/arch/mips64/mm/r4xx0.c
--- v2.4.10/linux/arch/mips64/mm/r4xx0.c	Sun Sep 23 11:40:55 2001
+++ linux/arch/mips64/mm/r4xx0.c	Sun Sep 30 12:26:08 2001
@@ -2109,8 +2109,8 @@
 	printk("Lo      : %016lx\n", regs->lo);
 
 	/* Saved cp0 registers. */
-	printk("epc     : %016lx\nbadvaddr: %016lx\n",
-	       regs->cp0_epc, regs->cp0_badvaddr);
+	printk("epc     : %016lx    %s\nbadvaddr: %016lx\n",
+	       regs->cp0_epc, print_tainted(), regs->cp0_badvaddr);
 	printk("Status  : %08x\nCause   : %08x\n",
 	       (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
 }
diff -u --recursive --new-file v2.4.10/linux/arch/parisc/hpux/entry_hpux.S linux/arch/parisc/hpux/entry_hpux.S
--- v2.4.10/linux/arch/parisc/hpux/entry_hpux.S	Tue Dec  5 12:29:39 2000
+++ linux/arch/parisc/hpux/entry_hpux.S	Fri Oct  5 12:22:07 2001
@@ -6,8 +6,6 @@
  */
 
 
-#define ASSEMBLY
-
 #include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/unistd.h>
diff -u --recursive --new-file v2.4.10/linux/arch/parisc/kernel/traps.c linux/arch/parisc/kernel/traps.c
--- v2.4.10/linux/arch/parisc/kernel/traps.c	Wed Dec  6 11:46:39 2000
+++ linux/arch/parisc/kernel/traps.c	Sun Sep 30 12:26:08 2001
@@ -82,7 +82,7 @@
 
 	printk("     YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\nPSW: ");
 	printbinary(regs->gr[0], 32);
-	printk("\n");
+	printk("    %s\n", print_tainted());
 
 	for (i = 0; i < 32; i += 4) {
 		int j;
diff -u --recursive --new-file v2.4.10/linux/arch/parisc/mm/pa11.c linux/arch/parisc/mm/pa11.c
--- v2.4.10/linux/arch/parisc/mm/pa11.c	Tue Dec  5 12:29:39 2000
+++ linux/arch/parisc/mm/pa11.c	Sun Sep 30 12:26:08 2001
@@ -127,8 +127,9 @@
 	/*
 	 * Saved cp0 registers
 	 */
-	printk("epc  : %08lx\nStatus: %08x\nCause : %08x\n",
-	       (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status,
+	printk("epc  : %08lx    %s\nStatus: %08x\nCause : %08x\n",
+	       (unsigned long) regs->cp0_epc, print_tainted(),
+	       (unsigned int) regs->cp0_status,
 	       (unsigned int) regs->cp0_cause);
 }
 
diff -u --recursive --new-file v2.4.10/linux/arch/parisc/mm/pa20.c linux/arch/parisc/mm/pa20.c
--- v2.4.10/linux/arch/parisc/mm/pa20.c	Tue Dec  5 12:29:39 2000
+++ linux/arch/parisc/mm/pa20.c	Sun Sep 30 12:26:08 2001
@@ -127,8 +127,9 @@
 	/*
 	 * Saved cp0 registers
 	 */
-	printk("epc  : %08lx\nStatus: %08x\nCause : %08x\n",
-	       (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status,
+	printk("epc  : %08lx    %s\nStatus: %08x\nCause : %08x\n",
+	       (unsigned long) regs->cp0_epc, print_tainted(),
+	       (unsigned int) regs->cp0_status,
 	       (unsigned int) regs->cp0_cause);
 }
 
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/8260_io/enet.c linux/arch/ppc/8260_io/enet.c
--- v2.4.10/linux/arch/ppc/8260_io/enet.c	Mon May 21 17:04:46 2001
+++ linux/arch/ppc/8260_io/enet.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.enet.c 1.6 05/17/01 18:14:19 cort
+ * BK Id: SCCS/s.enet.c 1.9 09/14/01 18:01:16 trini
  */
 /*
  * Ethernet driver for Motorola MPC8260.
@@ -13,7 +13,7 @@
  * This version of the driver is somewhat selectable for the different
  * processor/board combinations.  It works for the boards I know about
  * now, and should be easily modified to include others.  Some of the
- * configuration information is contained in "commproc.h" and the
+ * configuration information is contained in <asm/commproc.h> and the
  * remainder is here.
  *
  * Buffer descriptors are kept in the CPM dual port RAM, and the frame
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/8xx_io/commproc.c linux/arch/ppc/8xx_io/commproc.c
--- v2.4.10/linux/arch/ppc/8xx_io/commproc.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/8xx_io/commproc.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.commproc.c 1.11 06/15/01 13:00:20 paulus
+ * BK Id: SCCS/s.commproc.c 1.13 09/14/01 18:01:16 trini
  */
 
 /*
@@ -36,7 +36,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/8xx_immap.h>
-#include "commproc.h"
+#include <asm/commproc.h>
 
 static	uint	dp_alloc_base;	/* Starting offset in DP ram */
 static	uint	dp_alloc_top;	/* Max offset + 1 */
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/8xx_io/commproc.h linux/arch/ppc/8xx_io/commproc.h
--- v2.4.10/linux/arch/ppc/8xx_io/commproc.h	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/8xx_io/commproc.h	Wed Dec 31 16:00:00 1969
@@ -1,796 +0,0 @@
-/*
- * BK Id: SCCS/s.commproc.h 1.13 06/15/01 13:00:20 paulus
- */
-
-/*
- * MPC8xx Communication Processor Module.
- * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
- *
- * This file contains structures and information for the communication
- * processor channels.  Some CPM control and status is available
- * throught the MPC8xx internal memory map.  See immap.h for details.
- * This file only contains what I need for the moment, not the total
- * CPM capabilities.  I (or someone else) will add definitions as they
- * are needed.  -- Dan
- *
- * On the MBX board, EPPC-Bug loads CPM microcode into the first 512
- * bytes of the DP RAM and relocates the I2C parameter area to the
- * IDMA1 space.  The remaining DP RAM is available for buffer descriptors
- * or other use.
- */
-#ifndef __CPM_8XX__
-#define __CPM_8XX__
-
-#include <linux/config.h>
-#include <asm/8xx_immap.h>
-
-/* CPM Command register.
-*/
-#define CPM_CR_RST	((ushort)0x8000)
-#define CPM_CR_OPCODE	((ushort)0x0f00)
-#define CPM_CR_CHAN	((ushort)0x00f0)
-#define CPM_CR_FLG	((ushort)0x0001)
-
-/* Some commands (there are more...later)
-*/
-#define CPM_CR_INIT_TRX		((ushort)0x0000)
-#define CPM_CR_INIT_RX		((ushort)0x0001)
-#define CPM_CR_INIT_TX		((ushort)0x0002)
-#define CPM_CR_HUNT_MODE	((ushort)0x0003)
-#define CPM_CR_STOP_TX		((ushort)0x0004)
-#define CPM_CR_RESTART_TX	((ushort)0x0006)
-#define CPM_CR_SET_GADDR	((ushort)0x0008)
-
-/* Channel numbers.
-*/
-#define CPM_CR_CH_SCC1	((ushort)0x0000)
-#define CPM_CR_CH_I2C	((ushort)0x0001)	/* I2C and IDMA1 */
-#define CPM_CR_CH_SCC2	((ushort)0x0004)
-#define CPM_CR_CH_SPI	((ushort)0x0005)	/* SPI / IDMA2 / Timers */
-#define CPM_CR_CH_SCC3	((ushort)0x0008)
-#define CPM_CR_CH_SMC1	((ushort)0x0009)	/* SMC1 / DSP1 */
-#define CPM_CR_CH_SCC4	((ushort)0x000c)
-#define CPM_CR_CH_SMC2	((ushort)0x000d)	/* SMC2 / DSP2 */
-
-#define mk_cr_cmd(CH, CMD)	((CMD << 8) | (CH << 4))
-
-/* The dual ported RAM is multi-functional.  Some areas can be (and are
- * being) used for microcode.  There is an area that can only be used
- * as data ram for buffer descriptors, which is all we use right now.
- * Currently the first 512 and last 256 bytes are used for microcode.
- */
-#define CPM_DATAONLY_BASE	((uint)0x0800)
-#define CPM_DATAONLY_SIZE	((uint)0x0700)
-#define CPM_DP_NOSPACE		((uint)0x7fffffff)
-
-/* Export the base address of the communication processor registers
- * and dual port ram.
- */
-extern	cpm8xx_t	*cpmp;		/* Pointer to comm processor */
-uint		m8xx_cpm_dpalloc(uint size);
-uint		m8xx_cpm_hostalloc(uint size);
-void		m8xx_cpm_setbrg(uint brg, uint rate);
-
-/* Buffer descriptors used by many of the CPM protocols.
-*/
-typedef struct cpm_buf_desc {
-	ushort	cbd_sc;		/* Status and Control */
-	ushort	cbd_datlen;	/* Data length in buffer */
-	uint	cbd_bufaddr;	/* Buffer address in host memory */
-} cbd_t;
-
-#define BD_SC_EMPTY	((ushort)0x8000)	/* Receive is empty */
-#define BD_SC_READY	((ushort)0x8000)	/* Transmit is ready */
-#define BD_SC_WRAP	((ushort)0x2000)	/* Last buffer descriptor */
-#define BD_SC_INTRPT	((ushort)0x1000)	/* Interrupt on change */
-#define BD_SC_LAST	((ushort)0x0800)	/* Last buffer in frame */
-#define BD_SC_CM	((ushort)0x0200)	/* Continous mode */
-#define BD_SC_ID	((ushort)0x0100)	/* Rec'd too many idles */
-#define BD_SC_P		((ushort)0x0100)	/* xmt preamble */
-#define BD_SC_BR	((ushort)0x0020)	/* Break received */
-#define BD_SC_FR	((ushort)0x0010)	/* Framing error */
-#define BD_SC_PR	((ushort)0x0008)	/* Parity error */
-#define BD_SC_OV	((ushort)0x0002)	/* Overrun */
-#define BD_SC_CD	((ushort)0x0001)	/* ?? */
-
-/* Parameter RAM offsets.
-*/
-#define PROFF_SCC1	((uint)0x0000)
-#define PROFF_IIC	((uint)0x0080)
-#define PROFF_SCC2	((uint)0x0100)
-#define PROFF_SCC3	((uint)0x0200)
-#define PROFF_SMC1	((uint)0x0280)
-#define PROFF_SCC4	((uint)0x0300)
-#define PROFF_SMC2	((uint)0x0380)
-
-/* Define enough so I can at least use the serial port as a UART.
- * The MBX uses SMC1 as the host serial port.
- */
-typedef struct smc_uart {
-	ushort	smc_rbase;	/* Rx Buffer descriptor base address */
-	ushort	smc_tbase;	/* Tx Buffer descriptor base address */
-	u_char	smc_rfcr;	/* Rx function code */
-	u_char	smc_tfcr;	/* Tx function code */
-	ushort	smc_mrblr;	/* Max receive buffer length */
-	uint	smc_rstate;	/* Internal */
-	uint	smc_idp;	/* Internal */
-	ushort	smc_rbptr;	/* Internal */
-	ushort	smc_ibc;	/* Internal */
-	uint	smc_rxtmp;	/* Internal */
-	uint	smc_tstate;	/* Internal */
-	uint	smc_tdp;	/* Internal */
-	ushort	smc_tbptr;	/* Internal */
-	ushort	smc_tbc;	/* Internal */
-	uint	smc_txtmp;	/* Internal */
-	ushort	smc_maxidl;	/* Maximum idle characters */
-	ushort	smc_tmpidl;	/* Temporary idle counter */
-	ushort	smc_brklen;	/* Last received break length */
-	ushort	smc_brkec;	/* rcv'd break condition counter */
-	ushort	smc_brkcr;	/* xmt break count register */
-	ushort	smc_rmask;	/* Temporary bit mask */
-} smc_uart_t;
-
-/* Function code bits.
-*/
-#define SMC_EB	((u_char)0x10)	/* Set big endian byte order */
-
-/* SMC uart mode register.
-*/
-#define	SMCMR_REN	((ushort)0x0001)
-#define SMCMR_TEN	((ushort)0x0002)
-#define SMCMR_DM	((ushort)0x000c)
-#define SMCMR_SM_GCI	((ushort)0x0000)
-#define SMCMR_SM_UART	((ushort)0x0020)
-#define SMCMR_SM_TRANS	((ushort)0x0030)
-#define SMCMR_SM_MASK	((ushort)0x0030)
-#define SMCMR_PM_EVEN	((ushort)0x0100)	/* Even parity, else odd */
-#define SMCMR_REVD	SMCMR_PM_EVEN
-#define SMCMR_PEN	((ushort)0x0200)	/* Parity enable */
-#define SMCMR_BS	SMCMR_PEN
-#define SMCMR_SL	((ushort)0x0400)	/* Two stops, else one */
-#define SMCR_CLEN_MASK	((ushort)0x7800)	/* Character length */
-#define smcr_mk_clen(C)	(((C) << 11) & SMCR_CLEN_MASK)
-
-/* SMC2 as Centronics parallel printer.  It is half duplex, in that
- * it can only receive or transmit.  The parameter ram values for
- * each direction are either unique or properly overlap, so we can
- * include them in one structure.
- */
-typedef struct smc_centronics {
-	ushort	scent_rbase;
-	ushort	scent_tbase;
-	u_char	scent_cfcr;
-	u_char	scent_smask;
-	ushort	scent_mrblr;
-	uint	scent_rstate;
-	uint	scent_r_ptr;
-	ushort	scent_rbptr;
-	ushort	scent_r_cnt;
-	uint	scent_rtemp;
-	uint	scent_tstate;
-	uint	scent_t_ptr;
-	ushort	scent_tbptr;
-	ushort	scent_t_cnt;
-	uint	scent_ttemp;
-	ushort	scent_max_sl;
-	ushort	scent_sl_cnt;
-	ushort	scent_character1;
-	ushort	scent_character2;
-	ushort	scent_character3;
-	ushort	scent_character4;
-	ushort	scent_character5;
-	ushort	scent_character6;
-	ushort	scent_character7;
-	ushort	scent_character8;
-	ushort	scent_rccm;
-	ushort	scent_rccr;
-} smc_cent_t;
-
-/* Centronics Status Mask Register.
-*/
-#define SMC_CENT_F	((u_char)0x08)
-#define SMC_CENT_PE	((u_char)0x04)
-#define SMC_CENT_S	((u_char)0x02)
-
-/* SMC Event and Mask register.
-*/
-#define	SMCM_BRKE	((unsigned char)0x40)	/* When in UART Mode */
-#define	SMCM_BRK	((unsigned char)0x10)	/* When in UART Mode */
-#define	SMCM_TXE	((unsigned char)0x10)	/* When in Transparent Mode */
-#define	SMCM_BSY	((unsigned char)0x04)
-#define	SMCM_TX		((unsigned char)0x02)
-#define	SMCM_RX		((unsigned char)0x01)
-
-/* Baud rate generators.
-*/
-#define CPM_BRG_RST		((uint)0x00020000)
-#define CPM_BRG_EN		((uint)0x00010000)
-#define CPM_BRG_EXTC_INT	((uint)0x00000000)
-#define CPM_BRG_EXTC_CLK2	((uint)0x00004000)
-#define CPM_BRG_EXTC_CLK6	((uint)0x00008000)
-#define CPM_BRG_ATB		((uint)0x00002000)
-#define CPM_BRG_CD_MASK		((uint)0x00001ffe)
-#define CPM_BRG_DIV16		((uint)0x00000001)
-
-/* SCCs.
-*/
-#define SCC_GSMRH_IRP		((uint)0x00040000)
-#define SCC_GSMRH_GDE		((uint)0x00010000)
-#define SCC_GSMRH_TCRC_CCITT	((uint)0x00008000)
-#define SCC_GSMRH_TCRC_BISYNC	((uint)0x00004000)
-#define SCC_GSMRH_TCRC_HDLC	((uint)0x00000000)
-#define SCC_GSMRH_REVD		((uint)0x00002000)
-#define SCC_GSMRH_TRX		((uint)0x00001000)
-#define SCC_GSMRH_TTX		((uint)0x00000800)
-#define SCC_GSMRH_CDP		((uint)0x00000400)
-#define SCC_GSMRH_CTSP		((uint)0x00000200)
-#define SCC_GSMRH_CDS		((uint)0x00000100)
-#define SCC_GSMRH_CTSS		((uint)0x00000080)
-#define SCC_GSMRH_TFL		((uint)0x00000040)
-#define SCC_GSMRH_RFW		((uint)0x00000020)
-#define SCC_GSMRH_TXSY		((uint)0x00000010)
-#define SCC_GSMRH_SYNL16	((uint)0x0000000c)
-#define SCC_GSMRH_SYNL8		((uint)0x00000008)
-#define SCC_GSMRH_SYNL4		((uint)0x00000004)
-#define SCC_GSMRH_RTSM		((uint)0x00000002)
-#define SCC_GSMRH_RSYN		((uint)0x00000001)
-
-#define SCC_GSMRL_SIR		((uint)0x80000000)	/* SCC2 only */
-#define SCC_GSMRL_EDGE_NONE	((uint)0x60000000)
-#define SCC_GSMRL_EDGE_NEG	((uint)0x40000000)
-#define SCC_GSMRL_EDGE_POS	((uint)0x20000000)
-#define SCC_GSMRL_EDGE_BOTH	((uint)0x00000000)
-#define SCC_GSMRL_TCI		((uint)0x10000000)
-#define SCC_GSMRL_TSNC_3	((uint)0x0c000000)
-#define SCC_GSMRL_TSNC_4	((uint)0x08000000)
-#define SCC_GSMRL_TSNC_14	((uint)0x04000000)
-#define SCC_GSMRL_TSNC_INF	((uint)0x00000000)
-#define SCC_GSMRL_RINV		((uint)0x02000000)
-#define SCC_GSMRL_TINV		((uint)0x01000000)
-#define SCC_GSMRL_TPL_128	((uint)0x00c00000)
-#define SCC_GSMRL_TPL_64	((uint)0x00a00000)
-#define SCC_GSMRL_TPL_48	((uint)0x00800000)
-#define SCC_GSMRL_TPL_32	((uint)0x00600000)
-#define SCC_GSMRL_TPL_16	((uint)0x00400000)
-#define SCC_GSMRL_TPL_8		((uint)0x00200000)
-#define SCC_GSMRL_TPL_NONE	((uint)0x00000000)
-#define SCC_GSMRL_TPP_ALL1	((uint)0x00180000)
-#define SCC_GSMRL_TPP_01	((uint)0x00100000)
-#define SCC_GSMRL_TPP_10	((uint)0x00080000)
-#define SCC_GSMRL_TPP_ZEROS	((uint)0x00000000)
-#define SCC_GSMRL_TEND		((uint)0x00040000)
-#define SCC_GSMRL_TDCR_32	((uint)0x00030000)
-#define SCC_GSMRL_TDCR_16	((uint)0x00020000)
-#define SCC_GSMRL_TDCR_8	((uint)0x00010000)
-#define SCC_GSMRL_TDCR_1	((uint)0x00000000)
-#define SCC_GSMRL_RDCR_32	((uint)0x0000c000)
-#define SCC_GSMRL_RDCR_16	((uint)0x00008000)
-#define SCC_GSMRL_RDCR_8	((uint)0x00004000)
-#define SCC_GSMRL_RDCR_1	((uint)0x00000000)
-#define SCC_GSMRL_RENC_DFMAN	((uint)0x00003000)
-#define SCC_GSMRL_RENC_MANCH	((uint)0x00002000)
-#define SCC_GSMRL_RENC_FM0	((uint)0x00001000)
-#define SCC_GSMRL_RENC_NRZI	((uint)0x00000800)
-#define SCC_GSMRL_RENC_NRZ	((uint)0x00000000)
-#define SCC_GSMRL_TENC_DFMAN	((uint)0x00000600)
-#define SCC_GSMRL_TENC_MANCH	((uint)0x00000400)
-#define SCC_GSMRL_TENC_FM0	((uint)0x00000200)
-#define SCC_GSMRL_TENC_NRZI	((uint)0x00000100)
-#define SCC_GSMRL_TENC_NRZ	((uint)0x00000000)
-#define SCC_GSMRL_DIAG_LE	((uint)0x000000c0)	/* Loop and echo */
-#define SCC_GSMRL_DIAG_ECHO	((uint)0x00000080)
-#define SCC_GSMRL_DIAG_LOOP	((uint)0x00000040)
-#define SCC_GSMRL_DIAG_NORM	((uint)0x00000000)
-#define SCC_GSMRL_ENR		((uint)0x00000020)
-#define SCC_GSMRL_ENT		((uint)0x00000010)
-#define SCC_GSMRL_MODE_ENET	((uint)0x0000000c)
-#define SCC_GSMRL_MODE_DDCMP	((uint)0x00000009)
-#define SCC_GSMRL_MODE_BISYNC	((uint)0x00000008)
-#define SCC_GSMRL_MODE_V14	((uint)0x00000007)
-#define SCC_GSMRL_MODE_AHDLC	((uint)0x00000006)
-#define SCC_GSMRL_MODE_PROFIBUS	((uint)0x00000005)
-#define SCC_GSMRL_MODE_UART	((uint)0x00000004)
-#define SCC_GSMRL_MODE_SS7	((uint)0x00000003)
-#define SCC_GSMRL_MODE_ATALK	((uint)0x00000002)
-#define SCC_GSMRL_MODE_HDLC	((uint)0x00000000)
-
-#define SCC_TODR_TOD		((ushort)0x8000)
-
-/* SCC Event and Mask register.
-*/
-#define	SCCM_TXE	((unsigned char)0x10)
-#define	SCCM_BSY	((unsigned char)0x04)
-#define	SCCM_TX		((unsigned char)0x02)
-#define	SCCM_RX		((unsigned char)0x01)
-
-typedef struct scc_param {
-	ushort	scc_rbase;	/* Rx Buffer descriptor base address */
-	ushort	scc_tbase;	/* Tx Buffer descriptor base address */
-	u_char	scc_rfcr;	/* Rx function code */
-	u_char	scc_tfcr;	/* Tx function code */
-	ushort	scc_mrblr;	/* Max receive buffer length */
-	uint	scc_rstate;	/* Internal */
-	uint	scc_idp;	/* Internal */
-	ushort	scc_rbptr;	/* Internal */
-	ushort	scc_ibc;	/* Internal */
-	uint	scc_rxtmp;	/* Internal */
-	uint	scc_tstate;	/* Internal */
-	uint	scc_tdp;	/* Internal */
-	ushort	scc_tbptr;	/* Internal */
-	ushort	scc_tbc;	/* Internal */
-	uint	scc_txtmp;	/* Internal */
-	uint	scc_rcrc;	/* Internal */
-	uint	scc_tcrc;	/* Internal */
-} sccp_t;
-
-/* Function code bits.
-*/
-#define SCC_EB	((u_char)0x10)	/* Set big endian byte order */
-
-/* CPM Ethernet through SCCx.
- */
-typedef struct scc_enet {
-	sccp_t	sen_genscc;
-	uint	sen_cpres;	/* Preset CRC */
-	uint	sen_cmask;	/* Constant mask for CRC */
-	uint	sen_crcec;	/* CRC Error counter */
-	uint	sen_alec;	/* alignment error counter */
-	uint	sen_disfc;	/* discard frame counter */
-	ushort	sen_pads;	/* Tx short frame pad character */
-	ushort	sen_retlim;	/* Retry limit threshold */
-	ushort	sen_retcnt;	/* Retry limit counter */
-	ushort	sen_maxflr;	/* maximum frame length register */
-	ushort	sen_minflr;	/* minimum frame length register */
-	ushort	sen_maxd1;	/* maximum DMA1 length */
-	ushort	sen_maxd2;	/* maximum DMA2 length */
-	ushort	sen_maxd;	/* Rx max DMA */
-	ushort	sen_dmacnt;	/* Rx DMA counter */
-	ushort	sen_maxb;	/* Max BD byte count */
-	ushort	sen_gaddr1;	/* Group address filter */
-	ushort	sen_gaddr2;
-	ushort	sen_gaddr3;
-	ushort	sen_gaddr4;
-	uint	sen_tbuf0data0;	/* Save area 0 - current frame */
-	uint	sen_tbuf0data1;	/* Save area 1 - current frame */
-	uint	sen_tbuf0rba;	/* Internal */
-	uint	sen_tbuf0crc;	/* Internal */
-	ushort	sen_tbuf0bcnt;	/* Internal */
-	ushort	sen_paddrh;	/* physical address (MSB) */
-	ushort	sen_paddrm;
-	ushort	sen_paddrl;	/* physical address (LSB) */
-	ushort	sen_pper;	/* persistence */
-	ushort	sen_rfbdptr;	/* Rx first BD pointer */
-	ushort	sen_tfbdptr;	/* Tx first BD pointer */
-	ushort	sen_tlbdptr;	/* Tx last BD pointer */
-	uint	sen_tbuf1data0;	/* Save area 0 - current frame */
-	uint	sen_tbuf1data1;	/* Save area 1 - current frame */
-	uint	sen_tbuf1rba;	/* Internal */
-	uint	sen_tbuf1crc;	/* Internal */
-	ushort	sen_tbuf1bcnt;	/* Internal */
-	ushort	sen_txlen;	/* Tx Frame length counter */
-	ushort	sen_iaddr1;	/* Individual address filter */
-	ushort	sen_iaddr2;
-	ushort	sen_iaddr3;
-	ushort	sen_iaddr4;
-	ushort	sen_boffcnt;	/* Backoff counter */
-
-	/* NOTE: Some versions of the manual have the following items
-	 * incorrectly documented.  Below is the proper order.
-	 */
-	ushort	sen_taddrh;	/* temp address (MSB) */
-	ushort	sen_taddrm;
-	ushort	sen_taddrl;	/* temp address (LSB) */
-} scc_enet_t;
-
-/***  MBX  ************************************************************/
-
-#ifdef CONFIG_MBX
-/* Bits in parallel I/O port registers that have to be set/cleared
- * to configure the pins for SCC1 use.  The TCLK and RCLK seem unique
- * to the MBX860 board.  Any two of the four available clocks could be
- * used, and the MPC860 cookbook manual has an example using different
- * clock pins.
- */
-#define PA_ENET_RXD	((ushort)0x0001)
-#define PA_ENET_TXD	((ushort)0x0002)
-#define PA_ENET_TCLK	((ushort)0x0200)
-#define PA_ENET_RCLK	((ushort)0x0800)
-#define PC_ENET_TENA	((ushort)0x0001)
-#define PC_ENET_CLSN	((ushort)0x0010)
-#define PC_ENET_RENA	((ushort)0x0020)
-
-/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
- * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
- */
-#define SICR_ENET_MASK	((uint)0x000000ff)
-#define SICR_ENET_CLKRT	((uint)0x0000003d)
-#endif	/* CONFIG_MBX */
-
-/***  RPXLITE  ********************************************************/
-
-#ifdef CONFIG_RPXLITE
-/* This ENET stuff is for the MPC850 with ethernet on SCC2.  Some of
- * this may be unique to the RPX-Lite configuration.
- * Note TENA is on Port B.
- */
-#define PA_ENET_RXD	((ushort)0x0004)
-#define PA_ENET_TXD	((ushort)0x0008)
-#define PA_ENET_TCLK	((ushort)0x0200)
-#define PA_ENET_RCLK	((ushort)0x0800)
-#define PB_ENET_TENA	((uint)0x00002000)
-#define PC_ENET_CLSN	((ushort)0x0040)
-#define PC_ENET_RENA	((ushort)0x0080)
-
-#define SICR_ENET_MASK	((uint)0x0000ff00)
-#define SICR_ENET_CLKRT	((uint)0x00003d00)
-#endif	/* CONFIG_RPXLITE */
-
-/***  BSEIP  **********************************************************/
-
-#ifdef CONFIG_BSEIP
-/* This ENET stuff is for the MPC823 with ethernet on SCC2.
- * This is unique to the BSE ip-Engine board.
- */
-#define PA_ENET_RXD	((ushort)0x0004)
-#define PA_ENET_TXD	((ushort)0x0008)
-#define PA_ENET_TCLK	((ushort)0x0100)
-#define PA_ENET_RCLK	((ushort)0x0200)
-#define PB_ENET_TENA	((uint)0x00002000)
-#define PC_ENET_CLSN	((ushort)0x0040)
-#define PC_ENET_RENA	((ushort)0x0080)
-
-/* BSE uses port B and C bits for PHY control also.
-*/
-#define PB_BSE_POWERUP	((uint)0x00000004)
-#define PB_BSE_FDXDIS	((uint)0x00008000)
-#define PC_BSE_LOOPBACK	((ushort)0x0800)
-
-#define SICR_ENET_MASK	((uint)0x0000ff00)
-#define SICR_ENET_CLKRT	((uint)0x00002c00)
-#endif	/* CONFIG_BSEIP */
-
-/***  RPXCLASSIC  *****************************************************/
-
-#ifdef CONFIG_RPXCLASSIC
-/* Bits in parallel I/O port registers that have to be set/cleared
- * to configure the pins for SCC1 use.
- */
-#define PA_ENET_RXD	((ushort)0x0001)
-#define PA_ENET_TXD	((ushort)0x0002)
-#define PA_ENET_TCLK	((ushort)0x0200)
-#define PA_ENET_RCLK	((ushort)0x0800)
-#define PB_ENET_TENA	((uint)0x00001000)
-#define PC_ENET_CLSN	((ushort)0x0010)
-#define PC_ENET_RENA	((ushort)0x0020)
-
-/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
- * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
- */
-#define SICR_ENET_MASK	((uint)0x000000ff)
-#define SICR_ENET_CLKRT	((uint)0x0000003d)
-#endif	/* CONFIG_RPXCLASSIC */
-
-/***  TQM823L, TQM850L  ***********************************************/
-
-#if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L)
-/* Bits in parallel I/O port registers that have to be set/cleared
- * to configure the pins for SCC1 use.
- */
-#define PA_ENET_RXD	((ushort)0x0004)	/* PA 13 */
-#define PA_ENET_TXD	((ushort)0x0008)	/* PA 12 */
-#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
-#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
-
-#define PB_ENET_TENA	((uint)0x00002000)	/* PB 18 */
-
-#define PC_ENET_CLSN	((ushort)0x0040)	/* PC  9 */
-#define PC_ENET_RENA	((ushort)0x0080)	/* PC  8 */
-
-/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
- * SCC2.  Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
- */
-#define SICR_ENET_MASK	((uint)0x0000ff00)
-#define SICR_ENET_CLKRT	((uint)0x00002600)
-#endif	/* CONFIG_TQM823L, CONFIG_TQM850L */
-
-/***  FPS850L  *********************************************************/
-
-#ifdef CONFIG_FPS850L
-/* Bits in parallel I/O port registers that have to be set/cleared
- * to configure the pins for SCC1 use.
- */
-#define PA_ENET_RXD	((ushort)0x0004)	/* PA 13 */
-#define PA_ENET_TXD	((ushort)0x0008)	/* PA 12 */
-#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
-#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
-
-#define PC_ENET_TENA	((ushort)0x0002)	/* PC 14 */
-#define PC_ENET_CLSN	((ushort)0x0040)	/* PC  9 */
-#define PC_ENET_RENA	((ushort)0x0080)	/* PC  8 */
-
-/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
- * SCC2.  Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
- */
-#define SICR_ENET_MASK	((uint)0x0000ff00)
-#define SICR_ENET_CLKRT	((uint)0x00002600)
-#endif	/* CONFIG_FPS850L */
-
-/***  TQM860L  ********************************************************/
-
-#ifdef CONFIG_TQM860L
-/* Bits in parallel I/O port registers that have to be set/cleared
- * to configure the pins for SCC1 use.
- */
-#define PA_ENET_RXD	((ushort)0x0001)	/* PA 15 */
-#define PA_ENET_TXD	((ushort)0x0002)	/* PA 14 */
-#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
-#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
-
-#define PC_ENET_TENA	((ushort)0x0001)	/* PC 15 */
-#define PC_ENET_CLSN	((ushort)0x0010)	/* PC 11 */
-#define PC_ENET_RENA	((ushort)0x0020)	/* PC 10 */
-
-/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
- * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
- */
-#define SICR_ENET_MASK	((uint)0x000000ff)
-#define SICR_ENET_CLKRT	((uint)0x00000026)
-#endif	/* CONFIG_TQM860L */
-
-/***  SPD823TS  *******************************************************/
-
-#ifdef CONFIG_SPD823TS
-/* Bits in parallel I/O port registers that have to be set/cleared
- * to configure the pins for SCC2 use.
- */
-#define PA_ENET_MDC	((ushort)0x0001)	/* PA 15 !!! */
-#define PA_ENET_MDIO	((ushort)0x0002)	/* PA 14 !!! */
-#define PA_ENET_RXD	((ushort)0x0004)	/* PA 13 */
-#define PA_ENET_TXD	((ushort)0x0008)	/* PA 12 */
-#define PA_ENET_RCLK	((ushort)0x0200)	/* PA  6 */
-#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
-
-#define PB_ENET_TENA	((uint)0x00002000)	/* PB 18 */
-
-#define PC_ENET_CLSN	((ushort)0x0040)	/* PC  9 */
-#define PC_ENET_RENA	((ushort)0x0080)	/* PC  8 */
-#define	PC_ENET_RESET	((ushort)0x0100)	/* PC  7 !!! */
-
-/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK2) to
- * SCC2.  Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
- */
-#define SICR_ENET_MASK	((uint)0x0000ff00)
-#define SICR_ENET_CLKRT	((uint)0x00002E00)
-#endif	/* CONFIG_SPD823TS */
-
-
-/***  SM850  *********************************************************/
-
-/* The SM850 Service Module uses SCC2 for IrDA and SCC3 for Ethernet */
-
-#ifdef CONFIG_SM850
-#define PB_ENET_RXD	((uint)0x00000004)	/* PB 29 */
-#define PB_ENET_TXD	((uint)0x00000002)	/* PB 30 */
-#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
-#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
-
-#define PC_ENET_LBK	((ushort)0x0008)	/* PC 12 */
-#define PC_ENET_TENA	((ushort)0x0004)	/* PC 13 */
-
-#define PC_ENET_RENA	((ushort)0x0800)	/* PC  4 */
-#define PC_ENET_CLSN	((ushort)0x0400)	/* PC  5 */
-
-/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
- * SCC3.  Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero.
- */
-#define SICR_ENET_MASK	((uint)0x00FF0000)
-#define SICR_ENET_CLKRT	((uint)0x00260000)
-#endif	/* CONFIG_SM850 */
-
-/*********************************************************************/
-
-/* SCC Event register as used by Ethernet.
-*/
-#define SCCE_ENET_GRA	((ushort)0x0080)	/* Graceful stop complete */
-#define SCCE_ENET_TXE	((ushort)0x0010)	/* Transmit Error */
-#define SCCE_ENET_RXF	((ushort)0x0008)	/* Full frame received */
-#define SCCE_ENET_BSY	((ushort)0x0004)	/* All incoming buffers full */
-#define SCCE_ENET_TXB	((ushort)0x0002)	/* A buffer was transmitted */
-#define SCCE_ENET_RXB	((ushort)0x0001)	/* A buffer was received */
-
-/* SCC Mode Register (PMSR) as used by Ethernet.
-*/
-#define SCC_PMSR_HBC	((ushort)0x8000)	/* Enable heartbeat */
-#define SCC_PMSR_FC	((ushort)0x4000)	/* Force collision */
-#define SCC_PMSR_RSH	((ushort)0x2000)	/* Receive short frames */
-#define SCC_PMSR_IAM	((ushort)0x1000)	/* Check individual hash */
-#define SCC_PMSR_ENCRC	((ushort)0x0800)	/* Ethernet CRC mode */
-#define SCC_PMSR_PRO	((ushort)0x0200)	/* Promiscuous mode */
-#define SCC_PMSR_BRO	((ushort)0x0100)	/* Catch broadcast pkts */
-#define SCC_PMSR_SBT	((ushort)0x0080)	/* Special backoff timer */
-#define SCC_PMSR_LPB	((ushort)0x0040)	/* Set Loopback mode */
-#define SCC_PMSR_SIP	((ushort)0x0020)	/* Sample Input Pins */
-#define SCC_PMSR_LCW	((ushort)0x0010)	/* Late collision window */
-#define SCC_PMSR_NIB22	((ushort)0x000a)	/* Start frame search */
-#define SCC_PMSR_FDE	((ushort)0x0001)	/* Full duplex enable */
-
-/* Buffer descriptor control/status used by Ethernet receive.
-*/
-#define BD_ENET_RX_EMPTY	((ushort)0x8000)
-#define BD_ENET_RX_WRAP		((ushort)0x2000)
-#define BD_ENET_RX_INTR		((ushort)0x1000)
-#define BD_ENET_RX_LAST		((ushort)0x0800)
-#define BD_ENET_RX_FIRST	((ushort)0x0400)
-#define BD_ENET_RX_MISS		((ushort)0x0100)
-#define BD_ENET_RX_LG		((ushort)0x0020)
-#define BD_ENET_RX_NO		((ushort)0x0010)
-#define BD_ENET_RX_SH		((ushort)0x0008)
-#define BD_ENET_RX_CR		((ushort)0x0004)
-#define BD_ENET_RX_OV		((ushort)0x0002)
-#define BD_ENET_RX_CL		((ushort)0x0001)
-#define BD_ENET_RX_STATS	((ushort)0x013f)	/* All status bits */
-
-/* Buffer descriptor control/status used by Ethernet transmit.
-*/
-#define BD_ENET_TX_READY	((ushort)0x8000)
-#define BD_ENET_TX_PAD		((ushort)0x4000)
-#define BD_ENET_TX_WRAP		((ushort)0x2000)
-#define BD_ENET_TX_INTR		((ushort)0x1000)
-#define BD_ENET_TX_LAST		((ushort)0x0800)
-#define BD_ENET_TX_TC		((ushort)0x0400)
-#define BD_ENET_TX_DEF		((ushort)0x0200)
-#define BD_ENET_TX_HB		((ushort)0x0100)
-#define BD_ENET_TX_LC		((ushort)0x0080)
-#define BD_ENET_TX_RL		((ushort)0x0040)
-#define BD_ENET_TX_RCMASK	((ushort)0x003c)
-#define BD_ENET_TX_UN		((ushort)0x0002)
-#define BD_ENET_TX_CSL		((ushort)0x0001)
-#define BD_ENET_TX_STATS	((ushort)0x03ff)	/* All status bits */
-
-/* SCC as UART
-*/
-typedef struct scc_uart {
-	sccp_t	scc_genscc;
-	uint	scc_res1;	/* Reserved */
-	uint	scc_res2;	/* Reserved */
-	ushort	scc_maxidl;	/* Maximum idle chars */
-	ushort	scc_idlc;	/* temp idle counter */
-	ushort	scc_brkcr;	/* Break count register */
-	ushort	scc_parec;	/* receive parity error counter */
-	ushort	scc_frmec;	/* receive framing error counter */
-	ushort	scc_nosec;	/* receive noise counter */
-	ushort	scc_brkec;	/* receive break condition counter */
-	ushort	scc_brkln;	/* last received break length */
-	ushort	scc_uaddr1;	/* UART address character 1 */
-	ushort	scc_uaddr2;	/* UART address character 2 */
-	ushort	scc_rtemp;	/* Temp storage */
-	ushort	scc_toseq;	/* Transmit out of sequence char */
-	ushort	scc_char1;	/* control character 1 */
-	ushort	scc_char2;	/* control character 2 */
-	ushort	scc_char3;	/* control character 3 */
-	ushort	scc_char4;	/* control character 4 */
-	ushort	scc_char5;	/* control character 5 */
-	ushort	scc_char6;	/* control character 6 */
-	ushort	scc_char7;	/* control character 7 */
-	ushort	scc_char8;	/* control character 8 */
-	ushort	scc_rccm;	/* receive control character mask */
-	ushort	scc_rccr;	/* receive control character register */
-	ushort	scc_rlbc;	/* receive last break character */
-} scc_uart_t;
-
-/* SCC Event and Mask registers when it is used as a UART.
-*/
-#define UART_SCCM_GLR		((ushort)0x1000)
-#define UART_SCCM_GLT		((ushort)0x0800)
-#define UART_SCCM_AB		((ushort)0x0200)
-#define UART_SCCM_IDL		((ushort)0x0100)
-#define UART_SCCM_GRA		((ushort)0x0080)
-#define UART_SCCM_BRKE		((ushort)0x0040)
-#define UART_SCCM_BRKS		((ushort)0x0020)
-#define UART_SCCM_CCR		((ushort)0x0008)
-#define UART_SCCM_BSY		((ushort)0x0004)
-#define UART_SCCM_TX		((ushort)0x0002)
-#define UART_SCCM_RX		((ushort)0x0001)
-
-/* The SCC PMSR when used as a UART.
-*/
-#define SCU_PMSR_FLC		((ushort)0x8000)
-#define SCU_PMSR_SL		((ushort)0x4000)
-#define SCU_PMSR_CL		((ushort)0x3000)
-#define SCU_PMSR_UM		((ushort)0x0c00)
-#define SCU_PMSR_FRZ		((ushort)0x0200)
-#define SCU_PMSR_RZS		((ushort)0x0100)
-#define SCU_PMSR_SYN		((ushort)0x0080)
-#define SCU_PMSR_DRT		((ushort)0x0040)
-#define SCU_PMSR_PEN		((ushort)0x0010)
-#define SCU_PMSR_RPM		((ushort)0x000c)
-#define SCU_PMSR_REVP		((ushort)0x0008)
-#define SCU_PMSR_TPM		((ushort)0x0003)
-#define SCU_PMSR_TEVP		((ushort)0x0003)
-
-/* CPM Transparent mode SCC.
- */
-typedef struct scc_trans {
-	sccp_t	st_genscc;
-	uint	st_cpres;	/* Preset CRC */
-	uint	st_cmask;	/* Constant mask for CRC */
-} scc_trans_t;
-
-#define BD_SCC_TX_LAST		((ushort)0x0800)
-
-/* IIC parameter RAM.
-*/
-typedef struct iic {
-	ushort	iic_rbase;	/* Rx Buffer descriptor base address */
-	ushort	iic_tbase;	/* Tx Buffer descriptor base address */
-	u_char	iic_rfcr;	/* Rx function code */
-	u_char	iic_tfcr;	/* Tx function code */
-	ushort	iic_mrblr;	/* Max receive buffer length */
-	uint	iic_rstate;	/* Internal */
-	uint	iic_rdp;	/* Internal */
-	ushort	iic_rbptr;	/* Internal */
-	ushort	iic_rbc;	/* Internal */
-	uint	iic_rxtmp;	/* Internal */
-	uint	iic_tstate;	/* Internal */
-	uint	iic_tdp;	/* Internal */
-	ushort	iic_tbptr;	/* Internal */
-	ushort	iic_tbc;	/* Internal */
-	uint	iic_txtmp;	/* Internal */
-} iic_t;
-
-#define BD_IIC_START		((ushort)0x0400)
-
-/* CPM interrupts.  There are nearly 32 interrupts generated by CPM
- * channels or devices.  All of these are presented to the PPC core
- * as a single interrupt.  The CPM interrupt handler dispatches its
- * own handlers, in a similar fashion to the PPC core handler.  We
- * use the table as defined in the manuals (i.e. no special high
- * priority and SCC1 == SCCa, etc...).
- */
-#define CPMVEC_NR		32
-#define	CPMVEC_PIO_PC15		((ushort)0x1f)
-#define	CPMVEC_SCC1		((ushort)0x1e)
-#define	CPMVEC_SCC2		((ushort)0x1d)
-#define	CPMVEC_SCC3		((ushort)0x1c)
-#define	CPMVEC_SCC4		((ushort)0x1b)
-#define	CPMVEC_PIO_PC14		((ushort)0x1a)
-#define	CPMVEC_TIMER1		((ushort)0x19)
-#define	CPMVEC_PIO_PC13		((ushort)0x18)
-#define	CPMVEC_PIO_PC12		((ushort)0x17)
-#define	CPMVEC_SDMA_CB_ERR	((ushort)0x16)
-#define CPMVEC_IDMA1		((ushort)0x15)
-#define CPMVEC_IDMA2		((ushort)0x14)
-#define CPMVEC_TIMER2		((ushort)0x12)
-#define CPMVEC_RISCTIMER	((ushort)0x11)
-#define CPMVEC_I2C		((ushort)0x10)
-#define	CPMVEC_PIO_PC11		((ushort)0x0f)
-#define	CPMVEC_PIO_PC10		((ushort)0x0e)
-#define CPMVEC_TIMER3		((ushort)0x0c)
-#define	CPMVEC_PIO_PC9		((ushort)0x0b)
-#define	CPMVEC_PIO_PC8		((ushort)0x0a)
-#define	CPMVEC_PIO_PC7		((ushort)0x09)
-#define CPMVEC_TIMER4		((ushort)0x07)
-#define	CPMVEC_PIO_PC6		((ushort)0x06)
-#define	CPMVEC_SPI		((ushort)0x05)
-#define	CPMVEC_SMC1		((ushort)0x04)
-#define	CPMVEC_SMC2		((ushort)0x03)
-#define	CPMVEC_PIO_PC5		((ushort)0x02)
-#define	CPMVEC_PIO_PC4		((ushort)0x01)
-#define	CPMVEC_ERROR		((ushort)0x00)
-
-/* CPM interrupt configuration vector.
-*/
-#define	CICR_SCD_SCC4		((uint)0x00c00000)	/* SCC4 @ SCCd */
-#define	CICR_SCC_SCC3		((uint)0x00200000)	/* SCC3 @ SCCc */
-#define	CICR_SCB_SCC2		((uint)0x00040000)	/* SCC2 @ SCCb */
-#define	CICR_SCA_SCC1		((uint)0x00000000)	/* SCC1 @ SCCa */
-#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrrupt */
-#define CICR_HP_MASK		((uint)0x00001f00)	/* Hi-pri int. */
-#define CICR_IEN		((uint)0x00000080)	/* Int. enable */
-#define CICR_SPS		((uint)0x00000001)	/* SCC Spread */
-
-extern void cpm_install_handler(int vec, 
-		void (*handler)(void *, struct pt_regs *regs), void *dev_id);
-extern void cpm_free_handler(int vec);
-
-#endif /* __CPM_8XX__ */
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/8xx_io/enet.c linux/arch/ppc/8xx_io/enet.c
--- v2.4.10/linux/arch/ppc/8xx_io/enet.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/8xx_io/enet.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.enet.c 1.10 05/17/01 18:14:20 cort
+ * BK Id: SCCS/s.enet.c 1.15 09/14/01 18:01:16 trini
  */
 /*
  * Ethernet driver for Motorola MPC8xx.
@@ -11,7 +11,7 @@
  * This version of the driver is somewhat selectable for the different
  * processor/board combinations.  It works for the boards I know about
  * now, and should be easily modified to include others.  Some of the
- * configuration information is contained in "commproc.h" and the
+ * configuration information is contained in <asm/commproc.h> and the
  * remainder is here.
  *
  * Buffer descriptors are kept in the CPM dual port RAM, and the frame
@@ -47,7 +47,7 @@
 #include <asm/mpc8xx.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
-#include "commproc.h"
+#include <asm/commproc.h>
 
 /*
  *				Theory of Operation
@@ -83,7 +83,7 @@
  * programming documents for details unique to your board.
  *
  * For the TQM8xx(L) modules, there is no control register interface.
- * All functions are directly controlled using I/O pins.  See commproc.h.
+ * All functions are directly controlled using I/O pins.  See <asm/commproc.h>.
  */
 
 /* The transmitter timeout
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/8xx_io/fec.c linux/arch/ppc/8xx_io/fec.c
--- v2.4.10/linux/arch/ppc/8xx_io/fec.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/8xx_io/fec.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.fec.c 1.12 05/18/01 07:54:04 patch
+ * BK Id: SCCS/s.fec.c 1.18 09/22/01 09:12:32 trini
  */
 /*
  * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
@@ -60,7 +60,7 @@
 #include <asm/irq.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
-#include "commproc.h"
+#include <asm/commproc.h>
 
 #ifdef	CONFIG_USE_MDIO
 /* Forward declarations of some structures to support different PHYs
@@ -412,8 +412,10 @@
 		bdp++;
 	}
 
-	if (bdp->cbd_sc & BD_ENET_TX_READY)
+	if (bdp->cbd_sc & BD_ENET_TX_READY) {
 		netif_stop_queue(dev);
+		fep->tx_full = 1;
+	}
 
 	fep->cur_tx = (cbd_t *)bdp;
 
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/8xx_io/uart.c linux/arch/ppc/8xx_io/uart.c
--- v2.4.10/linux/arch/ppc/8xx_io/uart.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/8xx_io/uart.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.uart.c 1.14 06/27/01 14:49:55 trini
+ * BK Id: SCCS/s.uart.c 1.16 09/14/01 18:01:17 trini
  */
 /*
  *  UART driver for MPC860 CPM SCC or SMC
@@ -43,7 +43,7 @@
 #include <asm/uaccess.h>
 #include <asm/8xx_immap.h>
 #include <asm/mpc8xx.h>
-#include "commproc.h"
+#include <asm/commproc.h>
 #ifdef CONFIG_MAGIC_SYSRQ
 #include <linux/sysrq.h>
 #endif
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/boot/mbx/iic.c linux/arch/ppc/boot/mbx/iic.c
--- v2.4.10/linux/arch/ppc/boot/mbx/iic.c	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/mbx/iic.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.iic.c 1.8 05/18/01 07:54:04 patch
+ * BK Id: SCCS/s.iic.c 1.10 09/14/01 19:30:13 trini
  */
 
 /* Minimal support functions to read configuration from IIC EEPROMS
@@ -9,7 +9,7 @@
 #include <linux/types.h>
 #include <asm/uaccess.h>
 #include <asm/mpc8xx.h>
-#include "../../8xx_io/commproc.h"
+#include <asm/commproc.h>
 
 
 /* IIC functions.
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/boot/mbx/m8xx_tty.c linux/arch/ppc/boot/mbx/m8xx_tty.c
--- v2.4.10/linux/arch/ppc/boot/mbx/m8xx_tty.c	Thu May 24 15:02:06 2001
+++ linux/arch/ppc/boot/mbx/m8xx_tty.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.m8xx_tty.c 1.8 05/18/01 07:54:04 patch
+ * BK Id: SCCS/s.m8xx_tty.c 1.10 09/14/01 19:30:13 trini
  */
 
 
@@ -17,7 +17,7 @@
 #include <linux/types.h>
 #include <asm/uaccess.h>
 #include <asm/mpc8xx.h>
-#include "../../8xx_io/commproc.h"
+#include <asm/commproc.h>
 
 #ifdef CONFIG_MBX
 #define MBX_CSR1	((volatile u_char *)0xfa100000)
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/boot/prep/Makefile linux/arch/ppc/boot/prep/Makefile
--- v2.4.10/linux/arch/ppc/boot/prep/Makefile	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/boot/prep/Makefile	Mon Oct  8 11:43:01 2001
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.24 08/01/01 13:25:40 trini
+# BK Id: SCCS/s.Makefile 1.26 09/25/01 07:54:40 trini
 #
 # arch/ppc/boot/Makefile
 #
@@ -44,7 +44,7 @@
 	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
 		-DZIMAGE_SIZE=0 -c -o $@ $*.c
 
-zvmlinux.initrd: zvmlinux ../images/vmlinux.gz
+zvmlinux.initrd: $(obj-y) $(LIBS) ../images/vmlinux.gz
 	$(LD) $(ZLINKFLAGS) -o $@.tmp $(obj-y) $(LIBS)
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
 		--add-section=initrd=../images/ramdisk.image.gz \
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/configs/IVMS8_defconfig linux/arch/ppc/configs/IVMS8_defconfig
--- v2.4.10/linux/arch/ppc/configs/IVMS8_defconfig	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/configs/IVMS8_defconfig	Mon Oct  8 11:40:13 2001
@@ -110,6 +110,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -197,10 +198,17 @@
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_MPC8xx_IDE=y
+CONFIG_IDE_8xx_PCCARD=y
+# CONFIG_IDE_8xx_DIRECT is not set
+# CONFIG_IDE_EXT_DIRECT is not set
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -226,11 +234,9 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
@@ -249,9 +255,9 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
@@ -312,6 +318,10 @@
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Macintosh device drivers
@@ -341,7 +351,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -391,6 +405,7 @@
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
@@ -475,6 +490,7 @@
 #
 CONFIG_8xx_COPYBACK=y
 # CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
 CONFIG_BLK_DEV_MPC8xx_IDE=y
 
 #
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/configs/TQM860L_defconfig linux/arch/ppc/configs/TQM860L_defconfig
--- v2.4.10/linux/arch/ppc/configs/TQM860L_defconfig	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/configs/TQM860L_defconfig	Mon Oct  8 11:40:13 2001
@@ -111,6 +111,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -163,9 +164,52 @@
 #
 # ATA/IDE/MFM/RLL support
 #
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_MPC8xx_IDE=y
+CONFIG_IDE_8xx_PCCARD=y
+# CONFIG_IDE_8xx_DIRECT is not set
+# CONFIG_IDE_EXT_DIRECT is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -191,11 +235,9 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
@@ -214,9 +256,9 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
@@ -277,6 +319,10 @@
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Macintosh device drivers
@@ -306,7 +352,11 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
 
 #
 # Input core support is needed for joysticks
@@ -356,6 +406,7 @@
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
@@ -374,7 +425,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
 # CONFIG_UDF_RW is not set
@@ -411,8 +462,12 @@
 # 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 is not set
+CONFIG_MAC_PARTITION=y
+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
@@ -444,6 +499,8 @@
 #
 CONFIG_8xx_COPYBACK=y
 # CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+CONFIG_BLK_DEV_MPC8xx_IDE=y
 
 #
 # USB support
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/cputable.c linux/arch/ppc/kernel/cputable.c
--- v2.4.10/linux/arch/ppc/kernel/cputable.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/cputable.c	Mon Oct  8 11:40:13 2001
@@ -171,7 +171,7 @@
 	__setup_cpu_7450
     },
     {	/* 82xx (8240, 8245, 8260 are all 603e cores) */
-	0xffff0000, 0x00810000, "82xx",
+	0x7fff0000, 0x00810000, "82xx",
 	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
 	COMMON_PPC,
 	32, 32,
@@ -231,7 +231,7 @@
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
     	PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
  	16, 16,
-	0, __setup_cpu_8xx
+	__setup_cpu_8xx	/* Empty */
     },
 #endif /* CONFIG_8xx */
 #ifdef CONFIG_4xx
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/m8260_setup.c linux/arch/ppc/kernel/m8260_setup.c
--- v2.4.10/linux/arch/ppc/kernel/m8260_setup.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/m8260_setup.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.m8260_setup.c 1.24 08/20/01 15:25:16 paulus
+ * BK Id: SCCS/s.m8260_setup.c 1.26 09/22/01 11:33:22 trini
  */
 /*
  *  linux/arch/ppc/kernel/setup.c
@@ -270,13 +270,6 @@
 #ifdef CONFIG_MAGIC_SYSRQ
 	ppc_md.kbd_sysrq_xlate	 = NULL;
 #endif
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.default_irq = m8xx_ide_default_irq;
-        ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
-        ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
-        ppc_ide_md.ide_request_irq = m8xx_ide_request_irq;
-#endif		
 }
 
 /* Mainly for ksyms.
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/m8xx_setup.c linux/arch/ppc/kernel/m8xx_setup.c
--- v2.4.10/linux/arch/ppc/kernel/m8xx_setup.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/m8xx_setup.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.m8xx_setup.c 1.29 08/30/01 09:01:04 trini
+ * BK Id: SCCS/s.m8xx_setup.c 1.32 09/27/01 09:01:12 trini
  *
  *  linux/arch/ppc/kernel/setup.c
  *
@@ -32,8 +32,6 @@
 #include <linux/init.h>
 #include <linux/blk.h>
 #include <linux/ioport.h>
-#include <asm/mpc8xx.h>  /* Before ide.h to avoid warning: `MAX_HWIFS' redefined */
-#include <linux/ide.h>
 #include <linux/bootmem.h>
 
 #include <asm/mmu.h>
@@ -41,7 +39,7 @@
 #include <asm/residual.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
-#include <asm/ide.h>
+#include <asm/mpc8xx.h>
 #include <asm/8xx_immap.h>
 #include <asm/machdep.h>
 
@@ -49,67 +47,12 @@
 #include "ppc8xx_pic.h"
 
 static int m8xx_set_rtc_time(unsigned long time);
-unsigned long m8xx_get_rtc_time(void);
+static unsigned long m8xx_get_rtc_time(void);
 void m8xx_calibrate_decr(void);
 
 unsigned char __res[sizeof(bd_t)];
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-
-#ifdef	CONFIG_BLK_DEV_MPC8xx_IDE
-#include "../../../drivers/ide/ide_modes.h"
-
-static void m8xx_ide_tuneproc(ide_drive_t *drive, byte pio);
-
-typedef	struct ide_ioport_desc {
-	unsigned long	base_off;		/* Offset to PCMCIA memory */
-	ide_ioreg_t	reg_off[IDE_NR_PORTS];	/* controller reg. offsets */
-	int		irq;			/* IRQ	*/
-} ide_ioport_desc_t;
-
-ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = {
-#ifdef IDE0_BASE_OFFSET
-	{ IDE0_BASE_OFFSET,
-	    {
-		IDE0_DATA_REG_OFFSET,
-		IDE0_ERROR_REG_OFFSET,
-		IDE0_NSECTOR_REG_OFFSET,
-		IDE0_SECTOR_REG_OFFSET,
-		IDE0_LCYL_REG_OFFSET,
-		IDE0_HCYL_REG_OFFSET,
-		IDE0_SELECT_REG_OFFSET,
-		IDE0_STATUS_REG_OFFSET,
-		IDE0_CONTROL_REG_OFFSET,
-		IDE0_IRQ_REG_OFFSET,
-	    },
-	    IDE0_INTERRUPT,
-	},
-# ifdef IDE1_BASE_OFFSET
-	{ IDE1_BASE_OFFSET,
-	    {
-		IDE1_DATA_REG_OFFSET,
-		IDE1_ERROR_REG_OFFSET,
-		IDE1_NSECTOR_REG_OFFSET,
-		IDE1_SECTOR_REG_OFFSET,
-		IDE1_LCYL_REG_OFFSET,
-		IDE1_HCYL_REG_OFFSET,
-		IDE1_SELECT_REG_OFFSET,
-		IDE1_STATUS_REG_OFFSET,
-		IDE1_CONTROL_REG_OFFSET,
-		IDE1_IRQ_REG_OFFSET,
-	    },
-	    IDE1_INTERRUPT,
-	},
-# endif /* IDE1_BASE_OFFSET */
-#endif	/* IDE0_BASE_OFFSET */
-};
-
-ide_pio_timings_t ide_pio_clocks[6];
 
-/* Make clock cycles and always round up */
-#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U )
-
-#endif	/* CONFIG_BLK_DEV_MPC8xx_IDE */
-#endif	/* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
+extern void m8xx_ide_init();
 
 #ifdef CONFIG_BLK_DEV_RAM
 extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
@@ -306,8 +249,8 @@
 
 	bp = (bd_t *)__res;
 			
-	len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
-		       "bus clock\t: %dMHz\n",
+	len += sprintf(len+buffer,"clock\t\t: %ldMHz\n"
+		       "bus clock\t: %ldMHz\n",
 		       bp->bi_intfreq / 1000000,
 		       bp->bi_busfreq / 1000000);
 
@@ -345,214 +288,6 @@
 #endif
 }
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-
-/*
- * IDE stuff.
- */
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-static void ide_interrupt_handler (void *dev)
-{
-}
-#endif
-
-static int
-m8xx_ide_default_irq(ide_ioreg_t base)
-{
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-	if (base >= MAX_HWIFS)
-		return 0;
-	
-	return (ioport_dsc[base].irq);
-#else
-        return 9;
-#endif
-}
-
-static ide_ioreg_t
-m8xx_ide_default_io_base(int index)
-{
-        return index;
-}
-
-static int
-m8xx_ide_request_irq(unsigned int irq,
-		       void (*handler)(int, void *, struct pt_regs *),
-		       unsigned long flags, 
-		       const char *device,
-		       void *dev_id)
-{
-	return request_8xxirq(irq, handler, flags, device, dev_id);
-}
-
-/* We can use an external IDE controller
- * or wire the IDE interface to the internal PCMCIA controller.
- *
- * See include/linux/ide.h for definition of hw_regs_t (p, base)
- */
-static void
-m8xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, 
-		ide_ioreg_t ctrl_port, int *irq)
-{
-	int i;
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-	ide_ioreg_t *p = hw->io_ports;
-	volatile pcmconf8xx_t	*pcmp;
-
-	static unsigned long pcmcia_base = 0;
-	unsigned long base;
-#endif
-
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-	*p = 0;
-	if (irq)
-		*irq = 0;
-
-	pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
-
-	if (!pcmcia_base) {
-		/* relies PCMCIA registers being set up by firmware */
-		pcmcia_base = (unsigned long) ioremap(PCMCIA_MEM_ADDR,
-						      PCMCIA_MEM_SIZE);
-
-		/* Compute clock cycles for PIO timings */
-		for (i=0; i<6; ++i) {
-			bd_t	*binfo = (bd_t *)__res;
-
-			ide_pio_clocks[i].hold_time   =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].hold_time,
-						binfo->bi_busfreq);
-			ide_pio_clocks[i].setup_time  =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time,
-						binfo->bi_busfreq);
-			ide_pio_clocks[i].active_time =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].active_time,
-						binfo->bi_busfreq);
-			ide_pio_clocks[i].cycle_time  =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time,
-						binfo->bi_busfreq);
-#if 0
-			printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n",
-				i,
-				ide_pio_clocks[i].setup_time,
-				ide_pio_clocks[i].active_time,
-				ide_pio_clocks[i].hold_time,
-				ide_pio_clocks[i].cycle_time,
-				ide_pio_timings[i].setup_time,
-				ide_pio_timings[i].active_time,
-				ide_pio_timings[i].hold_time,
-				ide_pio_timings[i].cycle_time);
-#endif
-		}
-	}
-
-	if (data_port >= MAX_HWIFS)
-		return;
-
-	base = pcmcia_base + ioport_dsc[data_port].base_off;
-
-# if (!defined(CONFIG_SPD823TS) && !defined(CONFIG_IVMS8))
-	/* SPD823TS and IVMS8 have a direct connection */
-	if (pcmp->pcmc_pipr & 0x18000000)
-		return;		/* No card in slot */
-# endif	/* CONFIG_SPD823TS, CONFIG_IVMS8 */
-
-	for (i = 0; i < IDE_NR_PORTS; ++i) {
-		*p++ = base + ioport_dsc[data_port].reg_off[i] - _IO_BASE;
-	}
-
-	if (irq) {
-	    *irq = ioport_dsc[data_port].irq;
-	}
-
-	/* register routine to tune PIO mode */
-	ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc;
-
-	/* Enable Harddisk Interrupt,
-	 * and make it edge sensitive
-	 */
-	hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_handler;
-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |=
-					(0x80000000 >> ioport_dsc[data_port].irq);
-
-#else	/* ! CONFIG_BLK_DEV_MPC8xx_IDE */
-	
-	/* Just a regular IDE drive on some I/O port.
-	*/
-	if (data_port == 0)
-		return;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i)
-		hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET;
-
-	hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-        return;
-
-#endif	/* CONFIG_BLK_DEV_MPC8xx_IDE */
-}
-
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-
-/* PCMCIA Timing */
-#ifndef	PCMCIA_SHT
-#define PCMCIA_SHT(t)	((t & 0x0F)<<16)	/* Strobe Hold  Time 	*/
-#define PCMCIA_SST(t)	((t & 0x0F)<<12)	/* Strobe Setup Time	*/
-#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length	*/
-#endif
-
-/* Calculate PIO timings */
-static void
-m8xx_ide_tuneproc(ide_drive_t *drive, byte pio)
-{
-	volatile pcmconf8xx_t	*pcmp;
-	ide_pio_data_t d;
-	ulong timing, mask, reg;
-
-	pio = ide_get_best_pio_mode(drive, pio, 4, &d);
-
-#if 1
-	printk("%s[%d] %s: best PIO mode: %d\n",
-		__FILE__,__LINE__,__FUNCTION__, pio);
-#endif
-	pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
-
-	mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF));
-
-	timing  = PCMCIA_SHT(ide_pio_clocks[pio].hold_time  )
-		| PCMCIA_SST(ide_pio_clocks[pio].setup_time )
-		| PCMCIA_SL (ide_pio_clocks[pio].active_time)
-		;
-
-#if 1
-	printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing);
-#endif
-	if ((reg = pcmp->pcmc_por0 & mask) != 0)
-		pcmp->pcmc_por0 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por1 & mask) != 0)
-		pcmp->pcmc_por1 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por2 & mask) != 0)
-		pcmp->pcmc_por2 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por3 & mask) != 0)
-		pcmp->pcmc_por3 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por4 & mask) != 0)
-		pcmp->pcmc_por4 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por5 & mask) != 0)
-		pcmp->pcmc_por5 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por6 & mask) != 0)
-		pcmp->pcmc_por6 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por7 & mask) != 0)
-		pcmp->pcmc_por7 = reg | timing;
-}
-#endif	/* CONFIG_BLK_DEV_MPC8xx_IDE */
-#endif	/* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
-
 /* -------------------------------------------------------------------- */
 
 /*
@@ -669,8 +404,6 @@
 #endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-        ppc_ide_md.default_irq = m8xx_ide_default_irq;
-        ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
-        ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
+	m8xx_ide_init();
 #endif		
 }
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.4.10/linux/arch/ppc/kernel/ppc_ksyms.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/ppc_ksyms.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ppc_ksyms.c 1.51 08/24/01 17:05:47 paulus
+ * BK Id: SCCS/s.ppc_ksyms.c 1.55 10/02/01 12:33:42 trini
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -52,7 +52,7 @@
 #include <asm/btext.h>
 
 #ifdef  CONFIG_8xx
-#include "../8xx_io/commproc.h"
+#include <asm/commproc.h>
 #endif
 
 /* Tell string.h we don't want memcpy etc. as cpp defines */
@@ -73,8 +73,10 @@
 long long __ashldi3(long long, int);
 long long __lshrdi3(long long, int);
 int abs(int);
-extern unsigned long ret_to_user_hook;
 
+extern unsigned char __res[];
+
+extern unsigned long ret_to_user_hook;
 extern unsigned long mm_ptov (unsigned long paddr);
 
 EXPORT_SYMBOL(clear_page);
@@ -338,6 +340,7 @@
 #endif
 
 #ifdef  CONFIG_8xx
+EXPORT_SYMBOL(__res);
 EXPORT_SYMBOL(request_8xxirq);
 EXPORT_SYMBOL(cpm_install_handler);
 EXPORT_SYMBOL(cpm_free_handler);
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.4.10/linux/arch/ppc/kernel/process.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/process.c	Mon Oct  8 11:43:01 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.process.c 1.27 08/28/01 22:01:21 paulus
+ * BK Id: SCCS/s.process.c 1.31 10/02/01 09:51:41 paulus
  */
 /*
  *  linux/arch/ppc/kernel/process.c
@@ -226,8 +226,10 @@
 	if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
 		giveup_altivec(prev);
 #endif /* CONFIG_ALTIVEC */	
-	current_set[smp_processor_id()] = new;
 #endif /* CONFIG_SMP */
+
+	current_set[smp_processor_id()] = new;
+
 	/* Avoid the trap.  On smp this this never happens since
 	 * we don't set last_task_used_altivec -- Cort
 	 */
@@ -243,8 +245,8 @@
 {
 	int i;
 
-	printk("NIP: %08lX XER: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx\n",
-	       regs->nip, regs->xer, regs->link, regs->gpr[1], regs,regs->trap);
+	printk("NIP: %08lX XER: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx    %s\n",
+	       regs->nip, regs->xer, regs->link, regs->gpr[1], regs,regs->trap, print_tainted());
 	printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
 	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
 	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c
--- v2.4.10/linux/arch/ppc/kernel/residual.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/residual.c	Mon Oct  8 11:43:01 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.residual.c 1.11 09/08/01 15:47:42 paulus
+ * BK Id: SCCS/s.residual.c 1.13 09/11/01 16:54:34 trini
  */
 /*
  * Code to deal with the PReP residual data.
@@ -248,7 +248,7 @@
 
 static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType, 
 					     unsigned char SubType) {
-	const unsigned char ** s=PnP_SUB_TYPES;
+	unsigned char ** s=PnP_SUB_TYPES;
 	while (*s && !((*s)[0]==BaseType 
 		       && (*s)[1]==SubType)) s++;
 	if (*s) return *s+2;
@@ -258,7 +258,7 @@
 static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType, 
 					      unsigned char SubType,
 					      unsigned char Interface) {
-	const unsigned char ** s=PnP_INTERFACES;
+	unsigned char ** s=PnP_INTERFACES;
 	while (*s && !((*s)[0]==BaseType 
 		       && (*s)[1]==SubType 
 		       && (*s)[2]==Interface)) s++;
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.4.10/linux/arch/ppc/kernel/time.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/time.c	Mon Oct  8 11:43:01 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.time.c 1.21 08/20/01 22:08:08 paulus
+ * BK Id: SCCS/s.time.c 1.26 10/05/01 08:29:42 trini
  */
 /*
  * Common time routines among all ppc machines.
@@ -200,10 +200,10 @@
 #ifdef CONFIG_SMP
 	smp_local_timer_interrupt(regs);
 #endif /* CONFIG_SMP */
-	
+
 	if (ppc_md.heartbeat && !ppc_md.heartbeat_count--)
 		ppc_md.heartbeat();
-	
+
 	hardirq_exit(cpu);
 
 	if (softirq_pending(cpu))
@@ -235,7 +235,7 @@
 	read_unlock_irqrestore(&xtime_lock, flags);
 
 	usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta);
-	while (usec > 1000000) {
+	while (usec >= 1000000) {
 	  	sec++;
 		usec -= 1000000;
 	}
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.4.10/linux/arch/ppc/kernel/traps.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/kernel/traps.c	Sun Sep 30 12:26:08 2001
@@ -191,8 +191,8 @@
 void
 UnknownException(struct pt_regs *regs)
 {
-	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
-	       regs->nip, regs->msr, regs->trap);
+	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx    %s\n",
+	       regs->nip, regs->msr, regs->trap, print_tainted());
 	_exception(SIGTRAP, regs);	
 }
 
@@ -338,9 +338,9 @@
 void
 trace_syscall(struct pt_regs *regs)
 {
-	printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld\n",
+	printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
 	       current, current->pid, regs->nip, regs->link, regs->gpr[0],
-	       regs->ccr&0x10000000?"Error=":"", regs->gpr[3]);
+	       regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
 }
 
 #ifdef CONFIG_8xx
@@ -376,8 +376,8 @@
 void
 TAUException(struct pt_regs *regs)
 {
-	printk("TAU trap at PC: %lx, SR: %lx, vector=%lx\n",
-	       regs->nip, regs->msr, regs->trap);
+	printk("TAU trap at PC: %lx, SR: %lx, vector=%lx    %s\n",
+	       regs->nip, regs->msr, regs->trap, print_tainted());
 }
 #endif /* CONFIG_INT_TAU */
 
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v2.4.10/linux/arch/ppc/mm/fault.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/mm/fault.c	Tue Oct  2 09:12:44 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.fault.c 1.13 06/28/01 15:50:17 paulus
+ * BK Id: SCCS/s.fault.c 1.15 09/24/01 16:35:10 paulus
  */
 /*
  *  arch/ppc/mm/fault.c
@@ -150,6 +150,7 @@
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
+ survive:
         switch (handle_mm_fault(mm, vma, address, is_write)) {
         case 1:
                 current->min_flt++;
@@ -195,6 +196,12 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
+	if (current->pid == 1) {
+		current->policy |= SCHED_YIELD;
+		schedule();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
@@ -346,34 +353,3 @@
         return(retval);
 }
 #endif /* CONFIG_8xx */
-
-#if 0
-/*
- * Misc debugging functions.  Please leave them here. -- Cort
- */
-void print_pte(struct _PTE p)
-{
-	printk(
-"%08x %08x vsid: %06x h: %01x api: %02x rpn: %05x rcwimg: %d%d%d%d%d%d pp: %02x\n",
-		*((unsigned long *)(&p)), *((long *)&p+1),
-		p.vsid, p.h, p.api, p.rpn,
-		p.r,p.c,p.w,p.i,p.m,p.g,p.pp);
-}
-
-/*
- * Search the hw hash table for a mapping to the given physical
- * address. -- Cort
- */
-unsigned long htab_phys_to_va(unsigned long address)
-{
-	extern PTE *Hash, *Hash_end;
-	PTE *ptr;
-
-	for ( ptr = Hash ; ptr < Hash_end ; ptr++ )
-	{
-		if ( ptr->rpn == (address>>12) )
-			printk("phys %08lX -> va ???\n",
-			       address);
-	}
-}
-#endif
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.4.10/linux/arch/ppc/mm/init.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/mm/init.c	Tue Oct  2 09:12:44 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.init.c 1.34 08/20/01 22:12:43 paulus
+ * BK Id: SCCS/s.init.c 1.36 09/22/01 14:03:09 paulus
  */
 /*
  *  PowerPC version 
@@ -44,11 +44,14 @@
 #include <asm/smp.h>
 #include <asm/machdep.h>
 #include <asm/btext.h>
+#include <asm/tlb.h>
 
 #include "mem_pieces.h"
 #include "mmu_decl.h"
 
 #define MAX_LOW_MEM	(0xF0000000UL - KERNELBASE)
+
+mmu_gather_t mmu_gathers[NR_CPUS];
 
 void *end_of_DRAM;
 unsigned long total_memory;
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/mm/mmu_context.c linux/arch/ppc/mm/mmu_context.c
--- v2.4.10/linux/arch/ppc/mm/mmu_context.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/mm/mmu_context.c	Tue Oct  2 09:12:44 2001
@@ -36,7 +36,7 @@
 #include <asm/mmu_context.h>
 
 mm_context_t next_mmu_context;
-unsigned long context_map[(LAST_CONTEXT+1) / (8*sizeof(unsigned long))];
+unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
 #ifdef FEW_CONTEXTS
 atomic_t nr_free_contexts;
 struct mm_struct *context_mm[LAST_CONTEXT+1];
@@ -57,7 +57,7 @@
 	context_map[0] = (1 << FIRST_CONTEXT) - 1;
 	next_mmu_context = FIRST_CONTEXT;
 #ifdef FEW_CONTEXTS
-	atomic_set(&nr_free_contexts, LAST_CONTEXT);
+	atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
 #endif /* FEW_CONTEXTS */
 }
 
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/mm/pgtable.c linux/arch/ppc/mm/pgtable.c
--- v2.4.10/linux/arch/ppc/mm/pgtable.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/ppc/mm/pgtable.c	Tue Oct  2 09:12:44 2001
@@ -211,12 +211,12 @@
 #else
 		if ((char *) v < _stext || (char *) v >= etext)
 			f |= _PAGE_RW | _PAGE_DIRTY;
-#ifndef CONFIG_8xx
+#ifdef CONFIG_PPC_STD_MMU
 		else
-			/* On the powerpc (not 8xx), no user access
+			/* On the powerpc (not all), no user access
 			   forces R/W kernel access */
 			f |= _PAGE_USER;
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_PPC_STD_MMU */
 #endif /* CONFIG_KGDB */
 		map_page(v, p, f);
 		v += PAGE_SIZE;
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/xmon/start_8xx.c linux/arch/ppc/xmon/start_8xx.c
--- v2.4.10/linux/arch/ppc/xmon/start_8xx.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/xmon/start_8xx.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.start_8xx.c 1.7 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.start_8xx.c 1.10 09/14/01 18:01:17 trini
  */
 /*
  * Copyright (C) 1996 Paul Mackerras.
@@ -18,7 +18,7 @@
 #include <asm/processor.h>
 #include <asm/8xx_immap.h>
 #include <asm/mpc8xx.h>
-#include "../8xx_io/commproc.h"
+#include <asm/commproc.h>
 
 extern void xmon_printf(const char *fmt, ...);
 extern int xmon_8xx_write(char *str, int nb);
diff -u --recursive --new-file v2.4.10/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c
--- v2.4.10/linux/arch/ppc/xmon/xmon.c	Tue Jul  3 17:08:18 2001
+++ linux/arch/ppc/xmon/xmon.c	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.xmon.c 1.14 06/28/01 15:50:17 paulus
+ * BK Id: SCCS/s.xmon.c 1.16 09/22/01 15:25:10 trini
  */
 /*
  * Routines providing a simple monitor for use on the PowerMac.
@@ -813,10 +813,12 @@
 		printf("sprg0-3 = %x %x %x %x\n", get_sprg0(), get_sprg1(),
 		       get_sprg2(), get_sprg3());
 		printf("srr0 = %x, srr1 = %x\n", get_srr0(), get_srr1());
+#ifdef CONFIG_PPC_STD_MMU
 		printf("sr0-15 =");
 		for (i = 0; i < 16; ++i)
 			printf(" %x", get_sr(i));
 		printf("\n");
+#endif
 		asm("mr %0,1" : "=r" (i) :);
 		printf("sp = %x ", i);
 		asm("mr %0,2" : "=r" (i) :);
diff -u --recursive --new-file v2.4.10/linux/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
--- v2.4.10/linux/arch/s390/kernel/entry.S	Mon Aug 27 12:41:39 2001
+++ linux/arch/s390/kernel/entry.S	Mon Oct  8 10:35:41 2001
@@ -9,8 +9,6 @@
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
  */
 
-#define ASSEMBLY
-
 #include <linux/sys.h>
 #include <linux/linkage.h>
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.10/linux/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
--- v2.4.10/linux/arch/s390/kernel/process.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/s390/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -129,9 +129,10 @@
 		break;
 	case sp_psw:
 		if(regs)
-			linelen=sprintf(buff, "%s PSW:    %08lx %08lx\n", mode,
+			linelen=sprintf(buff, "%s PSW:    %08lx %08lx    %s\n", mode,
 				(unsigned long) regs->psw.mask,
-				(unsigned long) regs->psw.addr);
+				(unsigned long) regs->psw.addr,
+				print_tainted());
 		else
 			linelen=sprintf(buff,"pt_regs=NULL some info unavailable\n");
 		break;
diff -u --recursive --new-file v2.4.10/linux/arch/s390x/kernel/entry.S linux/arch/s390x/kernel/entry.S
--- v2.4.10/linux/arch/s390x/kernel/entry.S	Mon Aug 27 12:41:39 2001
+++ linux/arch/s390x/kernel/entry.S	Mon Oct  8 10:39:18 2001
@@ -9,8 +9,6 @@
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
  */
 
-#define ASSEMBLY
-
 #include <linux/sys.h>
 #include <linux/linkage.h>
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.10/linux/arch/s390x/kernel/process.c linux/arch/s390x/kernel/process.c
--- v2.4.10/linux/arch/s390x/kernel/process.c	Mon Aug 27 12:41:39 2001
+++ linux/arch/s390x/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -133,9 +133,10 @@
 		break;
 	case sp_psw:
 		if(regs)
-			linelen=sprintf(buff, "%s PSW:    %016lx %016lx\n", mode,
+			linelen=sprintf(buff, "%s PSW:    %016lx %016lx    %s\n", mode,
 				(unsigned long) regs->psw.mask,
-				(unsigned long) regs->psw.addr);
+				(unsigned long) regs->psw.addr,
+				print_tainted());
 		else
 			linelen=sprintf(buff,"pt_regs=NULL some info unavailable\n");
 		break;
diff -u --recursive --new-file v2.4.10/linux/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
--- v2.4.10/linux/arch/sh/kernel/process.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sh/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -81,8 +81,8 @@
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
-	printk("PC  : %08lx SP  : %08lx SR  : %08lx TEA : %08x\n",
-	       regs->pc, regs->regs[15], regs->sr, ctrl_inl(MMU_TEA));
+	printk("PC  : %08lx SP  : %08lx SR  : %08lx TEA : %08x    %s\n",
+	       regs->pc, regs->regs[15], regs->sr, ctrl_inl(MMU_TEA), print_tainted());
 	printk("R0  : %08lx R1  : %08lx R2  : %08lx R3  : %08lx\n",
 	       regs->regs[0],regs->regs[1],
 	       regs->regs[2],regs->regs[3]);
diff -u --recursive --new-file v2.4.10/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- v2.4.10/linux/arch/sparc/kernel/process.c	Sun Feb 18 19:49:44 2001
+++ linux/arch/sparc/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -268,8 +268,8 @@
 
 void show_regs(struct pt_regs * regs)
 {
-        printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx\n", regs->psr,
-	       regs->pc, regs->npc, regs->y);
+        printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx    %s\n", regs->psr,
+	       regs->pc, regs->npc, regs->y, print_tainted());
 	printk("g0: %08lx g1: %08lx g2: %08lx g3: %08lx ",
 	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
 	       regs->u_regs[3]);
diff -u --recursive --new-file v2.4.10/linux/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c
--- v2.4.10/linux/arch/sparc/mm/init.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc/mm/init.c	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.99 2001/07/17 16:17:33 anton Exp $
+/*  $Id: init.c,v 1.100 2001/09/21 22:51:47 davem Exp $
  *  linux/arch/sparc/mm/init.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.4.10/linux/arch/sparc64/defconfig	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/defconfig	Mon Oct  1 09:19:56 2001
@@ -753,6 +753,7 @@
 #
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_CATC=m
+CONFIG_USB_CDCETHER=m
 CONFIG_USB_KAWETH=m
 CONFIG_USB_USBNET=m
 
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/dtlb_backend.S linux/arch/sparc64/kernel/dtlb_backend.S
--- v2.4.10/linux/arch/sparc64/kernel/dtlb_backend.S	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/dtlb_backend.S	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: dtlb_backend.S,v 1.14 2001/09/07 18:26:17 kanoj Exp $
+/* $Id: dtlb_backend.S,v 1.15 2001/09/24 21:54:09 davem Exp $
  * dtlb_backend.S: Back end to DTLB miss replacement strategy.
  *                 This is included directly into the trap table.
  *
@@ -13,12 +13,14 @@
 	 sllx		%g2, 62, r1
 #define FILL_VALID_SZ_BITS2(r1)
 #define FILL_VALID_SZ_BITS_NOP nop
-#else /* PAGE_SHIFT */
+#elif PAGE_SHIFT == 16
 #define FILL_VALID_SZ_BITS1(r1) \
 	or		%g0, 5, r1
 #define FILL_VALID_SZ_BITS2(r1) \
 	sllx		r1, 61, r1
 #define FILL_VALID_SZ_BITS_NOP
+#else
+#error unsupported PAGE_SIZE
 #endif /* PAGE_SHIFT */
 
 #define VPTE_BITS		(_PAGE_CP | _PAGE_CV | _PAGE_P )
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/head.S linux/arch/sparc64/kernel/head.S
--- v2.4.10/linux/arch/sparc64/kernel/head.S	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/head.S	Sat Oct  6 08:50:28 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.81 2001/09/07 23:00:15 kanoj Exp $
+/* $Id: head.S,v 1.82 2001/10/04 23:37:04 davem Exp $
  * head.S: Initial boot code for the Sparc64 port of Linux.
  *
  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -590,7 +590,8 @@
 
 	ldxa		[%g0] ASI_SAFARI_CONFIG, %g1
 	srlx		%g1, 17, %g1
-	and		%g1, 0x3ff, %g1		! 10bit Safari Agent ID
+	ba,pt		%xcc, set_worklist
+	 and		%g1, 0x3ff, %g1		! 10bit Safari Agent ID
 
 not_cheetah:
 	ldxa	[%g0] ASI_UPA_CONFIG, %g1
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- v2.4.10/linux/arch/sparc64/kernel/process.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/process.c	Sun Sep 30 12:26:08 2001
@@ -282,8 +282,8 @@
 	       local_irq_count(smp_processor_id()),
 	       irqs_running());
 #endif
-	printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x\n", regs->tstate,
-	       regs->tpc, regs->tnpc, regs->y);
+	printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x    %s\n", regs->tstate,
+	       regs->tpc, regs->tnpc, regs->y, print_tainted());
 	printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
 	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
 	       regs->u_regs[3]);
@@ -349,8 +349,8 @@
 
 void show_regs32(struct pt_regs32 *regs)
 {
-	printk("PSR: %08x PC: %08x NPC: %08x Y: %08x\n", regs->psr,
-	       regs->pc, regs->npc, regs->y);
+	printk("PSR: %08x PC: %08x NPC: %08x Y: %08x    %s\n", regs->psr,
+	       regs->pc, regs->npc, regs->y, print_tainted());
 	printk("g0: %08x g1: %08x g2: %08x g3: %08x ",
 	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
 	       regs->u_regs[3]);
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
--- v2.4.10/linux/arch/sparc64/kernel/ptrace.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/ptrace.c	Mon Oct  1 09:19:56 2001
@@ -25,6 +25,7 @@
 #include <asm/uaccess.h>
 #include <asm/psrcompat.h>
 #include <asm/visasm.h>
+#include <asm/spitfire.h>
 
 #define MAGIC_CONSTANT 0x80000000
 
@@ -596,7 +597,7 @@
 				spitfire_put_dcache_tag(va, 0x0);
 			/* No need to mess with I-cache on Cheetah. */
 		} else {
-			for (va =  0; va < (PAGE_SIZE << 1); va += 32)
+			for (va =  0; va < L1DCACHE_SIZE; va += 32)
 				spitfire_put_dcache_tag(va, 0x0);
 			if (request == PTRACE_PEEKTEXT ||
 			    request == PTRACE_POKETEXT ||
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- v2.4.10/linux/arch/sparc64/kernel/setup.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/setup.c	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.66 2001/09/20 00:35:31 davem Exp $
+/*  $Id: setup.c,v 1.67 2001/09/21 03:17:06 kanoj Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -38,6 +38,7 @@
 #include <asm/idprom.h>
 #include <asm/head.h>
 #include <asm/starfire.h>
+#include <asm/hardirq.h>
 
 #ifdef CONFIG_IP_PNP
 #include <net/ipconfig.h>
@@ -95,6 +96,14 @@
 	if (!(cmd = (char *)args[0]))
 		return -1;
 
+	/*
+	 * The callback can be invoked on the cpu that first dropped 
+	 * into prom_cmdline after taking the serial interrupt, or on 
+	 * a slave processor that was smp_captured() if the 
+	 * administrator has done a switch-cpu inside obp. In either 
+	 * case, the cpu is marked as in-interrupt. Drop IRQ locks.
+	 */
+	irq_exit(smp_processor_id(), 0);
 	save_and_cli(flags);
 	cons = console_drivers;
 	while (cons) {
@@ -271,6 +280,10 @@
 		register_console(cons);
 	}
 	restore_flags(flags);
+	/*
+	 * Restore in-interrupt status for a resume from obp.
+	 */
+	irq_enter(smp_processor_id(), 0);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- v2.4.10/linux/arch/sparc64/kernel/sparc64_ksyms.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.111 2001/08/30 03:22:00 kanoj Exp $
+/* $Id: sparc64_ksyms.c,v 1.112 2001/09/25 23:30:23 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -278,6 +278,7 @@
 EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(__strlen_user);
+EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(strcpy);
 EXPORT_SYMBOL(strncpy);
 EXPORT_SYMBOL(strcat);
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.4.10/linux/arch/sparc64/kernel/sys_sparc32.c	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/sys_sparc32.c	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.178 2001/08/13 14:40:07 davem Exp $
+/* $Id: sys_sparc32.c,v 1.179 2001/09/25 00:48:09 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -4015,7 +4015,7 @@
 	ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
 	set_fs(old_fs);
 	
-	if (!ret && offset && put_user(of, offset))
+	if (offset && put_user(of, offset))
 		return -EFAULT;
 		
 	return ret;
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/traps.c linux/arch/sparc64/kernel/traps.c
--- v2.4.10/linux/arch/sparc64/kernel/traps.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/kernel/traps.c	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.78 2001/09/14 19:49:32 kanoj Exp $
+/* $Id: traps.c,v 1.79 2001/09/21 02:14:39 kanoj Exp $
  * arch/sparc64/kernel/traps.c
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -1636,44 +1636,6 @@
 {
 	die_if_kernel("TL1: Tag Overflow Exception", regs);
 }
-
-#ifdef CONFIG_EC_FLUSH_TRAP
-void cache_flush_trap(struct pt_regs *regs)
-{
-#ifndef CONFIG_SMP
-	unsigned node = linux_cpus[get_cpuid()].prom_node;
-#else
-#error cache_flush_trap not supported on sparc64/SMP yet
-#endif
-
-#if 0
-/* Broken */
-	int size = prom_getintdefault(node, "ecache-size", 512*1024);
-	int i, j;
-	unsigned long addr;
-	struct page *page, *end;
-
-	regs->tpc = regs->tnpc;
-	regs->tnpc = regs->tnpc + 4;
-	if (!capable(CAP_SYS_ADMIN)) return;
-	size >>= PAGE_SHIFT;
-	addr = PAGE_OFFSET - PAGE_SIZE;
-	page = mem_map - 1;
-	end = mem_map + max_mapnr;
-	for (i = 0; i < size; i++) {
-		do {
-			addr += PAGE_SIZE;
-			page++;
-			if (page >= end)
-				return;
-		} while (!PageReserved(page));
-		/* E-Cache line size is 64B. Let us pollute it :)) */
-		for (j = 0; j < PAGE_SIZE; j += 64)
-			__asm__ __volatile__ ("ldx [%0 + %1], %%g1" : : "r" (j), "r" (addr) : "g1");
-	}
-#endif
-}
-#endif
 
 void do_getpsr(struct pt_regs *regs)
 {
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/kernel/ttable.S linux/arch/sparc64/kernel/ttable.S
--- v2.4.10/linux/arch/sparc64/kernel/ttable.S	Mon Aug 27 12:41:40 2001
+++ linux/arch/sparc64/kernel/ttable.S	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: ttable.S,v 1.34 2001/08/12 09:08:56 davem Exp $
+/* $Id: ttable.S,v 1.35 2001/09/21 02:14:39 kanoj Exp $
  * ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions.
  *
  * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu)
@@ -144,12 +144,7 @@
 tl0_resv169:	BTRAP(0x169) BTRAP(0x16a) BTRAP(0x16b) BTRAP(0x16c)
 tl0_linux64:	LINUX_64BIT_SYSCALL_TRAP
 tl0_gsctx:	TRAP(sparc64_get_context) TRAP(sparc64_set_context)
-tl0_resv170:	BTRAP(0x170) BTRAP(0x171) 
-#ifdef CONFIG_EC_FLUSH_TRAP
-					  TRAP(cache_flush_trap)
-#else
-					  BTRAP(0x172)
-#endif
+tl0_resv170:	BTRAP(0x170) BTRAP(0x171) BTRAP(0x172)
 tl0_resv173:	BTRAP(0x173) BTRAP(0x174) BTRAP(0x175) BTRAP(0x176) BTRAP(0x177)
 tl0_resv178:	BTRAP(0x178) BTRAP(0x179) BTRAP(0x17a) BTRAP(0x17b) BTRAP(0x17c)
 tl0_resv17d:	BTRAP(0x17d) BTRAP(0x17e) BTRAP(0x17f)
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/lib/VIScopy.S linux/arch/sparc64/lib/VIScopy.S
--- v2.4.10/linux/arch/sparc64/lib/VIScopy.S	Thu Nov  9 15:57:41 2000
+++ linux/arch/sparc64/lib/VIScopy.S	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: VIScopy.S,v 1.25 2000/11/01 09:29:19 davem Exp $
+/* $Id: VIScopy.S,v 1.26 2001/09/27 04:36:24 kanoj Exp $
  * VIScopy.S: High speed copy operations utilizing the UltraSparc
  *            Visual Instruction Set.
  *
@@ -310,17 +310,6 @@
 		.globl			__memcpy
 		.type			__memcpy,@function
 
-		.globl			__memcpy_384plus
-		.type			__memcpy_384plus,@function
-
-		.globl			__memcpy_16plus
-		.type			__memcpy_16plus,@function
-
-		.globl			__memcpy_short
-		.type			__memcpy_short,@function
-
-		.globl			__memcpy_entry
-		.type			__memcpy_entry,@function
 memcpy_private:
 __memcpy:
 memcpy:		mov		ASI_P, asi_src			! IEU0	Group
@@ -395,7 +384,6 @@
 
 	.align			32
 #ifdef __KERNEL__
-__memcpy_384plus:
 	andcc			%o0, 7, %g2			! IEU1	Group
 #endif
 VIS_enter:
@@ -735,9 +723,6 @@
 	bleu,pn		%xcc, __memcpy_short			! CTI
 	 cmp		%o2, (64 * 6)				! IEU1	Group
 	bgeu,pn		%xcc, VIS_enter				! CTI
-#ifdef __KERNEL__
-__memcpy_16plus:
-#endif
 	 andcc		%o0, 7, %g2				! IEU1	Group
 	sub		%o0, %o1, %g5				! IEU0
 	andcc		%g5, 3, %o5				! IEU1	Group
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/lib/blockops.S linux/arch/sparc64/lib/blockops.S
--- v2.4.10/linux/arch/sparc64/lib/blockops.S	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/lib/blockops.S	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.35 2001/09/04 16:39:53 kanoj Exp $
+/* $Id: blockops.S,v 1.36 2001/09/24 21:44:03 davem Exp $
  * blockops.S: UltraSparc block zero optimized routines.
  *
  * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
@@ -25,7 +25,7 @@
 
 #if (PAGE_SHIFT == 13) || (PAGE_SHIFT == 19)
 #define PAGE_SIZE_REM	0x80
-#elif (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21)
+#elif (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
 #define PAGE_SIZE_REM	0x100
 #else
 #error Wrong PAGE_SHIFT specified
@@ -64,7 +64,7 @@
 	cmp		%o2, PAGE_SIZE_REM
 	bne,pt		%xcc, 1b
 	 add		%o0, 0x40, %o0
-#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21)
+#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
 	TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
 	ldda		[%o1] ASI_BLK_P, %f32
 	stda		%f48, [%o0] ASI_BLK_P
@@ -287,7 +287,7 @@
 	cmp		%o2, PAGE_SIZE_REM
 	bne,pt		%xcc, 1b
 	 add		%o0, 0x40, %o0
-#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21)
+#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
 	TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
 	ldda		[%o1] ASI_BLK_P, %f32
 	stda		%f48, [%o0] ASI_BLK_P
@@ -353,7 +353,7 @@
 	cmp		%o2, PAGE_SIZE_REM
 	bne,pt		%xcc, 1b
 	 add		%o0, 0x40, %o0
-#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 21)
+#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
 	TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
 	ldda		[%o1] ASI_BLK_P, %f32
 	stda		%f48, [%o0] ASI_BLK_COMMIT_P
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.4.10/linux/arch/sparc64/mm/init.c	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/mm/init.c	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.189 2001/09/02 23:27:18 kanoj Exp $
+/*  $Id: init.c,v 1.193 2001/09/25 22:47:35 davem Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -30,6 +30,7 @@
 #include <asm/dma.h>
 #include <asm/starfire.h>
 #include <asm/tlb.h>
+#include <asm/spitfire.h>
 
 mmu_gather_t mmu_gathers[NR_CPUS];
 
@@ -113,16 +114,17 @@
 
 	if (VALID_PAGE(page) && page->mapping &&
 	    test_bit(PG_dcache_dirty, &page->flags)) {
-		__flush_dcache_page(page->virtual,
-				    (tlb_type == spitfire));
+#if (L1DCACHE_SIZE > PAGE_SIZE)			/* is there D$ aliasing problem */
+		__flush_dcache_page(page->virtual, (tlb_type == spitfire));
+#else
+		if (tlb_type == spitfire)	/* fix local I$ coherency */
+			__flush_icache_page(__get_phys((unsigned long)(page->virtual)));
+#endif
 		clear_bit(PG_dcache_dirty, &page->flags);
 	}
 	__update_mmu_cache(vma, address, pte);
 }
 
-/* In arch/sparc64/mm/ultra.S */
-extern void __flush_icache_page(unsigned long);
-
 void flush_icache_range(unsigned long start, unsigned long end)
 {
 	/* Cheetah has coherent I-cache. */
@@ -887,23 +889,28 @@
  * addresses. The idea is that if the vpte color and PAGE_OFFSET range 
  * color is the same, then when the kernel initializes the pagetable 
  * using the later address range, accesses with the first address
- * range will not see the newly initialized data rather than the
- * garbage.
+ * range will see the newly initialized data rather than the garbage.
  */
- 
+#if (L1DCACHE_SIZE > PAGE_SIZE)			/* is there D$ aliasing problem */
+#define DC_ALIAS_SHIFT	1
+#else
+#define DC_ALIAS_SHIFT	0
+#endif
 pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	struct page *page = alloc_pages(GFP_KERNEL, 1);
-	unsigned long color = ((address >> (PAGE_SHIFT + 10)) & 1UL);
+	struct page *page = alloc_pages(GFP_KERNEL, DC_ALIAS_SHIFT);
+	unsigned long color = VPTE_COLOR(address);
 
 	if (page) {
 		unsigned long *to_free;
 		unsigned long paddr;
 		pte_t *pte;
 
+#if (L1DCACHE_SIZE > PAGE_SIZE)			/* is there D$ aliasing problem */
 		set_page_count((page + 1), 1);
+#endif
 		paddr = (unsigned long) page_address(page);
-		memset((char *)paddr, 0, (PAGE_SIZE << 1));
+		memset((char *)paddr, 0, (PAGE_SIZE << DC_ALIAS_SHIFT));
 
 		if (!color) {
 			pte = (pte_t *) paddr;
@@ -913,10 +920,12 @@
 			to_free = (unsigned long *) paddr;
 		}
 
+#if (L1DCACHE_SIZE > PAGE_SIZE)			/* is there D$ aliasing problem */
 		/* Now free the other one up, adjust cache size. */
 		*to_free = (unsigned long) pte_quicklist[color ^ 0x1];
 		pte_quicklist[color ^ 0x1] = to_free;
 		pgtable_cache_size++;
+#endif
 
 		return pte;
 	}
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/mm/ultra.S linux/arch/sparc64/mm/ultra.S
--- v2.4.10/linux/arch/sparc64/mm/ultra.S	Sun Sep 23 11:40:56 2001
+++ linux/arch/sparc64/mm/ultra.S	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.57 2001/09/06 19:27:17 kanoj Exp $
+/* $Id: ultra.S,v 1.61 2001/09/25 18:04:51 kanoj Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -237,6 +237,16 @@
 	retl
 /*IC22*/ wrpr		%g1, 0x0, %pstate
 
+/*
+ * The following code flushes one page_size worth.
+ */
+#if (PAGE_SHIFT == 13)
+#define ITAG_MASK 0xfe
+#elif (PAGE_SHIFT == 16)
+#define ITAG_MASK 0x7fe
+#else
+#error unsupported PAGE_SIZE
+#endif
 	.align		32
 	.globl		__flush_icache_page
 __flush_icache_page:	/* %o0 = phys_page */
@@ -250,7 +260,7 @@
 	or		%o0, %g1, %o0		! VALID+phys-addr comparitor
 
 	sllx		%g2, 1, %g2
-	andn		%g2, 0xfe, %g2		! IC_tag mask
+	andn		%g2, ITAG_MASK, %g2	! IC_tag mask
 	nop
 	nop
 	nop
@@ -313,6 +323,16 @@
 	retl
 	 nop
 
+#if (PAGE_SHIFT == 13)
+#define DTAG_MASK 0x3
+#elif (PAGE_SHIFT == 16)
+#define DTAG_MASK 0x1f
+#elif (PAGE_SHIFT == 19)
+#define DTAG_MASK 0xff
+#elif (PAGE_SHIFT == 22)
+#define DTAG_MASK 0x3ff
+#endif
+
 flush_dcpage_spitfire:
 	clr		%o4
 	srlx		%o0, 11, %o0
@@ -323,19 +343,19 @@
 	add		%o4, (1 << 5), %o4		! IEU0
 	ldxa		[%o4] ASI_DCACHE_TAG, %g2	! LSU	Group	o3 available
 	add		%o4, (1 << 5), %o4		! IEU0
-	andn		%o3, 0x3, %o3			! IEU1
+	andn		%o3, DTAG_MASK, %o3		! IEU1
 	ldxa		[%o4] ASI_DCACHE_TAG, %g3	! LSU	Group
 	add		%o4, (1 << 5), %o4		! IEU0
-	andn		%g1, 0x3, %g1			! IEU1
+	andn		%g1, DTAG_MASK, %g1		! IEU1
 	cmp		%o0, %o3			! IEU1	Group
 	be,a,pn		%xcc, dflush1			! CTI
 	 sub		%o4, (4 << 5), %o4		! IEU0	(Group)
 	cmp		%o0, %g1			! IEU1	Group
-	andn		%g2, 0x3, %g2			! IEU0
+	andn		%g2, DTAG_MASK, %g2		! IEU0
 	be,a,pn		%xcc, dflush2			! CTI
 	 sub		%o4, (3 << 5), %o4		! IEU0	(Group)
 	cmp		%o0, %g2			! IEU1	Group
-	andn		%g3, 0x3, %g3			! IEU0
+	andn		%g3, DTAG_MASK, %g3		! IEU0
 	be,a,pn		%xcc, dflush3			! CTI
 	 sub		%o4, (2 << 5), %o4		! IEU0	(Group)
 	cmp		%o0, %g3			! IEU1	Group
diff -u --recursive --new-file v2.4.10/linux/arch/sparc64/prom/misc.c linux/arch/sparc64/prom/misc.c
--- v2.4.10/linux/arch/sparc64/prom/misc.c	Wed Jul  5 22:15:25 2000
+++ linux/arch/sparc64/prom/misc.c	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.19 2000/06/30 10:18:38 davem Exp $
+/* $Id: misc.c,v 1.20 2001/09/21 03:17:07 kanoj Exp $
  * misc.c:  Miscellaneous prom functions that don't belong
  *          anywhere else.
  *
@@ -59,25 +59,15 @@
 		prom_palette (1);
 #endif
 
-	/* We always arrive here via a serial interrupt.
-	 * So in order for everything to work reliably, even
-	 * on SMP, we need to drop the IRQ locks we hold.
-	 */
 #ifdef CONFIG_SMP
-	irq_exit(smp_processor_id(), 0);
 	smp_capture();
-#else
-	local_irq_count(smp_processor_id())--;
 #endif
 
 	p1275_cmd ("enter", P1275_INOUT(0,0));
 
 #ifdef CONFIG_SMP
 	smp_release();
-	irq_enter(smp_processor_id(), 0);
 	spin_unlock_wait(&__br_write_locks[BR_GLOBALIRQ_LOCK].lock);
-#else
-	local_irq_count(smp_processor_id())++;
 #endif
 
 #ifdef CONFIG_SUN_CONSOLE
diff -u --recursive --new-file v2.4.10/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.4.10/linux/drivers/block/genhd.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/genhd.c	Mon Oct  1 10:19:22 2001
@@ -47,9 +47,27 @@
 void
 add_gendisk(struct gendisk *gp)
 {
+	struct gendisk *sgp;
+
 	write_lock(&gendisk_lock);
+
+	/*
+ 	 *	In 2.5 this will go away. Fix the drivers who rely on
+ 	 *	old behaviour.
+ 	 */
+
+	for (sgp = gendisk_head; sgp; sgp = sgp->next)
+	{
+		if (sgp == gp)
+		{
+//			printk(KERN_ERR "add_gendisk: device major %d is buggy and added a live gendisk!\n",
+//				sgp->major)
+			goto out;
+		}
+	}
 	gp->next = gendisk_head;
 	gendisk_head = gp;
+out:
 	write_unlock(&gendisk_lock);
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.4.10/linux/drivers/block/loop.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/loop.c	Fri Sep 28 11:21:40 2001
@@ -719,7 +719,7 @@
 	return err;
 }  
 
-static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
+static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
 {
 	struct file *filp = lo->lo_backing_file;
 	int gfp = lo->old_gfp_mask;
@@ -752,7 +752,7 @@
 	memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
 	memset(lo->lo_name, 0, LO_NAME_SIZE);
 	loop_sizes[lo->lo_number] = 0;
-	invalidate_buffers(dev);
+	invalidate_bdev(bdev, 0);
 	filp->f_dentry->d_inode->i_mapping->gfp_mask = gfp;
 	lo->lo_state = Lo_unbound;
 	fput(filp);
@@ -852,7 +852,7 @@
 		err = loop_set_fd(lo, file, inode->i_rdev, arg);
 		break;
 	case LOOP_CLR_FD:
-		err = loop_clr_fd(lo, inode->i_rdev);
+		err = loop_clr_fd(lo, inode->i_bdev);
 		break;
 	case LOOP_SET_STATUS:
 		err = loop_set_status(lo, (struct loop_info *) arg);
diff -u --recursive --new-file v2.4.10/linux/drivers/block/paride/Makefile linux/drivers/block/paride/Makefile
--- v2.4.10/linux/drivers/block/paride/Makefile	Fri Apr  6 10:42:55 2001
+++ linux/drivers/block/paride/Makefile	Fri Oct  5 12:06:51 2001
@@ -7,6 +7,8 @@
 
 L_TARGET := paride.a
 
+export-objs := bpck6.o
+
 obj-$(CONFIG_PARIDE)		+= paride.o
 obj-$(CONFIG_PARIDE_PD)		+= pd.o
 obj-$(CONFIG_PARIDE_PCD)	+= pcd.o
diff -u --recursive --new-file v2.4.10/linux/drivers/block/paride/bpck6.c linux/drivers/block/paride/bpck6.c
--- v2.4.10/linux/drivers/block/paride/bpck6.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/paride/bpck6.c	Fri Oct  5 12:06:51 2001
@@ -25,7 +25,6 @@
 
 #define BACKPACK_VERSION "2.0.2"
 
-#define EXPORT_SYMTAB 
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c
--- v2.4.10/linux/drivers/block/paride/paride.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/block/paride/paride.c	Mon Oct  8 11:54:10 2001
@@ -44,7 +44,7 @@
 
 static struct pi_protocol	*protocols[MAX_PROTOS];
 
-spinlock_t	pi_spinlock = SPIN_LOCK_UNLOCKED;
+static spinlock_t	pi_spinlock = SPIN_LOCK_UNLOCKED;
 
 void pi_write_regr( PIA *pi, int cont, int regr, int val)
 
diff -u --recursive --new-file v2.4.10/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.4.10/linux/drivers/block/rd.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/block/rd.c	Mon Oct  8 11:25:14 2001
@@ -276,7 +276,6 @@
 			if (!Page_Uptodate(page)) {
 				memset(kmap(page), 0, PAGE_CACHE_SIZE);
 				kunmap(page);
-				flush_dcache_page(page);
 				SetPageUptodate(page);
 			}
 
@@ -301,8 +300,11 @@
 		kunmap(page);
 		bh_kunmap(sbh);
 
-		if (rw != READ)
+		if (rw == READ) {
+			flush_dcache_page(page);
+		} else {
 			SetPageDirty(page);
+		}
 		if (unlock)
 			UnlockPage(page);
 		__free_page(page);
diff -u --recursive --new-file v2.4.10/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.4.10/linux/drivers/char/Config.in	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/Config.in	Fri Oct  5 12:13:50 2001
@@ -205,8 +205,8 @@
 
 dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
 if [ "$CONFIG_AGP" != "n" ]; then
-   bool '  Intel 440LX/BX/GX and I815/I840/I850 support' CONFIG_AGP_INTEL
-   bool '  Intel I810/I815 (on-board) support' CONFIG_AGP_I810
+   bool '  Intel 440LX/BX/GX and I815/I830M/I840/I850 support' CONFIG_AGP_INTEL
+   bool '  Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810
    bool '  VIA chipset support' CONFIG_AGP_VIA
    bool '  AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD
    bool '  Generic SiS support' CONFIG_AGP_SIS
diff -u --recursive --new-file v2.4.10/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.4.10/linux/drivers/char/Makefile	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/Makefile	Mon Oct  8 10:46:20 2001
@@ -23,7 +23,7 @@
 
 export-objs     :=	busmouse.o console.o keyboard.o sysrq.o \
 			misc.o pty.o random.o selection.o serial.o \
-			sonypi.o tty_io.o tty_ioctl.o
+			sonypi.o tty_io.o tty_ioctl.o generic_serial.o
 
 mod-subdirs	:=	joystick ftape drm pcmcia
 
diff -u --recursive --new-file v2.4.10/linux/drivers/char/agp/agp.h linux/drivers/char/agp/agp.h
--- v2.4.10/linux/drivers/char/agp/agp.h	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/agp/agp.h	Fri Oct  5 12:13:50 2001
@@ -133,6 +133,10 @@
 #define INREG16(mmap, addr)         __raw_readw((mmap)+(addr))
 #define INREG8(mmap, addr)         __raw_readb((mmap)+(addr))
 
+#define KB(x) ((x) * 1024)
+#define MB(x) (KB (KB (x)))
+#define GB(x) (MB (KB (x)))
+
 #define CACHE_FLUSH	agp_bridge.cache_flush
 #define A_SIZE_8(x)	((aper_size_info_8 *) x)
 #define A_SIZE_16(x)	((aper_size_info_16 *) x)
@@ -196,6 +200,12 @@
 #ifndef PCI_DEVICE_ID_INTEL_815_1
 #define PCI_DEVICE_ID_INTEL_815_1       0x1132
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_830_M_0
+#define PCI_DEVICE_ID_INTEL_830_M_0     0x3575
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_830_M_1
+#define PCI_DEVICE_ID_INTEL_830_M_1     0x3577
+#endif
 #ifndef PCI_DEVICE_ID_INTEL_82443GX_1
 #define PCI_DEVICE_ID_INTEL_82443GX_1   0x71a1
 #endif
@@ -266,6 +276,22 @@
 #define I810_DRAM_CTL          0x3000
 #define I810_DRAM_ROW_0        0x00000001
 #define I810_DRAM_ROW_0_SDRAM  0x00000001
+
+/* intel i830 registers */
+#define I830_GMCH_CTRL             0x52
+#define I830_GMCH_ENABLED          0x4
+#define I830_GMCH_MEM_MASK         0x1
+#define I830_GMCH_MEM_64M          0x1
+#define I830_GMCH_MEM_128M         0
+#define I830_GMCH_GMS_MASK         0x70
+#define I830_GMCH_GMS_DISABLED     0x00
+#define I830_GMCH_GMS_LOCAL        0x10
+#define I830_GMCH_GMS_STOLEN_512   0x20
+#define I830_GMCH_GMS_STOLEN_1024  0x30
+#define I830_GMCH_GMS_STOLEN_8192  0x40
+#define I830_RDRAM_CHANNEL_TYPE    0x03010
+#define I830_RDRAM_ND(x)           (((x) & 0x20) >> 5)
+#define I830_RDRAM_DDT(x)          (((x) & 0x18) >> 3)
 
 /* VIA register */
 #define VIA_APBASE      0x10
diff -u --recursive --new-file v2.4.10/linux/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- v2.4.10/linux/drivers/char/agp/agpgart_be.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/agp/agpgart_be.c	Fri Oct  5 13:25:14 2001
@@ -1113,6 +1113,290 @@
 	return 0;
 }
 
+static aper_size_info_fixed intel_i830_sizes[] =
+{
+	{128, 32768, 5},
+	/* The 64M mode still requires a 128k gatt */
+	{64, 16384, 5}
+};
+
+static struct _intel_i830_private {
+	struct pci_dev *i830_dev;   /* device one */
+	volatile u8 *registers;
+	int gtt_entries;
+} intel_i830_private;
+
+static void intel_i830_init_gtt_entries(void) {
+	u16 gmch_ctrl;
+	int gtt_entries;
+	u8 rdct;
+	static const int ddt[4] = { 0, 16, 32, 64 };
+
+	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+
+	switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+	case I830_GMCH_GMS_STOLEN_512:
+		gtt_entries = KB(512);
+		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
+		break;
+	case I830_GMCH_GMS_STOLEN_1024:
+		gtt_entries = MB(1);
+		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
+		break;
+	case I830_GMCH_GMS_STOLEN_8192:
+		gtt_entries = MB(8);
+		printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
+		break;
+	case I830_GMCH_GMS_LOCAL:
+		rdct = INREG8(intel_i830_private.registers,I830_RDRAM_CHANNEL_TYPE);
+		gtt_entries = (I830_RDRAM_ND(rdct) + 1) * MB(ddt[I830_RDRAM_DDT(rdct)]);
+		printk(KERN_INFO PFX "detected %dK local memory.\n",gtt_entries / KB(1));
+		break;
+	default:
+		printk(KERN_INFO PFX "no video memory detected.\n");
+		gtt_entries = 0;
+		break;
+	}
+
+	gtt_entries /= KB(4);
+
+	intel_i830_private.gtt_entries = gtt_entries;
+}
+
+/* The intel i830 automatically initializes the agp aperture during POST.
+ * Use the memory already set aside for in the GTT.
+ */
+static int intel_i830_create_gatt_table(void)
+{
+	int page_order;
+	aper_size_info_fixed *size;
+	int num_entries;
+	u32 temp;
+
+	size = agp_bridge.current_size;
+	page_order = size->page_order;
+	num_entries = size->num_entries;
+	agp_bridge.gatt_table_real = 0;
+
+	pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
+	temp &= 0xfff80000;
+
+	intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096);
+	if (!intel_i830_private.registers) return (-ENOMEM);
+
+	temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
+	CACHE_FLUSH();
+
+	/* we have to call this as early as possible after the MMIO base address is known */
+	intel_i830_init_gtt_entries();
+
+	agp_bridge.gatt_table = NULL;
+
+	agp_bridge.gatt_bus_addr = temp;
+
+	return(0);
+}
+
+/* Return the gatt table to a sane state. Use the top of stolen
+ * memory for the GTT.
+ */
+static int intel_i830_free_gatt_table(void)
+{
+	return(0);
+}
+
+static int intel_i830_fetch_size(void)
+{
+	u16 gmch_ctrl;
+	aper_size_info_fixed *values;
+
+	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
+
+	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
+		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
+		agp_bridge.aperture_size_idx = 0;
+		return(values[0].size);
+	} else {
+		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
+		agp_bridge.aperture_size_idx = 1;
+		return(values[1].size);
+	}
+
+	return(0);
+}
+
+static int intel_i830_configure(void)
+{
+	aper_size_info_fixed *current_size;
+	u32 temp;
+	u16 gmch_ctrl;
+	int i;
+
+	current_size = A_SIZE_FIX(agp_bridge.current_size);
+
+	pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
+	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+	gmch_ctrl |= I830_GMCH_ENABLED;
+	pci_write_config_word(agp_bridge.dev,I830_GMCH_CTRL,gmch_ctrl);
+
+	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
+	CACHE_FLUSH();
+
+	if (agp_bridge.needs_scratch_page == TRUE)
+		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
+			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+
+	return (0);
+}
+
+static void intel_i830_cleanup(void)
+{
+	iounmap((void *) intel_i830_private.registers);
+}
+
+static int intel_i830_insert_entries(agp_memory *mem,off_t pg_start,int type)
+{
+	int i,j,num_entries;
+	void *temp;
+
+	temp = agp_bridge.current_size;
+	num_entries = A_SIZE_FIX(temp)->num_entries;
+
+	if (pg_start < intel_i830_private.gtt_entries) {
+		printk (KERN_DEBUG "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
+				pg_start,intel_i830_private.gtt_entries);
+
+		printk ("Trying to insert into local/stolen memory\n");
+		return (-EINVAL);
+	}
+
+	if ((pg_start + mem->page_count) > num_entries)
+		return (-EINVAL);
+
+	/* The i830 can't check the GTT for entries since its read only,
+	 * depend on the caller to make the correct offset decisions.
+	 */
+
+	if ((type != 0 && type != AGP_PHYS_MEMORY) ||
+		(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
+		return (-EINVAL);
+
+	CACHE_FLUSH();
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
+		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),mem->memory[i]);
+
+	CACHE_FLUSH();
+
+	agp_bridge.tlb_flush(mem);
+
+	return(0);
+}
+
+static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type)
+{
+	int i;
+
+	CACHE_FLUSH ();
+
+	if (pg_start < intel_i830_private.gtt_entries) {
+		printk ("Trying to disable local/stolen memory\n");
+		return (-EINVAL);
+	}
+
+	for (i = pg_start; i < (mem->page_count + pg_start); i++)
+		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+
+	CACHE_FLUSH();
+
+	agp_bridge.tlb_flush(mem);
+
+	return (0);
+}
+
+static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
+{
+	agp_memory *nw;
+
+	/* always return NULL for now */
+	if (type == AGP_DCACHE_MEMORY) return(NULL);
+
+	if (type == AGP_PHYS_MEMORY) {
+		unsigned long physical;
+
+		/* The i830 requires a physical address to program
+		 * it's mouse pointer into hardware. However the
+		 * Xserver still writes to it through the agp
+		 * aperture
+		 */
+
+		if (pg_count != 1) return(NULL);
+
+		nw = agp_create_memory(1);
+
+		if (nw == NULL) return(NULL);
+
+		MOD_INC_USE_COUNT;
+		nw->memory[0] = agp_bridge.agp_alloc_page();
+		physical = nw->memory[0];
+		if (nw->memory[0] == 0) {
+			/* free this structure */
+			agp_free_memory(nw);
+			return(NULL);
+		}
+
+		nw->memory[0] = agp_bridge.mask_memory(virt_to_phys((void *) nw->memory[0]),type);
+		nw->page_count = 1;
+		nw->num_scratch_pages = 1;
+		nw->type = AGP_PHYS_MEMORY;
+		nw->physical = virt_to_phys((void *) physical);
+		return(nw);
+	}
+
+	return(NULL);
+}
+
+static int __init intel_i830_setup(struct pci_dev *i830_dev)
+{
+	intel_i830_private.i830_dev = i830_dev;
+
+	agp_bridge.masks = intel_i810_masks;
+	agp_bridge.num_of_masks = 3;
+	agp_bridge.aperture_sizes = (void *) intel_i830_sizes;
+	agp_bridge.size_type = FIXED_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 2;
+
+	agp_bridge.dev_private_data = (void *) &intel_i830_private;
+	agp_bridge.needs_scratch_page = TRUE;
+
+	agp_bridge.configure = intel_i830_configure;
+	agp_bridge.fetch_size = intel_i830_fetch_size;
+	agp_bridge.cleanup = intel_i830_cleanup;
+	agp_bridge.tlb_flush = intel_i810_tlbflush;
+	agp_bridge.mask_memory = intel_i810_mask_memory;
+	agp_bridge.agp_enable = intel_i810_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+
+	agp_bridge.create_gatt_table = intel_i830_create_gatt_table;
+	agp_bridge.free_gatt_table = intel_i830_free_gatt_table;
+
+	agp_bridge.insert_memory = intel_i830_insert_entries;
+	agp_bridge.remove_memory = intel_i830_remove_entries;
+	agp_bridge.alloc_by_type = intel_i830_alloc_by_type;
+	agp_bridge.free_by_type = intel_i810_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+
+	return(0);
+}
+
 #endif /* CONFIG_AGP_I810 */
 
 #ifdef CONFIG_AGP_INTEL
@@ -2976,6 +3260,12 @@
 		"Intel",
 		"i815",
 		intel_generic_setup },
+	{ PCI_DEVICE_ID_INTEL_830_M_0,
+		PCI_VENDOR_ID_INTEL,
+		INTEL_I830_M,
+		"Intel",
+		"i830M",
+		intel_generic_setup },
 	{ PCI_DEVICE_ID_INTEL_840_0,
 		PCI_VENDOR_ID_INTEL,
 		INTEL_I840,
@@ -3240,17 +3530,38 @@
 						   PCI_DEVICE_ID_INTEL_815_1,
 						   NULL);
 			if (i810_dev == NULL) {
-				printk(KERN_ERR PFX "agpgart: Detected an "
+				printk(KERN_ERR PFX "Detected an "
 				       "Intel i815, but could not find the"
 				       " secondary device. Assuming a "
 				       "non-integrated video card.\n");
 				break;
 			}
-			printk(KERN_INFO PFX "agpgart: Detected an Intel i815 "
+			printk(KERN_INFO PFX "Detected an Intel i815 "
 			       "Chipset.\n");
 			agp_bridge.type = INTEL_I810;
 			return intel_i810_setup(i810_dev);
 
+		case PCI_DEVICE_ID_INTEL_830_M_0:
+			i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+									   PCI_DEVICE_ID_INTEL_830_M_1,
+									   NULL);
+			if(PCI_FUNC(i810_dev->devfn) != 0) {
+				i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+										   PCI_DEVICE_ID_INTEL_830_M_1,
+										   i810_dev);
+			}
+
+			if (i810_dev == NULL) {
+				printk(KERN_ERR PFX "Detected an "
+					   "Intel 830M, but could not find the"
+					   " secondary device.\n");
+				agp_bridge.type = NOT_SUPPORTED;
+				return -ENODEV;
+			}
+			printk(KERN_INFO PFX "Detected an Intel "
+				   "830M Chipset.\n");
+			agp_bridge.type = INTEL_I810;
+			return intel_i830_setup(i810_dev);
 		default:
 			break;
 		}
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/3780i.c linux/drivers/char/mwave/3780i.c
--- v2.4.10/linux/drivers/char/mwave/3780i.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/3780i.c	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,730 @@
+/*
+*
+* 3780i.c -- helper routines for the 3780i DSP
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include "smapi.h"
+#include "mwavedd.h"
+#include "3780i.h"
+
+static spinlock_t dsp_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long flags;
+
+
+static void PaceMsaAccess(unsigned short usDspBaseIO)
+{
+	if(current->need_resched)
+		schedule();
+	udelay(100);
+	if(current->need_resched)
+		schedule();
+}
+
+unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
+                                   unsigned long ulMsaAddr)
+{
+	unsigned short val;
+
+	PRINTK_3(TRACE_3780I,
+		"3780i::dsp3780I_ReadMsaCfg entry usDspBaseIO %x ulMsaAddr %lx\n",
+		usDspBaseIO, ulMsaAddr);
+
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr);
+	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16));
+	val = InWordDsp(DSP_MsaDataDSISHigh);
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	PRINTK_2(TRACE_3780I, "3780i::dsp3780I_ReadMsaCfg exit val %x\n", val);
+
+	return val;
+}
+
+void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
+                          unsigned long ulMsaAddr, unsigned short usValue)
+{
+
+	PRINTK_4(TRACE_3780I,
+		"3780i::dsp3780i_WriteMsaCfg entry usDspBaseIO %x ulMsaAddr %lx usValue %x\n",
+		usDspBaseIO, ulMsaAddr, usValue);
+
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr);
+	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16));
+	OutWordDsp(DSP_MsaDataDSISHigh, usValue);
+	spin_unlock_irqrestore(&dsp_lock, flags);
+}
+
+void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
+                          unsigned char ucValue)
+{
+	DSP_ISA_SLAVE_CONTROL rSlaveControl;
+	DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
+
+
+	PRINTK_4(TRACE_3780I,
+		"3780i::dsp3780i_WriteGenCfg entry usDspBaseIO %x uIndex %x ucValue %x\n",
+		usDspBaseIO, uIndex, ucValue);
+
+	MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl);
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780i_WriteGenCfg rSlaveControl %x\n",
+		MKBYTE(rSlaveControl));
+
+	rSlaveControl_Save = rSlaveControl;
+	rSlaveControl.ConfigMode = TRUE;
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780i_WriteGenCfg entry rSlaveControl+ConfigMode %x\n",
+		MKBYTE(rSlaveControl));
+
+	OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl));
+	OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex);
+	OutByteDsp(DSP_ConfigData, ucValue);
+	OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save));
+
+	PRINTK_1(TRACE_3780I, "3780i::dsp3780i_WriteGenCfg exit\n");
+
+
+}
+
+unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
+                                  unsigned uIndex)
+{
+	DSP_ISA_SLAVE_CONTROL rSlaveControl;
+	DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
+	unsigned char ucValue;
+
+
+	PRINTK_3(TRACE_3780I,
+		"3780i::dsp3780i_ReadGenCfg entry usDspBaseIO %x uIndex %x\n",
+		usDspBaseIO, uIndex);
+
+	MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl);
+	rSlaveControl_Save = rSlaveControl;
+	rSlaveControl.ConfigMode = TRUE;
+	OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl));
+	OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex);
+	ucValue = InByteDsp(DSP_ConfigData);
+	OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save));
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780i_ReadGenCfg exit ucValue %x\n", ucValue);
+
+
+	return ucValue;
+}
+
+int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
+                       unsigned short *pIrqMap,
+                       unsigned short *pDmaMap)
+{
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	int i;
+	DSP_UART_CFG_1 rUartCfg1;
+	DSP_UART_CFG_2 rUartCfg2;
+	DSP_HBRIDGE_CFG_1 rHBridgeCfg1;
+	DSP_HBRIDGE_CFG_2 rHBridgeCfg2;
+	DSP_BUSMASTER_CFG_1 rBusmasterCfg1;
+	DSP_BUSMASTER_CFG_2 rBusmasterCfg2;
+	DSP_ISA_PROT_CFG rIsaProtCfg;
+	DSP_POWER_MGMT_CFG rPowerMgmtCfg;
+	DSP_HBUS_TIMER_CFG rHBusTimerCfg;
+	DSP_LBUS_TIMEOUT_DISABLE rLBusTimeoutDisable;
+	DSP_CHIP_RESET rChipReset;
+	DSP_CLOCK_CONTROL_1 rClockControl1;
+	DSP_CLOCK_CONTROL_2 rClockControl2;
+	DSP_ISA_SLAVE_CONTROL rSlaveControl;
+	DSP_HBRIDGE_CONTROL rHBridgeControl;
+	unsigned short ChipID = 0;
+	unsigned short tval;
+
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780I_EnableDSP entry pSettings->bDSPEnabled %x\n",
+		pSettings->bDSPEnabled);
+
+
+	if (!pSettings->bDSPEnabled) {
+		PRINTK_ERROR( KERN_ERR "3780i::dsp3780I_EnableDSP: Error: DSP not enabled. Aborting.\n" );
+		return -EIO;
+	}
+
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780i_EnableDSP entry pSettings->bModemEnabled %x\n",
+		pSettings->bModemEnabled);
+
+	if (pSettings->bModemEnabled) {
+		rUartCfg1.Reserved = rUartCfg2.Reserved = 0;
+		rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow;
+		rUartCfg1.IrqPulse = pSettings->bUartIrqPulse;
+		rUartCfg1.Irq =
+			(unsigned char) pIrqMap[pSettings->usUartIrq];
+		switch (pSettings->usUartBaseIO) {
+		case 0x03F8:
+			rUartCfg1.BaseIO = 0;
+			break;
+		case 0x02F8:
+			rUartCfg1.BaseIO = 1;
+			break;
+		case 0x03E8:
+			rUartCfg1.BaseIO = 2;
+			break;
+		case 0x02E8:
+			rUartCfg1.BaseIO = 3;
+			break;
+		}
+		rUartCfg2.Enable = TRUE;
+	}
+
+	rHBridgeCfg1.Reserved = rHBridgeCfg2.Reserved = 0;
+	rHBridgeCfg1.IrqActiveLow = pSettings->bDspIrqActiveLow;
+	rHBridgeCfg1.IrqPulse = pSettings->bDspIrqPulse;
+	rHBridgeCfg1.Irq = (unsigned char) pIrqMap[pSettings->usDspIrq];
+	rHBridgeCfg1.AccessMode = 1;
+	rHBridgeCfg2.Enable = TRUE;
+
+
+	rBusmasterCfg2.Reserved = 0;
+	rBusmasterCfg1.Dma = (unsigned char) pDmaMap[pSettings->usDspDma];
+	rBusmasterCfg1.NumTransfers =
+		(unsigned char) pSettings->usNumTransfers;
+	rBusmasterCfg1.ReRequest = (unsigned char) pSettings->usReRequest;
+	rBusmasterCfg1.MEMCS16 = pSettings->bEnableMEMCS16;
+	rBusmasterCfg2.IsaMemCmdWidth =
+		(unsigned char) pSettings->usIsaMemCmdWidth;
+
+
+	rIsaProtCfg.Reserved = 0;
+	rIsaProtCfg.GateIOCHRDY = pSettings->bGateIOCHRDY;
+
+	rPowerMgmtCfg.Reserved = 0;
+	rPowerMgmtCfg.Enable = pSettings->bEnablePwrMgmt;
+
+	rHBusTimerCfg.LoadValue =
+		(unsigned char) pSettings->usHBusTimerLoadValue;
+
+	rLBusTimeoutDisable.Reserved = 0;
+	rLBusTimeoutDisable.DisableTimeout =
+		pSettings->bDisableLBusTimeout;
+
+	MKWORD(rChipReset) = ~pSettings->usChipletEnable;
+
+	rClockControl1.Reserved1 = rClockControl1.Reserved2 = 0;
+	rClockControl1.N_Divisor = pSettings->usN_Divisor;
+	rClockControl1.M_Multiplier = pSettings->usM_Multiplier;
+
+	rClockControl2.Reserved = 0;
+	rClockControl2.PllBypass = pSettings->bPllBypass;
+
+	/* Issue a soft reset to the chip */
+	/* Note: Since we may be coming in with 3780i clocks suspended, we must keep
+	* soft-reset active for 10ms.
+	*/
+	rSlaveControl.ClockControl = 0;
+	rSlaveControl.SoftReset = TRUE;
+	rSlaveControl.ConfigMode = FALSE;
+	rSlaveControl.Reserved = 0;
+
+	PRINTK_4(TRACE_3780I,
+		"3780i::dsp3780i_EnableDSP usDspBaseIO %x index %x taddr %x\n",
+		usDspBaseIO, DSP_IsaSlaveControl,
+		usDspBaseIO + DSP_IsaSlaveControl);
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780i_EnableDSP rSlaveContrl %x\n",
+		MKWORD(rSlaveControl));
+
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
+	MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780i_EnableDSP rSlaveControl 2 %x\n", tval);
+
+
+	for (i = 0; i < 11; i++)
+		udelay(2000);
+
+	rSlaveControl.SoftReset = FALSE;
+	OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
+
+	MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl);
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780i_EnableDSP rSlaveControl 3 %x\n", tval);
+
+
+	/* Program our general configuration registers */
+	WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1));
+	WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2));
+	WriteGenCfg(DSP_BusMasterCfg1Index, MKBYTE(rBusmasterCfg1));
+	WriteGenCfg(DSP_BusMasterCfg2Index, MKBYTE(rBusmasterCfg2));
+	WriteGenCfg(DSP_IsaProtCfgIndex, MKBYTE(rIsaProtCfg));
+	WriteGenCfg(DSP_PowerMgCfgIndex, MKBYTE(rPowerMgmtCfg));
+	WriteGenCfg(DSP_HBusTimerCfgIndex, MKBYTE(rHBusTimerCfg));
+
+	if (pSettings->bModemEnabled) {
+		WriteGenCfg(DSP_UartCfg1Index, MKBYTE(rUartCfg1));
+		WriteGenCfg(DSP_UartCfg2Index, MKBYTE(rUartCfg2));
+	}
+
+
+	rHBridgeControl.EnableDspInt = FALSE;
+	rHBridgeControl.MemAutoInc = TRUE;
+	rHBridgeControl.IoAutoInc = FALSE;
+	rHBridgeControl.DiagnosticMode = FALSE;
+
+	PRINTK_3(TRACE_3780I,
+		"3780i::dsp3780i_EnableDSP DSP_HBridgeControl %x rHBridgeControl %x\n",
+		DSP_HBridgeControl, MKWORD(rHBridgeControl));
+
+	OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+	WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable));
+	WriteMsaCfg(DSP_ClockControl_1, MKWORD(rClockControl1));
+	WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2));
+	WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset));
+
+	ChipID = ReadMsaCfg(DSP_ChipID);
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780I_EnableDSP exiting bRC=TRUE, ChipID %x\n",
+		ChipID);
+
+	return 0;
+}
+
+int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings)
+{
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	DSP_ISA_SLAVE_CONTROL rSlaveControl;
+
+
+	PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP entry\n");
+
+	rSlaveControl.ClockControl = 0;
+	rSlaveControl.SoftReset = TRUE;
+	rSlaveControl.ConfigMode = FALSE;
+	rSlaveControl.Reserved = 0;
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
+
+	udelay(5);
+
+	rSlaveControl.ClockControl = 1;
+	OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	udelay(5);
+
+
+	PRINTK_1(TRACE_3780I, "3780i::dsp3780i_DisableDSP exit\n");
+
+	return 0;
+}
+
+int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings)
+{
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	DSP_BOOT_DOMAIN rBootDomain;
+	DSP_HBRIDGE_CONTROL rHBridgeControl;
+
+
+	PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset entry\n");
+
+	spin_lock_irqsave(&dsp_lock, flags);
+	/* Mask DSP to PC interrupt */
+	MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
+
+	PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rHBridgeControl %x\n",
+		MKWORD(rHBridgeControl));
+
+	rHBridgeControl.EnableDspInt = FALSE;
+	OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	/* Reset the core via the boot domain register */
+	rBootDomain.ResetCore = TRUE;
+	rBootDomain.Halt = TRUE;
+	rBootDomain.NMI = TRUE;
+	rBootDomain.Reserved = 0;
+
+	PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Reset rBootDomain %x\n",
+		MKWORD(rBootDomain));
+
+	WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
+
+	/* Reset all the chiplets and then reactivate them */
+	WriteMsaCfg(DSP_ChipReset, 0xFFFF);
+	udelay(5);
+	WriteMsaCfg(DSP_ChipReset,
+			(unsigned short) (~pSettings->usChipletEnable));
+
+
+	PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Reset exit bRC=0\n");
+
+	return 0;
+}
+
+
+int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings)
+{
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	DSP_BOOT_DOMAIN rBootDomain;
+	DSP_HBRIDGE_CONTROL rHBridgeControl;
+
+
+	PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run entry\n");
+
+
+	/* Transition the core to a running state */
+	rBootDomain.ResetCore = TRUE;
+	rBootDomain.Halt = FALSE;
+	rBootDomain.NMI = TRUE;
+	rBootDomain.Reserved = 0;
+	WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
+
+	udelay(5);
+
+	rBootDomain.ResetCore = FALSE;
+	WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
+	udelay(5);
+
+	rBootDomain.NMI = FALSE;
+	WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain));
+	udelay(5);
+
+	/* Enable DSP to PC interrupt */
+	spin_lock_irqsave(&dsp_lock, flags);
+	MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
+	rHBridgeControl.EnableDspInt = TRUE;
+
+	PRINTK_2(TRACE_3780I, "3780i::dsp3780i_Run rHBridgeControl %x\n",
+		MKWORD(rHBridgeControl));
+
+	OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+
+	PRINTK_1(TRACE_3780I, "3780i::dsp3780i_Run exit bRC=TRUE\n");
+
+	return 0;
+}
+
+
+int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer,
+                        unsigned uCount, unsigned long ulDSPAddr)
+{
+	unsigned short *pusBuffer = pvBuffer;
+	unsigned short val;
+
+
+	PRINTK_5(TRACE_3780I,
+		"3780i::dsp3780I_ReadDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
+		usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
+
+
+	/* Set the initial MSA address. No adjustments need to be made to data store addresses */
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
+	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	/* Transfer the memory block */
+	while (uCount-- != 0) {
+		spin_lock_irqsave(&dsp_lock, flags);
+		val = InWordDsp(DSP_MsaDataDSISHigh);
+		spin_unlock_irqrestore(&dsp_lock, flags);
+		if(put_user(val, pusBuffer++))
+			return -EFAULT;
+
+		PRINTK_3(TRACE_3780I,
+			"3780I::dsp3780I_ReadDStore uCount %x val %x\n",
+			uCount, val);
+
+		PaceMsaAccess(usDspBaseIO);
+	}
+
+
+	PRINTK_1(TRACE_3780I,
+		"3780I::dsp3780I_ReadDStore exit bRC=TRUE\n");
+
+	return 0;
+}
+
+int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
+                                void *pvBuffer, unsigned uCount,
+                                unsigned long ulDSPAddr)
+{
+	unsigned short *pusBuffer = pvBuffer;
+	unsigned short val;
+
+
+	PRINTK_5(TRACE_3780I,
+		"3780i::dsp3780I_ReadAndDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
+		usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
+
+
+	/* Set the initial MSA address. No adjustments need to be made to data store addresses */
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
+	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	/* Transfer the memory block */
+	while (uCount-- != 0) {
+		spin_lock_irqsave(&dsp_lock, flags);
+		val = InWordDsp(DSP_ReadAndClear);
+		spin_unlock_irqrestore(&dsp_lock, flags);
+		if(put_user(val, pusBuffer++))
+			return -EFAULT;
+
+		PRINTK_3(TRACE_3780I,
+			"3780I::dsp3780I_ReadAndCleanDStore uCount %x val %x\n",
+			uCount, val);
+
+		PaceMsaAccess(usDspBaseIO);
+	}
+
+
+	PRINTK_1(TRACE_3780I,
+		"3780I::dsp3780I_ReadAndClearDStore exit bRC=TRUE\n");
+
+	return 0;
+}
+
+
+int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer,
+                         unsigned uCount, unsigned long ulDSPAddr)
+{
+	unsigned short *pusBuffer = pvBuffer;
+
+
+	PRINTK_5(TRACE_3780I,
+		"3780i::dsp3780D_WriteDStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
+		usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
+
+
+	/* Set the initial MSA address. No adjustments need to be made to data store addresses */
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
+	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	/* Transfer the memory block */
+	while (uCount-- != 0) {
+		unsigned short val;
+		if(get_user(val, pusBuffer++))
+			return -EFAULT;
+		spin_lock_irqsave(&dsp_lock, flags);
+		OutWordDsp(DSP_MsaDataDSISHigh, val);
+		spin_unlock_irqrestore(&dsp_lock, flags);
+
+		PRINTK_3(TRACE_3780I,
+			"3780I::dsp3780I_WriteDStore uCount %x val %x\n",
+			uCount, val);
+
+		PaceMsaAccess(usDspBaseIO);
+	}
+
+
+	PRINTK_1(TRACE_3780I,
+		"3780I::dsp3780D_WriteDStore exit bRC=TRUE\n");
+
+	return 0;
+}
+
+
+int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer,
+                        unsigned uCount, unsigned long ulDSPAddr)
+{
+	unsigned short *pusBuffer = pvBuffer;
+
+	PRINTK_5(TRACE_3780I,
+		"3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
+		usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
+
+	/*
+	* Set the initial MSA address. To convert from an instruction store
+	* address to an MSA address
+	* shift the address two bits to the left and set bit 22
+	*/
+	ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
+	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	/* Transfer the memory block */
+	while (uCount-- != 0) {
+		unsigned short val_lo, val_hi;
+		spin_lock_irqsave(&dsp_lock, flags);
+		val_lo = InWordDsp(DSP_MsaDataISLow);
+		val_hi = InWordDsp(DSP_MsaDataDSISHigh);
+		spin_unlock_irqrestore(&dsp_lock, flags);
+		if(put_user(val_lo, pusBuffer++))
+			return -EFAULT;
+		if(put_user(val_hi, pusBuffer++))
+			return -EFAULT;
+
+		PRINTK_4(TRACE_3780I,
+			"3780I::dsp3780I_ReadIStore uCount %x val_lo %x val_hi %x\n",
+			uCount, val_lo, val_hi);
+
+		PaceMsaAccess(usDspBaseIO);
+
+	}
+
+	PRINTK_1(TRACE_3780I,
+		"3780I::dsp3780I_ReadIStore exit bRC=TRUE\n");
+
+	return 0;
+}
+
+
+int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer,
+                         unsigned uCount, unsigned long ulDSPAddr)
+{
+	unsigned short *pusBuffer = pvBuffer;
+
+	PRINTK_5(TRACE_3780I,
+		"3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
+		usDspBaseIO, pusBuffer, uCount, ulDSPAddr);
+
+
+	/*
+	* Set the initial MSA address. To convert from an instruction store
+	* address to an MSA address
+	* shift the address two bits to the left and set bit 22
+	*/
+	ulDSPAddr = (ulDSPAddr << 2) | (1 << 22);
+	spin_lock_irqsave(&dsp_lock, flags);
+	OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr);
+	OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+	/* Transfer the memory block */
+	while (uCount-- != 0) {
+		unsigned short val_lo, val_hi;
+		if(get_user(val_lo, pusBuffer++))
+			return -EFAULT;
+		if(get_user(val_hi, pusBuffer++))
+			return -EFAULT;
+		spin_lock_irqsave(&dsp_lock, flags);
+		OutWordDsp(DSP_MsaDataISLow, val_lo);
+		OutWordDsp(DSP_MsaDataDSISHigh, val_hi);
+		spin_unlock_irqrestore(&dsp_lock, flags);
+
+		PRINTK_4(TRACE_3780I,
+			"3780I::dsp3780I_WriteIStore uCount %x val_lo %x val_hi %x\n",
+			uCount, val_lo, val_hi);
+
+		PaceMsaAccess(usDspBaseIO);
+
+	}
+
+	PRINTK_1(TRACE_3780I,
+		"3780I::dsp3780I_WriteIStore exit bRC=TRUE\n");
+
+	return 0;
+}
+
+
+int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
+                          unsigned short *pusIPCSource)
+{
+	DSP_HBRIDGE_CONTROL rHBridgeControl;
+	unsigned short temp;
+
+
+	PRINTK_3(TRACE_3780I,
+		"3780i::dsp3780I_GetIPCSource entry usDspBaseIO %x pusIPCSource %p\n",
+		usDspBaseIO, pusIPCSource);
+
+	/*
+	* Disable DSP to PC interrupts, read the interupt register,
+	* clear the pending IPC bits, and reenable DSP to PC interrupts
+	*/
+	spin_lock_irqsave(&dsp_lock, flags);
+	MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl);
+	rHBridgeControl.EnableDspInt = FALSE;
+	OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
+
+	*pusIPCSource = InWordDsp(DSP_Interrupt);
+	temp = (unsigned short) ~(*pusIPCSource);
+
+	PRINTK_3(TRACE_3780I,
+		"3780i::dsp3780I_GetIPCSource, usIPCSource %x ~ %x\n",
+		*pusIPCSource, temp);
+
+	OutWordDsp(DSP_Interrupt, (unsigned short) ~(*pusIPCSource));
+
+	rHBridgeControl.EnableDspInt = TRUE;
+	OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl));
+	spin_unlock_irqrestore(&dsp_lock, flags);
+
+
+	PRINTK_2(TRACE_3780I,
+		"3780i::dsp3780I_GetIPCSource exit usIPCSource %x\n",
+		*pusIPCSource);
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/3780i.h linux/drivers/char/mwave/3780i.h
--- v2.4.10/linux/drivers/char/mwave/3780i.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/3780i.h	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,362 @@
+/*
+*
+* 3780i.h -- declarations for 3780i.c
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#ifndef _LINUX_3780I_H
+#define _LINUX_3780I_H
+
+#include <asm/io.h>
+
+/* DSP I/O port offsets and definitions */
+#define DSP_IsaSlaveControl        0x0000	/* ISA slave control register */
+#define DSP_IsaSlaveStatus         0x0001	/* ISA slave status register */
+#define DSP_ConfigAddress          0x0002	/* General config address register */
+#define DSP_ConfigData             0x0003	/* General config data register */
+#define DSP_HBridgeControl         0x0002	/* HBridge control register */
+#define DSP_MsaAddrLow             0x0004	/* MSP System Address, low word */
+#define DSP_MsaAddrHigh            0x0006	/* MSP System Address, high word */
+#define DSP_MsaDataDSISHigh        0x0008	/* MSA data register: d-store word or high byte of i-store */
+#define DSP_MsaDataISLow           0x000A	/* MSA data register: low word of i-store */
+#define DSP_ReadAndClear           0x000C	/* MSA read and clear data register */
+#define DSP_Interrupt              0x000E	/* Interrupt register (IPC source) */
+
+typedef struct {
+	unsigned char ClockControl:1;	/* RW: Clock control: 0=normal, 1=stop 3780i clocks */
+	unsigned char SoftReset:1;	/* RW: Soft reset 0=normal, 1=soft reset active */
+	unsigned char ConfigMode:1;	/* RW: Configuration mode, 0=normal, 1=config mode */
+	unsigned char Reserved:5;	/* 0: Reserved */
+} DSP_ISA_SLAVE_CONTROL;
+
+
+typedef struct {
+	unsigned short EnableDspInt:1;	/* RW: Enable DSP to X86 ISA interrupt 0=mask it, 1=enable it */
+	unsigned short MemAutoInc:1;	/* RW: Memory address auto increment, 0=disable, 1=enable */
+	unsigned short IoAutoInc:1;	/* RW: I/O address auto increment, 0=disable, 1=enable */
+	unsigned short DiagnosticMode:1;	/* RW: Disgnostic mode 0=nromal, 1=diagnostic mode */
+	unsigned short IsaPacingTimer:12;	/* R: ISA access pacing timer: count of core cycles stolen */
+} DSP_HBRIDGE_CONTROL;
+
+
+/* DSP register indexes used with the configuration register address (index) register */
+#define DSP_UartCfg1Index          0x0003	/* UART config register 1 */
+#define DSP_UartCfg2Index          0x0004	/* UART config register 2 */
+#define DSP_HBridgeCfg1Index       0x0007	/* HBridge config register 1 */
+#define DSP_HBridgeCfg2Index       0x0008	/* HBridge config register 2 */
+#define DSP_BusMasterCfg1Index     0x0009	/* ISA bus master config register 1 */
+#define DSP_BusMasterCfg2Index     0x000A	/* ISA bus master config register 2 */
+#define DSP_IsaProtCfgIndex        0x000F	/* ISA protocol control register */
+#define DSP_PowerMgCfgIndex        0x0010	/* Low poser suspend/resume enable */
+#define DSP_HBusTimerCfgIndex      0x0011	/* HBUS timer load value */
+
+typedef struct {
+	unsigned char IrqActiveLow:1;	/* RW: IRQ active high or low: 0=high, 1=low */
+	unsigned char IrqPulse:1;	/* RW: IRQ pulse or level: 0=level, 1=pulse  */
+	unsigned char Irq:3;	/* RW: IRQ selection */
+	unsigned char BaseIO:2;	/* RW: Base I/O selection */
+	unsigned char Reserved:1;	/* 0: Reserved */
+} DSP_UART_CFG_1;
+
+typedef struct {
+	unsigned char Enable:1;	/* RW: Enable I/O and IRQ: 0=FALSE, 1=TRUE */
+	unsigned char Reserved:7;	/* 0: Reserved */
+} DSP_UART_CFG_2;
+
+typedef struct {
+	unsigned char IrqActiveLow:1;	/* RW: IRQ active high=0 or low=1 */
+	unsigned char IrqPulse:1;	/* RW: IRQ pulse=1 or level=0 */
+	unsigned char Irq:3;	/* RW: IRQ selection */
+	unsigned char AccessMode:1;	/* RW: 16-bit register access method 0=byte, 1=word */
+	unsigned char Reserved:2;	/* 0: Reserved */
+} DSP_HBRIDGE_CFG_1;
+
+typedef struct {
+	unsigned char Enable:1;	/* RW: enable I/O and IRQ: 0=FALSE, 1=TRUE */
+	unsigned char Reserved:7;	/* 0: Reserved */
+} DSP_HBRIDGE_CFG_2;
+
+
+typedef struct {
+	unsigned char Dma:3;	/* RW: DMA channel selection */
+	unsigned char NumTransfers:2;	/* RW: Maximum # of transfers once being granted the ISA bus */
+	unsigned char ReRequest:2;	/* RW: Minumum delay between releasing the ISA bus and requesting it again */
+	unsigned char MEMCS16:1;	/* RW: ISA signal MEMCS16: 0=disabled, 1=enabled */
+} DSP_BUSMASTER_CFG_1;
+
+typedef struct {
+	unsigned char IsaMemCmdWidth:2;	/* RW: ISA memory command width */
+	unsigned char Reserved:6;	/* 0: Reserved */
+} DSP_BUSMASTER_CFG_2;
+
+
+typedef struct {
+	unsigned char GateIOCHRDY:1;	/* RW: Enable IOCHRDY gating: 0=FALSE, 1=TRUE */
+	unsigned char Reserved:7;	/* 0: Reserved */
+} DSP_ISA_PROT_CFG;
+
+typedef struct {
+	unsigned char Enable:1;	/* RW: Enable low power suspend/resume 0=FALSE, 1=TRUE */
+	unsigned char Reserved:7;	/* 0: Reserved */
+} DSP_POWER_MGMT_CFG;
+
+typedef struct {
+	unsigned char LoadValue:8;	/* RW: HBUS timer load value */
+} DSP_HBUS_TIMER_CFG;
+
+
+
+/* DSP registers that exist in MSA I/O space */
+#define DSP_ChipID                 0x80000000
+#define DSP_MspBootDomain          0x80000580
+#define DSP_LBusTimeoutDisable     0x80000580
+#define DSP_ClockControl_1         0x8000058A
+#define DSP_ClockControl_2         0x8000058C
+#define DSP_ChipReset              0x80000588
+#define DSP_GpioModeControl_15_8   0x80000082
+#define DSP_GpioDriverEnable_15_8  0x80000076
+#define DSP_GpioOutputData_15_8    0x80000072
+
+typedef struct {
+	unsigned short NMI:1;	/* RW: non maskable interrupt */
+	unsigned short Halt:1;	/* RW: Halt MSP clock */
+	unsigned short ResetCore:1;	/* RW: Reset MSP core interface */
+	unsigned short Reserved:13;	/* 0: Reserved */
+} DSP_BOOT_DOMAIN;
+
+typedef struct {
+	unsigned short DisableTimeout:1;	/* RW: Disable LBus timeout */
+	unsigned short Reserved:15;	/* 0: Reserved */
+} DSP_LBUS_TIMEOUT_DISABLE;
+
+typedef struct {
+	unsigned short Memory:1;	/* RW: Reset memory interface */
+	unsigned short SerialPort1:1;	/* RW: Reset serial port 1 interface */
+	unsigned short SerialPort2:1;	/* RW: Reset serial port 2 interface */
+	unsigned short SerialPort3:1;	/* RW: Reset serial port 3 interface */
+	unsigned short Gpio:1;	/* RW: Reset GPIO interface */
+	unsigned short Dma:1;	/* RW: Reset DMA interface */
+	unsigned short SoundBlaster:1;	/* RW: Reset soundblaster interface */
+	unsigned short Uart:1;	/* RW: Reset UART interface */
+	unsigned short Midi:1;	/* RW: Reset MIDI interface */
+	unsigned short IsaMaster:1;	/* RW: Reset ISA master interface */
+	unsigned short Reserved:6;	/* 0: Reserved */
+} DSP_CHIP_RESET;
+
+typedef struct {
+	unsigned short N_Divisor:6;	/* RW: (N) PLL output clock divisor */
+	unsigned short Reserved1:2;	/* 0: reserved */
+	unsigned short M_Multiplier:6;	/* RW: (M) PLL feedback clock multiplier */
+	unsigned short Reserved2:2;	/* 0: reserved */
+} DSP_CLOCK_CONTROL_1;
+
+typedef struct {
+	unsigned short PllBypass:1;	/* RW: PLL Bypass */
+	unsigned short Reserved:15;	/* 0: Reserved */
+} DSP_CLOCK_CONTROL_2;
+
+typedef struct {
+	unsigned short Latch8:1;
+	unsigned short Latch9:1;
+	unsigned short Latch10:1;
+	unsigned short Latch11:1;
+	unsigned short Latch12:1;
+	unsigned short Latch13:1;
+	unsigned short Latch14:1;
+	unsigned short Latch15:1;
+	unsigned short Mask8:1;
+	unsigned short Mask9:1;
+	unsigned short Mask10:1;
+	unsigned short Mask11:1;
+	unsigned short Mask12:1;
+	unsigned short Mask13:1;
+	unsigned short Mask14:1;
+	unsigned short Mask15:1;
+} DSP_GPIO_OUTPUT_DATA_15_8;
+
+typedef struct {
+	unsigned short Enable8:1;
+	unsigned short Enable9:1;
+	unsigned short Enable10:1;
+	unsigned short Enable11:1;
+	unsigned short Enable12:1;
+	unsigned short Enable13:1;
+	unsigned short Enable14:1;
+	unsigned short Enable15:1;
+	unsigned short Mask8:1;
+	unsigned short Mask9:1;
+	unsigned short Mask10:1;
+	unsigned short Mask11:1;
+	unsigned short Mask12:1;
+	unsigned short Mask13:1;
+	unsigned short Mask14:1;
+	unsigned short Mask15:1;
+} DSP_GPIO_DRIVER_ENABLE_15_8;
+
+typedef struct {
+	unsigned short GpioMode8:2;
+	unsigned short GpioMode9:2;
+	unsigned short GpioMode10:2;
+	unsigned short GpioMode11:2;
+	unsigned short GpioMode12:2;
+	unsigned short GpioMode13:2;
+	unsigned short GpioMode14:2;
+	unsigned short GpioMode15:2;
+} DSP_GPIO_MODE_15_8;
+
+/* Component masks that are defined in dspmgr.h */
+#define MW_ADC_MASK    0x0001
+#define MW_AIC2_MASK   0x0006
+#define MW_MIDI_MASK   0x0008
+#define MW_CDDAC_MASK  0x8001
+#define MW_AIC1_MASK   0xE006
+#define MW_UART_MASK   0xE00A
+#define MW_ACI_MASK    0xE00B
+
+/*
+* Definition of 3780i configuration structure.  Unless otherwise stated,
+* these values are provided as input to the 3780i support layer.  At present,
+* the only values maintained by the 3780i support layer are the saved UART
+* registers.
+*/
+typedef struct _DSP_3780I_CONFIG_SETTINGS {
+
+	/* Location of base configuration register */
+	unsigned short usBaseConfigIO;
+
+	/* Enables for various DSP components */
+	int bDSPEnabled;
+	int bModemEnabled;
+	int bInterruptClaimed;
+
+	/* IRQ, DMA, and Base I/O addresses for various DSP components */
+	unsigned short usDspIrq;
+	unsigned short usDspDma;
+	unsigned short usDspBaseIO;
+	unsigned short usUartIrq;
+	unsigned short usUartBaseIO;
+
+	/* IRQ modes for various DSP components */
+	int bDspIrqActiveLow;
+	int bUartIrqActiveLow;
+	int bDspIrqPulse;
+	int bUartIrqPulse;
+
+	/* Card abilities */
+	unsigned uIps;
+	unsigned uDStoreSize;
+	unsigned uIStoreSize;
+	unsigned uDmaBandwidth;
+
+	/* Adapter specific 3780i settings */
+	unsigned short usNumTransfers;
+	unsigned short usReRequest;
+	int bEnableMEMCS16;
+	unsigned short usIsaMemCmdWidth;
+	int bGateIOCHRDY;
+	int bEnablePwrMgmt;
+	unsigned short usHBusTimerLoadValue;
+	int bDisableLBusTimeout;
+	unsigned short usN_Divisor;
+	unsigned short usM_Multiplier;
+	int bPllBypass;
+	unsigned short usChipletEnable;	/* Used with the chip reset register to enable specific chiplets */
+
+	/* Saved UART registers. These are maintained by the 3780i support layer. */
+	int bUartSaved;		/* True after a successful save of the UART registers */
+	unsigned char ucIER;	/* Interrupt enable register */
+	unsigned char ucFCR;	/* FIFO control register */
+	unsigned char ucLCR;	/* Line control register */
+	unsigned char ucMCR;	/* Modem control register */
+	unsigned char ucSCR;	/* Scratch register */
+	unsigned char ucDLL;	/* Divisor latch, low byte */
+	unsigned char ucDLM;	/* Divisor latch, high byte */
+} DSP_3780I_CONFIG_SETTINGS;
+
+
+/* 3780i support functions */
+int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
+                       unsigned short *pIrqMap,
+                       unsigned short *pDmaMap);
+int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings);
+int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings);
+int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings);
+int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer,
+                        unsigned uCount, unsigned long ulDSPAddr);
+int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
+                                void *pvBuffer, unsigned uCount,
+                                unsigned long ulDSPAddr);
+int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer,
+                         unsigned uCount, unsigned long ulDSPAddr);
+int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer,
+                        unsigned uCount, unsigned long ulDSPAddr);
+int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer,
+                         unsigned uCount, unsigned long ulDSPAddr);
+unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
+                                   unsigned long ulMsaAddr);
+void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
+                          unsigned long ulMsaAddr, unsigned short usValue);
+void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
+                          unsigned char ucValue);
+unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
+                                  unsigned uIndex);
+int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
+                          unsigned short *pusIPCSource);
+
+/* I/O port access macros */
+#define MKWORD(var) (*((unsigned short *)(&var)))
+#define MKBYTE(var) (*((unsigned char *)(&var)))
+
+#define WriteMsaCfg(addr,value) dsp3780I_WriteMsaCfg(usDspBaseIO,addr,value)
+#define ReadMsaCfg(addr) dsp3780I_ReadMsaCfg(usDspBaseIO,addr)
+#define WriteGenCfg(index,value) dsp3780I_WriteGenCfg(usDspBaseIO,index,value)
+#define ReadGenCfg(index) dsp3780I_ReadGenCfg(usDspBaseIO,index)
+
+#define InWordDsp(index)          inw(usDspBaseIO+index)
+#define InByteDsp(index)          inb(usDspBaseIO+index)
+#define OutWordDsp(index,value)   outw(value,usDspBaseIO+index)
+#define OutByteDsp(index,value)   outb(value,usDspBaseIO+index)
+
+#endif
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/Makefile linux/drivers/char/mwave/Makefile
--- v2.4.10/linux/drivers/char/mwave/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/Makefile	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,25 @@
+#
+# Makefile for ACP Modem (Mwave).
+#
+# See the README file in this directory for more info. <paulsch@us.ibm.com>
+#
+# 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).
+#
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes..
+#
+
+# To compile in lots (~20 KiB) of run-time enablable printk()s for debugging:
+EXTRA_CFLAGS += -DMW_TRACE
+
+# To have the mwave driver disable other uarts if necessary
+# EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES
+
+O_TARGET := mwave.o
+
+obj-y	:= mwavedd.o smapi.o tp3780i.o 3780i.o
+obj-m	:= $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/README linux/drivers/char/mwave/README
--- v2.4.10/linux/drivers/char/mwave/README	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/README	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,50 @@
+Module options
+--------------
+
+The mwave module takes the following options.  Note that these options
+are not saved by the BIOS and so do not persist after unload and reload.
+
+  mwave_debug=value, where value is bitwise OR of trace flags:
+	0x0001 mwavedd api tracing
+	0x0002 smapi api tracing
+	0x0004 3780i tracing
+	0x0008 tp3780i tracing
+
+        Tracing only occurs if the driver has been compiled with the
+        MW_TRACE macro #defined  (i.e. let EXTRA_CFLAGS += -DMW_TRACE
+        in the Makefile).
+
+  mwave_3780i_irq=5/7/10/11/15
+	If the dsp irq has not been setup and stored in bios by the 
+	thinkpad configuration utility then this parameter allows the
+	irq used by the dsp to be configured.
+
+  mwave_3780i_io=0x130/0x350/0x0070/0xDB0
+	If the dsp io range has not been setup and stored in bios by the 
+	thinkpad configuration utility then this parameter allows the
+	io range used by the dsp to be configured.
+
+  mwave_uart_irq=3/4
+	If the mwave's uart irq has not been setup and stored in bios by the 
+	thinkpad configuration utility then this parameter allows the
+	irq used by the mwave uart to be configured.
+
+  mwave_uart_io=0x3f8/0x2f8/0x3E8/0x2E8
+	If the uart io range has not been setup and stored in bios by the 
+	thinkpad configuration utility then this parameter allows the
+	io range used by the mwave uart to be configured.
+
+Example to enable the 3780i DSP using ttyS1 resources:
+	
+  insmod mwave mwave_3780i_irq=10 mwave_3780i_io=0x0130 mwave_uart_irq=3 mwave_uart_io=0x2f8
+
+Accessing the driver
+--------------------
+
+You must also create a node for the driver.  Without devfs:
+  mkdir -p /dev/modems
+  mknod --mode=660 /dev/modems/mwave c 10 219
+With devfs:
+  mkdir -p /dev/modems
+  ln -s ../misc/mwave /dev/modems/mwave
+
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/mwavedd.c linux/drivers/char/mwave/mwavedd.c
--- v2.4.10/linux/drivers/char/mwave/mwavedd.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/mwavedd.c	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,638 @@
+/*
+*
+* mwavedd.c -- mwave device driver
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/serial.h>
+#include <linux/sched.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#include <linux/spinlock.h>
+#else
+#include <asm/spinlock.h>
+#endif
+#include <linux/delay.h>
+#include "smapi.h"
+#include "mwavedd.h"
+#include "3780i.h"
+#include "tp3780i.h"
+
+#ifndef __exit
+#define __exit
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+static int mwave_get_info(char *buf, char **start, off_t offset, int len);
+#else
+static int mwave_read_proc(char *buf, char **start, off_t offset, int xlen, int unused);
+static struct proc_dir_entry mwave_proc = {
+	0,                      /* unsigned short low_ino */
+	5,                      /* unsigned short namelen */
+	"mwave",                /* const char *name */
+	S_IFREG | S_IRUGO,      /* mode_t mode */
+	1,                      /* nlink_t nlink */
+	0,                      /* uid_t uid */
+	0,                      /* gid_t gid */
+	0,                      /* unsigned long size */
+	NULL,                   /* struct inode_operations *ops */
+	&mwave_read_proc        /* int (*get_info) (...) */
+};
+#endif
+
+/*
+* These parameters support the setting of MWave resources. Note that no
+* checks are made against other devices (ie. superio) for conflicts.
+* We'll depend on users using the tpctl utility to do that for now
+*/
+int mwave_debug = 0;
+int mwave_3780i_irq = 0;
+int mwave_3780i_io = 0;
+int mwave_uart_irq = 0;
+int mwave_uart_io = 0;
+MODULE_PARM(mwave_debug, "i");
+MODULE_PARM(mwave_3780i_irq, "i");
+MODULE_PARM(mwave_3780i_io, "i");
+MODULE_PARM(mwave_uart_irq, "i");
+MODULE_PARM(mwave_uart_io, "i");
+
+static int mwave_open(struct inode *inode, struct file *file);
+static int mwave_close(struct inode *inode, struct file *file);
+static int mwave_ioctl(struct inode *inode, struct file *filp,
+                       unsigned int iocmd, unsigned long ioarg);
+
+MWAVE_DEVICE_DATA mwave_s_mdd;
+
+static int mwave_open(struct inode *inode, struct file *file)
+{
+	unsigned int retval = 0;
+
+	PRINTK_3(TRACE_MWAVE,
+		"mwavedd::mwave_open, entry inode %x file %x\n",
+		(int) inode, (int) file);
+	PRINTK_2(TRACE_MWAVE,
+		"mwavedd::mwave_open, exit return retval %x\n", retval);
+
+	MOD_INC_USE_COUNT;
+	return retval;
+}
+
+static int mwave_close(struct inode *inode, struct file *file)
+{
+	unsigned int retval = 0;
+
+	PRINTK_3(TRACE_MWAVE,
+		"mwavedd::mwave_close, entry inode %x file %x\n",
+		(int) inode, (int) file);
+
+	PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_close, exit retval %x\n",
+		retval);
+
+	MOD_DEC_USE_COUNT;
+	return retval;
+}
+
+static int mwave_ioctl(struct inode *inode, struct file *file,
+                       unsigned int iocmd, unsigned long ioarg)
+{
+	unsigned int retval = 0;
+	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
+
+	PRINTK_5(TRACE_MWAVE,
+		"mwavedd::mwave_ioctl, entry inode %x file %x cmd %x arg %x\n",
+		(int) inode, (int) file, iocmd, (int) ioarg);
+
+	switch (iocmd) {
+
+		case IOCTL_MW_RESET:
+			PRINTK_1(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl, IOCTL_MW_RESET calling tp3780I_ResetDSP\n");
+			retval = tp3780I_ResetDSP(&pDrvData->rBDData);
+			PRINTK_2(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl, IOCTL_MW_RESET retval %x from tp3780I_ResetDSP\n",
+				retval);
+			break;
+	
+		case IOCTL_MW_RUN:
+			PRINTK_1(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl, IOCTL_MW_RUN calling tp3780I_StartDSP\n");
+			retval = tp3780I_StartDSP(&pDrvData->rBDData);
+			PRINTK_2(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl, IOCTL_MW_RUN retval %x from tp3780I_StartDSP\n",
+				retval);
+			break;
+	
+		case IOCTL_MW_DSP_ABILITIES: {
+			MW_ABILITIES rAbilities;
+	
+			PRINTK_1(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES calling tp3780I_QueryAbilities\n");
+			retval = tp3780I_QueryAbilities(&pDrvData->rBDData, &rAbilities);
+			PRINTK_2(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES retval %x from tp3780I_QueryAbilities\n",
+				retval);
+			if (retval == 0) {
+				if( copy_to_user((char *) ioarg, (char *) &rAbilities, sizeof(MW_ABILITIES)) )
+					return -EFAULT;
+			}
+			PRINTK_2(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES exit retval %x\n",
+				retval);
+		}
+			break;
+	
+		case IOCTL_MW_READ_DATA:
+		case IOCTL_MW_READCLEAR_DATA: {
+			MW_READWRITE rReadData;
+			unsigned short *pusBuffer = 0;
+	
+			if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) )
+				return -EFAULT;
+			pusBuffer = (unsigned short *) (rReadData.pBuf);
+	
+			PRINTK_4(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_READ_DATA, size %lx, ioarg %lx pusBuffer %p\n",
+				rReadData.ulDataLength, ioarg, pusBuffer);
+			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd,
+				(void *) pusBuffer, rReadData.ulDataLength, rReadData.usDspAddress);
+		}
+			break;
+	
+		case IOCTL_MW_READ_INST: {
+			MW_READWRITE rReadData;
+			unsigned short *pusBuffer = 0;
+	
+			if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) )
+				return -EFAULT;
+			pusBuffer = (unsigned short *) (rReadData.pBuf);
+	
+			PRINTK_4(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_READ_INST, size %lx, ioarg %lx pusBuffer %p\n",
+				rReadData.ulDataLength / 2, ioarg,
+				pusBuffer);
+			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
+				iocmd, pusBuffer,
+				rReadData.ulDataLength / 2,
+				rReadData.usDspAddress);
+		}
+			break;
+	
+		case IOCTL_MW_WRITE_DATA: {
+			MW_READWRITE rWriteData;
+			unsigned short *pusBuffer = 0;
+	
+			if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) )
+				return -EFAULT;
+			pusBuffer = (unsigned short *) (rWriteData.pBuf);
+	
+			PRINTK_4(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA, size %lx, ioarg %lx pusBuffer %p\n",
+				rWriteData.ulDataLength, ioarg,
+				pusBuffer);
+			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd,
+				pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress);
+		}
+			break;
+	
+		case IOCTL_MW_WRITE_INST: {
+			MW_READWRITE rWriteData;
+			unsigned short *pusBuffer = 0;
+	
+			if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) )
+				return -EFAULT;
+			pusBuffer = (unsigned short *) (rWriteData.pBuf);
+	
+			PRINTK_4(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST, size %lx, ioarg %lx pusBuffer %p\n",
+				rWriteData.ulDataLength, ioarg,
+				pusBuffer);
+			retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, iocmd,
+					pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress);
+		}
+			break;
+	
+		case IOCTL_MW_REGISTER_IPC: {
+			unsigned int ipcnum = (unsigned int) ioarg;
+	
+			PRINTK_3(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x entry usIntCount %x\n",
+				ipcnum,
+				pDrvData->IPCs[ipcnum].usIntCount);
+	
+			if (ipcnum > 16) {
+				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum);
+				return -EINVAL;
+			}
+			pDrvData->IPCs[ipcnum].bIsHere = FALSE;
+			pDrvData->IPCs[ipcnum].bIsEnabled = TRUE;
+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+			current->nice = -20;	/* boost to provide priority timing */
+	#else
+			current->priority = 0x28;	/* boost to provide priority timing */
+	#endif
+	
+			PRINTK_2(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x exit\n",
+				ipcnum);
+		}
+			break;
+	
+		case IOCTL_MW_GET_IPC: {
+			unsigned int ipcnum = (unsigned int) ioarg;
+			spinlock_t ipc_lock = SPIN_LOCK_UNLOCKED;
+			unsigned long flags;
+	
+			PRINTK_3(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x, usIntCount %x\n",
+				ipcnum,
+				pDrvData->IPCs[ipcnum].usIntCount);
+			if (ipcnum > 16) {
+				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", ipcnum);
+				return -EINVAL;
+			}
+	
+			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
+				PRINTK_2(TRACE_MWAVE,
+					"mwavedd::mwave_ioctl, thread for ipc %x going to sleep\n",
+					ipcnum);
+	
+				spin_lock_irqsave(&ipc_lock, flags);
+				/* check whether an event was signalled by */
+				/* the interrupt handler while we were gone */
+				if (pDrvData->IPCs[ipcnum].usIntCount == 1) {	/* first int has occurred (race condition) */
+					pDrvData->IPCs[ipcnum].usIntCount = 2;	/* first int has been handled */
+					spin_unlock_irqrestore(&ipc_lock, flags);
+					PRINTK_2(TRACE_MWAVE,
+						"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x handling first int\n",
+						ipcnum);
+				} else {	/* either 1st int has not yet occurred, or we have already handled the first int */
+					pDrvData->IPCs[ipcnum].bIsHere = TRUE;
+					interruptible_sleep_on(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
+					pDrvData->IPCs[ipcnum].bIsHere = FALSE;
+					if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
+						pDrvData->IPCs[ipcnum].
+						usIntCount = 2;
+					}
+					spin_unlock_irqrestore(&ipc_lock, flags);
+					PRINTK_2(TRACE_MWAVE,
+						"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x woke up and returning to application\n",
+						ipcnum);
+				}
+				PRINTK_2(TRACE_MWAVE,
+					"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC, returning thread for ipc %x processing\n",
+					ipcnum);
+			}
+		}
+			break;
+	
+		case IOCTL_MW_UNREGISTER_IPC: {
+			unsigned int ipcnum = (unsigned int) ioarg;
+	
+			PRINTK_2(TRACE_MWAVE,
+				"mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC ipcnum %x\n",
+				ipcnum);
+			if (ipcnum > 16) {
+				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum);
+				return -EINVAL;
+			}
+			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
+				pDrvData->IPCs[ipcnum].bIsEnabled = FALSE;
+				if (pDrvData->IPCs[ipcnum].bIsHere == TRUE) {
+					wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
+				}
+			}
+		}
+			break;
+	
+		default:
+			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: Error: Unrecognized iocmd %x\n", iocmd);
+			return -ENOTTY;
+			break;
+	} /* switch */
+
+	PRINTK_2(TRACE_MWAVE, "mwavedd::mwave_ioctl, exit retval %x\n", retval);
+
+	return retval;
+}
+
+
+static ssize_t mwave_read(struct file *file, char *buf, size_t count,
+                          loff_t * ppos)
+{
+	PRINTK_5(TRACE_MWAVE,
+		"mwavedd::mwave_read entry file %p, buf %p, count %x ppos %p\n",
+		file, buf, count, ppos);
+
+	return -EINVAL;
+}
+
+
+static ssize_t mwave_write(struct file *file, const char *buf,
+                           size_t count, loff_t * ppos)
+{
+	PRINTK_5(TRACE_MWAVE,
+		"mwavedd::mwave_write entry file %p, buf %p, count %x ppos %p\n",
+		file, buf, count, ppos);
+
+	return -EINVAL;
+}
+
+
+static int register_serial_portandirq(unsigned int port, int irq)
+{
+	struct serial_struct serial;
+
+	switch ( port ) {
+		case 0x3f8:
+		case 0x2f8:
+		case 0x3e8:
+		case 0x2e8:
+			/* OK */
+			break;
+		default:
+			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::register_serial_portandirq: Error: Illegal port %x\n", port );
+			return -1;
+	} /* switch */
+	/* port is okay */
+
+	switch ( irq ) {
+		case 3:
+		case 4:
+		case 5:
+		case 7:
+			/* OK */
+			break;
+		default:
+			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::register_serial_portandirq: Error: Illegal irq %x\n", irq );
+			return -1;
+	} /* switch */
+	/* irq is okay */
+
+	memset(&serial, 0, sizeof(serial));
+	serial.port = port;
+	serial.irq = irq;
+	serial.flags = ASYNC_SHARE_IRQ;
+
+	return register_serial(&serial);
+}
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+static struct file_operations mwave_fops = {
+	owner:THIS_MODULE,
+	read:mwave_read,
+	write:mwave_write,
+	ioctl:mwave_ioctl,
+	open:mwave_open,
+	release:mwave_close
+};
+#else
+static struct file_operations mwave_fops = {
+	NULL,			/* lseek */
+	mwave_read,		/* read */
+	mwave_write,		/* write */
+	NULL,			/* readdir */
+	NULL,			/* poll */
+	mwave_ioctl,		/* ioctl */
+	NULL,			/* mmap */
+	mwave_open,		/* open */
+	NULL,			/* flush */
+	mwave_close		/* release */
+};
+#endif
+
+static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops };
+
+/*
+* mwave_init is called on module load
+*
+* mwave_exit is called on module unload
+* mwave_exit is also used to clean up after an aborted mwave_init
+*/
+static void __exit mwave_exit(void)
+{
+	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
+
+	PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit entry\n");
+
+	if (pDrvData->bProcEntryCreated) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		remove_proc_entry("mwave", NULL);
+#else
+		proc_unregister(&proc_root, mwave_proc.low_ino);
+#endif
+	}
+	if ( pDrvData->sLine >= 0 ) {
+		unregister_serial(pDrvData->sLine);
+	}
+	if (pDrvData->bMwaveDevRegistered) {
+		misc_deregister(&mwave_misc_dev);
+	}
+	if (pDrvData->bDSPEnabled) {
+		tp3780I_DisableDSP(&pDrvData->rBDData);
+	}
+	if (pDrvData->bResourcesClaimed) {
+		tp3780I_ReleaseResources(&pDrvData->rBDData);
+	}
+	if (pDrvData->bBDInitialized) {
+		tp3780I_Cleanup(&pDrvData->rBDData);
+	}
+
+	PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit exit\n");
+}
+
+module_exit(mwave_exit);
+
+static int __init mwave_init(void)
+{
+	int i;
+	int retval = 0;
+	unsigned int resultMiscRegister;
+	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
+
+	memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA));
+
+	PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n");
+
+	pDrvData->bBDInitialized = FALSE;
+	pDrvData->bResourcesClaimed = FALSE;
+	pDrvData->bDSPEnabled = FALSE;
+	pDrvData->bDSPReset = FALSE;
+	pDrvData->bMwaveDevRegistered = FALSE;
+	pDrvData->sLine = -1;
+	pDrvData->bProcEntryCreated = FALSE;
+
+	for (i = 0; i < 16; i++) {
+		pDrvData->IPCs[i].bIsEnabled = FALSE;
+		pDrvData->IPCs[i].bIsHere = FALSE;
+		pDrvData->IPCs[i].usIntCount = 0;	/* no ints received yet */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue);
+#endif
+	}
+
+	retval = tp3780I_InitializeBoardData(&pDrvData->rBDData);
+	PRINTK_2(TRACE_MWAVE,
+		"mwavedd::mwave_init, return from tp3780I_InitializeBoardData retval %x\n",
+		retval);
+	if (retval) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to initialize board data\n");
+		goto cleanup_error;
+	}
+	pDrvData->bBDInitialized = TRUE;
+
+	retval = tp3780I_CalcResources(&pDrvData->rBDData);
+	PRINTK_2(TRACE_MWAVE,
+		"mwavedd::mwave_init, return from tp3780I_CalcResources retval %x\n",
+		retval);
+	if (retval) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to calculate resources\n");
+		goto cleanup_error;
+	}
+
+	retval = tp3780I_ClaimResources(&pDrvData->rBDData);
+	PRINTK_2(TRACE_MWAVE,
+		"mwavedd::mwave_init, return from tp3780I_ClaimResources retval %x\n",
+		retval);
+	if (retval) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to claim resources\n");
+		goto cleanup_error;
+	}
+	pDrvData->bResourcesClaimed = TRUE;
+
+	retval = tp3780I_EnableDSP(&pDrvData->rBDData);
+	PRINTK_2(TRACE_MWAVE,
+		"mwavedd::mwave_init, return from tp3780I_EnableDSP retval %x\n",
+		retval);
+	if (retval) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to enable DSP\n");
+		goto cleanup_error;
+	}
+	pDrvData->bDSPEnabled = TRUE;
+
+	resultMiscRegister = misc_register(&mwave_misc_dev);
+	if (resultMiscRegister < 0) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to register misc device\n");
+		goto cleanup_error;
+	}
+	pDrvData->bMwaveDevRegistered = TRUE;
+
+	pDrvData->sLine = register_serial_portandirq(
+		pDrvData->rBDData.rDspSettings.usUartBaseIO,
+		pDrvData->rBDData.rDspSettings.usUartIrq
+	);
+	if (pDrvData->sLine < 0) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to register serial driver\n");
+		goto cleanup_error;
+	}
+	/* uart is registered */
+
+	if (
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+		!create_proc_info_entry("mwave", 0, NULL, mwave_get_info)
+#else
+		proc_register(&proc_root, &mwave_proc)
+#endif
+	) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to register /proc/mwave\n");
+		goto cleanup_error;
+	}
+	pDrvData->bProcEntryCreated = TRUE;
+
+	/* SUCCESS! */
+	return 0;
+
+	cleanup_error:
+	PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to initialize\n");
+	mwave_exit(); /* clean up */
+
+	return -EIO;
+}
+
+module_init(mwave_init);
+
+
+/*
+* proc entry stuff added by Ian Pilcher <pilcher@us.ibm.com>
+*/
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+static int mwave_get_info(char *buf, char **start, off_t offset, int len)
+{
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &mwave_s_mdd.rBDData.rDspSettings;
+
+	char *out = buf;
+
+	out += sprintf(out, "3780i_IRQ %i\n", pSettings->usDspIrq);
+	out += sprintf(out, "3780i_DMA %i\n", pSettings->usDspDma);
+	out += sprintf(out, "3780i_IO  %#.4x\n", pSettings->usDspBaseIO);
+	out += sprintf(out, "UART_IRQ  %i\n", pSettings->usUartIrq);
+	out += sprintf(out, "UART_IO   %#.4x\n", pSettings->usUartBaseIO);
+
+	return out - buf;
+}
+#else /* kernel version < 2.4.0 */
+static int mwave_read_proc(char *buf, char **start, off_t offset,
+                           int xlen, int unused)
+{
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &mwave_s_mdd.rBDData.rDspSettings;
+	int len;
+
+	len = sprintf(buf,        "3780i_IRQ %i\n", pSettings->usDspIrq);
+	len += sprintf(&buf[len], "3780i_DMA %i\n", pSettings->usDspDma);
+	len += sprintf(&buf[len], "3780i_IO  %#.4x\n", pSettings->usDspBaseIO);
+	len += sprintf(&buf[len], "UART_IRQ  %i\n", pSettings->usUartIrq);
+	len += sprintf(&buf[len], "UART_IO   %#.4x\n", pSettings->usUartBaseIO);
+
+	return len;
+}
+#endif
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/mwavedd.h linux/drivers/char/mwave/mwavedd.h
--- v2.4.10/linux/drivers/char/mwave/mwavedd.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/mwavedd.h	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,151 @@
+/*
+*
+* mwavedd.h -- declarations for mwave device driver
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#ifndef _LINUX_MWAVEDD_H
+#define _LINUX_MWAVEDD_H
+#include "3780i.h"
+#include "tp3780i.h"
+#include "mwavepub.h"
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+
+extern int mwave_debug;
+extern int mwave_3780i_irq;
+extern int mwave_3780i_io;
+extern int mwave_uart_irq;
+extern int mwave_uart_io;
+
+#define PRINTK_ERROR printk
+#define KERN_ERR_MWAVE KERN_ERR "mwave: "
+
+#define TRACE_MWAVE     0x0001
+#define TRACE_SMAPI     0x0002
+#define TRACE_3780I     0x0004
+#define TRACE_TP3780I   0x0008
+
+#ifdef MW_TRACE
+#define PRINTK_1(f,s)                       \
+  if (f & (mwave_debug)) {                  \
+    printk(s);                              \
+  }
+
+#define PRINTK_2(f,s,v1)                    \
+  if (f & (mwave_debug)) {                  \
+    printk(s,v1);                           \
+  }
+
+#define PRINTK_3(f,s,v1,v2)                 \
+  if (f & (mwave_debug)) {                  \
+    printk(s,v1,v2);                        \
+  }
+
+#define PRINTK_4(f,s,v1,v2,v3)              \
+  if (f & (mwave_debug)) {                  \
+    printk(s,v1,v2,v3);                     \
+  }
+
+#define PRINTK_5(f,s,v1,v2,v3,v4)           \
+  if (f & (mwave_debug)) {                  \
+    printk(s,v1,v2,v3,v4);                  \
+  }
+
+#define PRINTK_6(f,s,v1,v2,v3,v4,v5)        \
+  if (f & (mwave_debug)) {                  \
+    printk(s,v1,v2,v3,v4,v5);               \
+  }
+
+#define PRINTK_7(f,s,v1,v2,v3,v4,v5,v6)     \
+  if (f & (mwave_debug)) {                  \
+    printk(s,v1,v2,v3,v4,v5,v6);            \
+  }
+
+#define PRINTK_8(f,s,v1,v2,v3,v4,v5,v6,v7)  \
+  if (f & (mwave_debug)) {                  \
+    printk(s,v1,v2,v3,v4,v5,v6,v7);         \
+  }
+
+#else
+#define PRINTK_1(f,s)
+#define PRINTK_2(f,s,v1)
+#define PRINTK_3(f,s,v1,v2)
+#define PRINTK_4(f,s,v1,v2,v3)
+#define PRINTK_5(f,s,v1,v2,v3,v4)
+#define PRINTK_6(f,s,v1,v2,v3,v4,v5)
+#define PRINTK_7(f,s,v1,v2,v3,v4,v5,v6)
+#define PRINTK_8(f,s,v1,v2,v3,v4,v5,v6,v7)
+#endif
+
+
+typedef struct _MWAVE_IPC {
+	unsigned short usIntCount;	/* 0=none, 1=first, 2=greater than 1st */
+	BOOLEAN bIsEnabled;
+	BOOLEAN bIsHere;
+	/* entry spin lock */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	wait_queue_head_t ipc_wait_queue;
+#else
+	struct wait_queue *ipc_wait_queue;
+#endif
+} MWAVE_IPC;
+
+typedef struct _MWAVE_DEVICE_DATA {
+	THINKPAD_BD_DATA rBDData;	/* board driver's data area */
+	unsigned long ulIPCSource_ISR;	/* IPC source bits for recently processed intr, set during ISR processing */
+	unsigned long ulIPCSource_DPC;	/* IPC source bits for recently processed intr, set during DPC processing */
+	BOOLEAN bBDInitialized;
+	BOOLEAN bResourcesClaimed;
+	BOOLEAN bDSPEnabled;
+	BOOLEAN bDSPReset;
+	MWAVE_IPC IPCs[16];
+	BOOLEAN bMwaveDevRegistered;
+	BOOLEAN bProcEntryCreated;
+	short sLine;
+
+} MWAVE_DEVICE_DATA, *pMWAVE_DEVICE_DATA;
+
+#endif
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/mwavepub.h linux/drivers/char/mwave/mwavepub.h
--- v2.4.10/linux/drivers/char/mwave/mwavepub.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/mwavepub.h	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,94 @@
+/*
+*
+* mwavepub.h -- PUBLIC declarations for the mwave driver
+*               and applications using it
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#ifndef _LINUX_MWAVEPUB_H
+#define _LINUX_MWAVEPUB_H
+
+#ifndef MWAVEM_APP_DIST
+#include <linux/miscdevice.h>
+#endif
+
+#ifdef MWAVEM_APP_DIST
+#define MWAVE_MINOR      219
+#endif
+
+typedef struct _MW_ABILITIES {
+	unsigned long instr_per_sec;
+	unsigned long data_size;
+	unsigned long inst_size;
+	unsigned long bus_dma_bw;
+	unsigned short uart_enable;
+	short component_count;
+	unsigned long component_list[7];
+	char mwave_os_name[16];
+	char bios_task_name[16];
+} MW_ABILITIES, *pMW_ABILITIES;
+
+
+typedef struct _MW_READWRITE {
+	unsigned short usDspAddress;	/* The dsp address */
+	unsigned long ulDataLength;	/* The size in bytes of the data or user buffer */
+	void *pBuf;		/* Input:variable sized buffer */
+} MW_READWRITE, *pMW_READWRITE;
+
+#define IOCTL_MW_RESET           _IO(MWAVE_MINOR,1)
+#define IOCTL_MW_RUN             _IO(MWAVE_MINOR,2)
+#define IOCTL_MW_DSP_ABILITIES   _IOR(MWAVE_MINOR,3,MW_ABILITIES)
+#define IOCTL_MW_READ_DATA       _IOR(MWAVE_MINOR,4,MW_READWRITE)
+#define IOCTL_MW_READCLEAR_DATA  _IOR(MWAVE_MINOR,5,MW_READWRITE)
+#define IOCTL_MW_READ_INST       _IOR(MWAVE_MINOR,6,MW_READWRITE)
+#define IOCTL_MW_WRITE_DATA      _IOW(MWAVE_MINOR,7,MW_READWRITE)
+#define IOCTL_MW_WRITE_INST      _IOW(MWAVE_MINOR,8,MW_READWRITE)
+#define IOCTL_MW_REGISTER_IPC    _IOW(MWAVE_MINOR,9,int)
+#define IOCTL_MW_UNREGISTER_IPC  _IOW(MWAVE_MINOR,10,int)
+#define IOCTL_MW_GET_IPC         _IOW(MWAVE_MINOR,11,int)
+#define IOCTL_MW_TRACE           _IOR(MWAVE_MINOR,12,MW_READWRITE)
+
+
+#endif
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/smapi.c linux/drivers/char/mwave/smapi.c
--- v2.4.10/linux/drivers/char/mwave/smapi.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/smapi.c	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,563 @@
+/*
+*
+* smapi.c -- SMAPI interface routines
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>	/* CMOS defines */
+#include "smapi.h"
+#include "mwavedd.h"
+
+static unsigned short g_usSmapiPort = 0;
+
+
+int smapi_request(unsigned short inBX, unsigned short inCX,
+                  unsigned short inDI, unsigned short inSI,
+                  unsigned short *outAX, unsigned short *outBX,
+                  unsigned short *outCX, unsigned short *outDX,
+                  unsigned short *outDI, unsigned short *outSI)
+{
+	unsigned short myoutAX = 2, *pmyoutAX = &myoutAX;
+	unsigned short myoutBX = 3, *pmyoutBX = &myoutBX;
+	unsigned short myoutCX = 4, *pmyoutCX = &myoutCX;
+	unsigned short myoutDX = 5, *pmyoutDX = &myoutDX;
+	unsigned short myoutDI = 6, *pmyoutDI = &myoutDI;
+	unsigned short myoutSI = 7, *pmyoutSI = &myoutSI;
+	unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK;
+	unsigned int inBXCX = (inBX << 16) | inCX;
+	unsigned int inDISI = (inDI << 16) | inSI;
+	int retval = 0;
+
+	PRINTK_5(TRACE_SMAPI, "inBX %x inCX %x inDI %x inSI %x\n",
+		inBX, inCX, inDI, inSI);
+
+	__asm__ __volatile__("movw  $0x5380,%%ax\n\t"
+			    "movl  %7,%%ebx\n\t"
+			    "shrl  $16, %%ebx\n\t"
+			    "movw  %7,%%cx\n\t"
+			    "movl  %8,%%edi\n\t"
+			    "shrl  $16,%%edi\n\t"
+			    "movw  %8,%%si\n\t"
+			    "movw  %9,%%dx\n\t"
+			    "out   %%al,%%dx\n\t"
+			    "out   %%al,$0x4F\n\t"
+			    "cmpb  $0x53,%%ah\n\t"
+			    "je    2f\n\t"
+			    "1:\n\t"
+			    "orb   %%ah,%%ah\n\t"
+			    "jnz   2f\n\t"
+			    "movw  %%ax,%0\n\t"
+			    "movw  %%bx,%1\n\t"
+			    "movw  %%cx,%2\n\t"
+			    "movw  %%dx,%3\n\t"
+			    "movw  %%di,%4\n\t"
+			    "movw  %%si,%5\n\t"
+			    "movw  $1,%6\n\t"
+			    "2:\n\t":"=m"(*(unsigned short *) pmyoutAX),
+			    "=m"(*(unsigned short *) pmyoutBX),
+			    "=m"(*(unsigned short *) pmyoutCX),
+			    "=m"(*(unsigned short *) pmyoutDX),
+			    "=m"(*(unsigned short *) pmyoutDI),
+			    "=m"(*(unsigned short *) pmyoutSI),
+			    "=m"(*(unsigned short *) pusSmapiOK)
+			    :"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort)
+			    :"%eax", "%ebx", "%ecx", "%edx", "%edi",
+			    "%esi");
+
+	PRINTK_8(TRACE_SMAPI,
+		"myoutAX %x myoutBX %x myoutCX %x myoutDX %x myoutDI %x myoutSI %x usSmapiOK %x\n",
+		myoutAX, myoutBX, myoutCX, myoutDX, myoutDI, myoutSI,
+		usSmapiOK);
+	*outAX = myoutAX;
+	*outBX = myoutBX;
+	*outCX = myoutCX;
+	*outDX = myoutDX;
+	*outDI = myoutDI;
+	*outSI = myoutSI;
+
+	retval = (usSmapiOK == 1) ? 0 : -EIO;
+	PRINTK_2(TRACE_SMAPI, "smapi::smapi_request exit retval %x\n", retval);
+	return retval;
+}
+
+
+int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings)
+{
+	int bRC = -EIO;
+	unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
+	unsigned short ausDspBases[] = { 0x0030, 0x4E30, 0x8E30, 0xCE30, 0x0130, 0x0350, 0x0070, 0x0DB0 };
+	unsigned short ausUartBases[] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 };
+	unsigned short numDspBases = 8;
+	unsigned short numUartBases = 4;
+
+	PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg entry\n");
+
+	bRC = smapi_request(0x1802, 0x0000, 0, 0,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Error: Could not get DSP Settings. Aborting.\n");
+		return bRC;
+	}
+
+	PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
+
+	pSettings->bDSPPresent = ((usBX & 0x0100) != 0);
+	pSettings->bDSPEnabled = ((usCX & 0x0001) != 0);
+	pSettings->usDspIRQ = usSI & 0x00FF;
+	pSettings->usDspDMA = (usSI & 0xFF00) >> 8;
+	if ((usDI & 0x00FF) < numDspBases) {
+		pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF];
+	} else {
+		pSettings->usDspBaseIO = 0;
+	}
+	PRINTK_6(TRACE_SMAPI,
+		"smapi::smapi_query_DSP_cfg get DSP Settings bDSPPresent %x bDSPEnabled %x usDspIRQ %x usDspDMA %x usDspBaseIO %x\n",
+		pSettings->bDSPPresent, pSettings->bDSPEnabled,
+		pSettings->usDspIRQ, pSettings->usDspDMA,
+		pSettings->usDspBaseIO);
+
+	/* check for illegal values */
+	if ( pSettings->usDspBaseIO == 0 ) 
+		PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP base I/O address is 0\n");
+	if ( pSettings->usDspIRQ == 0 )
+		PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: DSP IRQ line is 0\n");
+
+	bRC = smapi_request(0x1804, 0x0000, 0, 0,
+	   	&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) {
+		PRINTK_ERROR("smapi::smapi_query_DSP_cfg: Error: Could not get DSP modem settings. Aborting.\n");
+		return bRC;
+	} 
+
+	PRINTK_1(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg, smapi_request OK\n");
+
+	pSettings->bModemEnabled = ((usCX & 0x0001) != 0);
+	pSettings->usUartIRQ = usSI & 0x000F;
+	if (((usSI & 0xFF00) >> 8) < numUartBases) {
+		pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8];
+	} else {
+		pSettings->usUartBaseIO = 0;
+	}
+
+	PRINTK_4(TRACE_SMAPI,
+		"smapi::smapi_query_DSP_cfg get DSP modem settings bModemEnabled %x usUartIRQ %x usUartBaseIO %x\n",
+		pSettings->bModemEnabled,
+		pSettings->usUartIRQ,
+		pSettings->usUartBaseIO);
+
+	/* check for illegal values */
+	if ( pSettings->usUartBaseIO == 0 ) 
+		PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART base I/O address is 0\n");
+	if ( pSettings->usUartIRQ == 0 )
+		PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_query_DSP_cfg: Worry: UART IRQ line is 0\n");
+
+	PRINTK_2(TRACE_SMAPI, "smapi::smapi_query_DSP_cfg exit bRC %x\n", bRC);
+
+	return bRC;
+}
+
+
+int smapi_set_DSP_cfg(void)
+{
+	int bRC = -EIO;
+	int i;
+	unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
+	unsigned short ausDspBases[] = { 0x0030, 0x4E30, 0x8E30, 0xCE30, 0x0130, 0x0350, 0x0070, 0x0DB0 };
+	unsigned short ausUartBases[] = { 0x03F8, 0x02F8, 0x03E8, 0x02E8 };
+	unsigned short ausDspIrqs[] = { 5, 7, 10, 11, 15 };
+	unsigned short ausUartIrqs[] = { 3, 4 };
+
+	unsigned short numDspBases = 8;
+	unsigned short numUartBases = 4;
+	unsigned short numDspIrqs = 5;
+	unsigned short numUartIrqs = 2;
+	unsigned short dspio_index = 0, uartio_index = 0;
+
+	PRINTK_5(TRACE_SMAPI,
+		"smapi::smapi_set_DSP_cfg entry mwave_3780i_irq %x mwave_3780i_io %x mwave_uart_irq %x mwave_uart_io %x\n",
+		mwave_3780i_irq, mwave_3780i_io, mwave_uart_irq, mwave_uart_io);
+
+	if (mwave_3780i_io) {
+		for (i = 0; i < numDspBases; i++) {
+			if (mwave_3780i_io == ausDspBases[i])
+				break;
+		}
+		if (i == numDspBases) {
+			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_io address %x. Aborting.\n", mwave_3780i_io);
+			return bRC;
+		}
+		dspio_index = i;
+	}
+
+	if (mwave_3780i_irq) {
+		for (i = 0; i < numDspIrqs; i++) {
+			if (mwave_3780i_irq == ausDspIrqs[i])
+				break;
+		}
+		if (i == numDspIrqs) {
+			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_3780i_irq %x. Aborting.\n", mwave_3780i_irq);
+			return bRC;
+		}
+	}
+
+	if (mwave_uart_io) {
+		for (i = 0; i < numUartBases; i++) {
+			if (mwave_uart_io == ausUartBases[i])
+				break;
+		}
+		if (i == numUartBases) {
+			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_io address %x. Aborting.\n", mwave_uart_io);
+			return bRC;
+		}
+		uartio_index = i;
+	}
+
+
+	if (mwave_uart_irq) {
+		for (i = 0; i < numUartIrqs; i++) {
+			if (mwave_uart_irq == ausUartIrqs[i])
+				break;
+		}
+		if (i == numUartIrqs) {
+			PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg: Error: Invalid mwave_uart_irq %x. Aborting.\n", mwave_uart_irq);
+			return bRC;
+		}
+	}
+
+	if (mwave_uart_irq || mwave_uart_io) {
+
+		/* Check serial port A */
+		bRC = smapi_request(0x1402, 0x0000, 0, 0,
+			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+		if (bRC) goto exit_smapi_request_error;
+		/* bRC == 0 */
+		if (usBX & 0x0100) {	/* serial port A is present */
+			if (usCX & 1) {	/* serial port is enabled */
+				if ((usSI & 0xFF) == mwave_uart_irq) {
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_ERROR(KERN_ERR_MWAVE
+#else
+					PRINTK_3(TRACE_SMAPI,
+#endif
+						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_1(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+					bRC = smapi_request(0x1403, 0x0100, 0, usSI,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1402, 0x0000, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+#else
+					goto exit_conflict;
+#endif
+				} else {
+					if ((usSI >> 8) == uartio_index) {
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+						PRINTK_ERROR(KERN_ERR_MWAVE
+#else
+						PRINTK_3(TRACE_SMAPI,
+#endif
+							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index);
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+						PRINTK_1(TRACE_SMAPI,
+							"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+						bRC = smapi_request (0x1403, 0x0100, 0, usSI,
+							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+						if (bRC) goto exit_smapi_request_error;
+						bRC = smapi_request (0x1402, 0x0000, 0, 0,
+							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+						if (bRC) goto exit_smapi_request_error;
+#else
+						goto exit_conflict;
+#endif
+					}
+				}
+			}
+		}
+
+		/* Check serial port B */
+		bRC = smapi_request(0x1404, 0x0000, 0, 0,
+			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+		if (bRC) goto exit_smapi_request_error;
+		/* bRC == 0 */
+		if (usBX & 0x0100) {	/* serial port B is present */
+			if (usCX & 1) {	/* serial port is enabled */
+				if ((usSI & 0xFF) == mwave_uart_irq) {
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_ERROR(KERN_ERR_MWAVE
+#else
+					PRINTK_3(TRACE_SMAPI,
+#endif
+						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_1(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+					bRC = smapi_request(0x1405, 0x0100, 0, usSI,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1404, 0x0000, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+#else
+					goto exit_conflict;
+#endif
+				} else {
+					if ((usSI >> 8) == uartio_index) {
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+						PRINTK_ERROR(KERN_ERR_MWAVE
+#else
+						PRINTK_3(TRACE_SMAPI,
+#endif
+							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index);
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+						PRINTK_1 (TRACE_SMAPI,
+						    "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+						bRC = smapi_request (0x1405, 0x0100, 0, usSI,
+							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+						if (bRC) goto exit_smapi_request_error;
+						bRC = smapi_request (0x1404, 0x0000, 0, 0,
+							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+						if (bRC) goto exit_smapi_request_error;
+#else
+						goto exit_conflict;
+#endif
+					}
+				}
+			}
+		}
+
+		/* Check IR port */
+		bRC = smapi_request(0x1700, 0x0000, 0, 0,
+			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+		if (bRC) goto exit_smapi_request_error;
+		bRC = smapi_request(0x1704, 0x0000, 0, 0,
+			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+		if (bRC) goto exit_smapi_request_error;
+		/* bRC == 0 */
+		if ((usCX & 0xff) == mwave_uart_irq) {	/* serial port is enabled */
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+			PRINTK_ERROR(KERN_ERR_MWAVE
+#else
+			PRINTK_3(TRACE_SMAPI,
+#endif
+				"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+			PRINTK_1(TRACE_SMAPI,
+				"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
+			bRC = smapi_request(0x1701, 0x0100, 0, 0,
+				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+			if (bRC) goto exit_smapi_request_error;
+			bRC = smapi_request(0x1700, 0, 0, 0,
+				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+			if (bRC) goto exit_smapi_request_error;
+			bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
+				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+			if (bRC) goto exit_smapi_request_error;
+			bRC = smapi_request(0x1704, 0x0000, 0, 0,
+				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+			if (bRC) goto exit_smapi_request_error;
+#else
+			goto exit_conflict;
+#endif
+		} else {
+			if ((usSI & 0xff) == uartio_index) {
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+				PRINTK_ERROR(KERN_ERR_MWAVE
+#else
+				PRINTK_3(TRACE_SMAPI,
+#endif
+					"smapi::smapi_set_DSP_cfg: IR port base I/O address index %x conflicts with uartio_index %x\n", usSI & 0xff, uartio_index);
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+				PRINTK_1(TRACE_SMAPI,
+					"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
+				bRC = smapi_request(0x1701, 0x0100, 0, 0,
+					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+				if (bRC) goto exit_smapi_request_error;
+				bRC = smapi_request(0x1700, 0, 0, 0,
+					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+				if (bRC) goto exit_smapi_request_error;
+				bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
+					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+				if (bRC) goto exit_smapi_request_error;
+				bRC = smapi_request(0x1704, 0x0000, 0, 0,
+					&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+				if (bRC) goto exit_smapi_request_error;
+#else
+				goto exit_conflict;
+#endif
+			}
+		}
+	}
+
+	bRC = smapi_request(0x1802, 0x0000, 0, 0,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) goto exit_smapi_request_error;
+
+	if (mwave_3780i_io) {
+		usDI = dspio_index;;
+	}
+	if (mwave_3780i_irq) {
+		usSI = (usSI & 0xff00) | mwave_3780i_irq;
+	}
+
+	bRC = smapi_request(0x1803, 0x0101, usDI, usSI,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) goto exit_smapi_request_error;
+
+	bRC = smapi_request(0x1804, 0x0000, 0, 0,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) goto exit_smapi_request_error;
+
+	if (mwave_uart_io) {
+		usSI = (usSI & 0x00ff) | (uartio_index << 8);
+	}
+	if (mwave_uart_irq) {
+		usSI = (usSI & 0xff00) | mwave_uart_irq;
+	}
+	bRC = smapi_request(0x1805, 0x0101, 0, usSI,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) goto exit_smapi_request_error;
+
+	bRC = smapi_request(0x1802, 0x0000, 0, 0,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) goto exit_smapi_request_error;
+
+	bRC = smapi_request(0x1804, 0x0000, 0, 0,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+	if (bRC) goto exit_smapi_request_error;
+
+/* normal exit: */
+	PRINTK_1(TRACE_SMAPI, "smapi::smapi_set_DSP_cfg exit\n");
+	return 0;
+
+exit_conflict:
+	/* Message has already been printed */
+	return -EIO;
+
+exit_smapi_request_error:
+	PRINTK_ERROR(KERN_ERR_MWAVE "smapi::smapi_set_DSP_cfg exit on smapi_request error bRC %x\n", bRC);
+	return bRC;
+}
+
+
+int smapi_set_DSP_power_state(BOOLEAN bOn)
+{
+	int bRC = -EIO;
+	unsigned short usAX, usBX, usCX, usDX, usDI, usSI;
+	unsigned short usPowerFunction;
+
+	PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state entry bOn %x\n", bOn);
+
+	usPowerFunction = (bOn) ? 1 : 0;
+
+	bRC = smapi_request(0x4901, 0x0000, 0, usPowerFunction,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+
+	PRINTK_2(TRACE_SMAPI, "smapi::smapi_set_DSP_power_state exit bRC %x\n", bRC);
+
+	return bRC;
+}
+
+
+int SmapiQuerySystemID(void)
+{
+	int bRC = -EIO;
+	unsigned short usAX = 0xffff, usBX = 0xffff, usCX = 0xffff,
+		usDX = 0xffff, usDI = 0xffff, usSI = 0xffff;
+
+	printk("smapi::SmapiQUerySystemID entry\n");
+	bRC = smapi_request(0x0000, 0, 0, 0,
+		&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+
+	if (bRC == 0) {
+		printk("AX=%x, BX=%x, CX=%x, DX=%x, DI=%x, SI=%x\n",
+			usAX, usBX, usCX, usDX, usDI, usSI);
+	} else {
+		printk("smapi::SmapiQuerySystemID smapi_request error\n");
+	}
+
+	return bRC;
+}
+
+
+int smapi_init(void)
+{
+	int retval = -EIO;
+	unsigned short usSmapiID = 0;
+	unsigned long flags;
+
+	PRINTK_1(TRACE_SMAPI, "smapi::smapi_init entry\n");
+
+	spin_lock_irqsave(&rtc_lock, flags);
+	usSmapiID = CMOS_READ(0x7C);
+	usSmapiID |= (CMOS_READ(0x7D) << 8);
+	spin_unlock_irqrestore(&rtc_lock, flags);
+	PRINTK_2(TRACE_SMAPI, "smapi::smapi_init usSmapiID %x\n", usSmapiID);
+
+	if (usSmapiID == 0x5349) {
+		spin_lock_irqsave(&rtc_lock, flags);
+		g_usSmapiPort = CMOS_READ(0x7E);
+		g_usSmapiPort |= (CMOS_READ(0x7F) << 8);
+		spin_unlock_irqrestore(&rtc_lock, flags);
+		if (g_usSmapiPort == 0) {
+			PRINTK_ERROR("smapi::smapi_init, ERROR unable to read from SMAPI port\n");
+		} else {
+			PRINTK_2(TRACE_SMAPI,
+				"smapi::smapi_init, exit TRUE g_usSmapiPort %x\n",
+				g_usSmapiPort);
+			retval = 0;
+			//SmapiQuerySystemID();
+		}
+	} else {
+		PRINTK_ERROR("smapi::smapi_init, ERROR invalid usSmapiID\n");
+		retval = -ENXIO;
+	}
+
+	return retval;
+}
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/smapi.h linux/drivers/char/mwave/smapi.h
--- v2.4.10/linux/drivers/char/mwave/smapi.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/smapi.h	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,80 @@
+/*
+*
+* smapi.h -- declarations for SMAPI interface routines
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#ifndef _LINUX_SMAPI_H
+#define _LINUX_SMAPI_H
+
+#define TRUE 1
+#define FALSE 0
+#define BOOLEAN int
+
+typedef struct {
+	int bDSPPresent;
+	int bDSPEnabled;
+	int bModemEnabled;
+	int bMIDIEnabled;
+	int bSblstEnabled;
+	unsigned short usDspIRQ;
+	unsigned short usDspDMA;
+	unsigned short usDspBaseIO;
+	unsigned short usUartIRQ;
+	unsigned short usUartBaseIO;
+	unsigned short usMidiIRQ;
+	unsigned short usMidiBaseIO;
+	unsigned short usSndblstIRQ;
+	unsigned short usSndblstDMA;
+	unsigned short usSndblstBaseIO;
+} SMAPI_DSP_SETTINGS;
+
+int smapi_init(void);
+int smapi_query_DSP_cfg(SMAPI_DSP_SETTINGS * pSettings);
+int smapi_set_DSP_cfg(void);
+int smapi_set_DSP_power_state(BOOLEAN bOn);
+
+
+#endif
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/tp3780i.c linux/drivers/char/mwave/tp3780i.c
--- v2.4.10/linux/drivers/char/mwave/tp3780i.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/tp3780i.c	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,589 @@
+/*
+*
+* tp3780i.c -- board driver for 3780i on ThinkPads
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include "smapi.h"
+#include "mwavedd.h"
+#include "tp3780i.h"
+#include "3780i.h"
+#include "mwavepub.h"
+
+extern MWAVE_DEVICE_DATA mwave_s_mdd;
+
+static unsigned short s_ausThinkpadIrqToField[16] =
+	{ 0xFFFF, 0xFFFF, 0xFFFF, 0x0001, 0x0002, 0x0003, 0xFFFF, 0x0004,
+	0xFFFF, 0xFFFF, 0x0005, 0x0006, 0xFFFF, 0xFFFF, 0xFFFF, 0x0007 };
+static unsigned short s_ausThinkpadDmaToField[8] =
+	{ 0x0001, 0x0002, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0003, 0x0004 };
+static unsigned short s_numIrqs = 16, s_numDmas = 8;
+
+
+static void EnableSRAM(THINKPAD_BD_DATA * pBDData)
+{
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	DSP_GPIO_OUTPUT_DATA_15_8 rGpioOutputData;
+	DSP_GPIO_DRIVER_ENABLE_15_8 rGpioDriverEnable;
+	DSP_GPIO_MODE_15_8 rGpioMode;
+
+	PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM, entry\n");
+
+	MKWORD(rGpioMode) = ReadMsaCfg(DSP_GpioModeControl_15_8);
+	rGpioMode.GpioMode10 = 0;
+	WriteMsaCfg(DSP_GpioModeControl_15_8, MKWORD(rGpioMode));
+
+	MKWORD(rGpioDriverEnable) = 0;
+	rGpioDriverEnable.Enable10 = TRUE;
+	rGpioDriverEnable.Mask10 = TRUE;
+	WriteMsaCfg(DSP_GpioDriverEnable_15_8, MKWORD(rGpioDriverEnable));
+
+	MKWORD(rGpioOutputData) = 0;
+	rGpioOutputData.Latch10 = 0;
+	rGpioOutputData.Mask10 = TRUE;
+	WriteMsaCfg(DSP_GpioOutputData_15_8, MKWORD(rGpioOutputData));
+
+	PRINTK_1(TRACE_TP3780I, "tp3780i::EnableSRAM exit\n");
+}
+
+
+static void UartInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	PRINTK_3(TRACE_TP3780I,
+		"tp3780i::UartInterrupt entry irq %x dev_id %x\n", irq, (int) dev_id);
+}
+
+static void DspInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pDrvData->rBDData.rDspSettings;
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	unsigned short usIPCSource = 0, usIsolationMask, usPCNum;
+
+	PRINTK_3(TRACE_TP3780I,
+		"tp3780i::DspInterrupt entry irq %x dev_id %x\n", irq, (int) dev_id);
+
+	if (dsp3780I_GetIPCSource(usDspBaseIO, &usIPCSource) == 0) {
+		PRINTK_2(TRACE_TP3780I,
+			"tp3780i::DspInterrupt, return from dsp3780i_GetIPCSource, usIPCSource %x\n",
+			usIPCSource);
+		usIsolationMask = 1;
+		for (usPCNum = 1; usPCNum <= 16; usPCNum++) {
+			if (usIPCSource & usIsolationMask) {
+				usIPCSource &= ~usIsolationMask;
+				PRINTK_3(TRACE_TP3780I,
+					"tp3780i::DspInterrupt usPCNum %x usIPCSource %x\n",
+					usPCNum, usIPCSource);
+				if (pDrvData->IPCs[usPCNum - 1].usIntCount == 0) {
+					pDrvData->IPCs[usPCNum - 1].usIntCount = 1;
+				}
+				PRINTK_2(TRACE_TP3780I,
+					"tp3780i::DspInterrupt usIntCount %x\n",
+					pDrvData->IPCs[usPCNum - 1].usIntCount);
+				if (pDrvData->IPCs[usPCNum - 1].bIsEnabled == TRUE) {
+					PRINTK_2(TRACE_TP3780I,
+						"tp3780i::DspInterrupt, waking up usPCNum %x\n",
+						usPCNum - 1);
+					wake_up_interruptible(&pDrvData->IPCs[usPCNum - 1].ipc_wait_queue);
+				} else {
+					PRINTK_2(TRACE_TP3780I,
+						"tp3780i::DspInterrupt, no one waiting for IPC %x\n",
+						usPCNum - 1);
+				}
+			}
+			if (usIPCSource == 0)
+				break;
+			/* try next IPC */
+			usIsolationMask = usIsolationMask << 1;
+		}
+	} else {
+		PRINTK_1(TRACE_TP3780I,
+			"tp3780i::DspInterrupt, return false from dsp3780i_GetIPCSource\n");
+	}
+	PRINTK_1(TRACE_TP3780I, "tp3780i::DspInterrupt exit\n");
+}
+
+
+int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData entry pBDData %p\n", pBDData);
+
+	pBDData->bDSPEnabled = FALSE;
+	pSettings->bInterruptClaimed = FALSE;
+
+	retval = smapi_init();
+	if (retval) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_InitializeBoardData: Error: SMAPI is not available on this machine\n");
+	} else {
+		if (mwave_3780i_irq || mwave_3780i_io || mwave_uart_irq || mwave_uart_io) {
+			retval = smapi_set_DSP_cfg();
+		}
+	}
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_InitializeBoardData exit retval %x\n", retval);
+
+	return retval;
+}
+
+int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData)
+{
+	int retval = 0;
+
+	PRINTK_2(TRACE_TP3780I,
+		"tp3780i::tp3780I_Cleanup entry and exit pBDData %p\n", pBDData);
+
+	return retval;
+}
+
+int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData)
+{
+	SMAPI_DSP_SETTINGS rSmapiInfo;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+
+	PRINTK_2(TRACE_TP3780I,
+		"tp3780i::tp3780I_CalcResources entry pBDData %p\n", pBDData);
+
+	if (smapi_query_DSP_cfg(&rSmapiInfo)) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Could not query DSP config. Aborting.\n");
+		return -EIO;
+	}
+
+	/* Sanity check */
+	if (
+		( rSmapiInfo.usDspIRQ == 0 )
+		|| ( rSmapiInfo.usDspBaseIO ==  0 )
+		|| ( rSmapiInfo.usUartIRQ ==  0 )
+		|| ( rSmapiInfo.usUartBaseIO ==  0 )
+	) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_CalcResources: Error: Illegal resource setting. Aborting.\n");
+		return -EIO;
+	}
+
+	pSettings->bDSPEnabled = (rSmapiInfo.bDSPEnabled && rSmapiInfo.bDSPPresent);
+	pSettings->bModemEnabled = rSmapiInfo.bModemEnabled;
+	pSettings->usDspIrq = rSmapiInfo.usDspIRQ;
+	pSettings->usDspDma = rSmapiInfo.usDspDMA;
+	pSettings->usDspBaseIO = rSmapiInfo.usDspBaseIO;
+	pSettings->usUartIrq = rSmapiInfo.usUartIRQ;
+	pSettings->usUartBaseIO = rSmapiInfo.usUartBaseIO;
+
+	pSettings->uDStoreSize = TP_ABILITIES_DATA_SIZE;
+	pSettings->uIStoreSize = TP_ABILITIES_INST_SIZE;
+	pSettings->uIps = TP_ABILITIES_INTS_PER_SEC;
+
+	if (pSettings->bDSPEnabled && pSettings->bModemEnabled && pSettings->usDspIrq == pSettings->usUartIrq) {
+		pBDData->bShareDspIrq = pBDData->bShareUartIrq = 1;
+	} else {
+		pBDData->bShareDspIrq = pBDData->bShareUartIrq = 0;
+	}
+
+	PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_CalcResources exit\n");
+
+	return 0;
+}
+
+
+int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	struct resource *pres;
+#endif
+
+	PRINTK_2(TRACE_TP3780I,
+		"tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+	pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
+	if ( pres == NULL ) retval = -EIO;
+#else
+	retval = check_region(pSettings->usDspBaseIO, 16);
+	if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
+#endif
+	if (retval) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO);
+		retval = -EIO;
+	}
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ClaimResources exit retval %x\n", retval);
+
+	return retval;
+}
+
+int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+
+	PRINTK_2(TRACE_TP3780I,
+		"tp3780i::tp3780I_ReleaseResources entry pBDData %p\n", pBDData);
+
+	release_region(pSettings->usDspBaseIO & (~3), 16);
+
+	if (pSettings->bInterruptClaimed) {
+		free_irq(pSettings->usDspIrq, 0);
+		pSettings->bInterruptClaimed = FALSE;
+	}
+
+	PRINTK_2(TRACE_TP3780I,
+		"tp3780i::tp3780I_ReleaseResources exit retval %x\n", retval);
+
+	return retval;
+}
+
+
+
+int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
+{
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+	BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE;
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);
+
+	if (pBDData->bDSPEnabled) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: DSP already enabled!\n");
+		goto exit_cleanup;
+	}
+
+	if (!pSettings->bDSPEnabled) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780::tp3780I_EnableDSP: Error: pSettings->bDSPEnabled not set\n");
+		goto exit_cleanup;
+	}
+
+	if (
+		(pSettings->usDspIrq >= s_numIrqs)
+		|| (pSettings->usDspDma >= s_numDmas)
+		|| (s_ausThinkpadIrqToField[pSettings->usDspIrq] == 0xFFFF)
+		|| (s_ausThinkpadDmaToField[pSettings->usDspDma] == 0xFFFF)
+	) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: invalid irq %x\n", pSettings->usDspIrq);
+		goto exit_cleanup;
+	}
+
+	if (
+		((pSettings->usDspBaseIO & 0xF00F) != 0)
+		|| (pSettings->usDspBaseIO & 0x0FF0) == 0
+	) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid DSP base I/O address %x\n", pSettings->usDspBaseIO);
+		goto exit_cleanup;
+	}
+
+	if (pSettings->bModemEnabled) {
+		if (
+			pSettings->usUartIrq >= s_numIrqs
+			|| s_ausThinkpadIrqToField[pSettings->usUartIrq] == 0xFFFF
+		) {
+			PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Invalid UART IRQ %x\n", pSettings->usUartIrq);
+			goto exit_cleanup;
+		}
+		switch (pSettings->usUartBaseIO) {
+			case 0x03F8:
+			case 0x02F8:
+			case 0x03E8:
+			case 0x02E8:
+				break;
+
+			default:
+				PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Invalid UART base I/O address %x\n", pSettings->usUartBaseIO);
+				goto exit_cleanup;
+		}
+	}
+
+	pSettings->bDspIrqActiveLow = pSettings->bDspIrqPulse = TRUE;
+	pSettings->bUartIrqActiveLow = pSettings->bUartIrqPulse = TRUE;
+
+	if (pBDData->bShareDspIrq) {
+		pSettings->bDspIrqActiveLow = FALSE;
+	}
+	if (pBDData->bShareUartIrq) {
+		pSettings->bUartIrqActiveLow = FALSE;
+	}
+
+	pSettings->usNumTransfers = TP_CFG_NumTransfers;
+	pSettings->usReRequest = TP_CFG_RerequestTimer;
+	pSettings->bEnableMEMCS16 = TP_CFG_MEMCS16;
+	pSettings->usIsaMemCmdWidth = TP_CFG_IsaMemCmdWidth;
+	pSettings->bGateIOCHRDY = TP_CFG_GateIOCHRDY;
+	pSettings->bEnablePwrMgmt = TP_CFG_EnablePwrMgmt;
+	pSettings->usHBusTimerLoadValue = TP_CFG_HBusTimerValue;
+	pSettings->bDisableLBusTimeout = TP_CFG_DisableLBusTimeout;
+	pSettings->usN_Divisor = TP_CFG_N_Divisor;
+	pSettings->usM_Multiplier = TP_CFG_M_Multiplier;
+	pSettings->bPllBypass = TP_CFG_PllBypass;
+	pSettings->usChipletEnable = TP_CFG_ChipletEnable;
+
+	if (request_irq(pSettings->usUartIrq, &UartInterrupt, 0, "mwave_uart", 0)) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: Could not get UART IRQ %x\n", pSettings->usUartIrq);
+		goto exit_cleanup;
+	} else {		/* no conflict just release */
+		free_irq(pSettings->usUartIrq, 0);
+	}
+
+	if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", 0)) {
+		PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: Could not get 3780i IRQ %x\n", pSettings->usDspIrq);
+		goto exit_cleanup;
+	} else {
+		PRINTK_3(TRACE_TP3780I,
+			"tp3780i::tp3780I_EnableDSP, got interrupt %x bShareDspIrq %x\n",
+			pSettings->usDspIrq, pBDData->bShareDspIrq);
+		bInterruptAllocated = TRUE;
+		pSettings->bInterruptClaimed = TRUE;
+	}
+
+	smapi_set_DSP_power_state(FALSE);
+	if (smapi_set_DSP_power_state(TRUE)) {
+		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_EnableDSP: Error: smapi_set_DSP_power_state(TRUE) failed\n");
+		goto exit_cleanup;
+	} else {
+		bDSPPoweredUp = TRUE;
+	}
+
+	if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
+		PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
+		goto exit_cleanup;
+	} else {
+		bDSPEnabled = TRUE;
+	}
+
+	EnableSRAM(pBDData);
+
+	pBDData->bDSPEnabled = TRUE;
+
+	PRINTK_1(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP exit\n");
+
+	return 0;
+
+exit_cleanup:
+	PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
+	if (bDSPEnabled)
+		dsp3780I_DisableDSP(pSettings);
+	if (bDSPPoweredUp)
+		smapi_set_DSP_power_state(FALSE);
+	if (bInterruptAllocated) {
+		free_irq(pSettings->usDspIrq, 0);
+		pSettings->bInterruptClaimed = FALSE;
+	}
+	return -EIO;
+}
+
+
+int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP entry pBDData %p\n", pBDData);
+
+	if (pBDData->bDSPEnabled) {
+		dsp3780I_DisableDSP(&pBDData->rDspSettings);
+		if (pSettings->bInterruptClaimed) {
+			free_irq(pSettings->usDspIrq, 0);
+			pSettings->bInterruptClaimed = FALSE;
+		}
+		smapi_set_DSP_power_state(FALSE);
+		pBDData->bDSPEnabled = FALSE;
+	}
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_DisableDSP exit retval %x\n", retval);
+
+	return retval;
+}
+
+
+int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP entry pBDData %p\n",
+		pBDData);
+
+	if (dsp3780I_Reset(pSettings) == 0) {
+		EnableSRAM(pBDData);
+	} else {
+		retval = -EIO;
+	}
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ResetDSP exit retval %x\n", retval);
+
+	return retval;
+}
+
+
+int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP entry pBDData %p\n", pBDData);
+
+	if (dsp3780I_Run(pSettings) == 0) {
+		// @BUG @TBD EnableSRAM(pBDData);
+	} else {
+		retval = -EIO;
+	}
+
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_StartDSP exit retval %x\n", retval);
+
+	return retval;
+}
+
+
+int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities)
+{
+	int retval = 0;
+
+	PRINTK_2(TRACE_TP3780I,
+		"tp3780i::tp3780I_QueryAbilities entry pBDData %p\n", pBDData);
+
+	/* fill out standard constant fields */
+	pAbilities->instr_per_sec = pBDData->rDspSettings.uIps;
+	pAbilities->data_size = pBDData->rDspSettings.uDStoreSize;
+	pAbilities->inst_size = pBDData->rDspSettings.uIStoreSize;
+	pAbilities->bus_dma_bw = pBDData->rDspSettings.uDmaBandwidth;
+
+	/* fill out dynamically determined fields */
+	pAbilities->component_list[0] = 0x00010000 | MW_ADC_MASK;
+	pAbilities->component_list[1] = 0x00010000 | MW_ACI_MASK;
+	pAbilities->component_list[2] = 0x00010000 | MW_AIC1_MASK;
+	pAbilities->component_list[3] = 0x00010000 | MW_AIC2_MASK;
+	pAbilities->component_list[4] = 0x00010000 | MW_CDDAC_MASK;
+	pAbilities->component_list[5] = 0x00010000 | MW_MIDI_MASK;
+	pAbilities->component_list[6] = 0x00010000 | MW_UART_MASK;
+	pAbilities->component_count = 7;
+
+	/* Fill out Mwave OS and BIOS task names */
+
+	memcpy(pAbilities->mwave_os_name, TP_ABILITIES_MWAVEOS_NAME,
+		sizeof(TP_ABILITIES_MWAVEOS_NAME));
+	memcpy(pAbilities->bios_task_name, TP_ABILITIES_BIOSTASK_NAME,
+		sizeof(TP_ABILITIES_BIOSTASK_NAME));
+
+	PRINTK_1(TRACE_TP3780I,
+		"tp3780i::tp3780I_QueryAbilities exit retval=SUCCESSFUL\n");
+
+	return retval;
+}
+
+int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
+                               void *pvBuffer, unsigned int uCount,
+                               unsigned long ulDSPAddr)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	BOOLEAN bRC = 0;
+
+	PRINTK_6(TRACE_TP3780I,
+		"tp3780i::tp3780I_ReadWriteDspDStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n",
+		pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr);
+
+	if (pBDData->bDSPEnabled) {
+		switch (uOpcode) {
+		case IOCTL_MW_READ_DATA:
+			bRC = dsp3780I_ReadDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
+			break;
+
+		case IOCTL_MW_READCLEAR_DATA:
+			bRC = dsp3780I_ReadAndClearDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
+			break;
+
+		case IOCTL_MW_WRITE_DATA:
+			bRC = dsp3780I_WriteDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
+			break;
+		}
+	}
+
+	retval = (bRC) ? -EIO : 0;
+	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_ReadWriteDspDStore exit retval %x\n", retval);
+
+	return retval;
+}
+
+
+int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
+                               void *pvBuffer, unsigned int uCount,
+                               unsigned long ulDSPAddr)
+{
+	int retval = 0;
+	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
+	unsigned short usDspBaseIO = pSettings->usDspBaseIO;
+	BOOLEAN bRC = 0;
+
+	PRINTK_6(TRACE_TP3780I,
+		"tp3780i::tp3780I_ReadWriteDspIStore entry pBDData %p, uOpcode %x, pvBuffer %p, uCount %x, ulDSPAddr %lx\n",
+		pBDData, uOpcode, pvBuffer, uCount, ulDSPAddr);
+
+	if (pBDData->bDSPEnabled) {
+		switch (uOpcode) {
+		case IOCTL_MW_READ_INST:
+			bRC = dsp3780I_ReadIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
+			break;
+
+		case IOCTL_MW_WRITE_INST:
+			bRC = dsp3780I_WriteIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr);
+			break;
+		}
+	}
+
+	retval = (bRC) ? -EIO : 0;
+
+	PRINTK_2(TRACE_TP3780I,
+		"tp3780i::tp3780I_ReadWriteDspIStore exit retval %x\n", retval);
+
+	return retval;
+}
+
diff -u --recursive --new-file v2.4.10/linux/drivers/char/mwave/tp3780i.h linux/drivers/char/mwave/tp3780i.h
--- v2.4.10/linux/drivers/char/mwave/tp3780i.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/tp3780i.h	Sun Sep 30 12:26:05 2001
@@ -0,0 +1,103 @@
+/*
+*
+* tp3780i.h -- declarations for tp3780i.c
+*
+*
+* Written By: Mike Sullivan IBM Corporation
+*
+* Copyright (C) 1999 IBM Corporation
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* NO WARRANTY
+* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+* solely responsible for determining the appropriateness of using and
+* distributing the Program and assumes all risks associated with its
+* exercise of rights under this Agreement, including but not limited to
+* the risks and costs of program errors, damage to or loss of data,
+* programs or equipment, and unavailability or interruption of operations.
+*
+* DISCLAIMER OF LIABILITY
+* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*
+* 10/23/2000 - Alpha Release
+*	First release to the public
+*/
+
+#ifndef _LINUX_TP3780I_H
+#define _LINUX_TP3780I_H
+
+#include <asm/io.h>
+#include "mwavepub.h"
+
+
+/* DSP abilities constants for 3780i based Thinkpads */
+#define TP_ABILITIES_INTS_PER_SEC       39160800
+#define TP_ABILITIES_DATA_SIZE          32768
+#define TP_ABILITIES_INST_SIZE          32768
+#define TP_ABILITIES_MWAVEOS_NAME       "mwaveos0700.dsp"
+#define TP_ABILITIES_BIOSTASK_NAME      "mwbio701.dsp"
+
+
+/* DSP configuration values for 3780i based Thinkpads */
+#define TP_CFG_NumTransfers     3	/* 16 transfers */
+#define TP_CFG_RerequestTimer   1	/* 2 usec */
+#define TP_CFG_MEMCS16          0	/* Disabled, 16-bit memory assumed */
+#define TP_CFG_IsaMemCmdWidth   3	/* 295 nsec (16-bit) */
+#define TP_CFG_GateIOCHRDY      0	/* No IOCHRDY gating */
+#define TP_CFG_EnablePwrMgmt    1	/* Enable low poser suspend/resume */
+#define TP_CFG_HBusTimerValue 255	/* HBus timer load value */
+#define TP_CFG_DisableLBusTimeout 0	/* Enable LBus timeout */
+#define TP_CFG_N_Divisor       32	/* Clock = 39.1608 Mhz */
+#define TP_CFG_M_Multiplier    37	/* " */
+#define TP_CFG_PllBypass        0	/* dont bypass */
+#define TP_CFG_ChipletEnable 0xFFFF	/* Enable all chiplets */
+
+typedef struct {
+	int bDSPEnabled;
+	int bShareDspIrq;
+	int bShareUartIrq;
+	DSP_3780I_CONFIG_SETTINGS rDspSettings;
+} THINKPAD_BD_DATA;
+
+int tp3780I_InitializeBoardData(THINKPAD_BD_DATA * pBDData);
+int tp3780I_CalcResources(THINKPAD_BD_DATA * pBDData);
+int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData);
+int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData);
+int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData);
+int tp3780I_DisableDSP(THINKPAD_BD_DATA * pBDData);
+int tp3780I_ResetDSP(THINKPAD_BD_DATA * pBDData);
+int tp3780I_StartDSP(THINKPAD_BD_DATA * pBDData);
+int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities);
+int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData);
+int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
+                               void *pvBuffer, unsigned int uCount,
+                               unsigned long ulDSPAddr);
+int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
+                               void *pvBuffer, unsigned int uCount,
+                               unsigned long ulDSPAddr);
+
+
+#endif
diff -u --recursive --new-file v2.4.10/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v2.4.10/linux/drivers/char/softdog.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/softdog.c	Sun Sep 30 12:26:05 2001
@@ -46,6 +46,7 @@
 static int soft_margin = TIMER_MARGIN;	/* in seconds */
 
 MODULE_PARM(soft_margin,"i");
+MODULE_LICENSE("GPL");
 
 /*
  *	Our timer
diff -u --recursive --new-file v2.4.10/linux/drivers/char/sysrq.c linux/drivers/char/sysrq.c
--- v2.4.10/linux/drivers/char/sysrq.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/char/sysrq.c	Tue Oct  2 09:20:37 2001
@@ -47,13 +47,13 @@
 	int i;
 	i = key - '0';
 	console_loglevel = 7;
-	printk("%d\n", i);
+	printk("Loglevel set to %d\n", i);
 	console_loglevel = i;
 }	
 static struct sysrq_key_op sysrq_loglevel_op = {
 	handler:	sysrq_handle_loglevel,
 	help_msg:	"loglevel0-8",
-	action_msg:	"Loglevel set to ",
+	action_msg:	"Changing Loglevel",
 };
 
 
@@ -68,7 +68,7 @@
 static struct sysrq_key_op sysrq_SAK_op = {
 	handler:	sysrq_handle_SAK,
 	help_msg:	"saK",
-	action_msg:	"SAK\n",
+	action_msg:	"SAK",
 };
 #endif
 
@@ -82,7 +82,7 @@
 static struct sysrq_key_op sysrq_unraw_op = {
 	handler:	sysrq_handle_unraw,
 	help_msg:	"unRaw",
-	action_msg:	"Keyboard mode set to XLATE\n",
+	action_msg:	"Keyboard mode set to XLATE",
 };
 
 
@@ -94,7 +94,7 @@
 static struct sysrq_key_op sysrq_reboot_op = {
 	handler:	sysrq_handle_reboot,
 	help_msg:	"reBoot",
-	action_msg:	"Resetting\n",
+	action_msg:	"Resetting",
 };
 
 
@@ -225,7 +225,7 @@
 static struct sysrq_key_op sysrq_sync_op = {
 	handler:	sysrq_handle_sync,
 	help_msg:	"Sync",
-	action_msg:	"Emergency Sync\n",
+	action_msg:	"Emergency Sync",
 };
 
 static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs,
@@ -236,7 +236,7 @@
 static struct sysrq_key_op sysrq_mountro_op = {
 	handler:	sysrq_handle_mountro,
 	help_msg:	"Unmount",
-	action_msg:	"Emergency Remount R/0\n",
+	action_msg:	"Emergency Remount R/O",
 };
 
 /* END SYNC SYSRQ HANDLERS BLOCK */
@@ -252,7 +252,7 @@
 static struct sysrq_key_op sysrq_showregs_op = {
 	handler:	sysrq_handle_showregs,
 	help_msg:	"showPc",
-	action_msg:	"Show Regs\n",
+	action_msg:	"Show Regs",
 };
 
 
@@ -263,7 +263,7 @@
 static struct sysrq_key_op sysrq_showstate_op = {
 	handler:	sysrq_handle_showstate,
 	help_msg:	"showTasks",
-	action_msg:	"Show State\n",
+	action_msg:	"Show State",
 };
 
 
@@ -274,7 +274,7 @@
 static struct sysrq_key_op sysrq_showmem_op = {
 	handler:	sysrq_handle_showmem,
 	help_msg:	"showMem",
-	action_msg:	"Show Memory\n",
+	action_msg:	"Show Memory",
 };
 
 /* SHOW SYSRQ HANDLERS BLOCK */
@@ -307,7 +307,7 @@
 static struct sysrq_key_op sysrq_term_op = {
 	handler:	sysrq_handle_term,
 	help_msg:	"tErm",
-	action_msg:	"Terminate All Tasks\n",
+	action_msg:	"Terminate All Tasks",
 };
 
 static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
@@ -318,7 +318,7 @@
 static struct sysrq_key_op sysrq_kill_op = {
 	handler:	sysrq_handle_kill,
 	help_msg:	"kIll",
-	action_msg:	"Kill All Tasks\n",
+	action_msg:	"Kill All Tasks",
 };
 
 static void sysrq_handle_killall(int key, struct pt_regs *pt_regs,
@@ -329,7 +329,7 @@
 static struct sysrq_key_op sysrq_killall_op = {
 	handler:	sysrq_handle_killall,
 	help_msg:	"killalL",
-	action_msg:	"Kill All Tasks (even init)\n",
+	action_msg:	"Kill All Tasks (even init)",
 };
 
 /* END SIGNAL SYSRQ HANDLERS BLOCK */
@@ -462,8 +462,9 @@
 
         op_p = __sysrq_get_key_op(key);
         if (op_p) {
-                printk ("%s", op_p->action_msg);
-                op_p->handler(key, pt_regs, kbd, tty);
+		printk ("%s\n", op_p->action_msg);
+		console_loglevel = orig_log_level;
+		op_p->handler(key, pt_regs, kbd, tty);
 	} else {
 		printk("HELP : ");
 		/* Only print the help msg once per handler */
@@ -474,8 +475,8 @@
 				printk ("%s ", sysrq_key_table[i]->help_msg);
 		}
 		printk ("\n");
+		console_loglevel = orig_log_level;
 	}
-	console_loglevel = orig_log_level;
 }
 
 EXPORT_SYMBOL(handle_sysrq);
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-adap-ite.c linux/drivers/i2c/i2c-adap-ite.c
--- v2.4.10/linux/drivers/i2c/i2c-adap-ite.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/i2c/i2c-adap-ite.c	Sun Sep 30 12:26:05 2001
@@ -299,6 +299,7 @@
  */
 MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
 MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(base, "i");
 MODULE_PARM(irq, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-algo-bit.c linux/drivers/i2c/i2c-algo-bit.c
--- v2.4.10/linux/drivers/i2c/i2c-algo-bit.c	Tue Mar  6 19:44:34 2001
+++ linux/drivers/i2c/i2c-algo-bit.c	Sun Sep 30 12:26:05 2001
@@ -621,6 +621,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(bit_test, "i");
 MODULE_PARM(bit_scan, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-algo-ite.c linux/drivers/i2c/i2c-algo-ite.c
--- v2.4.10/linux/drivers/i2c/i2c-algo-ite.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/i2c/i2c-algo-ite.c	Sun Sep 30 12:26:05 2001
@@ -844,6 +844,7 @@
  */
 MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
 MODULE_DESCRIPTION("ITE iic algorithm");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(iic_test, "i");
 MODULE_PARM(iic_scan, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-algo-pcf.c linux/drivers/i2c/i2c-algo-pcf.c
--- v2.4.10/linux/drivers/i2c/i2c-algo-pcf.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2c/i2c-algo-pcf.c	Sun Sep 30 12:26:05 2001
@@ -596,6 +596,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
 MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(pcf_test, "i");
 MODULE_PARM(pcf_scan, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-core.c linux/drivers/i2c/i2c-core.c
--- v2.4.10/linux/drivers/i2c/i2c-core.c	Fri Feb  9 11:40:02 2001
+++ linux/drivers/i2c/i2c-core.c	Sun Sep 30 12:26:05 2001
@@ -1369,6 +1369,7 @@
 MODULE_DESCRIPTION("I2C-Bus main module");
 MODULE_PARM(i2c_debug, "i");
 MODULE_PARM_DESC(i2c_debug,"debug level");
+MODULE_LICENSE("GPL");
 
 int init_module(void) 
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-dev.c linux/drivers/i2c/i2c-dev.c
--- v2.4.10/linux/drivers/i2c/i2c-dev.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/i2c/i2c-dev.c	Sun Sep 30 12:26:05 2001
@@ -530,6 +530,7 @@
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C /dev entries driver");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-elektor.c linux/drivers/i2c/i2c-elektor.c
--- v2.4.10/linux/drivers/i2c/i2c-elektor.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2c/i2c-elektor.c	Sun Sep 30 12:26:05 2001
@@ -277,6 +277,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
 MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(base, "i");
 MODULE_PARM(irq, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-elv.c linux/drivers/i2c/i2c-elv.c
--- v2.4.10/linux/drivers/i2c/i2c-elv.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2c/i2c-elv.c	Sun Sep 30 12:26:05 2001
@@ -199,8 +199,9 @@
 
 #ifdef MODULE
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter")
-;
+MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(base, "i");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-philips-par.c linux/drivers/i2c/i2c-philips-par.c
--- v2.4.10/linux/drivers/i2c/i2c-philips-par.c	Tue Jul 25 18:10:42 2000
+++ linux/drivers/i2c/i2c-philips-par.c	Sun Sep 30 12:26:05 2001
@@ -291,6 +291,7 @@
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus adapter routines for Philips parallel port adapter");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(type, "i");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/i2c/i2c-velleman.c linux/drivers/i2c/i2c-velleman.c
--- v2.4.10/linux/drivers/i2c/i2c-velleman.c	Wed Feb  9 18:48:03 2000
+++ linux/drivers/i2c/i2c-velleman.c	Sun Sep 30 12:26:05 2001
@@ -189,6 +189,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(base, "i");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/Config.in linux/drivers/ide/Config.in
--- v2.4.10/linux/drivers/ide/Config.in	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/Config.in	Mon Oct  8 11:40:13 2001
@@ -124,6 +124,16 @@
       if [ "$CONFIG_Q40" = "y" ]; then
 	 dep_bool '  Q40/Q60 IDE interface support' CONFIG_BLK_DEV_Q40IDE $CONFIG_Q40
       fi
+      if [ "$CONFIG_8xx" = "y" ]; then
+         dep_bool '  MPC8xx IDE support' CONFIG_BLK_DEV_MPC8xx_IDE $CONFIG_8xx
+      fi
+
+      if [ "$CONFIG_BLK_DEV_MPC8xx_IDE" = "y" ]; then
+         choice 'Type of MPC8xx IDE interface'		\
+		"8xx_PCCARD	CONFIG_IDE_8xx_PCCARD	\
+		 8xx_DIRECT	CONFIG_IDE_8xx_DIRECT	\
+		 EXT_DIRECT	CONFIG_IDE_EXT_DIRECT"	8xx_PCCARD
+      fi
 
       bool '  Other IDE chipset support' CONFIG_IDE_CHIPSETS
       if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
@@ -182,7 +192,8 @@
      "$CONFIG_BLK_DEV_SIS5513" = "y" -o \
      "$CONFIG_BLK_DEV_SLC90E66" = "y" -o \
      "$CONFIG_BLK_DEV_SL82C105" = "y" -o \
-     "$CONFIG_BLK_DEV_VIA82CXXX" = "y" ]; then
+     "$CONFIG_BLK_DEV_VIA82CXXX" = "y" -o \
+     "$CONFIG_BLK_DEV_MPC8xx_IDE" = "y" ]; then
    define_bool CONFIG_BLK_DEV_IDE_MODES y
 else
    define_bool CONFIG_BLK_DEV_IDE_MODES n
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/Makefile linux/drivers/ide/Makefile
--- v2.4.10/linux/drivers/ide/Makefile	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/Makefile	Tue Oct  9 09:18:37 2001
@@ -10,7 +10,7 @@
 
 O_TARGET := idedriver.o
 
-export-objs		:= ide.o ide-features.o
+export-objs		:= ide.o ide-features.o ataraid.o
 list-multi		:= ide-mod.o ide-probe-mod.o
 
 obj-y		:=
@@ -65,6 +65,7 @@
 ide-obj-$(CONFIG_BLK_DEV_TRM290)	+= trm290.o
 ide-obj-$(CONFIG_BLK_DEV_UMC8672)	+= umc8672.o
 ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX)	+= via82cxxx.o
+ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ide-m8xx.o
 
 # The virtualised raid layers MUST come after the ide itself or bad stuff
 # will happen.
@@ -74,7 +75,7 @@
 
 ide-obj-$(CONFIG_PROC_FS)		+= ide-proc.o
 
-ide-mod-objs		:= $(export-objs) $(ide-obj-y)
+ide-mod-objs		:= ide.o ide-features.o $(ide-obj-y)
 ide-probe-mod-objs	:= ide-probe.o ide-geometry.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ataraid.c linux/drivers/ide/ataraid.c
--- v2.4.10/linux/drivers/ide/ataraid.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/ataraid.c	Sun Sep 30 12:26:05 2001
@@ -63,12 +63,6 @@
 /* Bitmap for the devices currently in use */
 static unsigned int ataraiduse;
 
-/* structure for the splitting of bufferheads */
-
-struct ataraid_bh_private {
-	struct buffer_head *parent;
-	atomic_t count;
-};
 
 /* stub fops functions */
 
@@ -121,7 +115,7 @@
 	return -EINVAL;
 }
 
-static struct buffer_head *get_bhead(void)
+struct buffer_head *ataraid_get_bhead(void)
 {
 	void *ptr = NULL;
 	while (!ptr) {
@@ -135,7 +129,9 @@
 	return ptr;
 }
 
-static struct ataraid_bh_private *get_private(void)
+EXPORT_SYMBOL(ataraid_get_bhead);
+
+struct ataraid_bh_private *ataraid_get_private(void)
 {
 	void *ptr = NULL;
 	while (!ptr) {
@@ -149,7 +145,9 @@
 	return ptr;
 }
 
-static void ataraid_end_request(struct buffer_head *bh, int uptodate)
+EXPORT_SYMBOL(ataraid_get_private);
+
+void ataraid_end_request(struct buffer_head *bh, int uptodate)
 {
 	struct ataraid_bh_private *private = bh->b_private;
 
@@ -164,17 +162,19 @@
 	kfree(bh);
 }
 
+EXPORT_SYMBOL(ataraid_end_request);
+
 static void ataraid_split_request(request_queue_t *q, int rw, struct buffer_head * bh)
 {
 	struct buffer_head *bh1,*bh2;
 	struct ataraid_bh_private *private;
-	bh1=get_bhead();
-	bh2=get_bhead();
+	bh1=ataraid_get_bhead();
+	bh2=ataraid_get_bhead();
 
 	/* If either of those ever fails we're doomed */
 	if ((!bh1)||(!bh2))
 		BUG();
-	private = get_private();
+	private = ataraid_get_private();
 	if (private==NULL)
 		BUG();
 	
@@ -249,7 +249,7 @@
 	{
         	ataraid_hardsect_size[i] = 512;
 		ataraid_blksize_size[i] = 1024;  
-		ataraid_readahead[i] = 32;
+		ataraid_readahead[i] = 1023;
 	}
 	
 	if (blksize_size[ATAMAJOR]==NULL)
@@ -317,4 +317,5 @@
 EXPORT_SYMBOL(ataraid_release_device);
 EXPORT_SYMBOL(ataraid_gendisk);
 EXPORT_SYMBOL(ataraid_register_disk);
+MODULE_LICENSE("GPL");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ataraid.h linux/drivers/ide/ataraid.h
--- v2.4.10/linux/drivers/ide/ataraid.h	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/ataraid.h	Mon Oct  8 13:32:28 2001
@@ -49,6 +49,12 @@
 	unsigned char sectors;
 };
 
+/* structure for the splitting of bufferheads */
+
+struct ataraid_bh_private {
+	struct buffer_head *parent;
+	atomic_t count;
+};
 
 extern struct gendisk ataraid_gendisk;
 
@@ -56,4 +62,11 @@
 extern void ataraid_release_device(int device);
 extern int get_blocksize(kdev_t dev);
 extern void ataraid_register_disk(int device,long size);
+extern struct buffer_head *ataraid_get_bhead(void);
+extern struct ataraid_bh_private *ataraid_get_private(void);
+extern void ataraid_end_request(struct buffer_head *bh, int uptodate);
+
+
+
+
 
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/hptraid.c linux/drivers/ide/hptraid.c
--- v2.4.10/linux/drivers/ide/hptraid.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/hptraid.c	Sun Sep 30 12:26:05 2001
@@ -306,8 +306,8 @@
 	if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) {
         	int j=0;
         	struct gendisk *gd;
-
 		raid[device].disk[i].bdev = bdev;
+        	/* This is supposed to prevent others from stealing our underlying disks */
 		/* now blank the /proc/partitions table for the wrong partition table,
 		   so that scripts don't accidentally mount it and crash the kernel */
 		 /* XXX: the 0 is an utter hack  --hch */
@@ -408,12 +408,12 @@
 {
 	int i,device;
 	for (device = 0; device<16; device++) {
-		for (i=0;i<8;i++) {
+		for (i=0;i<8;i++)  {
 			struct block_device *bdev = raid[device].disk[i].bdev;
 			raid[device].disk[i].bdev = NULL;
 			if (bdev)
 				blkdev_put(bdev, BDEV_RAW);
-		}
+		}       
 		if (raid[device].sectors)
 			ataraid_release_device(device);
 	}
@@ -432,3 +432,4 @@
 
 module_init(hptraid_init);
 module_exit(hptraid_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c
--- v2.4.10/linux/drivers/ide/ide-cs.c	Fri Feb  9 11:40:02 2001
+++ linux/drivers/ide/ide-cs.c	Sun Sep 30 12:26:05 2001
@@ -74,6 +74,9 @@
 MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
 
+MODULE_LICENSE("GPL");
+
+
 /*====================================================================*/
 
 static const char ide_major[] = {
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- v2.4.10/linux/drivers/ide/ide-disk.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/ide-disk.c	Fri Sep 28 11:21:40 2001
@@ -481,7 +481,7 @@
 static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
 {
 	if (drive->removable && !drive->usage) {
-		invalidate_buffers(inode->i_rdev);
+		invalidate_bdev(inode->i_bdev, 0);
 		if (drive->doorlocking && ide_wait_cmd(drive, WIN_DOORUNLOCK, 0, 0, 0, NULL))
 			drive->doorlocking = 0;
 	}
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- v2.4.10/linux/drivers/ide/ide-floppy.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/ide-floppy.c	Fri Sep 28 11:21:40 2001
@@ -1750,7 +1750,7 @@
 	if (!drive->usage) {
 		idefloppy_floppy_t *floppy = drive->driver_data;
 
-		invalidate_buffers (inode->i_rdev);
+		invalidate_bdev (inode->i_bdev, 0);
 
 		/* IOMEGA Clik! drives do not support lock/unlock commands */
                 if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide-m8xx.c linux/drivers/ide/ide-m8xx.c
--- v2.4.10/linux/drivers/ide/ide-m8xx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/ide/ide-m8xx.c	Mon Oct  8 11:40:13 2001
@@ -0,0 +1,851 @@
+/*
+ *
+ *
+ *  linux/drivers/ide/ide-m8xx.c
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/blk.h>
+#include <linux/ioport.h>
+#include <linux/ide.h>
+#include <linux/bootmem.h>
+
+#include <asm/mpc8xx.h>
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/residual.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/ide.h>
+#include <asm/8xx_immap.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+
+#include "ide_modes.h"
+static int identify  (volatile unsigned char *p);
+static void print_fixed (volatile unsigned char *p);
+static void print_funcid (int func);
+static int check_ide_device (unsigned long base);
+
+static void ide_interrupt_ack (void *dev);
+static void m8xx_ide_tuneproc(ide_drive_t *drive, byte pio);
+
+typedef	struct ide_ioport_desc {
+	unsigned long	base_off;		/* Offset to PCMCIA memory	*/
+	ide_ioreg_t	reg_off[IDE_NR_PORTS];	/* controller register offsets	*/
+	int		irq;			/* IRQ				*/
+} ide_ioport_desc_t;
+
+ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = {
+#ifdef IDE0_BASE_OFFSET
+	{ IDE0_BASE_OFFSET,
+	    {
+		IDE0_DATA_REG_OFFSET,
+		IDE0_ERROR_REG_OFFSET,
+		IDE0_NSECTOR_REG_OFFSET,
+		IDE0_SECTOR_REG_OFFSET,
+		IDE0_LCYL_REG_OFFSET,
+		IDE0_HCYL_REG_OFFSET,
+		IDE0_SELECT_REG_OFFSET,
+		IDE0_STATUS_REG_OFFSET,
+		IDE0_CONTROL_REG_OFFSET,
+		IDE0_IRQ_REG_OFFSET,
+	    },
+	    IDE0_INTERRUPT,
+	},
+#ifdef IDE1_BASE_OFFSET
+	{ IDE1_BASE_OFFSET,
+	    {
+		IDE1_DATA_REG_OFFSET,
+		IDE1_ERROR_REG_OFFSET,
+		IDE1_NSECTOR_REG_OFFSET,
+		IDE1_SECTOR_REG_OFFSET,
+		IDE1_LCYL_REG_OFFSET,
+		IDE1_HCYL_REG_OFFSET,
+		IDE1_SELECT_REG_OFFSET,
+		IDE1_STATUS_REG_OFFSET,
+		IDE1_CONTROL_REG_OFFSET,
+		IDE1_IRQ_REG_OFFSET,
+	    },
+	    IDE1_INTERRUPT,
+	},
+#endif /* IDE1_BASE_OFFSET */
+#endif	/* IDE0_BASE_OFFSET */
+};
+
+ide_pio_timings_t ide_pio_clocks[6];
+int hold_time[6] =  {30, 20, 15, 10, 10, 10 };   /* PIO Mode 5 with IORDY (nonstandard) */
+
+/*
+ * Warning: only 1 (ONE) PCMCIA slot supported here,
+ * which must be correctly initialized by the firmware (PPCBoot).
+ */
+static int _slot_ = -1;			/* will be read from PCMCIA registers   */
+
+/* Make clock cycles and always round up */
+#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U )
+
+
+
+/*
+ * IDE stuff.
+ */
+static int
+m8xx_ide_default_irq(ide_ioreg_t base)
+{
+#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
+	if (base >= MAX_HWIFS)
+		return 0;
+
+	printk("[%d] m8xx_ide_default_irq %d\n",__LINE__,ioport_dsc[base].irq);
+	
+	return (ioport_dsc[base].irq);
+#else
+        return 9;
+#endif
+}
+
+static ide_ioreg_t
+m8xx_ide_default_io_base(int index)
+{
+        return index;
+}
+
+#define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
+
+/*
+ * The TQM850L hardware has two pins swapped! Grrrrgh!
+ */
+#ifdef	CONFIG_TQM850L
+#define __MY_PCMCIA_GCRX_CXRESET	PCMCIA_GCRX_CXOE
+#define __MY_PCMCIA_GCRX_CXOE		PCMCIA_GCRX_CXRESET
+#else
+#define __MY_PCMCIA_GCRX_CXRESET	PCMCIA_GCRX_CXRESET
+#define __MY_PCMCIA_GCRX_CXOE		PCMCIA_GCRX_CXOE
+#endif
+
+#if defined(CONFIG_BLK_DEV_MPC8xx_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
+#define PCMCIA_SCHLVL IDE0_INTERRUPT	/* Status Change Interrupt Level	*/
+static int pcmcia_schlvl = PCMCIA_SCHLVL;
+#endif
+
+/*
+ * See include/linux/ide.h for definition of hw_regs_t (p, base)
+ */
+
+/*
+ * m8xx_ide_init_hwif_ports for a direct IDE interface _using_
+ */
+#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
+static void
+m8xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, 
+		ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t *p = hw->io_ports;
+	int i;
+
+	typedef struct {
+		ulong br;
+		ulong or;
+	} pcmcia_win_t;
+	volatile pcmcia_win_t *win;
+	volatile pcmconf8xx_t *pcmp;
+
+	uint *pgcrx;
+	u32 pcmcia_phy_base;
+	u32 pcmcia_phy_end;
+	static unsigned long pcmcia_base = 0;
+	unsigned long base;
+
+	*p = 0;
+	if (irq)
+		*irq = 0;
+
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
+
+	if (!pcmcia_base) {
+                /*
+                 * Read out PCMCIA registers. Since the reset values
+                 * are undefined, we sure hope that they have been
+                 * set up by firmware
+		 */
+
+		/* Scan all registers for valid settings */
+		pcmcia_phy_base = 0xFFFFFFFF;
+		pcmcia_phy_end = 0;
+		/* br0 is start of brX and orX regs */
+		win = (pcmcia_win_t *) \
+			(&(((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0));
+		for (i = 0; i < 8; i++) {
+			if (win->or & 1) {	/* This bank is marked as valid */
+				if (win->br < pcmcia_phy_base) {
+					pcmcia_phy_base = win->br;
+				}
+				if ((win->br + PCMCIA_MEM_SIZE) > pcmcia_phy_end) {
+					pcmcia_phy_end  = win->br + PCMCIA_MEM_SIZE;
+				}
+				/* Check which slot that has been defined */
+				_slot_ = (win->or >> 2) & 1;
+
+			}					/* Valid bank */
+			win++;
+		}						/* for */
+
+		printk ("PCMCIA slot %c: phys mem %08x...%08x (size %08x)\n",
+			'A' + _slot_,
+			pcmcia_phy_base, pcmcia_phy_end,
+			pcmcia_phy_end - pcmcia_phy_base);
+
+		pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base,
+						   pcmcia_phy_end-pcmcia_phy_base);
+
+#ifdef DEBUG
+		printk ("PCMCIA virt base: %08lx\n", pcmcia_base);
+#endif
+		/* Compute clock cycles for PIO timings */
+		for (i=0; i<6; ++i) {
+			bd_t	*binfo = (bd_t *)__res;
+
+			hold_time[i]   =
+				PCMCIA_MK_CLKS (hold_time[i],
+						binfo->bi_busfreq);
+			ide_pio_clocks[i].setup_time  =
+				PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time,
+						binfo->bi_busfreq);
+			ide_pio_clocks[i].active_time =
+				PCMCIA_MK_CLKS (ide_pio_timings[i].active_time,
+						binfo->bi_busfreq);
+			ide_pio_clocks[i].cycle_time  =
+				PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time,
+						binfo->bi_busfreq);
+#if 0
+			printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n",
+				i,
+				ide_pio_clocks[i].setup_time,
+				ide_pio_clocks[i].active_time,
+				ide_pio_clocks[i].hold_time,
+				ide_pio_clocks[i].cycle_time,
+				ide_pio_timings[i].setup_time,
+				ide_pio_timings[i].active_time,
+				ide_pio_timings[i].hold_time,
+				ide_pio_timings[i].cycle_time);
+#endif
+		}
+	}
+
+	if (data_port >= MAX_HWIFS)
+		return;
+
+	if (_slot_ == -1) {
+		printk ("PCMCIA slot has not been defined! Using A as default\n");
+		_slot_ = 0;
+	}
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+
+#ifdef DEBUG
+	printk ("PIPR = 0x%08X  slot %c ==> mask = 0x%X\n",
+		pcmp->pcmc_pipr,
+		'A' + _slot_,
+		M8XX_PCMCIA_CD1(_slot_) | M8XX_PCMCIA_CD2(_slot_) );
+#endif /* DEBUG */
+
+	if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) {
+		printk ("No card in slot %c: PIPR=%08x\n",
+			'A' + _slot_, (u32) pcmp->pcmc_pipr);
+		return;		/* No card in slot */
+	}
+
+	check_ide_device (pcmcia_base);
+
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+
+	base = pcmcia_base + ioport_dsc[data_port].base_off;
+#ifdef DEBUG
+	printk ("base: %08x + %08x = %08x\n",
+			pcmcia_base, ioport_dsc[data_port].base_off, base);
+#endif
+
+	for (i = 0; i < IDE_NR_PORTS; ++i) {
+#ifdef DEBUG
+		printk ("port[%d]: %08x + %08x = %08x\n",
+			i,
+			base,
+			ioport_dsc[data_port].reg_off[i],
+			i, base + ioport_dsc[data_port].reg_off[i]);
+#endif
+	 	*p++ = base + ioport_dsc[data_port].reg_off[i];
+	}
+
+	if (irq) {
+#ifdef CONFIG_IDE_8xx_PCCARD
+		unsigned int reg;
+
+		*irq = ioport_dsc[data_port].irq;
+		if (_slot_)
+			pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb;
+		else
+			pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcra;
+
+		reg = *pgcrx;
+		reg |= mk_int_int_mask (pcmcia_schlvl) << 24;
+		reg |= mk_int_int_mask (pcmcia_schlvl) << 16;
+		*pgcrx = reg;
+#else	/* direct connected IDE drive, i.e. external IRQ, not the PCMCIA irq */
+		*irq = ioport_dsc[data_port].irq;
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+	}
+
+	/* register routine to tune PIO mode */
+	ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc;
+
+	hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
+	/* Enable Harddisk Interrupt,
+	 * and make it edge sensitive
+	 */
+	/* (11-18) Set edge detect for irq, no wakeup from low power mode */
+	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |=
+					(0x80000000 >> ioport_dsc[data_port].irq);
+
+#ifdef CONFIG_IDE_8xx_PCCARD
+	/* Make sure we dont get garbage irq */
+	((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pscr = 0xFFFF;
+
+	/* Enable falling edge irq */
+	pcmp->pcmc_per = 0x100000 >> (16 * _slot_);
+#endif	/* CONFIG_IDE_8xx_PCCARD */
+}	/* m8xx_ide_init_hwif_ports() using 8xx internal PCMCIA interface */
+#endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */
+
+/*
+ * m8xx_ide_init_hwif_ports for a direct IDE interface _not_ using
+ * MPC8xx's internal PCMCIA interface
+ */
+#if defined(CONFIG_IDE_EXT_DIRECT)
+void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
+	ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t *p = hw->io_ports;
+	int i;
+
+	u32 ide_phy_base;
+	u32 ide_phy_end;
+	static unsigned long ide_base = 0;
+	unsigned long base;
+
+	*p = 0;
+	if (irq)
+		*irq = 0;
+
+	if (!ide_base) {
+
+		/* TODO:
+		 * - add code to read ORx, BRx
+		 */
+		ide_phy_base = CFG_ATA_BASE_ADDR;
+		ide_phy_end  = CFG_ATA_BASE_ADDR + 0x200;
+
+		printk ("IDE phys mem : %08x...%08x (size %08x)\n",
+			ide_phy_base, ide_phy_end,
+			ide_phy_end - ide_phy_base);
+		
+		ide_base=(unsigned long)ioremap(ide_phy_base,
+						ide_phy_end-ide_phy_base);
+
+#ifdef DEBUG
+		printk ("IDE virt base: %08lx\n", ide_base);
+#endif
+	}
+
+	if (data_port >= MAX_HWIFS)
+		return;
+
+	base = ide_base + ioport_dsc[data_port].base_off;
+#ifdef DEBUG
+	printk ("base: %08x + %08x = %08x\n",
+		ide_base, ioport_dsc[data_port].base_off, base);
+#endif
+
+	for (i = 0; i < IDE_NR_PORTS; ++i) {
+#ifdef DEBUG
+		printk ("port[%d]: %08x + %08x = %08x\n",
+			i,
+			base,
+			ioport_dsc[data_port].reg_off[i],
+			i, base + ioport_dsc[data_port].reg_off[i]);
+#endif
+	 	*p++ = base + ioport_dsc[data_port].reg_off[i];
+	}
+
+	if (irq) {
+		/* direct connected IDE drive, i.e. external IRQ */
+		*irq = ioport_dsc[data_port].irq;
+	}
+
+	/* register routine to tune PIO mode */
+	ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc;
+
+	hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
+	/* Enable Harddisk Interrupt,
+	 * and make it edge sensitive
+	 */
+	/* (11-18) Set edge detect for irq, no wakeup from low power mode */
+	((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |=
+			(0x80000000 >> ioport_dsc[data_port].irq);
+}	/* m8xx_ide_init_hwif_ports() for CONFIG_IDE_8xx_DIRECT */ 
+
+#endif	/* CONFIG_IDE_8xx_DIRECT */
+
+
+/* -------------------------------------------------------------------- */
+
+
+/* PCMCIA Timing */
+#ifndef	PCMCIA_SHT
+#define PCMCIA_SHT(t)	((t & 0x0F)<<16)	/* Strobe Hold  Time 	*/
+#define PCMCIA_SST(t)	((t & 0x0F)<<12)	/* Strobe Setup Time	*/
+#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length	*/
+#endif
+
+
+/* Calculate PIO timings */
+static void
+m8xx_ide_tuneproc(ide_drive_t *drive, byte pio)
+{
+	ide_pio_data_t d;
+#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
+	volatile pcmconf8xx_t	*pcmp;
+	ulong timing, mask, reg;
+#endif
+
+	pio = ide_get_best_pio_mode(drive, pio, 4, &d);
+
+#if 1
+	printk("%s[%d] %s: best PIO mode: %d\n",
+		__FILE__,__LINE__,__FUNCTION__, pio);
+#endif
+
+#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
+	pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
+
+	mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF));
+
+	timing  = PCMCIA_SHT(hold_time[pio]  )
+		| PCMCIA_SST(ide_pio_clocks[pio].setup_time )
+		| PCMCIA_SL (ide_pio_clocks[pio].active_time)
+		;
+
+#if 1
+	printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing);
+#endif
+	if ((reg = pcmp->pcmc_por0 & mask) != 0)
+		pcmp->pcmc_por0 = reg | timing;
+
+	if ((reg = pcmp->pcmc_por1 & mask) != 0)
+		pcmp->pcmc_por1 = reg | timing;
+
+	if ((reg = pcmp->pcmc_por2 & mask) != 0)
+		pcmp->pcmc_por2 = reg | timing;
+
+	if ((reg = pcmp->pcmc_por3 & mask) != 0)
+		pcmp->pcmc_por3 = reg | timing;
+
+	if ((reg = pcmp->pcmc_por4 & mask) != 0)
+		pcmp->pcmc_por4 = reg | timing;
+
+	if ((reg = pcmp->pcmc_por5 & mask) != 0)
+		pcmp->pcmc_por5 = reg | timing;
+
+	if ((reg = pcmp->pcmc_por6 & mask) != 0)
+		pcmp->pcmc_por6 = reg | timing;
+
+	if ((reg = pcmp->pcmc_por7 & mask) != 0)
+		pcmp->pcmc_por7 = reg | timing;
+
+#elif defined(CONFIG_IDE_EXT_DIRECT)
+
+	printk("%s[%d] %s: not implemented yet!\n",
+		__FILE__,__LINE__,__FUNCTION__);
+#endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */
+}
+
+static void
+ide_interrupt_ack (void *dev)
+{
+#ifdef CONFIG_IDE_8xx_PCCARD
+	u_int pscr, pipr;
+
+#if (PCMCIA_SOCKETS_NO == 2)
+	u_int _slot_;
+#endif
+
+	/* get interrupt sources */
+
+	pscr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
+	pipr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
+
+	/*
+	 * report only if both card detect signals are the same
+	 * not too nice done,
+	 * we depend on that CD2 is the bit to the left of CD1...
+	 */
+
+	if(_slot_==-1){
+	  printk("PCMCIA slot has not been defined! Using A as default\n");
+	  _slot_=0;
+	}
+
+	if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1) ^
+	   (pipr & M8XX_PCMCIA_CD1(_slot_))         ) {
+	  printk ("card detect interrupt\n");
+	}
+	/* clear the interrupt sources */
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
+
+#else /* ! CONFIG_IDE_8xx_PCCARD */
+	/*
+	 * Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the
+	 * MPC8xx's PCMCIA controller, so there is nothing to be done here
+	 * for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT.
+	 * The interrupt is handled somewhere else.	-- Steven
+	 */
+#endif /* CONFIG_IDE_8xx_PCCARD */
+}
+
+
+
+/*
+ * CIS Tupel codes
+ */
+#define CISTPL_NULL		0x00
+#define CISTPL_DEVICE		0x01
+#define CISTPL_LONGLINK_CB	0x02
+#define CISTPL_INDIRECT		0x03
+#define CISTPL_CONFIG_CB	0x04
+#define CISTPL_CFTABLE_ENTRY_CB 0x05
+#define CISTPL_LONGLINK_MFC	0x06
+#define CISTPL_BAR		0x07
+#define CISTPL_PWR_MGMNT	0x08
+#define CISTPL_EXTDEVICE	0x09
+#define CISTPL_CHECKSUM		0x10
+#define CISTPL_LONGLINK_A	0x11
+#define CISTPL_LONGLINK_C	0x12
+#define CISTPL_LINKTARGET	0x13
+#define CISTPL_NO_LINK		0x14
+#define CISTPL_VERS_1		0x15
+#define CISTPL_ALTSTR		0x16
+#define CISTPL_DEVICE_A		0x17
+#define CISTPL_JEDEC_C		0x18
+#define CISTPL_JEDEC_A		0x19
+#define CISTPL_CONFIG		0x1a
+#define CISTPL_CFTABLE_ENTRY	0x1b
+#define CISTPL_DEVICE_OC	0x1c
+#define CISTPL_DEVICE_OA	0x1d
+#define CISTPL_DEVICE_GEO	0x1e
+#define CISTPL_DEVICE_GEO_A	0x1f
+#define CISTPL_MANFID		0x20
+#define CISTPL_FUNCID		0x21
+#define CISTPL_FUNCE		0x22
+#define CISTPL_SWIL		0x23
+#define CISTPL_END		0xff
+
+/*
+ * CIS Function ID codes
+ */
+#define CISTPL_FUNCID_MULTI	0x00
+#define CISTPL_FUNCID_MEMORY	0x01
+#define CISTPL_FUNCID_SERIAL	0x02
+#define CISTPL_FUNCID_PARALLEL	0x03
+#define CISTPL_FUNCID_FIXED	0x04
+#define CISTPL_FUNCID_VIDEO	0x05
+#define CISTPL_FUNCID_NETWORK	0x06
+#define CISTPL_FUNCID_AIMS	0x07
+#define CISTPL_FUNCID_SCSI	0x08
+
+/*
+ * Fixed Disk FUNCE codes
+ */
+#define CISTPL_IDE_INTERFACE	0x01
+
+#define CISTPL_FUNCE_IDE_IFACE	0x01
+#define CISTPL_FUNCE_IDE_MASTER	0x02
+#define CISTPL_FUNCE_IDE_SLAVE	0x03
+
+/* First feature byte */
+#define CISTPL_IDE_SILICON	0x04
+#define CISTPL_IDE_UNIQUE	0x08
+#define CISTPL_IDE_DUAL		0x10
+
+/* Second feature byte */
+#define CISTPL_IDE_HAS_SLEEP	0x01
+#define CISTPL_IDE_HAS_STANDBY	0x02
+#define CISTPL_IDE_HAS_IDLE	0x04
+#define CISTPL_IDE_LOW_POWER	0x08
+#define CISTPL_IDE_REG_INHIBIT	0x10
+#define CISTPL_IDE_HAS_INDEX	0x20
+#define CISTPL_IDE_IOIS16	0x40
+
+
+/* -------------------------------------------------------------------- */
+
+
+#define	MAX_TUPEL_SZ	512
+#define MAX_FEATURES	4
+
+static int check_ide_device (unsigned long base)
+{
+	volatile unsigned char *ident = NULL;
+	volatile unsigned char *feature_p[MAX_FEATURES];
+	volatile unsigned char *p, *start;
+	int n_features = 0;
+	unsigned char func_id = ~0;
+	unsigned char code, len;
+	unsigned short config_base = 0;
+	int found = 0;
+	int i;
+
+#ifdef DEBUG
+	printk ("PCMCIA MEM: %08lX\n", base);
+#endif
+	start = p = (volatile unsigned char *) base;
+
+	while ((p - start) < MAX_TUPEL_SZ) {
+
+		code = *p; p += 2;
+
+		if (code == 0xFF) { /* End of chain */
+			break;
+		}
+
+		len = *p; p += 2;
+#ifdef	DEBUG_PCMCIA
+		{ volatile unsigned char *q = p;
+			printk ("\nTuple code %02x  length %d\n\tData:",
+				code, len);
+
+			for (i = 0; i < len; ++i) {
+				printk (" %02x", *q);
+				q+= 2;
+			}
+		}
+#endif	/* DEBUG_PCMCIA */
+		switch (code) {
+		case CISTPL_VERS_1:
+			ident = p + 4;
+			break;
+		case CISTPL_FUNCID:
+			func_id = *p;
+			break;
+		case CISTPL_FUNCE:
+			if (n_features < MAX_FEATURES)
+				feature_p[n_features++] = p;
+			break;
+		case CISTPL_CONFIG:
+			config_base = (*(p+6) << 8) + (*(p+4));
+		default:
+			break;
+		}
+		p += 2 * len;
+	}
+
+	found = identify (ident);
+
+	if (func_id != ((unsigned char)~0)) {
+		print_funcid (func_id);
+
+		if (func_id == CISTPL_FUNCID_FIXED)
+			found = 1;
+		else
+			return (1);	/* no disk drive */
+	}
+
+	for (i=0; i<n_features; ++i) {
+		print_fixed (feature_p[i]);
+	}
+
+	if (!found) {
+		printk ("unknown card type\n");
+		return (1);
+	}
+
+	/* set level mode irq and I/O mapped device in config reg*/
+	*((unsigned char *)(base + config_base)) = 0x41;
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void print_funcid (int func)
+{
+	switch (func) {
+	case CISTPL_FUNCID_MULTI:
+		printk (" Multi-Function");
+		break;
+	case CISTPL_FUNCID_MEMORY:
+		printk (" Memory");
+		break;
+	case CISTPL_FUNCID_SERIAL:
+		printk (" Serial Port");
+		break;
+	case CISTPL_FUNCID_PARALLEL:
+		printk (" Parallel Port");
+		break;
+	case CISTPL_FUNCID_FIXED:
+		printk (" Fixed Disk");
+		break;
+	case CISTPL_FUNCID_VIDEO:
+		printk (" Video Adapter");
+		break;
+	case CISTPL_FUNCID_NETWORK:
+		printk (" Network Adapter");
+		break;
+	case CISTPL_FUNCID_AIMS:
+		printk (" AIMS Card");
+		break;
+	case CISTPL_FUNCID_SCSI:
+		printk (" SCSI Adapter");
+		break;
+	default:
+		printk (" Unknown");
+		break;
+	}
+	printk (" Card\n");
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void print_fixed (volatile unsigned char *p)
+{
+	if (p == NULL)
+		return;
+
+	switch (*p) {
+	case CISTPL_FUNCE_IDE_IFACE:
+	    {   unsigned char iface = *(p+2);
+
+		printk ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
+		printk (" interface ");
+		break;
+	    }
+	case CISTPL_FUNCE_IDE_MASTER:
+	case CISTPL_FUNCE_IDE_SLAVE:
+	    {   unsigned char f1 = *(p+2);
+		unsigned char f2 = *(p+4);
+
+		printk ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
+
+		if (f1 & CISTPL_IDE_UNIQUE)
+			printk (" [unique]");
+
+		printk ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
+
+		if (f2 & CISTPL_IDE_HAS_SLEEP)
+			printk (" [sleep]");
+
+		if (f2 & CISTPL_IDE_HAS_STANDBY)
+			printk (" [standby]");
+
+		if (f2 & CISTPL_IDE_HAS_IDLE)
+			printk (" [idle]");
+
+		if (f2 & CISTPL_IDE_LOW_POWER)
+			printk (" [low power]");
+
+		if (f2 & CISTPL_IDE_REG_INHIBIT)
+			printk (" [reg inhibit]");
+
+		if (f2 & CISTPL_IDE_HAS_INDEX)
+			printk (" [index]");
+
+		if (f2 & CISTPL_IDE_IOIS16)
+			printk (" [IOis16]");
+
+		break;
+	    }
+	}
+	printk ("\n");
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+#define MAX_IDENT_CHARS		64
+#define	MAX_IDENT_FIELDS	4
+
+static unsigned char *known_cards[] = {
+	"ARGOSY PnPIDE D5",
+	NULL
+};
+
+static int identify  (volatile unsigned char *p)
+{
+	unsigned char id_str[MAX_IDENT_CHARS];
+	unsigned char data;
+	unsigned char *t;
+	unsigned char **card;
+	int i, done;
+
+	if (p == NULL)
+		return (0);	/* Don't know */
+
+	t = id_str;
+	done =0;
+
+	for (i=0; i<=4 && !done; ++i, p+=2) {
+		while ((data = *p) != '\0') {
+			if (data == 0xFF) {
+				done = 1;
+				break;
+			}
+			*t++ = data;
+			if (t == &id_str[MAX_IDENT_CHARS-1]) {
+				done = 1;
+				break;
+			}
+			p += 2;
+		}
+		if (!done)
+			*t++ = ' ';
+	}
+	*t = '\0';
+	while (--t > id_str) {
+		if (*t == ' ')
+			*t = '\0';
+		else
+			break;
+	}
+	printk ("Card ID: %s\n", id_str);
+
+	for (card=known_cards; *card; ++card) {
+		if (strcmp(*card, id_str) == 0) {	/* found! */
+			return (1);
+		}
+	}
+
+	return (0);	/* don't know */
+}
+
+void m8xx_ide_init(void)
+{
+	ppc_ide_md.default_irq          = m8xx_ide_default_irq;
+	ppc_ide_md.default_io_base      = m8xx_ide_default_io_base;
+	ppc_ide_md.ide_init_hwif        = m8xx_ide_init_hwif_ports;
+}
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- v2.4.10/linux/drivers/ide/ide-pci.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/ide-pci.c	Sun Sep 30 12:26:05 2001
@@ -693,6 +693,8 @@
 		 */
 		if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) && (secondpdc++==1) && (port==1)  ) 
 			goto controller_ok;
+		if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262)) && (secondpdc++==1) && (port==1)  ) 
+			goto controller_ok;
 			
 		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val))
 			continue;	/* port not enabled */
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- v2.4.10/linux/drivers/ide/ide-pmac.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/ide/ide-pmac.c	Tue Oct  2 09:08:40 2001
@@ -5,9 +5,7 @@
  * These IDE interfaces are memory-mapped and have a DBDMA channel
  * for doing DMA.
  *
- *  Copyright (C) 1998 Paul Mackerras.
- *
- *  Bits from Benjamin Herrenschmidt
+ *  Copyright (C) 1998-2001 Paul Mackerras & Ben. Herrenschmidt
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
@@ -99,13 +97,13 @@
 /* allow up to 256 DBDMA commands per xfer */
 #define MAX_DCMDS		256
 
-/* Wait 1.5s for disk to answer on IDE bus after
+/* Wait 2s for disk to answer on IDE bus after
  * enable operation.
  * NOTE: There is at least one case I know of a disk that needs about 10sec
  *       before anwering on the bus. I beleive we could add a kernel command
  *       line arg to override this delay for such cases.
  */
-#define IDE_WAKEUP_DELAY_MS	1500
+#define IDE_WAKEUP_DELAY_MS	2000
 
 static void pmac_ide_setup_dma(struct device_node *np, int ix);
 static int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
@@ -236,13 +234,21 @@
 	}
 	if((stat & ERR_STAT) || timeout <= 0) {
 		if (stat & ERR_STAT) {
-			printk("ide_pmace: wait_for_ready, error status: %x\n", stat);
+			printk(KERN_ERR "ide_pmac: wait_for_ready, error status: %x\n", stat);
 		}
 		return 1;
 	}
 	return 0;
 }
 
+/* Note: We don't use the generic routine here because some of Apple's
+ * controller seem to be very sensitive about how things are done.
+ * We should probably set the NIEN bit, but that's an example of thing
+ * that can cause the controller to hang under some circumstances when
+ * done on the media-bay CD-ROM during boot. We do get occasional
+ * spurrious interrupts because of that.
+ * --BenH
+ */
 static int
 pmac_ide_do_setfeature(ide_drive_t *drive, byte command)
 {
@@ -256,7 +262,7 @@
 	SELECT_MASK(HWIF(drive), drive, 0);
 	udelay(1);
 	if(wait_for_ready(drive)) {
-		printk("pmac_ide_do_setfeature disk not ready before SET_FEATURE!\n");
+		printk(KERN_ERR "pmac_ide_do_setfeature disk not ready before SET_FEATURE!\n");
 		goto out;
 	}
 	OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
@@ -265,7 +271,7 @@
 	udelay(1);
 	result = wait_for_ready(drive);
 	if (result)
-		printk("pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
+		printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
 out:
 	restore_flags(flags);
 	
@@ -311,7 +317,7 @@
 	}
 
 #ifdef IDE_PMAC_DEBUG
-	printk("ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n",
+	printk(KERN_ERR "ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n",
 		pio,  *timings);
 #endif	
 		
@@ -562,7 +568,7 @@
 		   fixes in irq.c
 		 */
 		if (np->n_intrs == 0) {
-			printk("ide: no intrs for device %s, using 13\n",
+			printk(KERN_WARNING "ide: no intrs for device %s, using 13\n",
 			       np->full_name);
 			irq = 13;
 		} else {
@@ -598,7 +604,7 @@
 			 feature_set(np, FEATURE_IDE0_enable);
 		} else {
  			/* This is necessary to enable IDE when net-booting */
-			printk("pmac_ide: enabling IDE bus ID %d\n",
+			printk(KERN_INFO "pmac_ide: enabling IDE bus ID %d\n",
 				pmac_ide[i].aapl_bus_id);
 			switch(pmac_ide[i].aapl_bus_id) {
 			    case 0:
@@ -732,7 +738,7 @@
 			unsigned int tc = (size < 0xfe00)? size: 0xfe00;
 
 			if (++count >= MAX_DCMDS) {
-				printk("%s: DMA table too small\n",
+				printk(KERN_WARNING "%s: DMA table too small\n",
 				       drive->name);
 				return 0; /* revert to PIO for this request */
 			}
@@ -804,10 +810,10 @@
 	int ret;
 
 	/* Set feature on drive */
-    	printk("%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf);
+    	printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf);
 	ret = pmac_ide_do_setfeature(drive, feature);
 	if (ret) {
-	    	printk("%s: Failed !\n", drive->name);
+	    	printk(KERN_WARNING "%s: Failed !\n", drive->name);
 	    	return 0;
 	}
 
@@ -860,7 +866,7 @@
 			(accessTicks | (recTicks << 5) | (halfTick << 10)) << 11;
 	}
 #ifdef IDE_PMAC_DEBUG
-	printk("ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n",
+	printk(KERN_INFO "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n",
 		feature & 0xf, *timings);
 #endif
 	drive->current_speed = feature;	
@@ -879,10 +885,10 @@
 	int ret;
 
 	/* Set feature on drive */
-    	printk("%s: Enabling Ultra DMA %d\n", drive->name, feature & 0xf);
+    	printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, feature & 0xf);
 	ret = pmac_ide_do_setfeature(drive, feature);
 	if (ret) {
-		printk("%s: Failed !\n", drive->name);
+		printk(KERN_WARNING "%s: Failed !\n", drive->name);
 		return 0;
 	}
 
@@ -953,7 +959,7 @@
 
 int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
 {
-	int ix, dstat;
+	int ix, dstat, i;
 	volatile struct dbdma_regs *dma;
 
 	/* Can we stuff a pointer to our intf structure in config_data
@@ -966,7 +972,7 @@
 
 	switch (func) {
 	case ide_dma_off:
-		printk("%s: DMA disabled\n", drive->name);
+		printk(KERN_INFO "%s: DMA disabled\n", drive->name);
 	case ide_dma_off_quietly:
 		drive->using_dma = 0;
 		break;
@@ -994,7 +1000,27 @@
 		/* verify good dma status */
 		return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
 	case ide_dma_test_irq:
-		return (in_le32(&dma->status) & (RUN|ACTIVE)) == RUN;
+		if ((in_le32(&dma->status) & (RUN|ACTIVE)) == RUN)
+			return 1;
+		/* That's a bit ugly and dangerous, but works in our case
+		 * to workaround a problem with the channel status staying
+		 * active if the drive returns an error
+		 */
+		if (IDE_CONTROL_REG) {
+			byte stat;
+			stat = GET_ALTSTAT();
+			if (stat & ERR_STAT)
+				return 1;
+		}
+		/* In some edge cases, some datas may still be in the dbdma
+		 * engine fifo, we wait a bit for dbdma to complete
+		 */
+		while ((in_le32(&dma->status) & (RUN|ACTIVE)) != RUN) {
+			if (++i > 100)
+				return 0;
+			udelay(1);
+		}
+		return 1;
 
 		/* Let's implement tose just in case someone wants them */
 	case ide_dma_bad_drive:
@@ -1005,10 +1031,10 @@
 	case ide_dma_retune:
 	case ide_dma_lostirq:
 	case ide_dma_timeout:
-		printk("ide_pmac_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func),  func);
+		printk(KERN_WARNING "ide_pmac_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func),  func);
 		return 1;
 	default:
-		printk("ide_pmac_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func);
+		printk(KERN_WARNING "ide_pmac_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func);
 		return 1;
 	}
 	return 0;
@@ -1016,13 +1042,15 @@
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
 #ifdef CONFIG_PMAC_PBOOK
-static void idepmac_sleep_disk(int i, unsigned long base)
+static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base)
 {
-	struct device_node* np = pmac_ide[i].node;
 	int j;
-
-	/* FIXME: We only handle the master IDE */
-	if (ide_hwifs[i].drives[0].media == ide_disk) {
+	
+	/* FIXME: We only handle the master IDE disk, we shoud
+	 *        try to fix CD-ROMs here
+	 */
+	switch (drive->media) {
+	case ide_disk:
 		/* Spin down the drive */
 		outb(0xa0, base+0x60);
 		outb(0x0, base+0x30);
@@ -1038,86 +1066,112 @@
 			if (!(status & BUSY_STAT) && (status & DRQ_STAT))
 				break;
 		}
-	}
-	feature_set(np, FEATURE_IDE0_reset);
-	feature_clear(np, FEATURE_IDE0_enable);
-	switch(pmac_ide[i].aapl_bus_id) {
-	    case 0:
-		feature_set(np, FEATURE_IDE0_reset);
-		feature_clear(np, FEATURE_IDE0_enable);
 		break;
-	    case 1:
-		feature_set(np, FEATURE_IDE1_reset);
-		feature_clear(np, FEATURE_IDE1_enable);
+	case ide_cdrom:
+		// todo
 		break;
-	    case 2:
-		feature_set(np, FEATURE_IDE2_reset);
+	case ide_floppy:
+		// todo
 		break;
 	}
-	pmac_ide[i].timings[0] = 0;
-	pmac_ide[i].timings[1] = 0;
 }
 
-static void idepmac_wake_disk(int i, unsigned long base)
+static void idepmac_wake_device(ide_drive_t *drive, int used_dma)
+ {
+	/* We force the IDE subdriver to check for a media change
+	 * This must be done first or we may lost the condition
+	 *
+	 * Problem: This can schedule. I moved the block device
+	 * wakeup almost late by priority because of that.
+	 */
+	if (DRIVER(drive) && DRIVER(drive)->media_change)
+		DRIVER(drive)->media_change(drive);
+
+	/* We kick the VFS too (see fix in ide.c revalidate) */
+	check_disk_change(MKDEV(HWIF(drive)->major, (drive->select.b.unit) << PARTN_BITS));
+	
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+	/* We re-enable DMA on the drive if it was active. */
+	/* This doesn't work with the CD-ROM in the media-bay, probably
+	 * because of a pending unit attention. The problem if that if I
+	 * clear the error, the filesystem dies.
+	 */
+	if (used_dma && !ide_spin_wait_hwgroup(drive)) {
+		/* Lock HW group */
+		HWGROUP(drive)->busy = 1;
+		pmac_ide_check_dma(drive);
+		HWGROUP(drive)->busy = 0;
+		spin_unlock_irq(&io_request_lock);
+	}
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+}
+
+static void idepmac_sleep_interface(int i, unsigned base, int mediabay)
 {
 	struct device_node* np = pmac_ide[i].node;
-	int j;
 
-	/* Revive IDE disk and controller */
+	/* We clear the timings */
+	pmac_ide[i].timings[0] = 0;
+	pmac_ide[i].timings[1] = 0;
+	
+	/* The media bay will handle itself just fine */
+	if (mediabay)
+		return;
+	
+	/* Disable and reset the bus */
+	feature_set(np, FEATURE_IDE0_reset);
+	feature_clear(np, FEATURE_IDE0_enable);
 	switch(pmac_ide[i].aapl_bus_id) {
 	    case 0:
 		feature_set(np, FEATURE_IDE0_reset);
-		mdelay(10);
- 		feature_set(np, FEATURE_IDE0_enable);
-		mdelay(10);
-		feature_clear(np, FEATURE_IDE0_reset);
+		feature_clear(np, FEATURE_IDE0_enable);
 		break;
 	    case 1:
 		feature_set(np, FEATURE_IDE1_reset);
-		mdelay(10);
- 		feature_set(np, FEATURE_IDE1_enable);
-		mdelay(10);
-		feature_clear(np, FEATURE_IDE1_reset);
+		feature_clear(np, FEATURE_IDE1_enable);
 		break;
 	    case 2:
-	    	/* This one exists only for KL, I don't know
-		   about any enable bit */
 		feature_set(np, FEATURE_IDE2_reset);
-		mdelay(10);
-		feature_clear(np, FEATURE_IDE2_reset);
 		break;
 	}
-	mdelay(IDE_WAKEUP_DELAY_MS);
-
-	/* Reset timings */
-	pmac_ide_selectproc(&ide_hwifs[i].drives[0]);
-	mdelay(10);
-
-	/* Wait up to 10 seconds (enough for recent drives) */
-	for (j = 0; j < 100; j++) {
-		int status;
-		mdelay(100);
-		status = inb(base + 0x70);
-		if (!(status & BUSY_STAT))
-			break;
-	}
 }
 
-/* Here we handle media bay devices */
-static void
-idepmac_wake_bay(int i, unsigned long base)
+static void idepmac_wake_interface(int i, unsigned long base, int mediabay)
 {
-	int timeout;
+	struct device_node* np = pmac_ide[i].node;
 
+	if (!mediabay) {
+		/* Revive IDE disk and controller */
+		switch(pmac_ide[i].aapl_bus_id) {
+		    case 0:
+			feature_set(np, FEATURE_IDE0_reset);
+			feature_set(np, FEATURE_IOBUS_enable);
+			mdelay(10);
+	 		feature_set(np, FEATURE_IDE0_enable);
+			mdelay(10);
+			feature_clear(np, FEATURE_IDE0_reset);
+			break;
+		    case 1:
+			feature_set(np, FEATURE_IDE1_reset);
+			feature_set(np, FEATURE_IOBUS_enable);
+			mdelay(10);
+	 		feature_set(np, FEATURE_IDE1_enable);
+			mdelay(10);
+			feature_clear(np, FEATURE_IDE1_reset);
+			break;
+		    case 2:
+		    	/* This one exists only for KL, I don't know
+			   about any enable bit */
+			feature_set(np, FEATURE_IDE2_reset);
+			mdelay(10);
+			feature_clear(np, FEATURE_IDE2_reset);
+			break;
+		}
+	}
+	
 	/* Reset timings */
 	pmac_ide_selectproc(&ide_hwifs[i].drives[0]);
 	mdelay(10);
-
-	timeout = 10000;
-	while ((inb(base + 0x70) & BUSY_STAT) && timeout) {
-		mdelay(1);
-		--timeout;
-	}
 }
 
 /* Note: We support only master drives for now. This will have to be
@@ -1128,6 +1182,8 @@
 {
 	int i, ret;
 	unsigned long base;
+	unsigned long flags;
+	int big_delay;
 
 	switch (when) {
 	case PBOOK_SLEEP_REQUEST:
@@ -1136,34 +1192,104 @@
 		break;
 	case PBOOK_SLEEP_NOW:
 		for (i = 0; i < pmac_ide_count; ++i) {
+			ide_hwif_t *hwif;
+			ide_drive_t *drive;
+			int unlock = 0;
+
 			if ((base = pmac_ide[i].regbase) == 0)
-				continue;
+				continue;	
+
+			hwif = &ide_hwifs[i];
+			drive = &hwif->drives[0];
+			
+			if (drive->present) {
+				/* Wait for HW group to complete operations */
+				if (ide_spin_wait_hwgroup(drive)) {
+					// What can we do here ? Wake drive we had already
+					// put to sleep and return an error ?
+				} else {
+					unlock = 1;
+					/* Lock HW group */
+					HWGROUP(drive)->busy = 1;
+
+					/* Stop the device */
+					idepmac_sleep_device(drive, i, base);
+				
+				}
+			}
 			/* Disable irq during sleep */
 			disable_irq(pmac_ide[i].irq);
+			if (unlock)
+				spin_unlock_irq(&io_request_lock);
+			
+			/* Check if this is a media bay with an IDE device or not
+			 * a media bay.
+			 */
 			ret = check_media_bay_by_base(base, MB_CD);
-			if ((ret == -ENODEV) && ide_hwifs[i].drives[0].present)
-				/* not media bay - put the disk to sleep */
-				idepmac_sleep_disk(i, base);
+			if ((ret == 0) || (ret == -ENODEV))
+				idepmac_sleep_interface(i, base, (ret == 0));
 		}
 		break;
 	case PBOOK_WAKE:
+		big_delay = 0;
+		for (i = 0; i < pmac_ide_count; ++i) {
+
+			if ((base = pmac_ide[i].regbase) == 0)
+				continue;
+				
+			/* Check if this is a media bay with an IDE device or not
+			 * a media bay
+			 */
+			ret = check_media_bay_by_base(base, MB_CD);
+			if ((ret == 0) || (ret == -ENODEV)) {
+				idepmac_wake_interface(i, base, (ret == 0));				
+				big_delay = 1;
+			}
+
+		}
+		/* Let hardware get up to speed */
+		if (big_delay)
+			mdelay(IDE_WAKEUP_DELAY_MS);
+	
 		for (i = 0; i < pmac_ide_count; ++i) {
 			ide_hwif_t *hwif;
+			ide_drive_t *drive;			
+			int j, used_dma;
+			
 			if ((base = pmac_ide[i].regbase) == 0)
 				continue;
+				
 			hwif = &ide_hwifs[i];
-		        /* We don't handle media bay devices this way */
-			ret = check_media_bay_by_base(base, MB_CD);
-			if ((ret == -ENODEV) && ide_hwifs[i].drives[0].present)
-				idepmac_wake_disk(i, base);
-			else if (ret == 0)
-				idepmac_wake_bay(i, base);
-			enable_irq(pmac_ide[i].irq);
+			drive = &hwif->drives[0];
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
-			if (hwif->drives[0].present && hwif->drives[0].using_dma)
-				pmac_ide_check_dma(&hwif->drives[0]);
-#endif				
+			/* Wait for the drive to come up and set it's DMA */
+			if (drive->present) {
+				/* Wait up to 20 seconds */
+				for (j = 0; j < 200; j++) {
+					int status;
+					mdelay(100);
+					status = inb(base + 0x70);
+					if (!(status & BUSY_STAT))
+						break;
+				}
+			}
+			
+			/* We don't have re-configured DMA yet */
+			used_dma = drive->using_dma;
+			drive->using_dma = 0;
+
+			/* We resume processing on the HW group */
+			spin_lock_irqsave(&io_request_lock, flags);
+			enable_irq(pmac_ide[i].irq);
+			if (drive->present)
+				HWGROUP(drive)->busy = 0;
+			spin_unlock_irqrestore(&io_request_lock, flags);
+			
+			/* Wake the device
+			 * We could handle the slave here
+			 */
+			if (drive->present)
+				idepmac_wake_device(drive, used_dma);
 		}
 		break;
 	}
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide.c linux/drivers/ide/ide.c
--- v2.4.10/linux/drivers/ide/ide.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/ide.c	Sun Oct  7 20:11:18 2001
@@ -1146,7 +1146,9 @@
 		byte sel;
 #ifdef DEBUG
 		printk("%s: DRIVE_TASK_CMD data=x%02x cmd=0x%02x fr=0x%02x ns=0x%02x sc=0x%02x lcyl=0x%02x hcyl=0x%02x sel=0x%02x\n",
-			drive->name, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+			drive->name,
+			args[0], args[1], args[2], args[3],
+			args[4], args[5], args[6], args[7]);
 #endif
 		OUT_BYTE(args[1], IDE_FEATURE_REG);
 		OUT_BYTE(args[3], IDE_SECTOR_REG);
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/ide_modes.h linux/drivers/ide/ide_modes.h
--- v2.4.10/linux/drivers/ide/ide_modes.h	Tue Aug  7 12:50:04 2001
+++ linux/drivers/ide/ide_modes.h	Tue Oct  9 15:22:32 2001
@@ -201,7 +201,7 @@
 		}
 
 #if 0
-		if (drive->id->major_rev_num & 0x0004) printf("ATA-2 ");
+		if (drive->id->major_rev_num & 0x0004) printk("ATA-2 ");
 #endif
 
 		/*
diff -u --recursive --new-file v2.4.10/linux/drivers/ide/pdcraid.c linux/drivers/ide/pdcraid.c
--- v2.4.10/linux/drivers/ide/pdcraid.c	Sun Sep 23 11:40:57 2001
+++ linux/drivers/ide/pdcraid.c	Sun Sep 30 12:26:05 2001
@@ -36,14 +36,32 @@
 static int pdcraid_open(struct inode * inode, struct file * filp);
 static int pdcraid_release(struct inode * inode, struct file * filp);
 static int pdcraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-static int pdcraid_make_request (request_queue_t *q, int rw, struct buffer_head * bh);
+static int pdcraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh);
+static int pdcraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh);
 
+struct disk_dev {
+	int major;
+	int minor;
+	int device;
+};
+
+static struct disk_dev devlist[]= {
+	{IDE0_MAJOR,  0,  -1 },
+	{IDE0_MAJOR, 64,  -1 },
+	{IDE1_MAJOR,  0,  -1 },
+	{IDE1_MAJOR, 64,  -1 },
+	{IDE2_MAJOR,  0,  -1 },
+	{IDE2_MAJOR, 64,  -1 },
+	{IDE3_MAJOR,  0,  -1 },
+	{IDE3_MAJOR, 64,  -1 },
+};
 
 
 struct pdcdisk {
 	kdev_t	device;
 	unsigned long sectors;
 	struct block_device *bdev;
+	unsigned long last_pos;
 };
 
 struct pdcraid {
@@ -58,21 +76,31 @@
 	unsigned int cutoff_disks[8];
 };
 
-static struct raid_device_operations pdcraid_ops = {
+static struct raid_device_operations pdcraid0_ops = {
         open:                   pdcraid_open,
 	release:                pdcraid_release,
 	ioctl:			pdcraid_ioctl,
-	make_request:		pdcraid_make_request
+	make_request:		pdcraid0_make_request
+};
+
+static struct raid_device_operations pdcraid1_ops = {
+        open:                   pdcraid_open,
+	release:                pdcraid_release,
+	ioctl:			pdcraid_ioctl,
+	make_request:		pdcraid1_make_request
 };
 
 static struct pdcraid raid[16];
 
+
 static int pdcraid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	unsigned int minor;
-   	unsigned long sectors;
+   	unsigned long sectors,*larg;
 
-	if (!inode || !inode->i_rdev) 	
+	
+
+	if (!inode || !inode->i_rdev) 
 		return -EINVAL;
 
 	minor = MINOR(inode->i_rdev)>>SHIFT;
@@ -121,6 +149,7 @@
 			return blk_ioctl(inode->i_rdev, cmd, arg);
 
 		default:
+			printk("Invalid ioctl \n");
 			return -EINVAL;
 	};
 
@@ -128,7 +157,49 @@
 }
 
 
-static int pdcraid_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+unsigned long partition_map_normal(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride)
+{
+	return block + partition_off;
+}
+
+unsigned long partition_map_linux(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride)
+{
+	unsigned long newblock;
+	
+	newblock = stride - (partition_off%stride); if (newblock == stride) newblock = 0;
+	newblock += block;
+	newblock = newblock % partition_size;
+	newblock += partition_off;
+	
+	return newblock;
+}
+
+static int funky_remap[8] = { 0, 1,  2, 3, 4, 5, 6, 7 };
+
+unsigned long partition_map_linux_raid0_4disk(unsigned long block, unsigned long partition_off, unsigned long partition_size, int stride)
+{
+	unsigned long newblock,temp,temp2;
+	
+	newblock = stride - (partition_off%stride); if (newblock == stride) newblock = 0;
+
+	if (block < (partition_size / (8*stride))*8*stride ) {
+		temp = block % stride;
+		temp2 = block / stride;
+		temp2 = ((temp2>>3)<<3)|(funky_remap[temp2&7]);
+		block = temp2*stride+temp;
+	}
+
+	
+	newblock += block;
+	newblock = newblock % partition_size;
+	newblock += partition_off;
+	
+	return newblock;
+}
+
+
+
+static int pdcraid0_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
 {
 	unsigned long rsect;
 	unsigned long rsect_left,rsect_accum = 0;
@@ -159,7 +230,7 @@
 
 	/* Partitions need adding of the start sector of the partition to the requested sector */
 	
-	rsect += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect;
+	rsect = partition_map_normal(rsect, ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect, ataraid_gendisk.part[MINOR(bh->b_rdev)].nr_sects, thisraid->stride);
 
 	/* Woops we need to split the request to avoid crossing a stride barrier */
 	if ((rsect/thisraid->stride) != ((rsect+(bh->b_size/512)-1)/thisraid->stride)) {
@@ -208,9 +279,114 @@
 	 * Let the main block layer submit the IO and resolve recursion:
 	 */
 	return 1;
+
+ outerr:
+	buffer_IO_error(bh);
+	return 0;
+}
+
+static int pdcraid1_write_request(request_queue_t *q, int rw, struct buffer_head * bh)
+{
+	struct buffer_head *bh1;
+	struct ataraid_bh_private *private;
+	int device;
+	int i;
+
+	device = (bh->b_rdev >> SHIFT)&MAJOR_MASK;
+	private = ataraid_get_private();
+	if (private==NULL)
+		BUG();
+
+	private->parent = bh;
+	
+	atomic_set(&private->count,raid[device].disks);
+
+
+	for (i = 0; i< raid[device].disks; i++) { 
+		bh1=ataraid_get_bhead();
+		/* If this ever fails we're doomed */
+		if (!bh1)
+			BUG();
+	
+		/* dupe the bufferhead and update the parts that need to be different */
+		memcpy(bh1, bh, sizeof(*bh));
+		
+		bh1->b_end_io = ataraid_end_request;
+		bh1->b_private = private;
+		bh1->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect; /* partition offset */
+		bh1->b_rdev = raid[device].disk[i].device;
+
+		/* update the last known head position for the drive */
+		raid[device].disk[i].last_pos = bh1->b_rsector+(bh1->b_size>>9);
+
+		generic_make_request(rw,bh1);
+	}
+	return 0;
+}
+
+static int pdcraid1_read_request (request_queue_t *q, int rw, struct buffer_head * bh)
+{
+	int device;
+	int dist;
+	int bestsofar,bestdist,i;
+	static int previous;
+
+	/* Reads are simple in principle. Pick a disk and go. 
+	   Initially I cheat by just picking the one which the last known
+	   head position is closest by.
+	   Later on, online/offline checking and performance needs adding */
+	
+	device = (bh->b_rdev >> SHIFT)&MAJOR_MASK;
+	bh->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect;
+
+	bestsofar = 0; 
+	bestdist = raid[device].disk[0].last_pos - bh->b_rsector;
+	if (bestdist<0) 
+		bestdist=-bestdist;
+	if (bestdist>4095)
+		bestdist=4095;
+
+	for (i=1 ; i<raid[device].disks; i++) {
+		dist = raid[device].disk[i].last_pos - bh->b_rsector;
+		if (dist<0) 
+			dist = -dist;
+		if (dist>4095)
+			dist=4095;
+		
+		if (bestdist==dist) {  /* it's a tie; try to do some read balancing */
+			if ((previous>bestsofar)&&(previous<=i))  
+				bestsofar = i;
+			previous = (previous + 1) % raid[device].disks;
+		} else if (bestdist>dist) {
+			bestdist = dist;
+			bestsofar = i;
+		}
+	
+	}
+	
+	bh->b_rdev = raid[device].disk[bestsofar].device; 
+	raid[device].disk[bestsofar].last_pos = bh->b_rsector+(bh->b_size>>9);
+
+	/*
+	 * Let the main block layer submit the IO and resolve recursion:
+	 */
+                          	
+	return 1;
 }
 
 
+static int pdcraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+{
+	/* Read and Write are totally different cases; split them totally here */
+	if (rw==READA)
+		rw = READ;
+	
+	if (rw==READ)
+		return pdcraid1_read_request(q,rw,bh);
+	else
+		return pdcraid1_write_request(q,rw,bh);
+}
+
 #include "pdcraid.h"
 
 static unsigned long calc_pdcblock_offset (int major,int minor)
@@ -288,12 +464,22 @@
 	return sum;
 }
 
-static void __init probedisk(int major, int minor,int device)
+static int cookie = 0;
+
+static void __init probedisk(int devindex,int device, int raidlevel)
 {
 	int i;
+	int major, minor;
         struct promise_raid_conf *prom;
 	static unsigned char block[4096];
+	struct block_device *bdev;
+
+	if (devlist[devindex].device!=-1) /* already assigned to another array */
+		return;
 	
+	major = devlist[devindex].major;
+	minor = devlist[devindex].minor; 
+
         if (read_disk_sb(major,minor,(unsigned char*)&block,sizeof(block)))
         	return;
                                                                                                                  
@@ -302,26 +488,23 @@
         /* the checksums must match */
 	if (prom->checksum != calc_sb_csum((unsigned int*)prom))
 		return;
-	if (prom->raid.type!=0x00) /* Only raid 0 is supported right now */
+	if (prom->raid.type!=raidlevel) /* different raidlevel */
+		return;
+
+	if ((cookie!=0) && (cookie != prom->raid.magic_1)) /* different array */
 		return;
 	
+	cookie = prom->raid.magic_1;
 
 	/* This looks evil. But basically, we have to search for our adapternumber
 	   in the arraydefinition, both of which are in the superblock */	
         for (i=0;(i<prom->raid.total_disks)&&(i<8);i++) {
         	if ( (prom->raid.disk[i].channel== prom->raid.channel) &&
         	     (prom->raid.disk[i].device == prom->raid.device) ) {
-			struct block_device *bdev = bdget(MKDEV(major,minor));
-			if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) {
-        	        	struct gendisk *gd;
-        	        	int j;
-        	        	/* This is supposed to prevent others from stealing our underlying disks */
+
+        	        bdev = bdget(MKDEV(major,minor));
+        	        if (bdev && blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_RAW) == 0) {
 				raid[device].disk[i].bdev = bdev;
-				gd=get_gendisk(major);
-				if (gd!=NULL) {
-					for (j=1+(minor<<gd->minor_shift);j<((minor+1)<<gd->minor_shift);j++) 
-						gd->part[j].nr_sects=0;					
-				}
 			}
 			raid[device].disk[i].device = MKDEV(major,minor);
 			raid[device].disk[i].sectors = prom->raid.disk_secs;
@@ -331,7 +514,7 @@
 			raid[device].geom.heads = prom->raid.heads+1;
 			raid[device].geom.sectors = prom->raid.sectors;
 			raid[device].geom.cylinders = prom->raid.cylinders+1;
-			
+			devlist[devindex].device=device;
         	     }
         }
 	               
@@ -362,62 +545,91 @@
 	}
 }
 			   
-static __init int pdcraid_init_one(int device)
+static __init int pdcraid_init_one(int device,int raidlevel)
 {
+	request_queue_t *q;
 	int i,count;
 
-	probedisk(IDE0_MAJOR,  0, device);
-	probedisk(IDE0_MAJOR, 64, device);
-	probedisk(IDE1_MAJOR,  0, device);
-	probedisk(IDE1_MAJOR, 64, device);
-	probedisk(IDE2_MAJOR,  0, device);
-	probedisk(IDE2_MAJOR, 64, device);
-	probedisk(IDE3_MAJOR,  0, device);
-	probedisk(IDE3_MAJOR, 64, device);
+	probedisk(0, device, raidlevel);
+	probedisk(1, device, raidlevel);
+	probedisk(2, device, raidlevel);
+	probedisk(3, device, raidlevel);
+	probedisk(4, device, raidlevel);
+	probedisk(5, device, raidlevel);
+	probedisk(6, device, raidlevel);
+	probedisk(7, device, raidlevel);
 	
-	fill_cutoff(device);
+	if (raidlevel==0)
+		fill_cutoff(device);
 	
 	/* Initialize the gendisk structure */
 	
 	ataraid_register_disk(device,raid[device].sectors);        
 		
 	count=0;
-	printk(KERN_INFO "Promise Fasttrak(tm) Softwareraid driver for linux version 0.02\n");
 	
 	for (i=0;i<8;i++) {
 		if (raid[device].disk[i].device!=0) {
-			printk(KERN_INFO "Drive %i is %li Mb \n",
-				i,raid[device].disk[i].sectors/2048);
+			printk(KERN_INFO "Drive %i is %li Mb (%i / %i) \n",
+				i,raid[device].disk[i].sectors/2048,MAJOR(raid[device].disk[i].device),MINOR(raid[device].disk[i].device));
 			count++;
 		}
 	}
 	if (count) {
-		printk(KERN_INFO "Raid array consists of %i drives. \n",count);
+		printk(KERN_INFO "Raid%i array consists of %i drives. \n",raidlevel,count);
 		return 0;
 	} else {
-		printk(KERN_INFO "No raid array found\n");
 		return -ENODEV;
 	}
 }
 
 static __init int pdcraid_init(void)
 {
-	int retval,device;
+	int i,retval,device,count=0;
+
+	do {
 	
-	device=ataraid_get_device(&pdcraid_ops);
-	if (device<0)
-		return -ENODEV;
-	retval = pdcraid_init_one(device);
-	if (retval)
-		ataraid_release_device(device);
-	return retval;
+		cookie = 0;
+		device=ataraid_get_device(&pdcraid0_ops);
+		if (device<0)
+			break;
+		retval = pdcraid_init_one(device,0);
+		if (retval) {
+			ataraid_release_device(device);
+			break;
+		} else {
+			count++;
+		}
+	} while (1);
+
+	do {
+	
+		cookie = 0;
+		device=ataraid_get_device(&pdcraid1_ops);
+		if (device<0)
+			break;
+		retval = pdcraid_init_one(device,1);
+		if (retval) {
+			ataraid_release_device(device);
+			break;
+		} else {
+			count++;
+		}
+	} while (1);
+
+	if (count) {
+		printk(KERN_INFO "Promise Fasttrak(tm) Softwareraid driver for linux version 0.03beta\n");
+		return 0;
+	}
+	printk(KERN_DEBUG "Promise Fasttrak(tm) Softwareraid driver 0.03beta: No raid array found\n");
+	return -ENODEV;
 }
 
 static void __exit pdcraid_exit (void)
 {
 	int i,device;
 	for (device = 0; device<16; device++) {
-		for (i=0;i<8;i++)  {
+		for (i=0;i<8;i++) {
 			struct block_device *bdev = raid[device].disk[i].bdev;
 			raid[device].disk[i].bdev = NULL;
 			if (bdev)
@@ -441,3 +653,4 @@
 
 module_init(pdcraid_init);
 module_exit(pdcraid_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/Makefile linux/drivers/ieee1394/Makefile
--- v2.4.10/linux/drivers/ieee1394/Makefile	Wed Jul 25 17:10:20 2001
+++ linux/drivers/ieee1394/Makefile	Sun Oct  7 16:41:35 2001
@@ -4,7 +4,7 @@
 
 O_TARGET := ieee1394drv.o
 
-export-objs := ieee1394_syms.o
+export-objs := ieee1394_syms.o ohci1394.o
 
 list-multi := ieee1394.o
 ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/highlevel.c linux/drivers/ieee1394/highlevel.c
--- v2.4.10/linux/drivers/ieee1394/highlevel.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/ieee1394/highlevel.c	Mon Oct  1 21:24:24 2001
@@ -154,21 +154,18 @@
 }
 
 
-#define DEFINE_MULTIPLEXER(Function) \
-void highlevel_##Function(struct hpsb_host *host) \
-{ \
-        struct list_head *entry,*next; \
-        void (*funcptr)(struct hpsb_host*); \
-        read_lock(&hl_drivers_lock); \
-        entry = hl_drivers.next; \
-        while (entry != &hl_drivers) { \
-        	next = entry->next; \
-                funcptr = list_entry(entry, struct hpsb_highlevel, hl_list) \
-                          ->op->Function; \
-                if (funcptr) funcptr(host); \
-                entry = next; \
-        } \
-        read_unlock(&hl_drivers_lock); \
+#define DEFINE_MULTIPLEXER(Function)			\
+void highlevel_##Function(struct hpsb_host *host)	\
+{							\
+	struct list_head *lh;				\
+	void (*funcptr)(struct hpsb_host*);		\
+	read_lock(&hl_drivers_lock);			\
+	list_for_each(lh, &hl_drivers) {		\
+		funcptr = list_entry(lh, struct hpsb_highlevel, hl_list) \
+				->op->Function;		\
+		if (funcptr) funcptr(host);		\
+	}						\
+	read_unlock(&hl_drivers_lock);			\
 }
 
 DEFINE_MULTIPLEXER(add_host)
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/hosts.c linux/drivers/ieee1394/hosts.c
--- v2.4.10/linux/drivers/ieee1394/hosts.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/hosts.c	Mon Oct  1 21:24:24 2001
@@ -23,8 +23,8 @@
 #include "highlevel.h"
 
 
-static struct hpsb_host_template *templates = NULL;
-spinlock_t templates_lock = SPIN_LOCK_UNLOCKED;
+static LIST_HEAD(templates);
+static spinlock_t templates_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * This function calls the add_host/remove_host hooks for every host currently
@@ -32,13 +32,16 @@
  */
 void hl_all_hosts(struct hpsb_highlevel *hl, int init)
 {
+	struct list_head *tlh, *hlh;
         struct hpsb_host_template *tmpl;
         struct hpsb_host *host;
 
         spin_lock(&templates_lock);
 
-        for (tmpl = templates; tmpl != NULL; tmpl = tmpl->next) {
-                for (host = tmpl->hosts; host != NULL; host = host->next) {
+	list_for_each(tlh, &templates) {
+                tmpl = list_entry(tlh, struct hpsb_host_template, list);
+		list_for_each(hlh, &tmpl->hosts) {
+			host = list_entry(hlh, struct hpsb_host, list);
                         if (host->initialized) {
                                 if (init) {
                                         if (hl->op->add_host) {
@@ -58,21 +61,24 @@
 
 int hpsb_inc_host_usage(struct hpsb_host *host)
 {
+	struct list_head *tlh, *hlh;
         struct hpsb_host_template *tmpl;
-        struct hpsb_host *h;
         int retval = 0;
 	unsigned long flags;
 
         spin_lock_irqsave(&templates_lock, flags);
 
-        for (tmpl = templates; (tmpl != NULL) && !retval; tmpl = tmpl->next) {
-                for (h = tmpl->hosts; h != NULL; h = h->next) {
-                        if (h == host) {
-                                tmpl->devctl(h, MODIFY_USAGE, 1);
+	list_for_each(tlh, &templates) {
+                tmpl = list_entry(tlh, struct hpsb_host_template, list);
+		list_for_each(hlh, &tmpl->hosts) {
+			if (host == list_entry(hlh, struct hpsb_host, list)) {
+                                tmpl->devctl(host, MODIFY_USAGE, 1);
                                 retval = 1;
                                 break;
                         }
                 }
+		if (retval)
+			break;
         }
 
         spin_unlock_irqrestore(&templates_lock, flags);
@@ -113,32 +119,22 @@
         h->speed_map = (u8 *)(h->csr.speed_map + 2);
 
         h->template = tmpl;
-        if (hd_size) {
+        if (hd_size)
                 h->hostdata = &h->embedded_hostdata[0];
-        }
-
-        if (tmpl->hosts == NULL) {
-                tmpl->hosts = h;
-        } else {
-                struct hpsb_host *last = tmpl->hosts;
 
-                while (last->next != NULL) {
-                        last = last->next;
-                }
-                last->next = h;
-        }
+	list_add_tail(&h->list, &tmpl->hosts);
 
         return h;
 }
 
 static void free_all_hosts(struct hpsb_host_template *tmpl)
 {
-        struct hpsb_host *next, *host = tmpl->hosts;
+	struct list_head *hlh, *next;
+        struct hpsb_host *host;
 
-        while (host) {
-                next = host->next;
+	list_for_each_safe(hlh, next, &tmpl->hosts) {
+		host = list_entry(hlh, struct hpsb_host, list);
                 vfree(host);
-                host = next;
         }
 }
 
@@ -146,11 +142,13 @@
 static void init_hosts(struct hpsb_host_template *tmpl)
 {
         int count;
+	struct list_head *hlh;
         struct hpsb_host *host;
 
         count = tmpl->detect_hosts(tmpl);
 
-        for (host = tmpl->hosts; host != NULL; host = host->next) {
+	list_for_each(hlh, &tmpl->hosts) {
+		host = list_entry(hlh, struct hpsb_host, list);
                 if (tmpl->initialize_host(host)) {
                         host->initialized = 1;
 
@@ -166,9 +164,11 @@
 
 static void shutdown_hosts(struct hpsb_host_template *tmpl)
 {
+	struct list_head *hlh;
         struct hpsb_host *host;
 
-        for (host = tmpl->hosts; host != NULL; host = host->next) {
+	list_for_each(hlh, &tmpl->hosts) {
+		host = list_entry(hlh, struct hpsb_host, list);
                 if (host->initialized) {
                         host->initialized = 0;
                         abort_requests(host);
@@ -188,68 +188,17 @@
 }
 
 
-static int add_template(struct hpsb_host_template *new)
-{
-        new->next = NULL;
-        new->hosts = NULL;
-        new->number_of_hosts = 0;
-
-        spin_lock(&templates_lock);
-        if (templates == NULL) {
-                templates = new;
-        } else {
-                struct hpsb_host_template *last = templates;
-                while (last->next != NULL) {
-                        last = last->next;
-                }
-                last->next = new;
-        }
-        spin_unlock(&templates_lock);
-
-        return 0;
-}
-
-static int remove_template(struct hpsb_host_template *tmpl)
-{
-        int retval = 0;
-
-        if (tmpl->number_of_hosts) {
-                HPSB_ERR("attempted to remove busy host template "
-                         "of %s at address 0x%p", tmpl->name, tmpl);
-                return 1;
-        }
-
-        spin_lock(&templates_lock);
-        if (templates == tmpl) {
-                templates = tmpl->next;
-        } else {
-                struct hpsb_host_template *t;
-
-                t = templates;
-                while (t->next != tmpl && t->next != NULL) {
-                        t = t->next;
-                }
-
-                if (t->next == NULL) {
-                        HPSB_ERR("attempted to remove unregistered host template "
-                                 "of %s at address 0x%p", tmpl->name, tmpl);
-                        retval = -1;
-                } else {
-                        t->next = tmpl->next;
-                }
-        }
-        spin_unlock(&templates_lock);
-
-        return retval;
-}
-
-
 /*
  * The following two functions are exported symbols for module usage.
  */
 int hpsb_register_lowlevel(struct hpsb_host_template *tmpl)
 {
-        add_template(tmpl);
+	INIT_LIST_HEAD(&tmpl->hosts);
+	tmpl->number_of_hosts = 0;
+
+        spin_lock(&templates_lock);
+	list_add_tail(&tmpl->list, &templates);
+        spin_unlock(&templates_lock);
 
 	/* PCI cards should be smart and use the PCI detection layer, and
 	 * not this one shot deal. detect_hosts() will be obsoleted soon. */
@@ -265,7 +214,12 @@
 {
         shutdown_hosts(tmpl);
 
-        if (remove_template(tmpl)) {
-                HPSB_PANIC("remove_template failed on %s", tmpl->name);
-        }
+        if (tmpl->number_of_hosts)
+                HPSB_PANIC("attempted to remove busy host template "
+			   "of %s at address 0x%p", tmpl->name, tmpl);
+	else {
+		spin_lock(&templates_lock);
+		list_del(&tmpl->list);
+		spin_unlock(&templates_lock);
+	}
 }
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/hosts.h linux/drivers/ieee1394/hosts.h
--- v2.4.10/linux/drivers/ieee1394/hosts.h	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/hosts.h	Mon Oct  1 21:24:24 2001
@@ -3,6 +3,7 @@
 
 #include <linux/wait.h>
 #include <linux/tqueue.h>
+#include <linux/list.h>
 #include <asm/semaphore.h>
 
 #include "ieee1394_types.h"
@@ -13,7 +14,7 @@
 
 struct hpsb_host {
 /* private fields (hosts, do not use them) */
-        struct hpsb_host *next;
+	struct list_head list;
 
         atomic_t generation;
 
@@ -109,9 +110,9 @@
 };
 
 struct hpsb_host_template {
-        struct hpsb_host_template *next;
+	struct list_head list;
 
-        struct hpsb_host *hosts;
+        struct list_head hosts;
         int number_of_hosts;
 
         /* fields above will be ignored and overwritten after registering */
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
--- v2.4.10/linux/drivers/ieee1394/ieee1394_core.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/ieee1394/ieee1394_core.c	Mon Oct  1 21:24:24 2001
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <asm/bitops.h>
 #include <asm/byteorder.h>
 #include <asm/semaphore.h>
@@ -30,6 +31,13 @@
 #include "csr.h"
 #include "nodemgr.h"
 
+/*
+ * Disable the nodemgr detection and config rom reading functionality.
+ */
+MODULE_PARM(disable_nodemgr, "i");
+MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
+static int disable_nodemgr = 0;
+
 static kmem_cache_t *hpsb_packet_cache;
 
 
@@ -95,7 +103,7 @@
         INIT_TQ_HEAD(packet->complete_tq);
         INIT_LIST_HEAD(&packet->list);
         sema_init(&packet->state_change, 0);
-        packet->state = unused;
+        packet->state = hpsb_unused;
         packet->generation = -1;
         packet->data_be = 1;
 
@@ -352,14 +360,14 @@
         }
 
         if (ackcode != ACK_PENDING || !packet->expect_response) {
-                packet->state = completed;
+                packet->state = hpsb_complete;
                 up(&packet->state_change);
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
                 return;
         }
 
-        packet->state = pending;
+        packet->state = hpsb_pending;
         packet->sendtime = jiffies;
 
         spin_lock_irqsave(&host->pending_pkt_lock, flags);
@@ -393,9 +401,9 @@
                 return 0;
         }
 
-        packet->state = queued;
+        packet->state = hpsb_queued;
 
-        if (packet->type == async && packet->node_id != ALL_NODES) {
+        if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
                 packet->speed_code =
                         host->speed_map[(host->node_id & NODE_MASK) * 64
                                        + (packet->node_id & NODE_MASK)];
@@ -503,14 +511,14 @@
                 break;
         }
 
-        packet->state = completed;
+        packet->state = hpsb_complete;
         up(&packet->state_change);
         run_task_queue(&packet->complete_tq);
 }
 
 
-struct hpsb_packet *create_reply_packet(struct hpsb_host *host, quadlet_t *data,
-                                        size_t dsize)
+static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
+					       quadlet_t *data, size_t dsize)
 {
         struct hpsb_packet *p;
 
@@ -522,13 +530,15 @@
                 return NULL;
         }
 
-        p->type = async;
-        p->state = unused;
+        p->type = hpsb_async;
+        p->state = hpsb_unused;
         p->host = host;
         p->node_id = data[1] >> 16;
         p->tlabel = (data[0] >> 10) & 0x3f;
         p->no_waiter = 1;
 
+	p->generation = get_hpsb_generation(host);
+
         if (dsize % 4) {
                 p->data[dsize / 4] = 0;
         }
@@ -540,8 +550,8 @@
                 packet = create_reply_packet(host, data, length); \
                 if (packet == NULL) break
 
-void handle_incoming_packet(struct hpsb_host *host, int tcode, quadlet_t *data,
-                            size_t size, int write_acked)
+static void handle_incoming_packet(struct hpsb_host *host, int tcode,
+				   quadlet_t *data, size_t size, int write_acked)
 {
         struct hpsb_packet *packet;
         int length, rcode, extcode;
@@ -720,7 +730,7 @@
 
         list_for_each(lh, &llist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
-                packet->state = completed;
+                packet->state = hpsb_complete;
                 packet->ack_code = ACKX_ABORTED;
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
@@ -732,7 +742,7 @@
         unsigned long flags;
         struct hpsb_packet *packet;
         unsigned long expire;
-        struct list_head *lh;
+        struct list_head *lh, *next;
         LIST_HEAD(expiredlist);
 
         spin_lock_irqsave(&host->csr.lock, flags);
@@ -746,8 +756,9 @@
 
         spin_lock_irqsave(&host->pending_pkt_lock, flags);
 
-        list_for_each(lh, &host->pending_packets) {
+	for (lh = host->pending_packets.next; lh != &host->pending_packets; lh = next) {
                 packet = list_entry(lh, struct hpsb_packet, list);
+		next = lh->next;
                 if (time_before(packet->sendtime + expire, jiffies)) {
                         list_del(&packet->list);
                         list_add(&packet->list, &expiredlist);
@@ -761,7 +772,7 @@
 
         list_for_each(lh, &expiredlist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
-                packet->state = completed;
+                packet->state = hpsb_complete;
                 packet->ack_code = ACKX_TIMEOUT;
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
@@ -775,13 +786,19 @@
 					      0, 0, NULL, NULL);
 	init_hpsb_highlevel();
 	init_csr();
-	init_ieee1394_nodemgr();
+	if (!disable_nodemgr)
+		init_ieee1394_nodemgr();
+	else
+		HPSB_INFO("nodemgr functionality disabled");
+
 	return 0;
 }
 
 static void __exit ieee1394_cleanup(void)
 {
-	cleanup_ieee1394_nodemgr();
+	if (!disable_nodemgr)
+		cleanup_ieee1394_nodemgr();
+
 	cleanup_csr();
 	kmem_cache_destroy(hpsb_packet_cache);
 }
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ieee1394_core.h linux/drivers/ieee1394/ieee1394_core.h
--- v2.4.10/linux/drivers/ieee1394/ieee1394_core.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/ieee1394/ieee1394_core.h	Mon Oct  1 21:24:24 2001
@@ -20,16 +20,16 @@
 
         /* Async and Iso types should be clear, raw means send-as-is, do not
          * CRC!  Byte swapping shall still be done in this case. */
-        enum { async, iso, raw } __attribute__((packed)) type;
+        enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
 
         /* Okay, this is core internal and a no care for hosts.
          * queued   = queued for sending
          * pending  = sent, waiting for response
-         * completed = processing completed, successful or not
+         * complete = processing completed, successful or not
          * incoming = incoming packet
          */
         enum { 
-                unused, queued, pending, completed, incoming 
+                hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete, hpsb_incoming 
         } __attribute__((packed)) state;
 
         /* These are core internal. */
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ieee1394_hotplug.h linux/drivers/ieee1394/ieee1394_hotplug.h
--- v2.4.10/linux/drivers/ieee1394/ieee1394_hotplug.h	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ieee1394_hotplug.h	Mon Oct  1 21:24:24 2001
@@ -2,32 +2,75 @@
 #define _IEEE1394_HOTPLUG_H
 
 #include "ieee1394_core.h"
+#include "nodemgr.h"
 
-#define IEEE1394_DEVICE_ID_MATCH_VENDOR_ID		0x0001
-#define IEEE1394_DEVICE_ID_MATCH_MODEL_ID		0x0002
-#define IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_ID	0x0004
-#define IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_VERSION	0x0008
+#define IEEE1394_MATCH_VENDOR_ID	0x0001
+#define IEEE1394_MATCH_MODEL_ID		0x0002
+#define IEEE1394_MATCH_SPECIFIER_ID	0x0004
+#define IEEE1394_MATCH_VERSION		0x0008
 
 struct ieee1394_device_id {
 	u32 match_flags;
 	u32 vendor_id;
 	u32 model_id;
-	u32 sw_specifier_id;
-	u32 sw_specifier_version;
+	u32 specifier_id;
+	u32 version;
+	void *driver_data;
 };
 
-#define IEEE1394_PROTOCOL(id, version) {				       \
-	match_flags:		IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_ID |     \
-				IEEE1394_DEVICE_ID_MATCH_SW_SPECIFIER_VERSION, \
-	sw_specifier_id:	id,					       \
-	sw_specifier_version:	version					       \
-}
-
-#define IEEE1394_DEVICE(vendor_id, model_id) {			\
-	match_flags: 	IEEE1394_DEVICE_ID_MATCH_VENDOR_ID |	\
-			IEEE1394_DEVICE_ID_MATCH_MODEL_ID,	\
-	vendor_id:	vendor_id,				\
-	model_id:	vendor_id,				\
-}
+struct hpsb_protocol_driver {
+	/* The name of the driver, e.g. SBP2 or IP1394 */
+	const char *name;
+
+	/* 
+	 * The device id table describing the protocols and/or devices
+	 * supported by this driver.  This is used by the nodemgr to
+	 * decide if a driver could support a given node, but the
+	 * probe function below can implement further protocol
+	 * dependent or vendor dependent checking.
+	 */
+	struct ieee1394_device_id *id_table;
+
+	/* 
+	 * The probe function is called when a device is added to the
+	 * bus and the nodemgr finds a matching entry in the drivers
+	 * device id table or when registering this driver and a
+	 * previously unhandled device can be handled.  The driver may
+	 * decline to handle the device based on further investigation
+	 * of the device (or whatever reason) in which case a negative
+	 * error code should be returned, otherwise 0 should be
+	 * returned. The driver may use the driver_data field in the
+	 * unit directory to store per device driver specific data.
+	 */
+	int (*probe)(struct unit_directory *ud);
+
+	/* 
+	 * The disconnect function is called when a device is removed
+	 * from the bus or if it wasn't possible to read the guid
+	 * after the last bus reset.
+	 */
+	void (*disconnect)(struct unit_directory *ud);
+
+	/* 
+	 * The update function is called when the node has just
+	 * survived a bus reset, i.e. it is still present on the bus.
+	 * However, it may be necessary to reestablish the connection
+	 * or login into the node again, depending on the protocol.
+	 */
+	void (*update)(struct unit_directory *ud);
+
+	/* Driver in list of all registered drivers */
+	struct list_head list;
+
+	/* The list of unit directories managed by this driver */
+	struct list_head unit_directories;
+};
+
+int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
+void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
+
+int hpsb_claim_unit_directory(struct unit_directory *ud,
+			      struct hpsb_protocol_driver *driver);
+void hpsb_release_unit_directory(struct unit_directory *ud);
 
 #endif /* _IEEE1394_HOTPLUG_H */
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ieee1394_syms.c linux/drivers/ieee1394/ieee1394_syms.c
--- v2.4.10/linux/drivers/ieee1394/ieee1394_syms.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ieee1394_syms.c	Mon Oct  1 21:24:24 2001
@@ -18,6 +18,7 @@
 #include "hosts.h"
 #include "ieee1394_core.h"
 #include "ieee1394_transactions.h"
+#include "ieee1394_hotplug.h"
 #include "highlevel.h"
 #include "nodemgr.h"
 
@@ -75,7 +76,12 @@
 EXPORT_SYMBOL(highlevel_remove_host);
 EXPORT_SYMBOL(highlevel_host_reset);
 EXPORT_SYMBOL(highlevel_add_one_host);
+
 EXPORT_SYMBOL(hpsb_guid_get_entry);
 EXPORT_SYMBOL(hpsb_nodeid_get_entry);
 EXPORT_SYMBOL(hpsb_get_host_by_ne);
 EXPORT_SYMBOL(hpsb_guid_fill_packet);
+EXPORT_SYMBOL(hpsb_register_protocol);
+EXPORT_SYMBOL(hpsb_unregister_protocol);
+EXPORT_SYMBOL(hpsb_release_unit_directory);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ieee1394_transactions.c linux/drivers/ieee1394/ieee1394_transactions.c
--- v2.4.10/linux/drivers/ieee1394/ieee1394_transactions.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ieee1394_transactions.c	Mon Oct  1 21:24:24 2001
@@ -131,7 +131,7 @@
 
         packet->header_size = 4;
         packet->data_size = length;
-        packet->type = iso;
+        packet->type = hpsb_iso;
         packet->tcode = TCODE_ISO_DATA;
 }
 
@@ -142,7 +142,7 @@
         packet->header_size = 8;
         packet->data_size = 0;
         packet->expect_response = 0;
-        packet->type = raw;             /* No CRC added */
+        packet->type = hpsb_raw;             /* No CRC added */
         packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */
 }
 
@@ -488,7 +488,9 @@
         if (!packet)
                 return NULL;
 
-        if (length != 4)
+	/* Sometimes this may be called without data, just to allocate the
+	 * packet. */
+        if (length != 4 && buffer)
                 memcpy(packet->data, buffer, length);
 
 	return packet;
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ieee1394_types.h linux/drivers/ieee1394/ieee1394_types.h
--- v2.4.10/linux/drivers/ieee1394/ieee1394_types.h	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ieee1394_types.h	Mon Oct  1 21:24:24 2001
@@ -26,6 +26,13 @@
 #include <linux/spinlock.h>
 #endif
 
+#ifndef list_for_each_safe
+#define list_for_each_safe(pos, n, head) \
+	for (pos = (head)->next, n = pos->next; pos != (head); \
+		pos = n, n = pos->next)
+
+#endif
+
 #ifndef MIN
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/nodemgr.c linux/drivers/ieee1394/nodemgr.c
--- v2.4.10/linux/drivers/ieee1394/nodemgr.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/ieee1394/nodemgr.c	Mon Oct  1 21:24:24 2001
@@ -15,11 +15,13 @@
 #include <asm/atomic.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/kmod.h>
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
 #include "hosts.h"
 #include "ieee1394_transactions.h"
+#include "ieee1394_hotplug.h"
 #include "highlevel.h"
 #include "csr.h"
 #include "nodemgr.h"
@@ -47,6 +49,16 @@
 static LIST_HEAD(node_list);
 static rwlock_t node_lock = RW_LOCK_UNLOCKED;
 
+static LIST_HEAD(driver_list);
+static rwlock_t driver_lock = RW_LOCK_UNLOCKED;
+
+/* The rwlock unit_directory_lock is always held when manipulating the
+ * global unit_directory_list, but this also protects access to the
+ * lists of unit directories stored in the protocol drivers.
+ */
+static LIST_HEAD(unit_directory_list);
+static rwlock_t unit_directory_lock = RW_LOCK_UNLOCKED;
+
 static LIST_HEAD(host_info_list);
 static spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
 
@@ -56,7 +68,12 @@
 	struct list_head list;
 };
 
-static struct node_entry *create_node_entry(void)
+static void nodemgr_process_config_rom(struct node_entry *ne, 
+				       quadlet_t busoptions);
+
+
+static struct node_entry *nodemgr_create_node(octlet_t guid, quadlet_t busoptions,
+					      struct hpsb_host *host, nodeid_t nodeid)
 {
         struct node_entry *ne;
         unsigned long flags;
@@ -66,15 +83,21 @@
 
         INIT_LIST_HEAD(&ne->list);
 	INIT_LIST_HEAD(&ne->unit_directories);
-        ne->guid = (u64) -1;
-        ne->host = NULL;
-        ne->nodeid = 0;
-        atomic_set(&ne->generation, -1);
+        ne->host = host;
+        ne->nodeid = nodeid;
+        ne->guid = guid;
+	atomic_set(&ne->generation, get_hpsb_generation(ne->host));
 
         write_lock_irqsave(&node_lock, flags);
         list_add_tail(&ne->list, &node_list);
         write_unlock_irqrestore(&node_lock, flags);
 
+	nodemgr_process_config_rom (ne, busoptions);
+
+	HPSB_DEBUG("%s added: node " NODE_BUS_FMT ", GUID %016Lx",
+		   (host->node_id == nodeid) ? "Local host" : "Device",
+		   NODE_BUS_ARGS(nodeid), (unsigned long long)guid);
+
         return ne;
 }
 
@@ -104,16 +127,20 @@
 	return NULL;
 }
 
-int nodemgr_read_quadlet(struct node_entry *ne, 
+int nodemgr_read_quadlet(struct node_entry *ne,
 			 octlet_t address, quadlet_t *quad)
 {
-	if (hpsb_read(ne->host, ne->nodeid, address, quad, 4)) {
-		HPSB_DEBUG("read of address %Lx failed", address);
-		return -EAGAIN;
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < 3; i++) {
+		ret = hpsb_read(ne->host, ne->nodeid, address, quad, 4);
+		if (ret != -EAGAIN)
+			break;
 	}
 	*quad = be32_to_cpu(*quad);
 
-	return 0;
+	return ret;
 }
 
 #define CONFIG_ROM_VENDOR_ID		0x03
@@ -137,13 +164,14 @@
 	octlet_t a;
 	quadlet_t quad;
 	int length, i;
-	
 
 	if (!(ud = kmalloc (sizeof *ud, GFP_KERNEL)))
 		goto unit_directory_error;
 
 	memset (ud, 0, sizeof *ud);
+	ud->ne = ne;
 	ud->address = address;
+	ud->arb_count = 0;
 
 	if (nodemgr_read_quadlet(ne, address, &quad))
 		goto unit_directory_error;
@@ -151,7 +179,8 @@
 	a = address + 4;
 
 	for (i = 0; i < length; i++, a += 4) {
-		int code, value;
+		int code;
+		quadlet_t value;
 
 		if (nodemgr_read_quadlet(ne, a, &quad))
 			goto unit_directory_error;
@@ -183,10 +212,20 @@
 		case CONFIG_ROM_DESCRIPTOR_DIRECTORY:
 			/* TODO: read strings... icons? */
 			break;
+
+		default:
+			if (ud->arb_count < 16) {
+				/* Place them in the arbitrary pairs */
+				ud->arb_keys[ud->arb_count] = code;
+				ud->arb_values[ud->arb_count] = value;
+				ud->arb_count++;
+			}
 		}
 	}
 
-	list_add_tail (&ud->list, &ne->unit_directories);
+	list_add_tail(&ud->node_list, &ne->unit_directories);
+	list_add_tail(&ud->driver_list, &unit_directory_list);
+
 	return;
 
 unit_directory_error:	
@@ -194,27 +233,29 @@
 		kfree(ud);
 }
 
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 static void dump_directories (struct node_entry *ne)
 {
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 	struct list_head *l;
 
 	HPSB_DEBUG("vendor_id=0x%06x, capabilities=0x%06x",
 		   ne->vendor_id, ne->capabilities);
 	list_for_each (l, &ne->unit_directories) {
-		struct unit_directory *ud = list_entry (l, struct unit_directory, list);
+		struct unit_directory *ud = list_entry (l, struct unit_directory, node_list);
 		HPSB_DEBUG("unit directory:");
 		if (ud->flags & UNIT_DIRECTORY_VENDOR_ID)
 			HPSB_DEBUG("  vendor_id=0x%06x ", ud->vendor_id);
 		if (ud->flags & UNIT_DIRECTORY_MODEL_ID)
 			HPSB_DEBUG("  model_id=0x%06x ", ud->model_id);
 		if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
-			HPSB_DEBUG("  specifier_id=0x%06x ", ud->specifier_id);
+			HPSB_DEBUG("  sw_specifier_id=0x%06x ", ud->specifier_id);
 		if (ud->flags & UNIT_DIRECTORY_VERSION)
-			HPSB_DEBUG("  version=0x%06x ", ud->version);
+			HPSB_DEBUG("  sw_version=0x%06x ", ud->version);
 	}
-}
+#else
+	return;
 #endif
+}
 
 static void nodemgr_process_root_directory(struct node_entry *ne)
 {
@@ -260,86 +301,383 @@
 			break;
 		}
 	}
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+
 	dump_directories(ne);
+}
+
+#ifdef CONFIG_HOTPLUG
+
+static void nodemgr_call_policy(char *verb, struct unit_directory *ud)
+{
+	char *argv [3], **envp, *buf, *scratch;
+	int i = 0, value;
+
+	if (!hotplug_path [0])
+		return;
+	if (!current->fs->root)
+		return;
+	if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
+		HPSB_DEBUG ("ENOMEM");
+		return;
+	}
+	if (!(buf = kmalloc(256, GFP_KERNEL))) {
+		kfree(envp);
+		HPSB_DEBUG("ENOMEM2");
+		return;
+	}
+
+	/* only one standardized param to hotplug command: type */
+	argv[0] = hotplug_path;
+	argv[1] = "ieee1394";
+	argv[2] = 0;
+
+	/* minimal command environment */
+	envp[i++] = "HOME=/";
+	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	/* hint that policy agent should enter no-stdout debug mode */
+	envp[i++] = "DEBUG=kernel";
+#endif
+	/* extensible set of named bus-specific parameters,
+	 * supporting multiple driver selection algorithms.
+	 */
+	scratch = buf;
+
+	envp[i++] = scratch;
+	scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
+	envp[i++] = scratch;
+	scratch += sprintf(scratch, "VENDOR_ID=%06x", ud->ne->vendor_id) + 1;
+	envp[i++] = scratch;
+	scratch += sprintf(scratch, "GUID=%016Lx", (long long unsigned)ud->ne->guid) + 1;
+	envp[i++] = scratch;
+	scratch += sprintf(scratch, "SPECIFIER_ID=%06x", ud->specifier_id) + 1;
+	envp[i++] = scratch;
+	scratch += sprintf(scratch, "VERSION=%06x", ud->version) + 1;
+	envp[i++] = 0;
+
+	/* NOTE: user mode daemons can call the agents too */
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	HPSB_DEBUG("NodeMgr: %s %s %016Lx", argv[0], verb, (long long unsigned)ud->ne->guid);
 #endif
+	value = call_usermodehelper(argv[0], argv, envp);
+	kfree(buf);
+	kfree(envp);
+	if (value != 0)
+		HPSB_DEBUG("NodeMgr: hotplug policy returned 0x%x", value);
 }
 
-static void register_node(struct hpsb_host *host, nodeid_t nodeid, u64 guid,
-			  quadlet_t busoptions)
+#else
+
+static inline void
+nodemgr_call_policy(char *verb, struct unit_directory *ud)
 {
-        struct node_entry *ne;
-        unsigned long flags, new = 0;
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	HPSB_DEBUG("NodeMgr: nodemgr_call_policy(): hotplug not enabled");
+#else
+	return;
+#endif
+} 
 
-        read_lock_irqsave(&node_lock, flags);
-        ne = find_entry_by_guid(guid);
-        read_unlock_irqrestore(&node_lock, flags);
+#endif /* CONFIG_HOTPLUG */
 
-	/* New entry */
-	if (!ne) {
-		if ((ne = create_node_entry()) == NULL)
-			return;
+static void nodemgr_claim_unit_directory(struct unit_directory *ud,
+					 struct hpsb_protocol_driver *driver)
+{
+	ud->driver = driver;
+	list_del(&ud->driver_list);
+	list_add_tail(&ud->driver_list, &driver->unit_directories);
+}
+
+static void nodemgr_release_unit_directory(struct unit_directory *ud)
+{
+	ud->driver = NULL;
+	list_del(&ud->driver_list);
+	list_add_tail(&ud->driver_list, &unit_directory_list);
+}
+
+void hpsb_release_unit_directory(struct unit_directory *ud)
+{
+	unsigned long flags;
+
+	write_lock_irqsave(&unit_directory_lock, flags);
+	nodemgr_release_unit_directory(ud);
+	write_unlock_irqrestore(&unit_directory_lock, flags);
+}
+
+static void nodemgr_free_unit_directories(struct node_entry *ne)
+{
+	struct list_head *lh;
+	struct unit_directory *ud;
+
+	lh = ne->unit_directories.next;
+	while (lh != &ne->unit_directories) {
+		ud = list_entry(lh, struct unit_directory, node_list);
+		lh = lh->next;
+		if (ud->driver && ud->driver->disconnect)
+			ud->driver->disconnect(ud);
+		nodemgr_release_unit_directory(ud);
+		nodemgr_call_policy("remove", ud);
+		list_del(&ud->driver_list);
+		kfree(ud);
+	}
+}
+
+static struct ieee1394_device_id *
+nodemgr_match_driver(struct hpsb_protocol_driver *driver, 
+		     struct unit_directory *ud)
+{
+	struct ieee1394_device_id *id;
+
+	for (id = driver->id_table; id->match_flags != 0; id++) {
+		if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) &&
+		    id->vendor_id != ud->vendor_id)
+			continue;
+
+		if ((id->match_flags & IEEE1394_MATCH_MODEL_ID) &&
+		    id->model_id != ud->model_id)
+			continue;
+
+		if ((id->match_flags & IEEE1394_MATCH_SPECIFIER_ID) &&
+		    id->specifier_id != ud->specifier_id)
+			continue;
+
+		if ((id->match_flags & IEEE1394_MATCH_VERSION) &&
+		    id->version != ud->version)
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static struct hpsb_protocol_driver *
+nodemgr_find_driver(struct unit_directory *ud)
+{
+	struct list_head *l;
+	struct hpsb_protocol_driver *match, *driver;
+	struct ieee1394_device_id *device_id;
+
+	match = NULL;
+	list_for_each(l, &driver_list) {
+		driver = list_entry(l, struct hpsb_protocol_driver, list);
+		device_id = nodemgr_match_driver(driver, ud);
+
+		if (device_id != NULL) {
+			match = driver;
+			break;
+		}
+	}
+
+	return match;
+}
+
+static void nodemgr_bind_drivers (struct node_entry *ne)
+{
+	struct list_head *lh;
+	struct hpsb_protocol_driver *driver;
+	struct unit_directory *ud;
 
-		HPSB_DEBUG("%s added: node " NODE_BUS_FMT
-			   ", GUID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
-			   (host->node_id == nodeid) ? "Local host" : "Device",
-			   NODE_BUS_ARGS(nodeid), ((u8 *)&guid)[0],
-			   ((u8 *)&guid)[1], ((u8 *)&guid)[2], ((u8 *)&guid)[3],
-			   ((u8 *)&guid)[4], ((u8 *)&guid)[5], ((u8 *)&guid)[6],
-			   ((u8 *)&guid)[7]);
+	list_for_each(lh, &ne->unit_directories) {
+		ud = list_entry(lh, struct unit_directory, node_list);
+		driver = nodemgr_find_driver(ud);
+		if (driver != NULL && driver->probe(ud) == 0)
+			nodemgr_claim_unit_directory(ud, driver);
+		nodemgr_call_policy("add", ud);
+	}
+}
+
+int hpsb_register_protocol(struct hpsb_protocol_driver *driver)
+{
+	struct unit_directory *ud;
+	struct list_head *lh;
+	unsigned long flags;
+
+        write_lock_irqsave(&driver_lock, flags);
+	list_add_tail(&driver->list, &driver_list);
+	write_unlock_irqrestore(&driver_lock, flags);
+
+	write_lock_irqsave(&unit_directory_lock, flags);
+	INIT_LIST_HEAD(&driver->unit_directories);
+	lh = unit_directory_list.next;
+	while (lh != &unit_directory_list) {
+		ud = list_entry(lh, struct unit_directory, driver_list);
+		lh = lh->next;
+		if (nodemgr_match_driver(driver, ud) && driver->probe(ud) == 0)
+			nodemgr_claim_unit_directory(ud, driver);
+	}
+	write_unlock_irqrestore(&unit_directory_lock, flags);
+
+	/*
+	 * Right now registration always succeeds, but maybe we should
+	 * detect clashes in protocols handled by other drivers.
+	 */
+
+	return 0;
+}
+
+void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
+{
+	struct list_head *lh;
+	struct unit_directory *ud;
+	unsigned long flags;
 
-		ne->guid = guid;
-		new = 1;
+        write_lock_irqsave(&driver_lock, flags);
+	list_del(&driver->list);
+	write_unlock_irqrestore(&driver_lock, flags);
+
+	write_lock_irqsave(&unit_directory_lock, flags);
+	lh = driver->unit_directories.next;
+	while (lh != &driver->unit_directories) {
+		ud = list_entry(lh, struct unit_directory, driver_list);
+		lh = lh->next;
+		if (ud->driver && ud->driver->disconnect)
+			ud->driver->disconnect(ud);
+		nodemgr_release_unit_directory(ud);
 	}
+	write_unlock_irqrestore(&unit_directory_lock, flags);
+}
+
+static void nodemgr_process_config_rom(struct node_entry *ne, 
+				       quadlet_t busoptions)
+{
+	unsigned long flags;
+
+	ne->busopt.irmc		= (busoptions >> 31) & 1;
+	ne->busopt.cmc		= (busoptions >> 30) & 1;
+	ne->busopt.isc		= (busoptions >> 29) & 1;
+	ne->busopt.bmc		= (busoptions >> 28) & 1;
+	ne->busopt.pmc		= (busoptions >> 27) & 1;
+	ne->busopt.cyc_clk_acc	= (busoptions >> 16) & 0xff;
+	ne->busopt.max_rec	= 1 << (((busoptions >> 12) & 0xf) + 1);
+	ne->busopt.generation	= (busoptions >> 4) & 0xf;
+	ne->busopt.lnkspd	= busoptions & 0x7;
 
-	if (!new && ne->nodeid != nodeid)
+#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
+	HPSB_DEBUG("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d "
+		   "cyc_clk_acc=%d max_rec=%d gen=%d lspd=%d",
+		   busoptions, ne->busopt.irmc, ne->busopt.cmc,
+		   ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc,
+		   ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
+		   ne->busopt.generation, ne->busopt.lnkspd);
+#endif
+
+	/*
+	 * When the config rom changes we disconnect all drivers and
+	 * free the cached unit directories and reread the whole
+	 * thing.  If this was a new device, the call to
+	 * nodemgr_disconnect_drivers is a no-op and all is well.
+	 */
+	write_lock_irqsave(&unit_directory_lock, flags);
+	nodemgr_free_unit_directories(ne);
+	nodemgr_process_root_directory(ne);
+	nodemgr_bind_drivers(ne);
+	write_unlock_irqrestore(&unit_directory_lock, flags);
+}
+
+/*
+ * This function updates nodes that were present on the bus before the
+ * reset and still are after the reset.  The nodeid and the config rom
+ * may have changed, and the drivers managing this device must be
+ * informed that this device just went through a bus reset, to allow
+ * the to take whatever actions required.
+ */
+static void nodemgr_update_node(struct node_entry *ne, quadlet_t busoptions,
+                               struct hpsb_host *host, nodeid_t nodeid)
+{
+	struct list_head *lh;
+
+	if (ne->nodeid != nodeid)
 		HPSB_DEBUG("Node " NODE_BUS_FMT " changed to " NODE_BUS_FMT,
 			   NODE_BUS_ARGS(ne->nodeid), NODE_BUS_ARGS(nodeid));
 
 	ne->host = host;
-        ne->nodeid = nodeid;
+	ne->nodeid = nodeid;
 
-	/* Now set the bus options. Only do all this crap if this is a new
-	 * node, or if the generation number has changed.  */
-	if (new || ne->busopt.generation != ((busoptions >> 6) & 0x3)) {
-		ne->busopt.irmc		= (busoptions >> 31) & 1;
-		ne->busopt.cmc		= (busoptions >> 30) & 1;
-		ne->busopt.isc		= (busoptions >> 29) & 1;
-		ne->busopt.bmc		= (busoptions >> 28) & 1;
-		ne->busopt.pmc		= (busoptions >> 27) & 1;
-		ne->busopt.cyc_clk_acc	= (busoptions >> 16) & 0xff;
-		ne->busopt.max_rec	= 1 << (((busoptions >> 12) & 0xf) + 1);
-		ne->busopt.generation	= (busoptions >> 6) & 0x3;
-		ne->busopt.lnkspd	= busoptions & 0x7;
+	if (ne->busopt.generation != ((busoptions >> 4) & 0xf))
+		nodemgr_process_config_rom (ne, busoptions);
 
-		/* Now, process the rest of the tree */
-		nodemgr_process_root_directory(ne);
+	/* Since that's done, we can declare this record current */
+	atomic_set(&ne->generation, get_hpsb_generation(ne->host));
+
+	list_for_each (lh, &ne->unit_directories) {
+		struct unit_directory *ud;
+
+		ud = list_entry (lh, struct unit_directory, node_list);
+		if (ud->driver != NULL && ud->driver->update != NULL)
+			ud->driver->update(ud);
 	}
+}
 
-	/* Since that's done, we can declare this record current */
-	atomic_set(&ne->generation, get_hpsb_generation(host));
+static int read_businfo_block(struct hpsb_host *host, nodeid_t nodeid,
+			      quadlet_t *buffer, int buffer_length)
+{
+	octlet_t base = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
+	int retries = 3;
+	int header_count;
+	unsigned header_size;
+	quadlet_t quad;
+
+retry_configrom:
+
+	if (!retries--) {
+		HPSB_ERR("Giving up on node " NODE_BUS_FMT
+			 " for ConfigROM probe, too many errors",
+			 NODE_BUS_ARGS(nodeid));
+		return -1;
+	}
+
+	header_count = 0;
+	header_size = 0;
 
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-	HPSB_DEBUG("raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d cyc_clk_acc=%d "
-		   "max_rec=%d gen=%d lspd=%d", busoptions,
-		   ne->busopt.irmc, ne->busopt.cmc, ne->busopt.isc, ne->busopt.bmc,
-		   ne->busopt.pmc, ne->busopt.cyc_clk_acc, ne->busopt.max_rec,
-		   ne->busopt.generation, ne->busopt.lnkspd);
+	HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT,
+		  NODE_BUS_ARGS(nodeid));
 #endif
 
-	return;
+	/* Now, P1212 says that devices should support 64byte block
+	 * reads, aligned on 64byte boundaries. That doesn't seem
+	 * to work though, and we are forced to doing quadlet
+	 * sized reads.  */
+
+	if (hpsb_read(host, nodeid, base, &quad, 4)) {
+		HPSB_ERR("ConfigROM quadlet transaction error for node " NODE_BUS_FMT,
+			 NODE_BUS_ARGS(nodeid));
+		goto retry_configrom;
+	}
+	buffer[header_count++] = be32_to_cpu(quad);
+
+	header_size = buffer[0] >> 24;
+
+	if (header_size < 4) {
+		HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM format (%d quads), "
+			  "cannot parse", NODE_BUS_ARGS(nodeid), header_size);
+		return -1;
+	}
+
+	while (header_count <= header_size && header_count < buffer_length) {
+		if (hpsb_read(host, nodeid, base + (header_count<<2), &quad, 4)) {
+			HPSB_ERR("ConfigROM quadlet transaction error for " NODE_BUS_FMT,
+				 NODE_BUS_ARGS(nodeid));
+			goto retry_configrom;
+		}
+		buffer[header_count++] = be32_to_cpu(quad);
+	}
+
+	return 0;
 }
 
 static void nodemgr_remove_node(struct node_entry *ne)
 {
-	HPSB_DEBUG("Device removed: node " NODE_BUS_FMT ", GUID "
-		   "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
-		   NODE_BUS_ARGS(ne->nodeid),
-		   ((u8 *)&ne->guid)[0], ((u8 *)&ne->guid)[1],
-		   ((u8 *)&ne->guid)[2], ((u8 *)&ne->guid)[3],
-		   ((u8 *)&ne->guid)[4], ((u8 *)&ne->guid)[5],
-		   ((u8 *)&ne->guid)[6], ((u8 *)&ne->guid)[7]);
+	unsigned long flags;
 
+	HPSB_DEBUG("Device removed: node " NODE_BUS_FMT ", GUID %016Lx",
+		   NODE_BUS_ARGS(ne->nodeid), (unsigned long long)ne->guid);
+
+	write_lock_irqsave(&unit_directory_lock, flags);
+	nodemgr_free_unit_directories(ne);
+	write_unlock_irqrestore(&unit_directory_lock, flags);
 	list_del(&ne->list);
 	kfree(ne);
 
@@ -352,82 +690,26 @@
 {
 	struct hpsb_host *host = (struct hpsb_host *)data;
         struct selfid *sid = (struct selfid *)host->topology_map;
-	struct list_head *lh,*spare;
+	struct list_head *lh, *next;
 	struct node_entry *ne;
         int nodecount = host->node_count;
         nodeid_t nodeid = LOCAL_BUS;
-	quadlet_t buffer[5], quad;
-	octlet_t base = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
+	quadlet_t buffer[5];
+	octlet_t guid;
 	unsigned long flags;
 
 	/* We need to detect when the ConfigROM's generation has changed,
 	 * so we only update the node's info when it needs to be.  */
         for (; nodecount; nodecount--, nodeid++, sid++) {
-		int retries = 3;
-		int header_count;
-		unsigned header_size;
-		octlet_t guid;
-
 		/* Skip extended, and non-active node's */
                 while (sid->extended)
 			sid++;
                 if (!sid->link_active)
 			continue;
 
-		/* Just use our local ROM */
-		if (nodeid == host->node_id) {
-			int i;
-			for (i = 0; i < 5; i++)
-				buffer[i] = be32_to_cpu(host->csr.rom[i]);
-			goto set_options;
-		}
-
-retry_configrom:
-		
-		if (!retries--) {
-			HPSB_ERR("Giving up on node " NODE_BUS_FMT
-				 " for ConfigROM probe, too many errors",
-				 NODE_BUS_ARGS(nodeid));
+		if (read_businfo_block (host, nodeid, buffer, sizeof(buffer) >> 2))
 			continue;
-		}
-
-		header_count = 0;
-		header_size = 0;
-
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-		HPSB_INFO("Initiating ConfigROM request for node " NODE_BUS_FMT,
-			  NODE_BUS_ARGS(nodeid));
-#endif
 
-		/* Now, P1212 says that devices should support 64byte block
-		 * reads, aligned on 64byte boundaries. That doesn't seem
-		 * to work though, and we are forced to doing quadlet
-		 * sized reads.  */
-
-		if (hpsb_read(host, nodeid, base, &quad, 4)) {
-			HPSB_ERR("ConfigROM quadlet transaction error for node " NODE_BUS_FMT,
-				 NODE_BUS_ARGS(nodeid));
-			goto retry_configrom;
-		}
-		buffer[header_count++] = be32_to_cpu(quad);
-
-		header_size = buffer[0] >> 24;
-
-		if (header_size < 4) {
-			HPSB_INFO("Node " NODE_BUS_FMT " has non-standard ROM format (%d quads), "
-				  "cannot parse", NODE_BUS_ARGS(nodeid), header_size);
-			continue;
-		}
-
-		while (header_count <= header_size && (header_count<<2) < sizeof(buffer)) {
-			if (hpsb_read(host, nodeid, base + (header_count<<2), &quad, 4)) {
-				HPSB_ERR("ConfigROM quadlet transaction error for " NODE_BUS_FMT,
-					 NODE_BUS_ARGS(nodeid));
-				goto retry_configrom;
-			}
-			buffer[header_count++] = be32_to_cpu(quad);
-		}
-set_options:
 		if (buffer[1] != IEEE1394_BUSID_MAGIC) {
 			/* This isn't a 1394 device */
 			HPSB_ERR("Node " NODE_BUS_FMT " isn't an IEEE 1394 device",
@@ -435,15 +717,21 @@
 			continue;
 		}
 
-		guid = be64_to_cpu(((u64)buffer[3] << 32) | buffer[4]);
-		register_node(host, nodeid, guid, buffer[2]);
+		guid = ((u64)buffer[3] << 32) | buffer[4];
+		ne = hpsb_guid_get_entry(guid);
+
+		if (!ne)
+			nodemgr_create_node(guid, buffer[2], host, nodeid);
+		else
+			nodemgr_update_node(ne, buffer[2], host, nodeid);
         }
 
 	/* Now check to see if we have any nodes that aren't referenced
 	 * any longer.  */
         write_lock_irqsave(&node_lock, flags);
-	list_for_each_safe(lh, spare, &node_list) {
+	for (lh = node_list.next; lh != &node_list; lh = next) {
 		ne = list_entry(lh, struct node_entry, list);
+		next = lh->next;
 
 		/* Only checking this host */
 		if (ne->host != host)
@@ -453,7 +741,7 @@
 		 * node was removed, or it failed the above probe. Either
 		 * way, we remove references to it, since they are
 		 * invalid.  */
-		if (atomic_read(&ne->generation) != get_hpsb_generation(host))
+		if (!hpsb_node_entry_valid(ne))
 			nodemgr_remove_node(ne);
 	}
 	write_unlock_irqrestore(&node_lock, flags);
@@ -511,7 +799,7 @@
 	unsigned long flags;
 
 	if (!hi) {
-		HPSB_ERR ("Out of memory in Node Manager");
+		HPSB_ERR ("NodeMgr: out of memory in add host");
 		return;
 	}
 
@@ -544,7 +832,7 @@
 	}
 
 	if (hi == NULL) {
-		HPSB_ERR ("Could not process reset of non-existent host in Node Manager");
+		HPSB_ERR ("NodeMgr: could not process reset of non-existent host");
 		goto done_reset_host;
 	}
 
@@ -558,8 +846,7 @@
 
 static void nodemgr_remove_host(struct hpsb_host *host)
 {
-	struct list_head *lh;
-	struct host_info *hi = NULL;
+	struct list_head *lh, *next;
 	struct node_entry *ne;
 	unsigned long flags;
 
@@ -568,8 +855,10 @@
 
 	/* First remove all node entries for this host */
 	write_lock_irqsave(&node_lock, flags);
-	list_for_each(lh, &node_list) {
+
+	for (lh = node_list.next; lh != &node_list; lh = next) {
 		ne = list_entry(lh, struct node_entry, list);
+		next = lh->next;
 
 		/* Only checking this host */
 		if (ne->host != host)
@@ -581,22 +870,17 @@
 
 	spin_lock_irqsave (&host_info_lock, flags);
 	list_for_each(lh, &host_info_list) {
-		struct host_info *myhi = list_entry(lh, struct host_info, list);
-		if (myhi->host == host) {
-			hi = myhi;
+		struct host_info *hi = list_entry(lh, struct host_info, list);
+		if (hi->host == host) {
+			list_del(&hi->list);
+			kfree (hi);
 			break;
 		}
 	}
 
-	if (hi == NULL) {
-		HPSB_ERR ("Could not remove non-existent host in Node Manager");
-		goto done_remove_host;
-	}
-
-	list_del(&hi->list);
-	kfree (hi);
+	if (lh == host_info_list.next)
+		HPSB_ERR ("NodeMgr: could not remove non-existent host");
 
-done_remove_host:
 	spin_unlock_irqrestore (&host_info_lock, flags);
 
 	return;
@@ -614,7 +898,7 @@
 {
         hl = hpsb_register_highlevel("Node manager", &nodemgr_ops);
         if (!hl) {
-                HPSB_ERR("Out of memory during ieee1394 initialization");
+		HPSB_ERR("NodeMgr: out of memory during ieee1394 initialization");
         }
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/nodemgr.h linux/drivers/ieee1394/nodemgr.h
--- v2.4.10/linux/drivers/ieee1394/nodemgr.h	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/nodemgr.h	Mon Oct  1 21:24:24 2001
@@ -38,13 +38,23 @@
 	u16	max_rec;	/* Maximum packet size node can receive */
 };
 
-#define UNIT_DIRECTORY_VENDOR_ID    0x01
-#define UNIT_DIRECTORY_MODEL_ID     0x02
-#define UNIT_DIRECTORY_SPECIFIER_ID 0x04
-#define UNIT_DIRECTORY_VERSION      0x08
+#define UNIT_DIRECTORY_VENDOR_ID	0x01
+#define UNIT_DIRECTORY_MODEL_ID		0x02
+#define UNIT_DIRECTORY_SPECIFIER_ID	0x04
+#define UNIT_DIRECTORY_VERSION		0x08
 
+/*
+ * A unit directory corresponds to a protocol supported by the
+ * node. If a node supports eg. IP/1394 and AV/C, its config rom has a
+ * unit directory for each of these protocols.
+ * 
+ * Unit directories appear on two types of lists: for each node we
+ * maintain a list of the unit directories found in its config rom and
+ * for each driver we maintain a list of the unit directories
+ * (ie. devices) the driver manages.
+ */
 struct unit_directory {
-	struct list_head list;
+	struct node_entry *ne;  /* The node which this directory belongs to */
 	octlet_t address;	/* Address of the unit directory on the node */
 	u8 flags;		/* Indicates which entries were read */
 	quadlet_t vendor_id;
@@ -53,6 +63,20 @@
 	char *model_name;
 	quadlet_t specifier_id;
 	quadlet_t version;
+
+	/* Groupings for arbitrary key/value pairs */
+	int arb_count;			/* Number of arbitrary key/values */
+	char arb_keys[16];		/* Up to 16 keys */
+	quadlet_t arb_values[16];	/* Same for values */
+
+	struct hpsb_protocol_driver *driver;
+	void *driver_data;
+
+	/* For linking the nodes managed by the driver, or unmanaged nodes */
+	struct list_head driver_list;
+
+	/* For linking directories belonging to a node */
+	struct list_head node_list;
 };
 
 struct node_entry {
@@ -68,6 +92,11 @@
 	u32 capabilities;	
 	struct list_head unit_directories;
 };
+
+static inline int hpsb_node_entry_valid(struct node_entry *ne)
+{
+	return atomic_read(&ne->generation) == get_hpsb_generation(ne->host);
+}
 
 /*
  * Returns a node entry (which has its reference count incremented) or NULL if
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ohci1394.c linux/drivers/ieee1394/ohci1394.c
--- v2.4.10/linux/drivers/ieee1394/ohci1394.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ohci1394.c	Mon Oct  1 21:24:24 2001
@@ -105,6 +105,17 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 
+#ifdef CONFIG_ALL_PPC
+#include <asm/feature.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#endif
+
+/* Revert to old bus reset algorithm that works on my Pismo until
+ * the new one is fixed
+ */
+#undef BUSRESET_WORKAROUND
+
 #include "ieee1394.h"
 #include "ieee1394_types.h"
 #include "hosts.h"
@@ -112,7 +123,6 @@
 #include "highlevel.h"
 #include "ohci1394.h"
 
-
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 #define OHCI1394_DEBUG
 #endif
@@ -123,17 +133,17 @@
 
 #ifdef OHCI1394_DEBUG
 #define DBGMSG(card, fmt, args...) \
-printk(KERN_INFO "ohci1394_%d: " fmt "\n" , card , ## args)
+printk(KERN_INFO "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 #else
 #define DBGMSG(card, fmt, args...)
 #endif
 
 #ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG
 #define OHCI_DMA_ALLOC(fmt, args...) \
-	HPSB_ERR("ohci1394("__FUNCTION__")alloc(%d): "fmt, \
+	HPSB_ERR("%s("__FUNCTION__")alloc(%d): "fmt, OHCI1394_DRIVER_NAME, \
 		++global_outstanding_dmas, ## args)
 #define OHCI_DMA_FREE(fmt, args...) \
-	HPSB_ERR("ohci1394("__FUNCTION__")free(%d): "fmt, \
+	HPSB_ERR("%s("__FUNCTION__")free(%d): "fmt, OHCI1394_DRIVER_NAME, \
 		--global_outstanding_dmas, ## args)
 u32 global_outstanding_dmas = 0;
 #else
@@ -143,18 +153,11 @@
 
 /* print general (card independent) information */
 #define PRINT_G(level, fmt, args...) \
-printk(level "ohci1394: " fmt "\n" , ## args)
+printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
 
 /* print card specific information */
 #define PRINT(level, card, fmt, args...) \
-printk(level "ohci1394_%d: " fmt "\n" , card , ## args)
-
-#define FAIL(fmt, args...)				\
-do {							\
-	PRINT_G(KERN_ERR, fmt , ## args);		\
-	remove_card(ohci);				\
-	return 1;					\
-} while(0)
+printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
 #define PCI_CLASS_FIREWIRE_OHCI     ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
 
@@ -179,21 +182,48 @@
 MODULE_PARM_DESC(attempt_root, "Attempt to make the host root.");
 static int attempt_root = 0;
 
-#ifdef __LITTLE_ENDIAN
-/* Don't waste cycles on same sex byte swaps */
-#define packet_swab(w,x,y,z)
-#define block_swab32(x,y)
-#else
-static void packet_swab(quadlet_t *data, char tcode, int len, int payload_swap);
-static __inline__ void block_swab32(quadlet_t *data, size_t size);
-#endif
-
 static unsigned int card_id_counter = 0;
 
 static void dma_trm_tasklet(unsigned long data);
 static void remove_card(struct ti_ohci *ohci);
 static void dma_trm_reset(struct dma_trm_ctx *d);
 
+#ifndef __LITTLE_ENDIAN
+/* Swap a series of quads inplace. */
+static __inline__ void block_swab32(quadlet_t *data, size_t size) {
+	while (size--)
+		data[size] = swab32(data[size]);
+}
+
+static unsigned hdr_sizes[] = 
+{
+	3,	/* TCODE_WRITEQ */
+	4,	/* TCODE_WRITEB */
+	3,	/* TCODE_WRITE_RESPONSE */
+	0,	/* ??? */
+	3,	/* TCODE_READQ */
+	4,	/* TCODE_READB */
+	3,	/* TCODE_READQ_RESPONSE */
+	4,	/* TCODE_READB_RESPONSE */
+	1,	/* TCODE_CYCLE_START (???) */
+	4,	/* TCODE_LOCK_REQUEST */
+	2,	/* TCODE_ISO_DATA */
+	4,	/* TCODE_LOCK_RESPONSE */
+};
+
+/* Swap headers */
+static inline void packet_swab(quadlet_t *data, int tcode, int len)
+{
+	if (tcode > TCODE_LOCK_RESPONSE || hdr_sizes[tcode] == 0)
+		return;
+	block_swab32(data, hdr_sizes[tcode]);
+}
+#else
+/* Don't waste cycles on same sex byte swaps */
+#define packet_swab(w,x,y)
+#define block_swab32(x,y)
+#endif /* !LITTLE_ENDIAN */
+
 /***********************************
  * IEEE-1394 functionality section *
  ***********************************/
@@ -230,7 +260,7 @@
 {
 	int i;
 	unsigned long flags;
-	u32 r;
+	u32 r = 0;
 
 	spin_lock_irqsave (&ohci->phy_reg_lock, flags);
 
@@ -376,7 +406,7 @@
 }
 
 /* Generate the dma receive prgs and start the context */
-static void initialize_dma_rcv_ctx(struct dma_rcv_ctx *d)
+static void initialize_dma_rcv_ctx(struct dma_rcv_ctx *d, int generate_irq)
 {
 	struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
 	int i;
@@ -384,12 +414,17 @@
 	ohci1394_stop_context(ohci, d->ctrlClear, NULL);
 
 	for (i=0; i<d->num_desc; i++) {
+		u32 c;
 		
-		d->prg_cpu[i]->control =
-                   cpu_to_le32((0x280C << 16) | d->buf_size);
+		c = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
+			DMA_CTL_BRANCH;
+		if (generate_irq)
+			c |= DMA_CTL_IRQ;
+				
+		d->prg_cpu[i]->control = cpu_to_le32(c | d->buf_size);
 
 		/* End of descriptor list? */
-		if ((i+1) < d->num_desc) {
+		if (i + 1 < d->num_desc) {
 			d->prg_cpu[i]->branchAddress =
 				cpu_to_le32((d->prg_bus[i+1] & 0xfffffff0) | 0x1);
 		} else {
@@ -565,15 +600,15 @@
 	reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, 0xffffffff);
 
 	/* Initialize AR dma */
-	initialize_dma_rcv_ctx(ohci->ar_req_context);
-	initialize_dma_rcv_ctx(ohci->ar_resp_context);
+	initialize_dma_rcv_ctx(ohci->ar_req_context, 0);
+	initialize_dma_rcv_ctx(ohci->ar_resp_context, 0);
 
 	/* Initialize AT dma */
 	initialize_dma_trm_ctx(ohci->at_req_context);
 	initialize_dma_trm_ctx(ohci->at_resp_context);
 
 	/* Initialize IR dma */
-	initialize_dma_rcv_ctx(ohci->ir_context);
+	initialize_dma_rcv_ctx(ohci->ir_context, 1);
 
         /* Initialize IT dma */
         initialize_dma_trm_ctx(ohci->it_context);
@@ -604,7 +639,6 @@
 	/* Enable interrupts */
 	reg_write(ohci, OHCI1394_IntMaskSet, 
 		  OHCI1394_masterIntEnable | 
-		  OHCI1394_phyRegRcvd | 
 		  OHCI1394_busReset | 
 		  OHCI1394_selfIDComplete |
 		  OHCI1394_RSPkt |
@@ -674,9 +708,9 @@
 	} else 
 		d->prg_cpu[idx]->begin.status = 0;
 
-        if ( (packet->type == async) || (packet->type == raw) ) {
+        if ( (packet->type == hpsb_async) || (packet->type == hpsb_raw) ) {
 
-                if (packet->type == raw) {
+                if (packet->type == hpsb_raw) {
 			d->prg_cpu[idx]->data[0] = cpu_to_le32(OHCI1394_TCODE_PHY<<4);
                         d->prg_cpu[idx]->data[1] = packet->header[0];
                         d->prg_cpu[idx]->data[2] = packet->header[1];
@@ -689,14 +723,18 @@
                         d->prg_cpu[idx]->data[2] = packet->header[2];
                         d->prg_cpu[idx]->data[3] = packet->header[3];
 			packet_swab(d->prg_cpu[idx]->data, packet->tcode,
-					packet->header_size>>2, ohci->payload_swap);
+					packet->header_size>>2);
                 }
 
                 if (packet->data_size) { /* block transmit */
                         d->prg_cpu[idx]->begin.control =
-                                cpu_to_le32(OUTPUT_MORE_IMMEDIATE | 0x10);
+                                cpu_to_le32(DMA_CTL_OUTPUT_MORE |
+					    DMA_CTL_IMMEDIATE | 0x10);
                         d->prg_cpu[idx]->end.control =
-                                cpu_to_le32(OUTPUT_LAST | packet->data_size);
+                                cpu_to_le32(DMA_CTL_OUTPUT_LAST |
+					    DMA_CTL_IRQ | 
+					    DMA_CTL_BRANCH |
+					    packet->data_size);
                         /* 
                          * Check that the packet data buffer
                          * does not cross a page boundary.
@@ -716,9 +754,6 @@
                                                PCI_DMA_TODEVICE));
 			OHCI_DMA_ALLOC("single, block transmit packet");
 
-			if (ohci->payload_swap)
-				block_swab32(packet->data, packet->data_size >> 2);
-
                         d->prg_cpu[idx]->end.branchAddress = 0;
                         d->prg_cpu[idx]->end.status = 0;
                         if (d->branchAddrPtr) 
@@ -727,14 +762,20 @@
                         d->branchAddrPtr =
                                 &(d->prg_cpu[idx]->end.branchAddress);
                 } else { /* quadlet transmit */
-                        if (packet->type == raw)
-                                d->prg_cpu[idx]->begin.control = cpu_to_le32(
-                                        OUTPUT_LAST_IMMEDIATE |
-                                        (packet->header_size+4));
+                        if (packet->type == hpsb_raw)
+                                d->prg_cpu[idx]->begin.control = 
+					cpu_to_le32(DMA_CTL_OUTPUT_LAST |
+						    DMA_CTL_IMMEDIATE |
+						    DMA_CTL_IRQ | 
+						    DMA_CTL_BRANCH |
+						    (packet->header_size + 4));
                         else
-                                d->prg_cpu[idx]->begin.control = cpu_to_le32(
-                                        OUTPUT_LAST_IMMEDIATE |
-                                        packet->header_size);
+                                d->prg_cpu[idx]->begin.control =
+					cpu_to_le32(DMA_CTL_OUTPUT_LAST |
+						    DMA_CTL_IMMEDIATE |
+						    DMA_CTL_IRQ | 
+						    DMA_CTL_BRANCH |
+						    packet->header_size);
 
                         if (d->branchAddrPtr) 
                                 *(d->branchAddrPtr) =
@@ -747,20 +788,22 @@
                 d->prg_cpu[idx]->data[0] = packet->speed_code<<16 |
                         (packet->header[0] & 0xFFFF);
                 d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000;
-		packet_swab(d->prg_cpu[idx]->data, packet->tcode, packet->header_size>>2,
-				ohci->payload_swap);
+		packet_swab(d->prg_cpu[idx]->data, packet->tcode, packet->header_size>>2);
   
-                d->prg_cpu[idx]->begin.control = cpu_to_le32(OUTPUT_MORE_IMMEDIATE | 0x8);
-                d->prg_cpu[idx]->end.control = cpu_to_le32(
-                        OUTPUT_LAST | 0x08000000 | packet->data_size);
+                d->prg_cpu[idx]->begin.control = 
+			cpu_to_le32(DMA_CTL_OUTPUT_MORE | 
+				    DMA_CTL_IMMEDIATE | 0x8);
+                d->prg_cpu[idx]->end.control = 
+			cpu_to_le32(DMA_CTL_OUTPUT_LAST |
+				    DMA_CTL_UPDATE |
+				    DMA_CTL_IRQ |
+				    DMA_CTL_BRANCH |
+				    packet->data_size);
                 d->prg_cpu[idx]->end.address = cpu_to_le32(
 				pci_map_single(ohci->dev, packet->data,
 				packet->data_size, PCI_DMA_TODEVICE));
 		OHCI_DMA_ALLOC("single, iso transmit packet");
 
-		if (ohci->payload_swap)
-			block_swab32(packet->data, packet->data_size>>2);
-
                 d->prg_cpu[idx]->end.branchAddress = 0;
                 d->prg_cpu[idx]->end.status = 0;
                 DBGMSG(ohci->id, "Iso xmit context info: header[%08x %08x]\n"
@@ -947,7 +990,7 @@
 
 		if (arg<0 || arg>63) {
 			PRINT(KERN_ERR, ohci->id, __FUNCTION__
-			      "IS0 listne channel %d is out of range", 
+			      "IS0 listen channel %d is out of range", 
 			      arg);
 			return -EFAULT;
 		}
@@ -1083,13 +1126,16 @@
 	int phyid = -1, isroot = 0;
 	unsigned long flags;
 
-	/* Read the interrupt event register. We don't clear the bus reset
-	 * here. We wait till we get a selfid complete interrupt and clear
-	 * it then, and _only_ then.  */
+	/* Read and clear the interrupt event register.  Don't clear
+	 * the busReset event, though, this is done when we get the
+	 * selfIDComplete interrupt. */
 	spin_lock_irqsave(&ohci->event_lock, flags);
 	event = reg_read(ohci, OHCI1394_IntEventClear);
-	reg_write(ohci, OHCI1394_IntEventClear,
-		  event & ~(OHCI1394_selfIDComplete | OHCI1394_busReset));
+#ifdef BUSRESET_WORKAROUND
+	reg_write(ohci, OHCI1394_IntEventClear, event);
+#else
+	reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset);
+#endif
 	spin_unlock_irqrestore(&ohci->event_lock, flags);
 
 	if (!event) return;
@@ -1103,24 +1149,26 @@
 		return;
 	}
 
-	/* Someone wants a bus reset. Better watch what you wish for... */
 	if (event & OHCI1394_busReset) {
+		/* The busReset event bit can't be cleared during the
+		 * selfID phase, so we disable busReset interrupts, to
+		 * avoid burying the cpu in interrupt requests. */
+		spin_lock_irqsave(&ohci->event_lock, flags);
+#ifdef BUSRESET_WORKAROUND
+		reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
+#else
+  		reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
+#endif		
+		spin_unlock_irqrestore(&ohci->event_lock, flags);
 		if (!host->in_bus_reset) {
 			DBGMSG(ohci->id, "irq_handler: Bus reset requested%s",
 			      ((host->attempt_root || attempt_root) ?
 			      " and attempting to become root" : ""));
-			
-			/* Wait for the AT fifo to be flushed */
-			dma_trm_reset(ohci->at_req_context);
-			dma_trm_reset(ohci->at_resp_context);
 
 			/* Subsystem call */
 			hpsb_bus_reset(ohci->host);
-			
-			ohci->NumBusResets++;
 		}
-		/* Mask out everything except selfid */
-		event &= OHCI1394_selfIDComplete;
+		event &= ~OHCI1394_busReset;
 	}
 
 	/* XXX: We need a way to also queue the OHCI1394_reqTxComplete,
@@ -1234,11 +1282,12 @@
 
 				handle_selfid(ohci, host, 
 					      phyid, isroot);
-			} else 
+			} else {
 				PRINT(KERN_ERR, ohci->id, 
 				      "SelfID interrupt received, but "
 				      "NodeID is not valid: %08X",
 				      node_id);
+			}
 
 			/* Accept Physical requests from all nodes. */
 			reg_write(ohci,OHCI1394_AsReqFilterHiSet, 
@@ -1258,21 +1307,15 @@
 			PRINT(KERN_ERR, ohci->id, 
 			      "SelfID received outside of bus reset sequence");
 
-		/* Clear everything, it's a new day */
+		/* Finally, we clear the busReset event and reenable
+		 * the busReset interrupt. */
+#ifndef BUSRESET_WORKAROUND
 		spin_lock_irqsave(&ohci->event_lock, flags);
-		reg_write(ohci, OHCI1394_IntEventClear, 0xffffffff);
+		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); 
+		reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
 		spin_unlock_irqrestore(&ohci->event_lock, flags);
-
-		event &= ~OHCI1394_selfIDComplete;
-	}
-	if (event & OHCI1394_phyRegRcvd) {
-		if (host->in_bus_reset) {
-			DBGMSG (ohci->id, "PhyControl: %08X", 
-				reg_read(ohci, OHCI1394_PhyControl));
-		} else
-			PRINT(KERN_ERR, ohci->id, 
-			      "Physical register received outside of bus reset sequence");
-		event &= ~OHCI1394_phyRegRcvd;
+#endif
+		event &= ~OHCI1394_selfIDComplete;	
 	}
 
 	/* Make sure we handle everything, just in case we accidentally
@@ -1365,14 +1408,14 @@
 	dma_cache_wback_inv(buf_ptr, bytes_left);
 
 	while (bytes_left > 0) {
-		tcode = (cond_le32_to_cpu(buf_ptr[0], ohci->payload_swap) >> 4) & 0xf;
+		tcode = (cond_le32_to_cpu(buf_ptr[0], ohci->no_swap_incoming) >> 4) & 0xf;
 
 		/* packet_length() will return < 4 for an error */
-		length = packet_length(d, idx, buf_ptr, offset, tcode, ohci->payload_swap);
+		length = packet_length(d, idx, buf_ptr, offset, tcode, ohci->no_swap_incoming);
 
 		if (length < 4) { /* something is wrong */
 			sprintf(msg,"Unexpected tcode 0x%x(0x%08x) in AR ctx=%d, length=%d",
-				tcode, cond_le32_to_cpu(buf_ptr[0], ohci->payload_swap),
+				tcode, cond_le32_to_cpu(buf_ptr[0], ohci->no_swap_incoming),
 				d->ctx, length);
 			ohci1394_stop_context(ohci, d->ctrlClear, msg);
 			spin_unlock_irqrestore(&d->lock, flags);
@@ -1448,19 +1491,18 @@
 		/* We get one phy packet to the async descriptor for each
 		 * bus reset. We always ignore it.  */
 		if (tcode != OHCI1394_TCODE_PHY) {
-			if (!ohci->payload_swap)
-				packet_swab(d->spb, tcode, (length - 4) >> 2, 0);
-
+			if (!ohci->no_swap_incoming)
+				packet_swab(d->spb, tcode, (length - 4) >> 2);
 			DBGMSG(ohci->id, "Packet received from node"
 				" %d ack=0x%02X spd=%d tcode=0x%X"
 				" length=%d ctx=%d tlabel=%d",
 				(d->spb[1]>>16)&0x3f,
-				(cond_le32_to_cpu(d->spb[length/4-1], ohci->payload_swap)>>16)&0x1f,
-				(cond_le32_to_cpu(d->spb[length/4-1], ohci->payload_swap)>>21)&0x3,
+				(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f,
+				(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>21)&0x3,
 				tcode, length, d->ctx,
-				(cond_le32_to_cpu(d->spb[length/4-1], ohci->payload_swap)>>10)&0x3f);
+				(cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>10)&0x3f);
 
-			ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->payload_swap)>>16)&0x1f)
+			ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f)
 				== 0x11) ? 1 : 0;
 
 			hpsb_packet_received(ohci->host, d->spb, 
@@ -1510,7 +1552,7 @@
 	while (d->fifo_first) {
 		packet = d->fifo_first;
                 datasize = d->fifo_first->data_size;
-		if (datasize && packet->type != raw)
+		if (datasize && packet->type != hpsb_raw)
 			ack = le32_to_cpu(
 				d->prg_cpu[d->sent_ind]->end.status) >> 16;
 		else 
@@ -2032,6 +2074,14 @@
 	hw_csr_reg:		ohci_hw_csr_reg,
 };
 
+
+#define FAIL(fmt, args...)			\
+do {						\
+	PRINT_G(KERN_ERR, fmt , ## args);	\
+	remove_card(ohci);			\
+	return 1;				\
+} while(0)
+
 static int __devinit ohci1394_add_one(struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	struct ti_ohci *ohci;	/* shortcut to currently handled device */
@@ -2075,10 +2125,10 @@
 	 * noByteSwapData registers to see if they were not cleared to
 	 * zero. Should this work? Obviously it's not defined what these
 	 * registers will read when they aren't supported. Bleh! */
-	if (dev->vendor == PCI_VENDOR_ID_APPLE) {
-		ohci->payload_swap = 1;
-		if (dev->device != PCI_DEVICE_ID_APPLE_UNI_N_FW)
-			ohci->selfid_swap = 1;
+	if (dev->vendor == PCI_VENDOR_ID_APPLE && 
+		dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) {
+			ohci->no_swap_incoming = 1;
+			ohci->selfid_swap = 0;
 	} else
 		ohci->selfid_swap = 1;
 #endif
@@ -2248,6 +2298,23 @@
 	release_mem_region (pci_resource_start(ohci->dev, 0),
 			    pci_resource_len(ohci->dev, 0));
 
+#ifdef CONFIG_ALL_PPC
+	/* On UniNorth, power down the cable and turn off the
+	 * chip clock when the module is removed to save power
+	 * on laptops. Turning it back ON is done by the arch
+	 * code when pci_enable_device() is called
+	 */
+	{
+		struct device_node* of_node;
+
+		of_node = pci_device_to_OF_node(ohci->dev);
+		if (of_node) {
+			feature_set_firewire_power(of_node, 0);
+			feature_set_firewire_cable_power(of_node, 0);
+		}
+	}
+#endif /* CONFIG_ALL_PPC */
+
 	pci_set_drvdata(ohci->dev, NULL);
 }
 
@@ -2292,68 +2359,6 @@
 	}
 }
 
-#ifndef __LITTLE_ENDIAN
-
-/* Swap a series of quads inplace. */
-static __inline__ void block_swab32(quadlet_t *data, size_t size) {
-	while (size--)
-		data[size] = swab32(data[size]);
-}
-
-/* Swap headers and sometimes data too */
-static void packet_swab(quadlet_t *data, char tcode, int len, int payload_swap)
-{
-	if (payload_swap) {
-		block_swab32(data, len);
-		return;
-	}
-
-        switch(tcode)
-        {
-		/* 4 quad header */
-		case TCODE_READB_RESPONSE:
-		case TCODE_LOCK_RESPONSE:
-		case TCODE_LOCK_REQUEST:
-		case TCODE_WRITEB:
-		case TCODE_READB:
-			block_swab32(data, 4);
-			break;
-
-		/* 3 quad header, 1 quad payload */
-		case TCODE_WRITEQ:
-		case TCODE_READQ_RESPONSE:
-			block_swab32(data, 3);
-			break;
-
-		/* 3 quad header */
-		case TCODE_WRITE_RESPONSE:
-		case TCODE_READQ:
-			block_swab32(data, 3);
-			break;
-
-		/* 2 quad header */
-		case TCODE_ISO_DATA:
-			block_swab32(data, 2);
-			break;
-
-		case OHCI1394_TCODE_PHY:
-			break; /* should never happen anyway */
-
-		case TCODE_CYCLE_START:
-			PRINT_G(KERN_ERR, "Unhandled tcode in packet_swab (0x%x)", tcode);
-			/* Atleast swap one quad */
-			block_swab32(data, 1);
-			break;
-                default:
-			PRINT_G(KERN_ERR, "Invalid tcode in packet_swab (0x%x)", tcode);
-                        break;
-        }
-	return;
-}
-
-#endif /* !LITTLE_ENDIAN */
-
-
 #if 0
 int ohci1394_request_channel(struct ti_ohci *ohci, int channel)
 {
@@ -2402,6 +2407,7 @@
 
 MODULE_AUTHOR("Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>");
 MODULE_DESCRIPTION("Driver for PCI OHCI IEEE-1394 controllers");
+MODULE_LICENSE("GPL");
 
 static void __devexit ohci1394_remove_one(struct pci_dev *pdev)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/ohci1394.h linux/drivers/ieee1394/ohci1394.h
--- v2.4.10/linux/drivers/ieee1394/ohci1394.h	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/ohci1394.h	Mon Oct  1 21:24:24 2001
@@ -191,15 +191,14 @@
 	spinlock_t event_lock;
 
 	int self_id_errors;
-        int NumBusResets;
 
 	/* video device */
 	struct video_template *video_tmpl;
 
 	/* Swap the selfid buffer? */
 	unsigned int selfid_swap:1;
-	/* Swap the payload? */
-	unsigned int payload_swap:1;
+	/* Some Apple chipset seem to swap incoming headers for us */
+	unsigned int no_swap_incoming:1;
 };
 
 static inline int cross_bound(unsigned long addr, unsigned int size)
@@ -332,14 +331,16 @@
 #define OHCI1394_phyRegRcvd              0x04000000
 #define OHCI1394_masterIntEnable         0x80000000
 
-#define OUTPUT_MORE                      0x00000000
-#define OUTPUT_MORE_IMMEDIATE            0x02000000
-#define OUTPUT_LAST                      0x103c0000
-#define OUTPUT_LAST_IMMEDIATE            0x123c0000
-
-#define DMA_SPEED_100                    0x0
-#define DMA_SPEED_200                    0x1
-#define DMA_SPEED_400                    0x2
+/* DMA Control flags */
+#define DMA_CTL_OUTPUT_MORE              0x00000000
+#define DMA_CTL_OUTPUT_LAST              0x10000000
+#define DMA_CTL_INPUT_MORE               0x20000000
+#define DMA_CTL_INPUT_LAST               0x30000000
+#define DMA_CTL_UPDATE                   0x08000000
+#define DMA_CTL_IMMEDIATE                0x02000000
+#define DMA_CTL_IRQ                      0x00300000
+#define DMA_CTL_BRANCH                   0x000c0000
+#define DMA_CTL_WAIT                     0x00030000
 
 #define OHCI1394_TCODE_PHY               0xE
 
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/pcilynx.c linux/drivers/ieee1394/pcilynx.c
--- v2.4.10/linux/drivers/ieee1394/pcilynx.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/pcilynx.c	Mon Oct  1 21:24:24 2001
@@ -38,6 +38,7 @@
 #include "ieee1394_types.h"
 #include "hosts.h"
 #include "ieee1394_core.h"
+#include "highlevel.h"
 #include "pcilynx.h"
 
 
@@ -393,7 +394,7 @@
         struct lynx_send_data *d;
         struct hpsb_packet *packet;
 
-        d = (what == iso ? &lynx->iso_send : &lynx->async);
+        d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async);
         packet = d->queue;
 
         d->header_dma = pci_map_single(lynx->dev, packet->header,
@@ -419,13 +420,13 @@
         pcl.buffer[1].pointer = d->data_dma;
 
         switch (packet->type) {
-        case async:
+        case hpsb_async:
                 pcl.buffer[0].control |= PCL_CMD_XMT;
                 break;
-        case iso:
+        case hpsb_iso:
                 pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE;
                 break;
-        case raw:
+        case hpsb_raw:
                 pcl.buffer[0].control |= PCL_CMD_UNFXMT;
                 break;
         }                
@@ -606,11 +607,11 @@
         }
 
         switch (packet->type) {
-        case async:
-        case raw:
+        case hpsb_async:
+        case hpsb_raw:
                 d = &lynx->async;
                 break;
-        case iso:
+        case hpsb_iso:
                 d = &lynx->iso_send;
                 break;
         default:
@@ -1227,7 +1228,7 @@
                 }
 
                 if (lynx->async.queue != NULL) {
-                        send_next(lynx, async);
+                        send_next(lynx, hpsb_async);
                 }
 
                 spin_unlock(&lynx->async.queue_lock);
@@ -1259,7 +1260,7 @@
                 }
 
                 if (lynx->iso_send.queue != NULL) {
-                        send_next(lynx, iso);
+                        send_next(lynx, hpsb_iso);
                 }
 
                 spin_unlock(&lynx->iso_send.queue_lock);
@@ -1368,7 +1369,7 @@
                 FAIL("failed to allocate host structure");
 
         lynx->state = have_host_struct;
-
+	lynx->host->hostdata = lynx;
         lynx->id = num_of_cards-1;
         lynx->dev = dev;
 	lynx->host->pdev = dev;
@@ -1501,6 +1502,9 @@
                 PRINT(KERN_INFO, lynx->id, "found old 1394 PHY");
         }
 
+	/* Tell the highlevel this host is ready */
+	highlevel_add_one_host (lynx->host);
+
         return 0;
 #undef FAIL
 }
@@ -1627,13 +1631,14 @@
 
 MODULE_AUTHOR("Andreas E. Bombe <andreas.bombe@munich.netsurf.de>");
 MODULE_DESCRIPTION("driver for Texas Instruments PCI Lynx IEEE-1394 controller");
+MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("pcilynx");
 MODULE_DEVICE_TABLE(pci, pci_table);
 
 static void __exit pcilynx_cleanup(void)
 {
-        pci_unregister_driver(&lynx_pcidriver);
         hpsb_unregister_lowlevel(&lynx_template);
+	pci_unregister_driver(&lynx_pcidriver);
         PRINT_G(KERN_INFO, "removed " PCILYNX_DRIVER_NAME " module");
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c
--- v2.4.10/linux/drivers/ieee1394/raw1394.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/raw1394.c	Mon Oct  1 21:24:24 2001
@@ -290,8 +290,11 @@
         }
         spin_unlock_irqrestore(&host_info_lock, flags);
 
-        list_for_each(lh, &reqs) {
+        lh = reqs.next;
+        while (lh != &reqs) {
                 req = list_entry(lh, struct pending_request, list);
+                lh = lh->next;
+
                 queue_complete_req(req);
         }
 }
@@ -356,8 +359,11 @@
         }
         spin_unlock_irqrestore(&host_info_lock, flags);
 
-        list_for_each(lh, &reqs) {
+        lh = reqs.next;
+        while (lh != &reqs) {
                 req = list_entry(lh, struct pending_request, list);
+                lh = lh->next;
+
                 queue_complete_req(req);
         }
 }
@@ -746,6 +752,8 @@
         list_add_tail(&req->list, &fi->req_pending);
         spin_unlock_irq(&fi->reqlists_lock);
 
+	packet->generation = req->req.generation;
+
         if (!hpsb_send_packet(packet)) {
                 req->req.error = RAW1394_ERROR_SEND_ERROR;
                 req->req.length = 0;
@@ -766,7 +774,7 @@
 
         fill_iso_packet(packet, req->req.length, channel & 0x3f,
                         (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);
-        packet->type = iso;
+        packet->type = hpsb_iso;
         packet->speed_code = req->req.address & 0x3;
         packet->host = fi->host;
 
@@ -787,6 +795,9 @@
         list_add_tail(&req->list, &fi->req_pending);
         spin_unlock_irq(&fi->reqlists_lock);
 
+	/* Update the generation of the packet just before sending. */
+	packet->generation = get_hpsb_generation(fi->host);
+
         if (!hpsb_send_packet(packet)) {
                 req->req.error = RAW1394_ERROR_SEND_ERROR;
                 queue_complete_req(req);
@@ -1031,3 +1042,4 @@
 
 module_init(init_raw1394);
 module_exit(cleanup_raw1394);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/sbp2.c linux/drivers/ieee1394/sbp2.c
--- v2.4.10/linux/drivers/ieee1394/sbp2.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/sbp2.c	Mon Oct  1 21:24:25 2001
@@ -122,26 +122,14 @@
  *	  are some stress issues under investigation with deserialized I/O. To enable
  *	  deserialized I/O for testing, do "insmod sbp2 serialize_io=0"
  *
- *	- Hot-Plugging: Need to add procfs support and integration with linux
- *	  hot-plug support (http://linux-hotplug.sourceforge.net) for auto-mounting 
- *	  of drives.
- *
  *	- Error Handling: SCSI aborts and bus reset requests are handled somewhat
  *	  but the code needs additional debugging.
  *
- *	- IEEE-1394 Bus Management: There is currently little bus management
- *	  in the core IEEE-1394 stack. Because of this, the SBP-2 driver handles
- *	  detection of SBP-2 devices itself. This should be moved to the core
- *	  stack.
- *
  *	- The SBP-2 driver is currently only supported as a module. It would not take
  *	  much work to allow it to be compiled into the kernel, but you'd have to 
  *	  add some init code to the kernel to support this... and modules are much
  *	  more flexible anyway.   ;-)
  *
- *	- Workaround for PPC pismo firewire chipset (enable SBP2_PPC_PISMO_WORKAROUND
- *	  define below).
- *
  *
  * History:
  *
@@ -222,8 +210,18 @@
  *							 <bcollins@debian.org
  *	07/22/01 - Use NodeMngr to get info about the local host and
  *		   attached devices. Ben Collins
+ *
+ *      09/15/01 - Remove detection code, instead subscribe to the nodemgr
+ *                 driver management interface.  This also removes the
+ *                 initial bus scan stuff since the nodemgr calls
+ *                 sbp2_probe for each sbp2 device already on the bus,
+ *                 when we register our driver.  This change 
+ *                 automtically adds hotplug support to the driver.
+ *                                 Kristian Hogsberg <hogsberg@users.sf.net>
  */
     
+
+
 /*
  * Includes
  */
@@ -264,50 +262,26 @@
 #include "sbp2.h"
 
 /*
- * PPC firewire Pismo chipset workaround!!!
- *
- * This is a workaround for a bug in the firewire pismo chipset. For some odd reason the status
- * fifo address hi/lo must be byteswapped and the response address byteswapped, but no other
- * parts of the structure. Apple's drivers seem to specifically check for the pismo and do
- * the same workaround for sbp2. (Daniel Berlin)
- *
- * Please enable the following define if you're running on the PPC Pismo chipset.
- */
-
-#ifdef CONFIG_IEEE1394_SBP2_PISMO
-#define SBP2_NEED_LOGIN_DESCRIPTOR_WORKAROUND
-#endif
-
-/*
  * Module load parameter definitions
  */
 
 /*
- * Normally the sbp2 driver tries to catch the initial scsi bus scan to pick up any 
- * attached sbp2 devices. Setting no_bus_scan to 1 tells the sbp2 driver not to catch
- * this initial scsi bus scan on module load. You can always either add or remove devices 
- * later through the rescan-scsi-bus.sh script or scsi procfs.
- */
-MODULE_PARM(no_bus_scan,"i");
-MODULE_PARM_DESC(no_bus_scan, "Skip the initial scsi bus scan during module load");
-static int no_bus_scan = 0;
-
-/*
- * Set mode_sense_hack to 1 if you have some sort of unusual sbp2 device, like a 1394 memory 
- * stick reader, compact flash reader, or MO drive that does not support mode sense. Allows
- * you to mount the media rw instead of ro.
+ * Set mode_sense_hack to 1 if you have some sort of unusual sbp2 device,
+ * like a 1394 memory stick reader, compact flash reader, or MO drive that
+ * does not support mode sense. Allows you to mount the media rw instead
+ * of ro.
  */
 MODULE_PARM(mode_sense_hack,"i");
 MODULE_PARM_DESC(mode_sense_hack, "Emulate mode sense for devices like 1394 memory stick readers");
 static int mode_sense_hack = 0;
 
 /*
- * Change max_speed on module load if you have a bad IEEE-1394 controller that has trouble running
- * 2KB packets at 400mb.
+ * Change max_speed on module load if you have a bad IEEE-1394 controller
+ * that has trouble running 2KB packets at 400mb.
  *
- * NOTE: On certain OHCI parts I have seen short packets on async transmit (probably 
- * due to PCI latency/throughput issues with the part). You can bump down the speed if
- * you are running into problems.
+ * NOTE: On certain OHCI parts I have seen short packets on async transmit
+ * (probably due to PCI latency/throughput issues with the part). You can
+ * bump down the speed if you are running into problems.
  *
  * Valid values:
  * max_speed = 2 (default: max speed 400mb)
@@ -319,30 +293,37 @@
 static int max_speed = SPEED_400;
 
 /*
- * Set serialize_io to 1 if you'd like only one scsi command sent down to us at a time (debugging).
+ * Set serialize_io to 1 if you'd like only one scsi command sent down to
+ * us at a time (debugging).
  */
 MODULE_PARM(serialize_io,"i");
 MODULE_PARM_DESC(serialize_io, "Serialize all I/O coming down from the scsi drivers (debugging)");
 static int serialize_io = 1;	/* serialize I/O until stress issues are resolved */
 
 /*
- * Set no_large_packets to 1 if you'd like to limit the size of requests sent down to us (normally
- * the sbp2 driver will break up any requests to any individual devices with 128KB transfer size limits).
- * Sets max s/g list elements to 0x1f in size and disables s/g clustering.
+ * Set no_large_packets to 1 if you'd like to limit the size of requests
+ * sent down to us (normally the sbp2 driver will break up any requests to
+ * any individual devices with 128KB transfer size limits).  Sets max s/g
+ * list elements to 0x1f in size and disables s/g clustering.
  */
 MODULE_PARM(no_large_packets,"i");
 MODULE_PARM_DESC(no_large_packets, "Do not allow large transfers from scsi drivers (debugging)");
 static int no_large_packets = 0;
 
 /*
- * Export information about protocols/devices supported by this driver
+ * Export information about protocols/devices supported by this driver.
  */
 static struct ieee1394_device_id sbp2_id_table[] = {
-	IEEE1394_PROTOCOL(SBP2_UNIT_SPEC_ID_ENTRY, SBP2_SW_VERSION_ENTRY),
+	{
+		match_flags:  IEEE1394_MATCH_SPECIFIER_ID |
+		              IEEE1394_MATCH_VERSION,
+		specifier_id: SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
+		version:      SBP2_SW_VERSION_ENTRY & 0xffffff
+	},
 	{ }
 };
 
-MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table); 
+MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
 
 /*
  * Debug levels, configured via kernel config.
@@ -372,6 +353,7 @@
 #define SBP2_DMA_FREE(fmt, args...)
 #endif
 
+
 #if CONFIG_IEEE1394_SBP2_DEBUG >= 2
 #define SBP2_DEBUG(fmt, args...)	HPSB_ERR(fmt, ## args)	
 #define SBP2_INFO(fmt, args...)		HPSB_ERR(fmt, ## args)	
@@ -392,12 +374,14 @@
 #define SBP2_ERR(fmt, args...)		HPSB_ERR(fmt, ## args)
 
 /*
- * Spinlock debugging stuff. I'm playing it safe until the driver has been debugged on SMP. (JSG)
+ * Spinlock debugging stuff. I'm playing it safe until the driver has been
+ * debugged on SMP. (JSG)
  */
 /* #define SBP2_USE_REAL_SPINLOCKS */
 #ifdef SBP2_USE_REAL_SPINLOCKS
 #define sbp2_spin_lock(lock, flags)	spin_lock_irqsave(lock, flags)	
 #define sbp2_spin_unlock(lock, flags)	spin_unlock_irqrestore(lock, flags);
+static spinlock_t sbp2_host_info_lock = SPIN_LOCK_UNLOCKED;
 #else
 #define sbp2_spin_lock(lock, flags)	do {save_flags(flags); cli();} while (0)	
 #define sbp2_spin_unlock(lock, flags)	do {restore_flags(flags);} while (0)
@@ -411,28 +395,27 @@
 
 static LIST_HEAD(sbp2_host_info_list);
 static int sbp2_host_count = 0;
-static spinlock_t sbp2_host_info_lock = SPIN_LOCK_UNLOCKED;
 
 static struct hpsb_highlevel *sbp2_hl_handle = NULL;
 
 static struct hpsb_highlevel_ops sbp2_hl_ops = {
-	sbp2_add_host,
-	sbp2_remove_host,
-	sbp2_host_reset,
-	NULL,
-	NULL
+	add_host:	sbp2_add_host,
+	remove_host:	sbp2_remove_host,
 };
 
 static struct hpsb_address_ops sbp2_ops = {
-	write: sbp2_handle_status_write,
+	write: sbp2_handle_status_write
 };
 
-#if 0
-static struct hpsb_address_ops sbp2_physdma_ops = {
-	read: sbp2_handle_physdma_read,
-	write: sbp2_handle_physdma_write,
+static struct hpsb_protocol_driver sbp2_driver = {
+	name:		"SBP2 Driver",
+	id_table: 	sbp2_id_table,
+	probe: 		sbp2_probe,
+	disconnect: 	sbp2_disconnect,
+	update: 	sbp2_update
 };
-#endif
+
+
 
 /**************************************
  * General utility functions
@@ -472,108 +455,29 @@
 #endif
 
 /*
- * This function does quadlet sized reads (used by detection code)
- */
-static int sbp2util_read_quadlet(struct sbp2scsi_host_info *hi, nodeid_t node, u64 addr,
-				 quadlet_t *buffer)
-{
-	int retval = 0;
-	int retry_count = 3;
-
-	/*
-	 * Retry a couple times if needed (for slow devices)
-	 */
-	do {
-
-		retval = hpsb_read(hi->host, node, addr, buffer, 4);
-
-		if (retval) {
-			SBP2_DEBUG("sbp2: sbp2util_read_quadlet data packet error");
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(HZ/50);	/* 20ms delay */
-		}
-
-		retry_count--;
-
-	} while (retval && retry_count);
-
-	return(retval);
-}
-
-/*
- * This function returns the address of the unit directory.
- */
-static int sbp2util_unit_directory(struct sbp2scsi_host_info *hi, nodeid_t node_id, u64 *unit_directory_addr)
-{
-	quadlet_t root_directory_length, current_quadlet;
-	u64 current_addr;
-	int length, i;
-
-	/*
-	 * First, read the first quadlet of the root directory to determine its size
-	 */
-	if (sbp2util_read_quadlet(hi, LOCAL_BUS | node_id, CONFIG_ROM_ROOT_DIR_BASE, 
-				  &root_directory_length)) {
-		SBP2_DEBUG("sbp2: Error reading root directory length - bad status");
-		return(-EIO);   
-	}
-
-	current_addr = CONFIG_ROM_ROOT_DIR_BASE;
-	length = be32_to_cpu(root_directory_length) >> 16;
-
-	/*
-	 * Step through the root directory and look for the "Unit_Directory entry", which
-	 * contains the offset to the unit directory.
-	 */
-	for (i=0; i < length; i++) {
-
-		current_addr += 4;
-
-		if (sbp2util_read_quadlet(hi, LOCAL_BUS | node_id, current_addr, &current_quadlet)) {
-			SBP2_DEBUG("sbp2: Error reading at address 0x%08x%08x - bad status", 
-				   (unsigned int) ((current_addr) >> 32), (unsigned int) ((current_addr) & 0xffffffff));
-			return(-EIO);   
-		}
-
-		/*  
-		 * Check for unit directory offset tag 
-		 */
-		if ((be32_to_cpu(current_quadlet) >> 24) == SBP2_UNIT_DIRECTORY_OFFSET_KEY) {
-			*unit_directory_addr = current_addr + 4 * ((be32_to_cpu(current_quadlet) & 0xffffff));
-			SBP2_DEBUG("sbp2: unit_directory_addr = %lu", *unit_directory_addr);
-		}
-	}
-
-	return(0);
-}
-
-/*
- * This function is called to initially create a packet pool for use in sbp2 I/O requests.
- * This packet pool is used when sending out sbp2 command and agent reset requests, and 
- * allows us to remove all kmallocs/kfrees from the critical I/O paths.
+ * This function is called to initially create a packet pool for use in
+ * sbp2 I/O requests. This packet pool is used when sending out sbp2
+ * command and agent reset requests, and allows us to remove all
+ * kmallocs/kfrees from the critical I/O paths.
  */
 static int sbp2util_create_request_packet_pool(struct sbp2scsi_host_info *hi)
 {
 	struct hpsb_packet *packet;
 	int i;
-	unsigned long flags;
 
-	/*
-	 * Create SBP2_MAX_REQUEST_PACKETS number of request packets.
-	 */
-	sbp2_spin_lock(&hi->sbp2_request_packet_lock, flags);
+	/* Create SBP2_MAX_REQUEST_PACKETS number of request packets. */
 	for (i=0; i<SBP2_MAX_REQUEST_PACKETS; i++) {
 
 		/*
-		 * Max payload of 8 bytes since the sbp2 command request uses a payload of 
-		 * 8 bytes, and agent reset is a quadlet write request. Bump this up if we
-		 * plan on using this pool for other stuff.
+		 * Max payload of 8 bytes since the sbp2 command request
+		 * uses a payload of 8 bytes, and agent reset is a quadlet
+		 * write request. Bump this up if we plan on using this
+		 * pool for other stuff.
 		 */
 		packet = alloc_hpsb_packet(8);
 
 		if (!packet) {
 			SBP2_ERR("sbp2: sbp2util_create_request_packet_pool - packet allocation failed!");
-			sbp2_spin_unlock(&hi->sbp2_request_packet_lock, flags);
 			return(-ENOMEM);
 		}
 
@@ -585,13 +489,13 @@
 		list_add_tail(&hi->request_packet[i].list, &hi->sbp2_req_free);
 
 	}
-	sbp2_spin_unlock(&hi->sbp2_request_packet_lock, flags);
 
 	return(0);
 }
 
 /*
- * This function is called to remove the packet pool. It is called when the sbp2 driver is unloaded.
+ * This function is called to remove the packet pool. It is called when
+ * the sbp2 driver is unloaded.
  */
 static void sbp2util_remove_request_packet_pool(struct sbp2scsi_host_info *hi)
 {
@@ -624,15 +528,17 @@
 }
 
 /*
- * This function is called to retrieve a block write packet from our packet pool. This function is
- * used in place of calling alloc_hpsb_packet (which costs us three kmallocs). Instead we 
- * just pull out a free request packet and re-initialize values in it. I'm sure this can still
- * stand some more optimization. 
- */
-static struct sbp2_request_packet *sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
-									  nodeid_t node, u64 addr,
-									  size_t data_size,
-									  quadlet_t data) {
+ * This function is called to retrieve a block write packet from our
+ * packet pool. This function is used in place of calling
+ * alloc_hpsb_packet (which costs us three kmallocs). Instead we just pull
+ * out a free request packet and re-initialize values in it. I'm sure this
+ * can still stand some more optimization.
+ */
+static struct sbp2_request_packet *
+sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
+				       nodeid_t node, u64 addr,
+				       size_t data_size,
+				       quadlet_t data) {
 	struct list_head *lh;
 	struct sbp2_request_packet *request_packet = NULL;
 	struct hpsb_packet *packet;
@@ -651,13 +557,14 @@
 		packet = request_packet->packet;
 
 		/*
-		 * Initialize the packet (this is really initialization the core 1394 stack should do,
-		 * but I'm doing it myself to avoid the overhead).
+		 * Initialize the packet (this is really initialization
+		 * the core 1394 stack should do, but I'm doing it myself
+		 * to avoid the overhead).
 		 */
 		packet->data_size = data_size;
 		INIT_LIST_HEAD(&packet->list);
 		sema_init(&packet->state_change, 0);
-		packet->state = unused;
+		packet->state = hpsb_unused;
 		packet->generation = get_hpsb_generation(hi->host);
 		packet->data_be = 1;
 
@@ -672,8 +579,8 @@
 		}
 
 		/*
-		 * Set up a task queue completion routine, which returns the packet to the free list
-		 * and releases the tlabel
+		 * Set up a task queue completion routine, which returns
+		 * the packet to the free list and releases the tlabel.
 		 */
 		request_packet->tq.routine = (void (*)(void*))sbp2util_free_request_packet;
 		request_packet->tq.data = request_packet;
@@ -681,7 +588,7 @@
 		queue_task(&request_packet->tq, &packet->complete_tq);
 
 		/*
-		 * Now, put the packet on the in-use list
+		 * Now, put the packet on the in-use list.
 		 */
 		list_add_tail(&request_packet->list, &hi->sbp2_req_inuse);
 
@@ -694,8 +601,8 @@
 }
 
 /*
- * This function is called to return a packet to our packet pool. It is also called as a 
- * completion routine when a request packet is completed.
+ * This function is called to return a packet to our packet pool. It is
+ * also called as a completion routine when a request packet is completed.
  */
 static void sbp2util_free_request_packet(struct sbp2_request_packet *request_packet)
 {
@@ -703,7 +610,7 @@
 	struct sbp2scsi_host_info *hi = request_packet->hi_context;
 
 	/*
-	 * Free the tlabel, and return the packet to the free pool
+	 * Free the tlabel, and return the packet to the free pool.
 	 */
 	sbp2_spin_lock(&hi->sbp2_request_packet_lock, flags);
 	free_tlabel(hi->host, LOCAL_BUS | request_packet->packet->node_id,
@@ -716,8 +623,8 @@
 }
 
 /*
- * This function is called to create a pool of command orbs used for command processing. It is called
- * when a new sbp2 device is detected.
+ * This function is called to create a pool of command orbs used for
+ * command processing. It is called when a new sbp2 device is detected.
  */
 static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_id,
 					    struct sbp2scsi_host_info *hi)
@@ -785,10 +692,11 @@
 }
 
 /* 
- * This functions finds the sbp2_command for a given outstanding
- * command orb. Only looks at the inuse list.
+ * This functions finds the sbp2_command for a given outstanding command
+ * orb. Only looks at the inuse list.
  */
-static struct sbp2_command_info *sbp2util_find_command_for_orb(struct scsi_id_instance_data *scsi_id, dma_addr_t orb)
+static struct sbp2_command_info *sbp2util_find_command_for_orb(
+		struct scsi_id_instance_data *scsi_id, dma_addr_t orb)
 {
 	struct list_head *lh;
 	struct sbp2_command_info *command;
@@ -812,7 +720,8 @@
 }
 
 /* 
- * This functions finds the sbp2_command for a given outstanding SCpnt. Only looks at the inuse list 
+ * This functions finds the sbp2_command for a given outstanding SCpnt.
+ * Only looks at the inuse list.
  */
 static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt)
 {
@@ -837,10 +746,11 @@
 /*
  * This function allocates a command orb used to send a scsi command.
  */
-static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id, 
-							       Scsi_Cmnd *Current_SCpnt, 
-							       void (*Current_done)(Scsi_Cmnd *),
-							       struct sbp2scsi_host_info *hi)
+static struct sbp2_command_info *sbp2util_allocate_command_orb(
+		struct scsi_id_instance_data *scsi_id, 
+		Scsi_Cmnd *Current_SCpnt, 
+		void (*Current_done)(Scsi_Cmnd *),
+		struct sbp2scsi_host_info *hi)
 {
 	struct list_head *lh;
 	struct sbp2_command_info *command = NULL;
@@ -903,13 +813,15 @@
 	sbp2_spin_unlock(&scsi_id->sbp2_command_orb_lock, flags);
 }
 
+
+
 /*********************************************
  * IEEE-1394 core driver stack related section
  *********************************************/
 
 /*
- * This function is called at SCSI init in order to register our driver with the
- * IEEE-1394 stack
+ * This function is called at SCSI init in order to register our driver
+ * with the IEEE-1394 stack.
  */
 int sbp2_init(void)
 {
@@ -931,26 +843,21 @@
 	hpsb_register_addrspace(sbp2_hl_handle, &sbp2_ops, SBP2_STATUS_FIFO_ADDRESS,
 				SBP2_STATUS_FIFO_ADDRESS + sizeof(struct sbp2_status_block));
 
-	/*
-	 * Register physical dma address space... used for
-	 * adapters not supporting hardware phys dma.
-	 *
-	 * XXX: Disabled for now.
-	 */
-	/* hpsb_register_addrspace(sbp2_hl_handle, &sbp2_physdma_ops,
-				   0x0ULL, 0xfffffffcULL); */
+	hpsb_register_protocol(&sbp2_driver);
 
-	return(0);
+	return 0;
 }
 
 /*
- * This function is called from cleanup module, or during shut-down, in order to 
- * unregister our driver
+ * This function is called from cleanup module, or during shut-down, in
+ * order to unregister our driver.
  */
 void sbp2_cleanup(void)
 {
 	SBP2_DEBUG("sbp2: sbp2_cleanup");
 
+	hpsb_unregister_protocol(&sbp2_driver);
+
 	if (sbp2_hl_handle) {
 		hpsb_unregister_highlevel(sbp2_hl_handle);
 		sbp2_hl_handle = NULL;
@@ -958,73 +865,121 @@
 	return;
 }
 
-/*
- * This function is called after registering our operations in sbp2_init. We go ahead and
- * allocate some memory for our host info structure, and init some structures.
- */
-static void sbp2_add_host(struct hpsb_host *host)
+static int sbp2_probe(struct unit_directory *ud)
 {
 	struct sbp2scsi_host_info *hi;
-	unsigned long flags;
 
-	SBP2_DEBUG("sbp2: sbp2_add_host");
+	SBP2_DEBUG("sbp2: sbp2_probe");
+	hi = sbp2_find_host_info(ud->ne->host);
 
-	/*
-	 * Allocate some memory for our host info structure
-	 */
-	hi = (struct sbp2scsi_host_info *)kmalloc(sizeof(struct sbp2scsi_host_info), GFP_KERNEL);
+	return sbp2_start_device(hi, ud);
+}
 
-	if (hi != NULL) {
+static void sbp2_disconnect(struct unit_directory *ud)
+{
+	struct sbp2scsi_host_info *hi;
+	struct scsi_id_instance_data *scsi_id = ud->driver_data;
 
-		/*
-		 * Initialize some host stuff
-		 */
-		memset(hi, 0, sizeof(struct sbp2scsi_host_info));
-		INIT_LIST_HEAD(&hi->list);
-		INIT_LIST_HEAD(&hi->sbp2_req_inuse);
-		INIT_LIST_HEAD(&hi->sbp2_req_free);
-		hi->host = host;
-		hi->sbp2_command_lock = SPIN_LOCK_UNLOCKED;
-		hi->sbp2_request_packet_lock = SPIN_LOCK_UNLOCKED;
+	SBP2_DEBUG("sbp2: sbp2_disconnect");
+	hi = sbp2_find_host_info(ud->ne->host);
 
-		/*
-		 * Create our request packet pool (pool of packets for use in I/O)
+	if (hi != NULL)
+		sbp2_remove_device(hi, scsi_id);
+}
+
+static void sbp2_update(struct unit_directory *ud)
+{
+	struct sbp2scsi_host_info *hi;
+	struct scsi_id_instance_data *scsi_id = ud->driver_data;
+	unsigned long flags;
+
+	SBP2_DEBUG("sbp2: sbp2_update");
+	hi = sbp2_find_host_info(ud->ne->host);
+
+	if (sbp2_reconnect_device(hi, scsi_id)) {
+		
+		/* Ok, reconnect has failed.  Perhaps we didn't
+		 * reconnect fast enough. Try doing a regular login.
 		 */
-		if (sbp2util_create_request_packet_pool(hi)) {
-			SBP2_ERR("sbp2: sbp2util_create_request_packet_pool failed!");
+		if (sbp2_login_device(hi, scsi_id)) {
+
+			/* Login failed too... so, just mark him as
+			 * unvalidated, so that he gets cleaned up
+			 * later.
+			 */
+			SBP2_ERR("sbp2: sbp2_reconnect_device failed!");
+			sbp2_remove_device(hi, scsi_id);
 			return;
 		}
+	}
 
-		sbp2_spin_lock(&sbp2_host_info_lock, flags);
-		list_add_tail(&hi->list, &sbp2_host_info_list);
-		sbp2_host_count++;
-		sbp2_spin_unlock(&sbp2_host_info_lock, flags);
+	/* Set max retries to something large on the device. */
+	sbp2_set_busy_timeout(hi, scsi_id);
 
-		/*
-		 * Initialize us to bus reset in progress
-		 */
-		hi->bus_reset_in_progress = 1;
+	/* Do a SBP-2 fetch agent reset. */
+	sbp2_agent_reset(hi, scsi_id, 0);
+	
+	/* Get the max speed and packet size that we can use. */
+	sbp2_max_speed_and_size(hi, scsi_id);
 
-		/*
-		 * Register our host with the SCSI stack. 
-		 */
-		sbp2scsi_register_scsi_host(hi);
+	/* Complete any pending commands with busy (so they get
+	 * retried) and remove them from our queue
+	 */
+	sbp2_spin_lock(&hi->sbp2_command_lock, flags);
+	sbp2scsi_complete_all_commands(hi, scsi_id, DID_BUS_BUSY);
+	sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
+}
 
-		/*
-		 * Start our kernel thread to deal with sbp2 device detection
-		 */
-		init_waitqueue_head(&hi->sbp2_detection_wait);
-		hi->sbp2_detection_pid = 0;
-		hi->sbp2_detection_pid = kernel_thread(sbp2_detection_thread, hi, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+/*
+ * This function is called after registering our operations in sbp2_init.
+ * We go ahead and allocate some memory for our host info structure, and
+ * init some structures.
+ */
+static void sbp2_add_host(struct hpsb_host *host)
+{
+	struct sbp2scsi_host_info *hi;
+	unsigned long flags;
+
+	SBP2_DEBUG("sbp2: sbp2_add_host");
+
+	/* Allocate some memory for our host info structure */
+	hi = (struct sbp2scsi_host_info *)kmalloc(sizeof(struct sbp2scsi_host_info),
+						  GFP_KERNEL);
 
+	if (hi == NULL) {
+		SBP2_ERR("sbp2: out of memory in sbp2_add_host");
+		return;
+	}
+
+	/* Initialize some host stuff */
+	memset(hi, 0, sizeof(struct sbp2scsi_host_info));
+	INIT_LIST_HEAD(&hi->list);
+	INIT_LIST_HEAD(&hi->sbp2_req_inuse);
+	INIT_LIST_HEAD(&hi->sbp2_req_free);
+	hi->host = host;
+	hi->sbp2_command_lock = SPIN_LOCK_UNLOCKED;
+	hi->sbp2_request_packet_lock = SPIN_LOCK_UNLOCKED;
+
+	/* Create our request packet pool (pool of packets for use in I/O) */
+	if (sbp2util_create_request_packet_pool(hi)) {
+		SBP2_ERR("sbp2: sbp2util_create_request_packet_pool failed!");
+		return;
 	}
 
+	sbp2_spin_lock(&sbp2_host_info_lock, flags);
+	list_add_tail(&hi->list, &sbp2_host_info_list);
+	sbp2_host_count++;
+	sbp2_spin_unlock(&sbp2_host_info_lock, flags);
+
+	/* Register our host with the SCSI stack. */
+	sbp2scsi_register_scsi_host(hi);
+
 	return;
 }
 
 /*
- * This fuction returns a host info structure from the host structure,
- * in case we have multiple hosts
+ * This fuction returns a host info structure from the host structure, in
+ * case we have multiple hosts.
  */
 static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host)
 {
@@ -1047,206 +1002,55 @@
 static void sbp2_remove_host(struct hpsb_host *host)
 {
 	struct sbp2scsi_host_info *hi;
-	int i;
 	unsigned long flags;
+	int i;
 
 	SBP2_DEBUG("sbp2: sbp2_remove_host");
 
 	sbp2_spin_lock(&sbp2_host_info_lock, flags);
-	hi = sbp2_find_host_info(host);
 
+	hi = sbp2_find_host_info(host);
 	if (hi != NULL) {
-
-		/*
-		 * Need to remove any attached SBP-2 devices. Also make sure to logout of all devices.
+		/* Here's an annoying hack: we get a disconnect
+		 * callback for each device, so this loop shouldn't be
+		 * necessary.  However, the sbp2 driver receives the
+		 * remove_host callback before the nodemgr, so when we
+		 * get the disconnect callback, we've already freed
+		 * the host.  Thus, we free the devices here...
 		 */
-		for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-			if (hi->scsi_id[i]) {
+		for (i = 0; i < SBP2SCSI_MAX_SCSI_IDS; i++) {
+			if (hi->scsi_id[i] != NULL) {
 				sbp2_logout_device(hi, hi->scsi_id[i]);
-				hi->scsi_id[i]->validated = 0;
+				sbp2_remove_device(hi, hi->scsi_id[i]);
 			}
 		}
-
-		sbp2_remove_unvalidated_devices(hi);
-
-		list_del(&hi->list);
+		sbp2util_remove_request_packet_pool(hi);
 		sbp2_host_count--;
+		list_del(&hi->list);
+		kfree(hi);
 	}
-	sbp2_spin_unlock(&sbp2_host_info_lock, flags);
-
-	if (hi == NULL) {
+	else
 		SBP2_ERR("sbp2: attempt to remove unknown host %p", host);
-		return;
-	}
-
-	/*
-	 * Remove the packet pool (release the packets)
-	 */
-	sbp2util_remove_request_packet_pool(hi);
-
-	/* 
-	 * Kill our detection thread 
-	 */
-	if (hi->sbp2_detection_pid >= 0) {
-		kill_proc(hi->sbp2_detection_pid, SIGINT, 1);
-	}
-
-	/*
-	 * Give the detection thread a little time to exit
-	 */
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(HZ);	/* 1 second delay */
-
-	kfree(hi);
-	hi = NULL;
-
-	return;
-}
 
-/*
- * This is our sbp2 detection thread. It is signalled when bus resets occur
- * so that we can find and initialize any sbp2 devices. 
- */
-static int sbp2_detection_thread(void *__hi)
-{
-	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *)__hi;
-
-	SBP2_DEBUG("sbp2: sbp2_detection_thread");
-
-	lock_kernel();
-
-	/*
-	 * This thread doesn't need any user-level access,
-	 * so get rid of all our resources
-	 */
-#if LINUX_VERSION_CODE > 0x20300
-	daemonize();
-#endif
-
-	/* 
-	 * Set-up a nice name
-	 */
-	strcpy(current->comm, SBP2_DEVICE_NAME);
-
-	unlock_kernel();
-        
-	while ((!signal_pending(current)) && hi) {
-
-		/*
-		 * Process our bus reset now
-		 */
-		if (hi) {
-			MOD_INC_USE_COUNT;
-			sbp2_bus_reset_handler(hi);
-			MOD_DEC_USE_COUNT;
-		}
-
-		/*
-		 * Sleep until next bus reset
-		 */
-		if (hi) {
-			interruptible_sleep_on(&hi->sbp2_detection_wait);
-		}
-	}
-
-	return(0);
+	sbp2_spin_unlock(&sbp2_host_info_lock, flags);
 }
 
 /*
- * This function is where we first pull the node unique ids, and then allocate memory and register
- * a SBP-2 device
+ * This function is where we first pull the node unique ids, and then
+ * allocate memory and register a SBP-2 device.
  */
-static int sbp2_start_device(struct sbp2scsi_host_info *hi, int node_id)
+static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_directory *ud)
 {
-	u64 node_unique_id;
 	struct scsi_id_instance_data *scsi_id = NULL;
 	struct node_entry *ne;
 	int i;
 
 	SBP2_DEBUG("sbp2: sbp2_start_device");
-
-	/* XXX: This will go away once we start using the nodemgr's
-	 * feature subscription API.  */
-	ne = hpsb_nodeid_get_entry(node_id|(hi->host->node_id & BUS_MASK));
-	if (!ne) {
-		HPSB_ERR("sbp2: Could not find device node");
-		return -ENXIO;
-	}
-
-	node_unique_id = ne->guid;
+	ne = ud->ne;
 
 	/*
-	 * First, we need to find out whether this is a "new" SBP-2 device plugged in, or one that already
-	 * exists and is initialized. We do this by looping through our scsi id instance data structures
-	 * looking for matching node unique ids.
-	 */
-	for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-
-		if (hi->scsi_id[i]) {
-
-			if (hi->scsi_id[i]->node_unique_id == node_unique_id) {
-
-				/*
-				 * Update our node id
-				 */
-				hi->scsi_id[i]->node_id = node_id;
-
-				/*
-				 * Mark the device as validated, since it still exists on the bus
-				 */
-				hi->scsi_id[i]->validated = 1;
-				SBP2_DEBUG("sbp2: SBP-2 device re-validated, SCSI ID = %x", (unsigned int) i);
-
-				/*
-				 * Reconnect to the sbp-2 device
-				 */
-				if (sbp2_reconnect_device(hi, hi->scsi_id[i])) {
-
-					/*
-					 * Ok, reconnect has failed. Perhaps we didn't reconnect fast enough. Try
-					 * doing a regular login.
-					 */
-					if (sbp2_login_device(hi, hi->scsi_id[i])) {
-
-						/*
-						 * Login failed too... so, just mark him as unvalidated, so that he gets cleaned up
-						 * later
-						 */
-						SBP2_ERR("sbp2: sbp2_reconnect_device failed!");
-						hi->scsi_id[i]->validated = 0;
-					}
-				}
-
-				if (hi->scsi_id[i]->validated) {
-
-					/*
-					 * Set max retries to something large on the device
-					 */
-					sbp2_set_busy_timeout(hi, hi->scsi_id[i]);
-
-					/*
-					 * Do a SBP-2 fetch agent reset
-					 */
-					sbp2_agent_reset(hi, hi->scsi_id[i], 0);
-
-					/*
-					 * Get the max speed and packet size that we can use
-					 */
-					sbp2_max_speed_and_size(hi, hi->scsi_id[i]);
-
-				}
-
-				/*
-				 * Nothing more to do, since we found the device
-				 */
-				return(0);
-
-			}
-		}
-	}
-
-	/*
-	 * This really is a "new" device plugged in. Let's allocate memory for our scsi id instance data
+	 * This really is a "new" device plugged in. Let's allocate memory
+	 * for our scsi id instance data.
 	 */
 	scsi_id = (struct scsi_id_instance_data *)kmalloc(sizeof(struct scsi_id_instance_data),
 							  GFP_KERNEL);
@@ -1292,509 +1096,195 @@
 			SBP2_DMA_FREE("logout ORB DMA");
 		}
 
-		if (scsi_id->reconnect_orb) {
-			pci_free_consistent(hi->host->pdev,
-					sizeof(struct sbp2_reconnect_orb),
-					scsi_id->reconnect_orb,
-					scsi_id->reconnect_orb_dma);
-			SBP2_DMA_FREE("reconnect ORB DMA");
-		}
-
-		if (scsi_id->login_response) {
-			pci_free_consistent(hi->host->pdev,
-					sizeof(struct sbp2_login_response),
-					scsi_id->login_response,
-					scsi_id->login_response_dma);
-			SBP2_DMA_FREE("login FIFO DMA");
-		}
-
-		kfree(scsi_id);
-alloc_fail_first:
-		SBP2_ERR ("sbp2: Could not allocate memory for scsi_id");
-		return(-ENOMEM);
-	}
-	SBP2_DMA_ALLOC("consistent DMA region for login ORB");
-
-	/*
-	 * Initialize some of the fields in this structure
-	 */
-	scsi_id->node_id = node_id;
-	scsi_id->node_unique_id = node_unique_id;
-	scsi_id->validated = 1;
-	scsi_id->speed_code = SPEED_100;
-	scsi_id->max_payload_size = MAX_PAYLOAD_S100;
-
-	init_waitqueue_head(&scsi_id->sbp2_login_wait);
-
-	/* 
-	 * Initialize structures needed for the command orb pool.
-	 */
-	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
-	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
-	scsi_id->sbp2_command_orb_lock = SPIN_LOCK_UNLOCKED;
-	scsi_id->sbp2_total_command_orbs = 0;
-
-	/*
-	 * Make sure that we've gotten ahold of the sbp2 management agent address. Also figure out the
-	 * command set being used (SCSI or RBC).
-	 */
-	if (sbp2_parse_unit_directory(hi, scsi_id)) {
-		SBP2_ERR("sbp2: Error while parsing sbp2 unit directory");
-		hi->scsi_id[i]->validated = 0;
-		return(-EIO);
-	}
-
-	scsi_id->sbp2_total_command_orbs = SBP2_MAX_COMMAND_ORBS;
-
-	/* 
-	 * Knock the total command orbs down if we are serializing I/O
-	 */
-	if (serialize_io) {
-		scsi_id->sbp2_total_command_orbs = 2;	/* one extra for good measure */
-	}
-
-	/*
-	 * Allocate some extra command orb structures for devices with 128KB limit
-	 */
-	if (scsi_id->sbp2_firmware_revision == SBP2_128KB_BROKEN_FIRMWARE) {
-		scsi_id->sbp2_total_command_orbs *= 4;
-	} 
-
-	/*
-	 * Create our command orb pool
-	 */
-	if (sbp2util_create_command_orb_pool(scsi_id, hi)) {
-		SBP2_ERR("sbp2: sbp2util_create_command_orb_pool failed!");
-		hi->scsi_id[i]->validated = 0;
-		return (-ENOMEM);
-	}
-
-	/*
-	 * Find an empty spot to stick our scsi id instance data. 
-	 */
-	for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-		if (!hi->scsi_id[i]) {
-			hi->scsi_id[i] = scsi_id;
-			SBP2_DEBUG("sbp2: New SBP-2 device inserted, SCSI ID = %x", (unsigned int) i);
-			break;
-		}
-	}
-
-	/*
-	 * Make sure we are not out of space
-	 */
-	if (i >= SBP2SCSI_MAX_SCSI_IDS) {
-		SBP2_ERR("sbp2: No slots left for SBP-2 device");
-		hi->scsi_id[i]->validated = 0;
-		return(-EBUSY);
-	}
-
-	/*
-	 * Login to the sbp-2 device
-	 */
-	if (sbp2_login_device(hi, hi->scsi_id[i])) {
-
-		/*
-		 * Login failed... so, just mark him as unvalidated, so that he gets cleaned up later
-		 */
-		SBP2_ERR("sbp2: sbp2_login_device failed");
-		hi->scsi_id[i]->validated = 0;
-	}
-
-	if (hi->scsi_id[i]->validated) {
-
-		/*
-		 * Set max retries to something large on the device
-		 */
-		sbp2_set_busy_timeout(hi, hi->scsi_id[i]);
-
-		/*
-		 * Do a SBP-2 fetch agent reset
-		 */
-		sbp2_agent_reset(hi, hi->scsi_id[i], 0);
-
-		/*
-		 * Get the max speed and packet size that we can use
-		 */
-		sbp2_max_speed_and_size(hi, hi->scsi_id[i]);
-
-	}
-
-	return(0);
-}
-
-/*
- * This function tries to determine if a device is a valid SBP-2 device
- */
-static int sbp2_check_device(struct sbp2scsi_host_info *hi, int node_id)
-{
-	quadlet_t unit_spec_id_data = 0, unit_sw_ver_data = 0;
-	quadlet_t unit_directory_length, current_quadlet;
-	u64 unit_directory_addr, current_addr;
-	unsigned int i, length;
-
-	SBP2_DEBUG("sbp2: sbp2_check_device");
-
-	/*
-	 * Let's try and read the unit spec id and unit sw ver to determine if this is an SBP2 device...
-	 */
-
-	if (sbp2util_unit_directory(hi, LOCAL_BUS | node_id, &unit_directory_addr)) {
-		SBP2_DEBUG("sbp2: Error reading unit directory address - bad status");
-		return(-EIO);   
-	}
-
-	/*
-	 * Read the size of the unit directory
-	 */
-	if (sbp2util_read_quadlet(hi, LOCAL_BUS | node_id, unit_directory_addr, 
-				  &unit_directory_length)) {
-		SBP2_DEBUG("sbp2: Error reading root directory length - bad status");
-		return(-EIO);   
-	}
-
-	current_addr = unit_directory_addr;
-	length = be32_to_cpu(unit_directory_length) >> 16;
-
-	/*
-	 * Now, step through the unit directory and look for the unit_spec_ID and the unit_sw_version
-	 */
-	for (i=0; i < length; i++) {
-
-		current_addr += 4;
-
-		if (sbp2util_read_quadlet(hi, LOCAL_BUS | node_id, current_addr, &current_quadlet)) {
-			SBP2_DEBUG("sbp2: Error reading at address 0x%08x%08x - bad status", 
-				   (unsigned int) ((current_addr) >> 32), (unsigned int) ((current_addr) & 0xffffffff));
-			return(-EIO);   
-		}
-
-		/* 
-		 * Check for unit_spec_ID tag 
-		 */
-		if ((be32_to_cpu(current_quadlet) >> 24) == SBP2_UNIT_SPEC_ID_KEY) {
-			unit_spec_id_data = current_quadlet;
-			SBP2_DEBUG("sbp2: Node %x, unit spec id = %x", (LOCAL_BUS | node_id), 
-				   (unsigned int) be32_to_cpu(unit_spec_id_data));
-		}
-
-		/* 
-		 * Check for unit_sw_version tag 
-		 */
-		if ((be32_to_cpu(current_quadlet) >> 24) == SBP2_UNIT_SW_VERSION_KEY) {
-			unit_sw_ver_data = current_quadlet;
-			SBP2_DEBUG("sbp2: Node %x, unit sw version = %x", (LOCAL_BUS | node_id), 
-				   (unsigned int) be32_to_cpu(unit_sw_ver_data));
-		}
-	}
-
-	/*
-	 * Validate unit spec id and unit sw ver to see if this is an SBP-2 device
-	 */
-	if ((be32_to_cpu(unit_spec_id_data) != SBP2_UNIT_SPEC_ID_ENTRY) ||
-	    (be32_to_cpu(unit_sw_ver_data) != SBP2_SW_VERSION_ENTRY)) {
-
-		/*
-		 * Not an sbp2 device
-		 */
-		return(-ENXIO);
-	}
-
-	/*
-	 * This device is a valid SBP-2 device
-	 */
-	SBP2_INFO("sbp2: Node 0x%04x, Found SBP-2 device", (LOCAL_BUS | node_id));
-	return(0);
-}
-
-/*
- * This function removes (cleans-up after) any unvalidated sbp2 devices
- */
-static void sbp2_remove_unvalidated_devices(struct sbp2scsi_host_info *hi)
-{
-	int i;
-
-	/*
-	 * Loop through and free any unvalidated scsi id instance data structures
-	 */
-	for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-		if (hi->scsi_id[i]) {
-			if (!hi->scsi_id[i]->validated) {
-
-				/*
-				 * Complete any pending commands with selection timeout
-				 */
-				sbp2scsi_complete_all_commands(hi, hi->scsi_id[i], DID_NO_CONNECT);
-       			
-				/* 
-				 * Clean up any other structures
-				 */
-				if (hi->scsi_id[i]->sbp2_total_command_orbs) {
-					sbp2util_remove_command_orb_pool(hi->scsi_id[i], hi);
-				}
-				if (hi->scsi_id[i]->login_response) {
-					pci_free_consistent(hi->host->pdev,
-							    sizeof(struct sbp2_login_response),
-							    hi->scsi_id[i]->login_response,
-							    hi->scsi_id[i]->login_response_dma);
-					SBP2_DMA_FREE("single login FIFO");
-				}
-
-				if (hi->scsi_id[i]->login_orb) {
-					pci_free_consistent(hi->host->pdev,
-							    sizeof(struct sbp2_login_orb),
-							    hi->scsi_id[i]->login_orb,
-							    hi->scsi_id[i]->login_orb_dma);
-					SBP2_DMA_FREE("single login ORB");
-				}
-
-				if (hi->scsi_id[i]->reconnect_orb) {
-					pci_free_consistent(hi->host->pdev,
-							    sizeof(struct sbp2_reconnect_orb),
-							    hi->scsi_id[i]->reconnect_orb,
-							    hi->scsi_id[i]->reconnect_orb_dma);
-					SBP2_DMA_FREE("single reconnect orb");
-				}
-
-				if (hi->scsi_id[i]->logout_orb) {
-					pci_free_consistent(hi->host->pdev,
-							    sizeof(struct sbp2_logout_orb),
-							    hi->scsi_id[i]->logout_orb,
-							    hi->scsi_id[i]->reconnect_orb_dma);
-					SBP2_DMA_FREE("single logout orb");
-				}
-
-				kfree(hi->scsi_id[i]);
-				hi->scsi_id[i] = NULL;
-				SBP2_DEBUG("sbp2: Unvalidated SBP-2 device removed, SCSI ID = %x", (unsigned int) i);
-			}
-		}
-	}
-
-	return;
-}
-
-/*
- * This function is our reset handler. It is run out of a thread, since we get 
- * notified of a bus reset from a bh (or interrupt).
- */
-static void sbp2_bus_reset_handler(void *context)
-{
-	struct sbp2scsi_host_info *hi = context;
-	quadlet_t signature_data;
-	int i;
-	unsigned long flags;
-	struct scsi_id_instance_data *scsi_id;
-
-	SBP2_DEBUG("sbp2: sbp2_bus_reset_handler");
-
-	/*
-	 * TODO. Check and keep track of generation number of all requests, in case a
-	 * bus reset occurs while trying to find and login to SBP-2 devices.
-	 */
-
-	/*
-	 * First thing to do. Invalidate all SBP-2 devices. This is needed so that
-	 * we stop sending down I/O requests to the device, and also so that we can
-	 * figure out which devices have disappeared after a bus reset.
-	 */
-	for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-		if (hi->scsi_id[i]) {
-			hi->scsi_id[i]->validated = 0;
+		if (scsi_id->reconnect_orb) {
+			pci_free_consistent(hi->host->pdev,
+					sizeof(struct sbp2_reconnect_orb),
+					scsi_id->reconnect_orb,
+					scsi_id->reconnect_orb_dma);
+			SBP2_DMA_FREE("reconnect ORB DMA");
+		}
+
+		if (scsi_id->login_response) {
+			pci_free_consistent(hi->host->pdev,
+					sizeof(struct sbp2_login_response),
+					scsi_id->login_response,
+					scsi_id->login_response_dma);
+			SBP2_DMA_FREE("login FIFO DMA");
 		}
+
+		kfree(scsi_id);
+alloc_fail_first:
+		SBP2_ERR ("sbp2: Could not allocate memory for scsi_id");
+		return(-ENOMEM);
 	}
+	SBP2_DMA_ALLOC("consistent DMA region for login ORB");
 
 	/*
-	 * Give the sbp2 devices a little time to recover after the bus reset
+	 * Initialize some of the fields in this structure
 	 */
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(HZ/2);		/* 1/2 second delay */
+	scsi_id->ne = ne;
+	scsi_id->ud = ud;
+	scsi_id->speed_code = SPEED_100;
+	scsi_id->max_payload_size = MAX_PAYLOAD_S100;
+	ud->driver_data = scsi_id;
 
-	/*
-	 * Spit out what we know from the host
+	init_waitqueue_head(&scsi_id->sbp2_login_wait);
+
+	/* 
+	 * Initialize structures needed for the command orb pool.
 	 */
-	SBP2_DEBUG("host: node_count = %x", (unsigned int) hi->host->node_count);
-	SBP2_DEBUG("host: selfid_count = %x", (unsigned int) hi->host->selfid_count);
-	SBP2_DEBUG("host: node_id = %x", (unsigned int) hi->host->node_id);
-	SBP2_DEBUG("host: irm_id = %x", (unsigned int) hi->host->irm_id);
-	SBP2_DEBUG("host: busmgr_id = %x", (unsigned int) hi->host->busmgr_id);
-	SBP2_DEBUG("host: is_root = %x", (unsigned int) hi->host->is_root);
-	SBP2_DEBUG("host: is_cycmst = %x", (unsigned int) hi->host->is_cycmst);
-	SBP2_DEBUG("host: is_irm = %x", (unsigned int) hi->host->is_irm);
-	SBP2_DEBUG("host: is_busmgr = %x", (unsigned int) hi->host->is_busmgr);
+	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
+	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
+	scsi_id->sbp2_command_orb_lock = SPIN_LOCK_UNLOCKED;
+	scsi_id->sbp2_total_command_orbs = 0;
 
 	/*
-	 * Let's try and figure out which devices out there are SBP-2 devices! Loop through all 
-	 * nodes out there.
+	 * Make sure that we've gotten ahold of the sbp2 management agent
+	 * address. Also figure out the command set being used (SCSI or
+	 * RBC).
 	 */
-	for (i=0; i<hi->host->node_count; i++) {
-
-		/*
-		 * Don't read from ourselves!
-		 */
-		if (i != ((hi->host->node_id) & NODE_MASK)) {
-
-			/*
-			 * Try and send a request for a config rom signature. This is expected to fail for
-			 * some nodes, as they might be repeater phys or not be initialized.
-			 */
-			if (!sbp2util_read_quadlet(hi, LOCAL_BUS | i, CONFIG_ROM_SIGNATURE_ADDRESS, &signature_data)) {
+	sbp2_parse_unit_directory(scsi_id);
 
-				if (be32_to_cpu(signature_data) == IEEE1394_CONFIG_ROM_SIGNATURE) {
-
-					/*
-					 * Hey, we've got a valid responding IEEE1394 node. Need to now see if it's an SBP-2 device
-					 */
-					if (!sbp2_check_device(hi, i)) {
+	scsi_id->sbp2_total_command_orbs = SBP2_MAX_COMMAND_ORBS;
 
-						/*
-						 * Found an SBP-2 device. Now, actually start the device.
-						 */
-						sbp2_start_device(hi, i);
-					}
-				}
-			}
-		}
+	/* 
+	 * Knock the total command orbs down if we are serializing I/O
+	 */
+	if (serialize_io) {
+		scsi_id->sbp2_total_command_orbs = 2;	/* one extra for good measure */
 	}
 
 	/*
-	 * This code needs protection
+	 * Allocate some extra command orb structures for devices with
+	 * 128KB limit.
 	 */
-	sbp2_spin_lock(&hi->sbp2_command_lock, flags);
+	if (scsi_id->sbp2_firmware_revision == SBP2_128KB_BROKEN_FIRMWARE) {
+		scsi_id->sbp2_total_command_orbs *= 4;
+	} 
 
 	/*
-	 * Ok, we've discovered and re-validated all SBP-2 devices out there. Let's remove structures of all
-	 * devices not re-validated (meaning they've been removed).
+	 * Find an empty spot to stick our scsi id instance data. 
 	 */
-	sbp2_remove_unvalidated_devices(hi);
+	for (i = 0; i < SBP2SCSI_MAX_SCSI_IDS; i++) {
+		if (!hi->scsi_id[i]) {
+			hi->scsi_id[i] = scsi_id;
+			scsi_id->id = i;
+			SBP2_DEBUG("sbp2: New SBP-2 device inserted, SCSI ID = %x", (unsigned int) i);
+			break;
+		}
+	}
 
 	/*
-	 * Complete any pending commands with busy (so they get retried) and remove them from our queue
+	 * Create our command orb pool
 	 */
-	for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-		if (hi->scsi_id[i]) {
-			sbp2scsi_complete_all_commands(hi, hi->scsi_id[i], DID_BUS_BUSY);
-		}
+	if (sbp2util_create_command_orb_pool(scsi_id, hi)) {
+		SBP2_ERR("sbp2: sbp2util_create_command_orb_pool failed!");
+		sbp2_remove_device(hi, scsi_id);
+		return -ENOMEM;
 	}
 
 	/*
-	 * Now, note that the bus reset is complete (finally!)
+	 * Make sure we are not out of space
 	 */
-	hi->bus_reset_in_progress = 0;
+	if (i == SBP2SCSI_MAX_SCSI_IDS) {
+		SBP2_ERR("sbp2: No slots left for SBP-2 device");
+		sbp2_remove_device(hi, scsi_id);
+		return -EBUSY;
+	}
 
 	/*
-	 * Deal with the initial scsi bus scan if needed (since we only now know if there are
-	 * any sbp2 devices attached)
+	 * Login to the sbp-2 device
 	 */
-	if (!no_bus_scan && !hi->initial_scsi_bus_scan_complete && hi->bus_scan_SCpnt) {
+	if (sbp2_login_device(hi, scsi_id)) {
 
-		hi->initial_scsi_bus_scan_complete = 1;			
-		scsi_id = hi->scsi_id[hi->bus_scan_SCpnt->target];
-
-		/* 
-		 * If the sbp2 device exists, then let's now execute the command.
-		 * If not, then just complete it as a selection time-out. 
+		/*
+		 * Login failed... so, just mark him as unvalidated, so
+		 * that he gets cleaned up later.
 		 */
-                if (scsi_id) {
-			if (sbp2_send_command(hi, scsi_id, hi->bus_scan_SCpnt, hi->bus_scan_done)) {
-				SBP2_ERR("sbp2: Error sending SCSI command");
-				sbp2scsi_complete_command(hi, scsi_id, SBP2_SCSI_STATUS_SELECTION_TIMEOUT,
-							  hi->bus_scan_SCpnt, hi->bus_scan_done);
-			}
-		} else {
-			void (*done)(Scsi_Cmnd *) = hi->bus_scan_done;
-			hi->bus_scan_SCpnt->result = DID_NO_CONNECT << 16;
-			done (hi->bus_scan_SCpnt);
-		}
+		SBP2_ERR("sbp2: sbp2_login_device failed");
+		sbp2_remove_device(hi, scsi_id);
+		return -EBUSY;
 	}
 
-	sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
+	/*
+	 * Set max retries to something large on the device
+	 */
+	sbp2_set_busy_timeout(hi, scsi_id);
+	
+	/*
+	 * Do a SBP-2 fetch agent reset
+	 */
+	sbp2_agent_reset(hi, scsi_id, 0);
+	
+	/*
+	 * Get the max speed and packet size that we can use
+	 */
+	sbp2_max_speed_and_size(hi, scsi_id);
 
-	return;
+	return 0;
 }
 
-
 /*
- * This is called from the host's bh when a bus reset is complete. We wake up our detection thread
- * to deal with the reset
+ * This function removes (cleans-up after) any unvalidated sbp2 devices
  */
-static void sbp2_host_reset(struct hpsb_host *host)
+static void sbp2_remove_device(struct sbp2scsi_host_info *hi, 
+			       struct scsi_id_instance_data *scsi_id)
 {
-	unsigned long flags;
-	struct sbp2scsi_host_info *hi;
-	int i;
-
-	SBP2_INFO("sbp2: IEEE-1394 bus reset");
-	sbp2_spin_lock(&sbp2_host_info_lock, flags);
-	hi = sbp2_find_host_info(host);
-
-	if (hi != NULL) {
-
-		/*
-		 * Wake up our detection thread, only if it's not already handling a reset
-		 */
-		if (!hi->bus_reset_in_progress) {
-
-			/*
-			 * First thing to do. Invalidate all SBP-2 devices. This is needed so that
-			 * we stop sending down I/O requests to the device, and also so that we can
-			 * figure out which devices have disappeared after a bus reset.
-			 */
-			for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
-				if (hi->scsi_id[i]) {
-					hi->scsi_id[i]->validated = 0;
-				}
-			}
+	/* Complete any pending commands with selection timeout */
+	sbp2scsi_complete_all_commands(hi, scsi_id, DID_NO_CONNECT);
+       			
+	/* Clean up any other structures */
+	if (scsi_id->sbp2_total_command_orbs) {
+		sbp2util_remove_command_orb_pool(scsi_id, hi);
+	}
 
-			hi->bus_reset_in_progress = 1;
+	if (scsi_id->login_response) {
+		pci_free_consistent(hi->host->pdev,
+				    sizeof(struct sbp2_login_response),
+				    scsi_id->login_response,
+				    scsi_id->login_response_dma);
+		SBP2_DMA_FREE("single login FIFO");
+	}
 
-			wake_up(&hi->sbp2_detection_wait);
-		}
+	if (scsi_id->login_orb) {
+		pci_free_consistent(hi->host->pdev,
+				    sizeof(struct sbp2_login_orb),
+				    scsi_id->login_orb,
+				    scsi_id->login_orb_dma);
+		SBP2_DMA_FREE("single login ORB");
 	}
-	sbp2_spin_unlock(&sbp2_host_info_lock, flags);
-	return;
-}
 
-/* XXX: How best to handle these with DMA interface? */
+	if (scsi_id->reconnect_orb) {
+		pci_free_consistent(hi->host->pdev,
+				    sizeof(struct sbp2_reconnect_orb),
+				    scsi_id->reconnect_orb,
+				    scsi_id->reconnect_orb_dma);
+		SBP2_DMA_FREE("single reconnect orb");
+	}
 
-#if 0
-/*
- * This function deals with physical dma write requests (for adapters that do not support
- * physical dma in hardware).
- */
-static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, quadlet_t *data,
-				     u64 addr, unsigned int length)
-{
+	if (scsi_id->logout_orb) {
+		pci_free_consistent(hi->host->pdev,
+				    sizeof(struct sbp2_logout_orb),
+				    scsi_id->logout_orb,
+				    scsi_id->reconnect_orb_dma);
+		SBP2_DMA_FREE("single logout orb");
+	}
 
-	/*
-	 * Manually put the data in the right place.
-	 */
-	memcpy(bus_to_virt((u32)addr), data, length);
-	return(RCODE_COMPLETE);
+	SBP2_DEBUG("sbp2: Unvalidated SBP-2 device removed, SCSI ID = %d", 
+		   scsi_id->id);
+	hi->scsi_id[scsi_id->id] = NULL;
+	kfree(scsi_id);
 }
 
-/*
- * This function deals with physical dma read requests (for adapters that do not support
- * physical dma in hardware).
- */
-static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
-				    u64 addr, unsigned int length)
-{
-
-	/*
-	 * Grab data from memory and send a read response.
-	 */
-	memcpy(data, bus_to_virt((u32)addr), length);
-	return(RCODE_COMPLETE);
-}
-#endif
+
 
 /**************************************
  * SBP-2 protocol related section
  **************************************/
 
 /*
- * This function is called in order to login to a particular SBP-2 device, after a bus reset
+ * This function is called in order to login to a particular SBP-2 device,
+ * after a bus reset.
  */
 static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id) 
 {
@@ -1808,34 +1298,28 @@
 		return(-EIO);
 	}
 
-	/*
-	 * Set-up login ORB
-	 */
-	scsi_id->login_orb->password_hi = 0;		/* Assume no password */
+	/* Set-up login ORB, assume no password */
+	scsi_id->login_orb->password_hi = 0; 
 	scsi_id->login_orb->password_lo = 0;
 	SBP2_DEBUG("sbp2: sbp2_login_device: password_hi/lo initialized");
-#ifdef SBP2_NEED_LOGIN_DESCRIPTOR_WORKAROUND
-	scsi_id->login_orb->login_response_lo = cpu_to_le32(scsi_id->login_response_dma);
-	scsi_id->login_orb->login_response_hi = cpu_to_le32(ORB_SET_NODE_ID(hi->host->node_id));
-#else
+
 	scsi_id->login_orb->login_response_lo = scsi_id->login_response_dma;
 	scsi_id->login_orb->login_response_hi = ORB_SET_NODE_ID(hi->host->node_id);
-#endif
 	SBP2_DEBUG("sbp2: sbp2_login_device: login_response_hi/lo initialized");
+
 	scsi_id->login_orb->lun_misc = ORB_SET_FUNCTION(LOGIN_REQUEST);
 	scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0);	/* One second reconnect time */
 	scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(1);	/* Exclusive access to device */
 	scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1);		/* Notify us of login complete */
 	SBP2_DEBUG("sbp2: sbp2_login_device: lun_misc initialized");
-	scsi_id->login_orb->passwd_resp_lengths = ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response));
+
+	scsi_id->login_orb->passwd_resp_lengths =
+		ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response));
 	SBP2_DEBUG("sbp2: sbp2_login_device: passwd_resp_lengths initialized");
-#ifdef SBP2_NEED_LOGIN_DESCRIPTOR_WORKAROUND
-	scsi_id->login_orb->status_FIFO_lo = cpu_to_le32((u32)SBP2_STATUS_FIFO_ADDRESS_LO);
-	scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | cpu_to_le16(SBP2_STATUS_FIFO_ADDRESS_HI));
-#else
+
 	scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
-	scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI);
-#endif
+	scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) |
+					      SBP2_STATUS_FIFO_ADDRESS_HI);
 	SBP2_DEBUG("sbp2: sbp2_login_device: status FIFO initialized");
 
 	/*
@@ -1861,25 +1345,26 @@
 	sbp2util_cpu_to_be32_buffer(data, 8);
 
 	SBP2_DEBUG("sbp2: sbp2_login_device: prepared to write");
-
-	hpsb_write(hi->host, LOCAL_BUS | scsi_id->node_id, scsi_id->sbp2_management_agent_addr, data, 8);
+	hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
+	SBP2_DEBUG("sbp2: sbp2_login_device: written");
 
 	/*
-	 * Wait for login status... but, only if the device has not already logged-in (some devices are fast)
+	 * Wait for login status... but, only if the device has not
+	 * already logged-in (some devices are fast)
 	 */
 
-	SBP2_DEBUG("sbp2: sbp2_login_device: written");
 	save_flags(flags);
 	cli();
-	if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
-		interruptible_sleep_on_timeout(&scsi_id->sbp2_login_wait, 10*HZ);		/* 10 second timeout */
-	}
+	/* 10 second timeout */
+	if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma)
+		sleep_on_timeout(&scsi_id->sbp2_login_wait, 10*HZ);
 	restore_flags(flags);
 
 	SBP2_DEBUG("sbp2: sbp2_login_device: initial check");
 
 	/*
-	 * Match status to the login orb. If they do not match, it's probably because the login timed-out
+	 * Match status to the login orb. If they do not match, it's
+	 * probably because the login timed-out.
 	 */
 	if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
 		SBP2_ERR("sbp2: Error logging into SBP-2 device - login timed-out");
@@ -1900,17 +1385,21 @@
 	}
 
 	/*
-	 * Byte swap the login response, for use when reconnecting or logging out.
+	 * Byte swap the login response, for use when reconnecting or
+	 * logging out.
 	 */
 	sbp2util_cpu_to_be32_buffer(scsi_id->login_response, sizeof(struct sbp2_login_response));
 
 	/*
-	 * Grab our command block agent address from the login response
+	 * Grab our command block agent address from the login response.
 	 */
-	SBP2_DEBUG("sbp2: command_block_agent_hi = %x", (unsigned int)scsi_id->login_response->command_block_agent_hi);
-	SBP2_DEBUG("sbp2: command_block_agent_lo = %x", (unsigned int)scsi_id->login_response->command_block_agent_lo);
+	SBP2_DEBUG("sbp2: command_block_agent_hi = %x",
+		   (unsigned int)scsi_id->login_response->command_block_agent_hi);
+	SBP2_DEBUG("sbp2: command_block_agent_lo = %x",
+		   (unsigned int)scsi_id->login_response->command_block_agent_lo);
 
-	scsi_id->sbp2_command_block_agent_addr = ((u64)scsi_id->login_response->command_block_agent_hi) << 32;
+	scsi_id->sbp2_command_block_agent_addr =
+		((u64)scsi_id->login_response->command_block_agent_hi) << 32;
 	scsi_id->sbp2_command_block_agent_addr |= ((u64)scsi_id->login_response->command_block_agent_lo);
 	scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL;
 
@@ -1921,8 +1410,8 @@
 }
 
 /*
- * This function is called in order to logout from a particular SBP-2 device, usually called during driver
- * unload
+ * This function is called in order to logout from a particular SBP-2
+ * device, usually called during driver unload.
  */
 static int sbp2_logout_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id) 
 {
@@ -1937,17 +1426,17 @@
 	scsi_id->logout_orb->reserved2 = 0x0;
 	scsi_id->logout_orb->reserved3 = 0x0;
 	scsi_id->logout_orb->reserved4 = 0x0;
+
 	scsi_id->logout_orb->login_ID_misc = ORB_SET_FUNCTION(LOGOUT_REQUEST);
 	scsi_id->logout_orb->login_ID_misc |= ORB_SET_LOGIN_ID(scsi_id->login_response->length_login_ID);
-	scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1);		/* Notify us when complete */
+
+	/* Notify us when complete */
+	scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1);
+
 	scsi_id->logout_orb->reserved5 = 0x0;
-#ifdef SBP2_NEED_LOGIN_DESCRIPTOR_WORKAROUND
-	scsi_id->logout_orb->status_FIFO_lo = cpu_to_le32((u32)SBP2_STATUS_FIFO_ADDRESS_LO);
-	scsi_id->logout_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | cpu_to_le16(SBP2_STATUS_FIFO_ADDRESS_HI));
-#else
 	scsi_id->logout_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
-	scsi_id->logout_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI);
-#endif
+	scsi_id->logout_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) |
+					       SBP2_STATUS_FIFO_ADDRESS_HI);
 
 	/*
 	 * Byte swap ORB if necessary
@@ -1961,12 +1450,10 @@
 	data[1] = scsi_id->logout_orb_dma;
 	sbp2util_cpu_to_be32_buffer(data, 8);
 
-	hpsb_write(hi->host, LOCAL_BUS | scsi_id->node_id, scsi_id->sbp2_management_agent_addr, data, 8);
+	hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
 
-	/*
-	 * Wait for device to logout... 
-	 */
-	interruptible_sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);		/* 1 second timeout */
+	/* Wait for device to logout...1 second. */
+	sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);
 
 	SBP2_INFO("sbp2: Logged out of SBP-2 device");
 
@@ -1975,7 +1462,8 @@
 }
 
 /*
- * This function is called in order to reconnect to a particular SBP-2 device, after a bus reset
+ * This function is called in order to reconnect to a particular SBP-2
+ * device, after a bus reset.
  */
 static int sbp2_reconnect_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id) 
 {
@@ -1991,18 +1479,19 @@
 	scsi_id->reconnect_orb->reserved2 = 0x0;
 	scsi_id->reconnect_orb->reserved3 = 0x0;
 	scsi_id->reconnect_orb->reserved4 = 0x0;
+
 	scsi_id->reconnect_orb->login_ID_misc = ORB_SET_FUNCTION(RECONNECT_REQUEST);
-	scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_LOGIN_ID(scsi_id->login_response->length_login_ID);
-	scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1);		/* Notify us when complete */
+	scsi_id->reconnect_orb->login_ID_misc |=
+		ORB_SET_LOGIN_ID(scsi_id->login_response->length_login_ID);
+
+	/* Notify us when complete */
+	scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1);
+
 	scsi_id->reconnect_orb->reserved5 = 0x0;
-#ifdef SBP2_NEED_LOGIN_DESCRIPTOR_WORKAROUND
-	scsi_id->reconnect_orb->status_FIFO_lo = cpu_to_le32((u32)SBP2_STATUS_FIFO_ADDRESS_LO);
-	scsi_id->reconnect_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | cpu_to_le16(SBP2_STATUS_FIFO_ADDRESS_HI));
-#else
 	scsi_id->reconnect_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
-	scsi_id->reconnect_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI);
-#endif
-	
+	scsi_id->reconnect_orb->status_FIFO_hi =
+		(ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI);
+
 	/*
 	 * Byte swap ORB if necessary
 	 */
@@ -2020,20 +1509,22 @@
 	data[1] = scsi_id->reconnect_orb_dma;
 	sbp2util_cpu_to_be32_buffer(data, 8);
 
-	hpsb_write(hi->host, LOCAL_BUS | scsi_id->node_id, scsi_id->sbp2_management_agent_addr, data, 8);
+	hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
 
 	/*
-	 * Wait for reconnect status... but, only if the device has not already reconnected (some devices are fast)
+	 * Wait for reconnect status... but, only if the device has not
+	 * already reconnected (some devices are fast).
 	 */
 	save_flags(flags);
 	cli();
-	if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
-		interruptible_sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);		/* one second timeout */
-	}
+	/* One second timout */
+	if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma)
+		sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);
 	restore_flags(flags);
 
 	/*
-	 * Match status to the reconnect orb. If they do not match, it's probably because the reconnect timed-out
+	 * Match status to the reconnect orb. If they do not match, it's
+	 * probably because the reconnect timed-out.
 	 */
 	if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
 		SBP2_ERR("sbp2: Error reconnecting to SBP-2 device - reconnect timed-out");
@@ -2058,7 +1549,8 @@
 }
 
 /*
- * This function is called in order to set the busy timeout (number of retries to attempt) on the sbp2 device. 
+ * This function is called in order to set the busy timeout (number of
+ * retries to attempt) on the sbp2 device. 
  */
 static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id)
 {      
@@ -2071,7 +1563,7 @@
 	 */
 	data = cpu_to_be32(SBP2_BUSY_TIMEOUT_VALUE);
 
-	if (hpsb_write(hi->host, LOCAL_BUS | scsi_id->node_id, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) {
+	if (hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) {
 		SBP2_ERR("sbp2: sbp2_set_busy_timeout error");
 	}
 
@@ -2079,158 +1571,100 @@
 }
 
 /*
- * This function is called to parse sbp2 device's config rom unit directory. Used to determine
- * things like sbp2 management agent offset, and command set used (SCSI or RBC). 
+ * This function is called to parse sbp2 device's config rom unit
+ * directory. Used to determine things like sbp2 management agent offset,
+ * and command set used (SCSI or RBC). 
  */
-static int sbp2_parse_unit_directory(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id)
+static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
 {
-	quadlet_t unit_directory_length, unit_directory_data;
-	u64 unit_directory_addr;
-	u32 i;
+	struct unit_directory *ud;
+	int i;
 
 	SBP2_DEBUG("sbp2: sbp2_parse_unit_directory");
 
-	if (sbp2util_unit_directory(hi, LOCAL_BUS | scsi_id->node_id, &unit_directory_addr)) {
-		SBP2_DEBUG("sbp2: Error reading unit directory address - bad status");
-		return(-EIO);   
-	}
-
-	/*
-	 * Read the size of the unit directory
-	 */
-	if (sbp2util_read_quadlet(hi, LOCAL_BUS | scsi_id->node_id, unit_directory_addr, 
-				  &unit_directory_length)) {
-		SBP2_DEBUG("sbp2: Error reading unit directory length - bad status");
-		return(-EIO);   
-	}
-
-	unit_directory_length = ((be32_to_cpu(unit_directory_length)) >> 16);
-
-	/*
-	 * Now, sweep through the unit directory looking for the management agent offset
-	 * Give up if we hit any error or somehow miss it...
-	 */
-	for (i=0; i<unit_directory_length; i++) {
-
-		if (sbp2util_read_quadlet(hi, LOCAL_BUS | scsi_id->node_id, unit_directory_addr + (i<<2) + 4, 
-					  &unit_directory_data)) {
-			SBP2_DEBUG("sbp2: Error reading unit directory - bad status");
-			return(-EIO);
-		}
-
-		/* 
-		 * Handle different fields in the unit directory, based on keys
-		 */
-		unit_directory_data = be32_to_cpu(unit_directory_data);
-		switch (unit_directory_data >> 24) {
-			
-			case SBP2_CSR_OFFSET_KEY:
-
-				/*
-				 * Save off the management agent address
-				 */
-				scsi_id->sbp2_management_agent_addr = CONFIG_ROM_INITIAL_MEMORY_SPACE + 
-								      ((unit_directory_data & 0x00ffffff) << 2);
-
-				SBP2_DEBUG("sbp2: sbp2_management_agent_addr = %x", (unsigned int) scsi_id->sbp2_management_agent_addr);
-				break;
-
-			case SBP2_COMMAND_SET_SPEC_ID_KEY:
-
-				/*
-				 * Command spec organization
-				 */
-				scsi_id->sbp2_command_set_spec_id = unit_directory_data & 0xffffff;
-				SBP2_DEBUG("sbp2: sbp2_command_set_spec_id = %x", (unsigned int) scsi_id->sbp2_command_set_spec_id);
-				break;
-
-			case SBP2_COMMAND_SET_KEY:
-
-				/*
-				 * Command set used by sbp2 device
-				 */
-				scsi_id->sbp2_command_set = unit_directory_data & 0xffffff;
-				SBP2_DEBUG("sbp2: sbp2_command_set = %x", (unsigned int) scsi_id->sbp2_command_set);
-				break;
-
-			case SBP2_UNIT_CHARACTERISTICS_KEY:
-
-				/*
-				 * Unit characterisitcs (orb related stuff that I'm not yet paying attention to)
-				 */
-				scsi_id->sbp2_unit_characteristics = unit_directory_data & 0xffffff;
-				SBP2_DEBUG("sbp2: sbp2_unit_characteristics = %x", (unsigned int) scsi_id->sbp2_unit_characteristics);
-				break;
+	ud = scsi_id->ud;
 
-			case SBP2_DEVICE_TYPE_AND_LUN_KEY:
+	/* Handle different fields in the unit directory, based on keys */
+	for (i = 0; i < ud->arb_count; i++) {
+		switch (ud->arb_keys[i]) {
+		case SBP2_CSR_OFFSET_KEY:
+			/* Save off the management agent address */
+			scsi_id->sbp2_management_agent_addr =
+				CONFIG_ROM_INITIAL_MEMORY_SPACE + 
+				(ud->arb_values[i] << 2);
 
-				/*
-				 * Device type and lun (used for detemining type of sbp2 device)
-				 */
-				scsi_id->sbp2_device_type_and_lun = unit_directory_data & 0xffffff;
-				SBP2_DEBUG("sbp2: sbp2_device_type_and_lun = %x", (unsigned int) scsi_id->sbp2_device_type_and_lun);
-				break;
-
-			case SBP2_UNIT_SPEC_ID_KEY:
+			SBP2_DEBUG("sbp2: sbp2_management_agent_addr = %x",
+				   (unsigned int) scsi_id->sbp2_management_agent_addr);
+			break;
 
-				/*
-				 * Unit spec id (used for protocol detection)
-				 */
-				scsi_id->sbp2_unit_spec_id = unit_directory_data & 0xffffff;
-				SBP2_DEBUG("sbp2: sbp2_unit_spec_id = %x", (unsigned int) scsi_id->sbp2_unit_spec_id);
-				break;
+		case SBP2_COMMAND_SET_SPEC_ID_KEY:
+			/* Command spec organization */
+			scsi_id->sbp2_command_set_spec_id = ud->arb_values[i];
+			SBP2_DEBUG("sbp2: sbp2_command_set_spec_id = %x",
+				   (unsigned int) scsi_id->sbp2_command_set_spec_id);
+			break;
 
-			case SBP2_UNIT_SW_VERSION_KEY:
+		case SBP2_COMMAND_SET_KEY:
+			/* Command set used by sbp2 device */
+			scsi_id->sbp2_command_set = ud->arb_values[i];
+			SBP2_DEBUG("sbp2: sbp2_command_set = %x",
+				   (unsigned int) scsi_id->sbp2_command_set);
+			break;
 
-				/*
-				 * Unit sw version (used for protocol detection) 
-				 */
-				scsi_id->sbp2_unit_sw_version = unit_directory_data & 0xffffff;
-				SBP2_DEBUG("sbp2: sbp2_unit_sw_version = %x", (unsigned int) scsi_id->sbp2_unit_sw_version);
-				break;
+		case SBP2_UNIT_CHARACTERISTICS_KEY:
+			/*
+			 * Unit characterisitcs (orb related stuff
+			 * that I'm not yet paying attention to)
+			 */
+			scsi_id->sbp2_unit_characteristics = ud->arb_values[i];
+			SBP2_DEBUG("sbp2: sbp2_unit_characteristics = %x",
+				   (unsigned int) scsi_id->sbp2_unit_characteristics);
+			break;
 
-			case SBP2_FIRMWARE_REVISION_KEY:
+		case SBP2_DEVICE_TYPE_AND_LUN_KEY:
+			/*
+			 * Device type and lun (used for
+			 * detemining type of sbp2 device)
+			 */
+			scsi_id->sbp2_device_type_and_lun = ud->arb_values[i];
+			SBP2_DEBUG("sbp2: sbp2_device_type_and_lun = %x",
+				   (unsigned int) scsi_id->sbp2_device_type_and_lun);
+			break;
 
-				/*
-				 * Firmware revision (used to find broken devices). If the vendor id is 0xa0b8 
-				 * (Symbios vendor id), then we have a bridge with 128KB max transfer size limitation.
-				 */
-				scsi_id->sbp2_firmware_revision = unit_directory_data & 0xffff00;
-				if (scsi_id->sbp2_firmware_revision == SBP2_128KB_BROKEN_FIRMWARE) {
-					SBP2_WARN("sbp2: warning: Bridge chipset supports 128KB max transfer size");
-				}
-				break;
+		case SBP2_FIRMWARE_REVISION_KEY:
+			/*
+			 * Firmware revision (used to find broken
+			 * devices). If the vendor id is 0xa0b8
+			 * (Symbios vendor id), then we have a
+			 * bridge with 128KB max transfer size
+			 * limitation.
+			 */
+			scsi_id->sbp2_firmware_revision = ud->arb_values[i];
+			if (scsi_id->sbp2_firmware_revision ==
+			    SBP2_128KB_BROKEN_FIRMWARE) {
+				SBP2_WARN("sbp2: warning: Bridge chipset supports 128KB max transfer size");
+			}
+			break;
 
-			default:
-				break;
+		default:
+			break;
 		}
-
 	}
-
-	return(0);
 }
 
 /*
- * This function is called in order to determine the max speed and packet size we can use in our ORBs. 
+ * This function is called in order to determine the max speed and packet
+ * size we can use in our ORBs. 
  */
 static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id)
 {
 	u8 speed_code;
-	struct node_entry *ne;
+	unsigned int max_rec;
 
 	SBP2_DEBUG("sbp2: sbp2_max_speed_and_size");
 
-	/* Get this nodes information */
-	ne = hpsb_nodeid_get_entry(hi->host->node_id);
-
-	if (!ne) {
-		HPSB_ERR("sbp2: Unknown device, using S100, payload 512 bytes");
-		scsi_id->speed_code = SPEED_100;
-		scsi_id->max_payload_size = MAX_PAYLOAD_S100;
-		return(0);
-	}
-
-	speed_code = ne->busopt.lnkspd;
+	speed_code = scsi_id->ne->busopt.lnkspd;
+	max_rec = scsi_id->ne->busopt.max_rec;
 
 	/* Bump down our speed if there is a module parameter forcing us slower */
 	if (speed_code > max_speed) {
@@ -2240,11 +1674,11 @@
 
 	/* Support the devices max_rec and max speed. We choose a setting
 	 * that fits both values, since they may differ.  */
-	if (speed_code >= SPEED_400 && ne->busopt.max_rec >= MAX_REC_S400) {
+	if (speed_code >= SPEED_400 && max_rec >= MAX_REC_S400) {
 		HPSB_INFO("sbp2: SBP-2 device max speed S400 and payload 2KB");
 		scsi_id->speed_code = SPEED_400;
 		scsi_id->max_payload_size = MAX_PAYLOAD_S400;
-	} else if (speed_code >= SPEED_200 && ne->busopt.max_rec >= MAX_REC_S200) {
+	} else if (speed_code >= SPEED_200 && max_rec >= MAX_REC_S200) {
 		HPSB_INFO("sbp2: SBP-2 device max speed S200 and payload 1KB");
 		scsi_id->speed_code = SPEED_200;
 		scsi_id->max_payload_size = MAX_PAYLOAD_S200;
@@ -2269,9 +1703,11 @@
 	/*
 	 * Ok, let's write to the target's management agent register
 	 */
-	agent_reset_request_packet = sbp2util_allocate_write_request_packet(hi, LOCAL_BUS | scsi_id->node_id,
-									    scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET,
-									    0, ntohl(SBP2_AGENT_RESET_DATA));
+	agent_reset_request_packet =
+		sbp2util_allocate_write_request_packet(hi, LOCAL_BUS | scsi_id->ne->nodeid,
+						       scsi_id->sbp2_command_block_agent_addr +
+						       SBP2_AGENT_RESET_OFFSET,
+						       0, ntohl(SBP2_AGENT_RESET_DATA));
 
 	if (!agent_reset_request_packet) {
 		SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
@@ -2299,8 +1735,8 @@
 }
 
 /*
- * This function is called to create the actual command orb and s/g list out of the 
- * scsi command itself. 
+ * This function is called to create the actual command orb and s/g list
+ * out of the scsi command itself.
  */
 static int sbp2_create_command_orb(struct sbp2scsi_host_info *hi, 
 				   struct scsi_id_instance_data *scsi_id,
@@ -2321,9 +1757,10 @@
 	/*
 	 * Set-up our command ORB..
 	 *
-	 * NOTE: We're doing unrestricted page tables (s/g), as this is best performance 
-	 * (at least with the devices I have). This means that data_size becomes the number 
-	 * of s/g elements, and page_size should be zero (for unrestricted).
+	 * NOTE: We're doing unrestricted page tables (s/g), as this is
+	 * best performance (at least with the devices I have). This means
+	 * that data_size becomes the number of s/g elements, and
+	 * page_size should be zero (for unrestricted).
 	 */
 	command_orb->next_ORB_hi = 0xffffffff;
 	command_orb->next_ORB_lo = 0xffffffff;
@@ -2332,8 +1769,8 @@
 	command_orb->misc |= ORB_SET_NOTIFY(1);		/* Notify us when complete */
 
 	/*
-	 * Set-up our pagetable stuff... unfortunately, this has become messier than I'd like. Need to 
-	 * clean this up a bit.   ;-)
+	 * Set-up our pagetable stuff... unfortunately, this has become
+	 * messier than I'd like. Need to clean this up a bit.   ;-)
 	 */
 	if (sbp2scsi_direction_table[*scsi_cmd] == ORB_DIRECTION_NO_DATA_TRANSFER) {
 
@@ -2405,13 +1842,15 @@
 				}
 			}
 
-			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count); /* number of page table (s/g) elements */
+			/* Number of page table (s/g) elements */
+			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
 
 			/*
 			 * Byte swap page tables if necessary
 			 */
 			sbp2util_cpu_to_be32_buffer(scatter_gather_element, 
-						    (sizeof(struct sbp2_unrestricted_page_table)) * sg_count);
+						    (sizeof(struct sbp2_unrestricted_page_table)) *
+						    sg_count);
 
 		}
 
@@ -2427,8 +1866,8 @@
 		SBP2_DMA_ALLOC("single bulk");
 
 		/*
-		 * Handle case where we get a command w/o s/g enabled (but check
-		 * for transfers larger than 64K)
+		 * Handle case where we get a command w/o s/g enabled (but
+		 * check for transfers larger than 64K)
 		 */
 		if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) {
 
@@ -2438,7 +1877,8 @@
 			command_orb->misc |= ORB_SET_DIRECTION(sbp2scsi_direction_table[*scsi_cmd]);
 
 			/*
-			 * Sanity, in case our direction table is not up-to-date
+			 * Sanity, in case our direction table is not
+			 * up-to-date
 			 */
 			if (!scsi_request_bufflen) {
 				command_orb->data_descriptor_hi = 0xffffffff;
@@ -2448,15 +1888,19 @@
 
 		} else {
 			/*
-			 * Need to turn this into page tables, since the buffer is too large.
+			 * Need to turn this into page tables, since the
+			 * buffer is too large.
 			 */                     
 			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
 			command_orb->data_descriptor_lo = command->sge_dma;
-			command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);	/* use page tables (s/g) */
+
+			/* Use page tables (s/g) */
+			command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
 			command_orb->misc |= ORB_SET_DIRECTION(sbp2scsi_direction_table[*scsi_cmd]);
 
 			/*
-			 * fill out our sbp-2 page tables (and split up the large buffer)
+			 * fill out our sbp-2 page tables (and split up
+			 * the large buffer)
 			 */
 			sg_count = 0;
 			sg_len = scsi_request_bufflen;
@@ -2476,7 +1920,8 @@
 				sg_count++;
 			}
 
-			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count); /* number of page table (s/g) elements */
+			/* Number of page table (s/g) elements */
+			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
 
 			/*
 			 * Byte swap page tables if necessary
@@ -2524,11 +1969,12 @@
 		/*
 		 * Ok, let's write to the target's management agent register
 		 */
-		if (!hi->bus_reset_in_progress) {
+		if (hpsb_node_entry_valid(scsi_id->ne)) {
 
-			command_request_packet = sbp2util_allocate_write_request_packet(hi, LOCAL_BUS | scsi_id->node_id,
-											scsi_id->sbp2_command_block_agent_addr + SBP2_ORB_POINTER_OFFSET,
-											8, 0);
+			command_request_packet =
+				sbp2util_allocate_write_request_packet(hi, LOCAL_BUS | scsi_id->ne->nodeid,
+								scsi_id->sbp2_command_block_agent_addr +
+								SBP2_ORB_POINTER_OFFSET, 8, 0);
 		
 			if (!command_request_packet) {
 				SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
@@ -2561,16 +2007,19 @@
 		 * modifying these next orb pointers, as they are accessed
 		 * both by the sbp2 device and us.
 		 */
-		scsi_id->last_orb->next_ORB_lo = cpu_to_be32(command->command_orb_dma);
-		scsi_id->last_orb->next_ORB_hi = 0x0;	/* Tells hardware that this pointer is valid */
-		
+		scsi_id->last_orb->next_ORB_lo =
+			cpu_to_be32(command->command_orb_dma);
+		/* Tells hardware that this pointer is valid */
+		scsi_id->last_orb->next_ORB_hi = 0x0;
+
 		/*
-		 * Only ring the doorbell if we need to (first parts of linked orbs don't need this)
+		 * Only ring the doorbell if we need to (first parts of
+		 * linked orbs don't need this).
 		 */
-		if (!command->linked && !hi->bus_reset_in_progress) {
+		if (!command->linked && hpsb_node_entry_valid(scsi_id->ne)) {
 
 			command_request_packet = sbp2util_allocate_write_request_packet(hi,
-				LOCAL_BUS | scsi_id->node_id,
+				LOCAL_BUS | scsi_id->ne->nodeid,
 				scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET,
 				0, cpu_to_be32(command->command_orb_dma));
 	
@@ -2610,8 +2059,8 @@
 	SBP2_DEBUG("sbp2: SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg);
 
 	/*
-	 * Check for broken devices that can't handle greater than 128K transfers, and deal with them in a 
-	 * hacked ugly way.
+	 * Check for broken devices that can't handle greater than 128K
+	 * transfers, and deal with them in a hacked ugly way.
 	 */
 	if ((scsi_id->sbp2_firmware_revision == SBP2_128KB_BROKEN_FIRMWARE) && 
 	    (SCpnt->request_bufflen > SBP2_BROKEN_FIRMWARE_MAX_TRANSFER) && 
@@ -2620,7 +2069,8 @@
 	    (*cmd == 0x28 || *cmd == 0x2a || *cmd == 0x0a || *cmd == 0x08)) {
 
 		/*
-		 * Darn, a broken device. We'll need to split up the transfer ourselves
+		 * Darn, a broken device. We'll need to split up the
+		 * transfer ourselves.
 		 */
 		sbp2_send_split_command(hi, scsi_id, SCpnt, done);
 		return(0);
@@ -2637,13 +2087,12 @@
 	/*
 	 * Now actually fill in the comamnd orb and sbp2 s/g list
 	 */
-	sbp2_create_command_orb(hi, scsi_id, command, cmd, SCpnt->use_sg, 
-				SCpnt->request_bufflen, SCpnt->request_buffer,
-				scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
-	
+	sbp2_create_command_orb(hi, scsi_id, command, cmd, SCpnt->use_sg,
+			SCpnt->request_bufflen, SCpnt->request_buffer,
+			scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); 
 	/*
-	 * Update our cdb if necessary (to handle sbp2 RBC command set differences).
-	 * This is where the command set hacks go!   =)
+	 * Update our cdb if necessary (to handle sbp2 RBC command set
+	 * differences).  This is where the command set hacks go!   =)
 	 */
 	if ((device_type == TYPE_DISK) ||
 	    (device_type == TYPE_SDAD) ||
@@ -2665,7 +2114,8 @@
 }
 
 /*
- * This function is called for broken sbp2 device, where we have to break up large transfers. 
+ * This function is called for broken sbp2 device, where we have to break
+ * up large transfers.
  */
 static int sbp2_send_split_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
 				   Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
@@ -2779,8 +2229,8 @@
 }
 
 /*
- * This function deals with command set differences between Linux scsi command set and sbp2 RBC
- * command set.
+ * This function deals with command set differences between Linux scsi
+ * command set and sbp2 RBC command set.
  */
 static void sbp2_check_sbp2_command(unchar *cmd)
 {
@@ -3001,9 +2451,9 @@
 	 */
 	for (i=0; i<SBP2SCSI_MAX_SCSI_IDS; i++) {
 		if (hi->scsi_id[i]) {
-			if (hi->scsi_id[i]->node_id == (nodeid & NODE_MASK)) {
+			if ((hi->scsi_id[i]->ne->nodeid & NODE_MASK) == (nodeid & NODE_MASK)) {
 				scsi_id = hi->scsi_id[i];
-				SBP2_DEBUG("sbp2: SBP-2 status write from node %x", scsi_id->node_id);
+				SBP2_DEBUG("sbp2: SBP-2 status write from node %x", scsi_id->ne->nodeid);
 				break;
 			}
 		}
@@ -3089,6 +2539,7 @@
 	return(RCODE_COMPLETE);
 }
 
+
 
 /**************************************
  * SCSI interface related section
@@ -3121,18 +2572,8 @@
 	scsi_id = hi->scsi_id[SCpnt->target];
 
 	/*
-	 * Save off the command if this is the initial bus scan... so that we can
-	 * complete it after we find all our sbp2 devices on the 1394 bus
-	 */
-	if (!no_bus_scan && !hi->initial_scsi_bus_scan_complete) {
-		hi->bus_scan_SCpnt = SCpnt;
-		hi->bus_scan_done = done;
-		return(0);
-	}
-
-	/*
-	 * If scsi_id is null, it means there is no device in this slot, so we should return 
-	 * selection timeout.
+	 * If scsi_id is null, it means there is no device in this slot,
+	 * so we should return selection timeout.
 	 */
 	if (!scsi_id) {
 		SCpnt->result = DID_NO_CONNECT << 16;
@@ -3141,7 +2582,8 @@
 	}
 
 	/*
-	 * Until we handle multiple luns, just return selection time-out to any IO directed at non-zero LUNs
+	 * Until we handle multiple luns, just return selection time-out
+	 * to any IO directed at non-zero LUNs
 	 */
 	if (SCpnt->lun) {
 		SCpnt->result = DID_NO_CONNECT << 16;
@@ -3150,7 +2592,8 @@
 	}
 
 	/*
-	 * Check for request sense command, and handle it here (autorequest sense)
+	 * Check for request sense command, and handle it here
+	 * (autorequest sense)
 	 */
 	if (SCpnt->cmnd[0] == REQUEST_SENSE) {
 		SBP2_DEBUG("sbp2: REQUEST_SENSE");
@@ -3161,9 +2604,10 @@
 	}
 
 	/*
-	 * Check to see if there is a command in progress and just return busy (to be queued later)
+	 * Check to see if there is a command in progress and just return
+	 * busy (to be queued later)
 	 */
-	if (hi->bus_reset_in_progress) {
+	if (!hpsb_node_entry_valid(scsi_id->ne)) {
 		SBP2_ERR("sbp2: Bus reset in progress - rejecting command");
 		SCpnt->result = DID_BUS_BUSY << 16;
 		done (SCpnt);
@@ -3184,9 +2628,11 @@
 }
 
 /*
- * This function is called in order to complete all outstanding SBP-2 commands (in case of resets, etc.). 
+ * This function is called in order to complete all outstanding SBP-2
+ * commands (in case of resets, etc.).
  */
-static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, 
+static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi,
+					   struct scsi_id_instance_data *scsi_id, 
 					   u32 status)
 {
 	struct list_head *lh;
@@ -3210,7 +2656,7 @@
 }
 
 /*
- * This function is called in order to complete a regular SBP-2 command. 
+ * This function is called in order to complete a regular SBP-2 command.
  */
 static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, u32 scsi_status,
 				      Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
@@ -3226,10 +2672,11 @@
 	}
 
 	/*
-	 * If a bus reset is in progress and there was an error, don't complete the command,
-	 * just let it get retried at the end of the bus reset.
+	 * If a bus reset is in progress and there was an error, don't
+	 * complete the command, just let it get retried at the end of the
+	 * bus reset.
 	 */
-	if ((hi->bus_reset_in_progress) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
+	if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
 		SBP2_ERR("sbp2: Bus reset in progress - retry command later");
 		return;
 	}
@@ -3283,9 +2730,10 @@
 	}
 
 	/*
-	 * One more quick hack (not enabled by default). Some sbp2 devices do not support 
-	 * mode sense. Turn-on this hack to allow the device to pass the sd driver's 
-	 * write-protect test (so that you can mount the device rw).
+	 * One more quick hack (not enabled by default). Some sbp2 devices
+	 * do not support mode sense. Turn-on this hack to allow the
+	 * device to pass the sd driver's write-protect test (so that you
+	 * can mount the device rw).
 	 */
 	if (mode_sense_hack && SCpnt->result != DID_OK && SCpnt->cmnd[0] == MODE_SENSE) {
 		SBP2_INFO("sbp2: Returning success to mode sense command");
@@ -3295,17 +2743,18 @@
 	}
 
 	/*
-	 * If a bus reset is in progress and there was an error, complete the command
-	 * as busy so that it will get retried.
+	 * If a bus reset is in progress and there was an error, complete
+	 * the command as busy so that it will get retried.
 	 */
-	if ((hi->bus_reset_in_progress) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
+	if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
 		SBP2_ERR("sbp2: Completing command with busy (bus reset)");
 		SCpnt->result = DID_BUS_BUSY << 16;
 	}
 
 	/*
-	 * If a unit attention occurs, return busy status so it gets retried... it could have happened because
-	 * of a 1394 bus reset or hot-plug...
+	 * If a unit attention occurs, return busy status so it gets
+	 * retried... it could have happened because of a 1394 bus reset
+	 * or hot-plug...
 	 */
 	if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && (SCpnt->sense_buffer[2] == UNIT_ATTENTION)) {
 		SBP2_INFO("sbp2: UNIT ATTENTION - return busy");
@@ -3321,8 +2770,8 @@
 }
 
 /*
- * Called by scsi stack when something has really gone wrong.
- * Usually called when a command has timed-out for some reason. 
+ * Called by scsi stack when something has really gone wrong.  Usually
+ * called when a command has timed-out for some reason.
  */
 static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) 
 {
@@ -3336,8 +2785,9 @@
 	if (scsi_id) {
 
 		/*
-		 * Right now, just return any matching command structures to the free pool (there may
-		 * be more than one because of broken up/linked commands).
+		 * Right now, just return any matching command structures
+		 * to the free pool (there may be more than one because of
+		 * broken up/linked commands).
 		 */
 		sbp2_spin_lock(&hi->sbp2_command_lock, flags);
 		do {
@@ -3445,10 +2895,6 @@
 		global_scsi_tpnt->use_clustering = DISABLE_CLUSTERING;
 	}
 
-	if (no_bus_scan) {
-		SBP2_ERR("sbp2: Initial scsi bus scan deferred (no_bus_scan = 1)");
-	}
-
 	if (mode_sense_hack) {
 		SBP2_ERR("sbp2: Mode sense emulation enabled (mode_sense_hack = 1)");
 	}
@@ -3457,21 +2903,19 @@
 
 	if (!sbp2_host_count) {
 		SBP2_ERR("sbp2: Please load the lower level IEEE-1394 driver (e.g. ohci1394) before sbp2...");
-		if (sbp2_hl_handle) {
-			hpsb_unregister_highlevel(sbp2_hl_handle);
-			sbp2_hl_handle = NULL;
-		}
+		sbp2_cleanup();
 	}
 
 	/*
-	 * Since we are returning this count, it means that sbp2 must be loaded "after" the 
-	 * host adapter module... 	 
+	 * Since we are returning this count, it means that sbp2 must be
+	 * loaded "after" the host adapter module...
 	 */
 	return(sbp2_host_count);
 }
 
 /*
- * This function is called from sbp2_add_host, and is where we register our scsi host
+ * This function is called from sbp2_add_host, and is where we register
+ * our scsi host
  */
 static void sbp2scsi_register_scsi_host(struct sbp2scsi_host_info *hi)
 {
@@ -3488,7 +2932,8 @@
 		shpnt = scsi_register (global_scsi_tpnt, sizeof(void *));
 
 		/*
-		 * If successful, save off a context (to be used when SCSI commands are received)
+		 * If successful, save off a context (to be used when SCSI
+		 * commands are received)
 		 */
 		if (shpnt) {
 			shpnt->hostdata[0] = (unsigned long)hi;
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/sbp2.h linux/drivers/ieee1394/sbp2.h
--- v2.4.10/linux/drivers/ieee1394/sbp2.h	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ieee1394/sbp2.h	Mon Oct  1 21:24:25 2001
@@ -36,13 +36,6 @@
 #define ORB_DIRECTION_READ_FROM_MEDIA   0x1
 #define ORB_DIRECTION_NO_DATA_TRANSFER  0x2
 
-#define SPEED_S100			0x0
-#define SPEED_S200			0x1
-#define SPEED_S400			0x2
-#define SPEED_S800			0x3
-#define SPEED_S1600			0x4
-#define SPEED_S3200			0x5
-
 /* 2^(MAX_PAYLOAD+1) = Maximum data transfer length */
 #define MAX_PAYLOAD_S100		0x7
 #define MAX_PAYLOAD_S200		0x8
@@ -232,8 +225,8 @@
  * Unit spec id and sw version entry for SBP-2 devices
  */
 
-#define SBP2_UNIT_SPEC_ID_ENTRY					0x1200609e
-#define SBP2_SW_VERSION_ENTRY					0x13010483
+#define SBP2_UNIT_SPEC_ID_ENTRY					0x0000609e
+#define SBP2_SW_VERSION_ENTRY					0x00010483
 
 /*
  * Miscellaneous general config rom related defines
@@ -243,11 +236,8 @@
 
 #define CONFIG_ROM_BASE_ADDRESS					0xfffff0000400ULL
 #define CONFIG_ROM_ROOT_DIR_BASE				0xfffff0000414ULL
-#define CONFIG_ROM_SIGNATURE_ADDRESS				0xfffff0000404ULL
 #define CONFIG_ROM_UNIT_DIRECTORY_OFFSET			0xfffff0000424ULL
 
-#define IEEE1394_CONFIG_ROM_SIGNATURE				0x31333934
-
 #define SBP2_128KB_BROKEN_FIRMWARE				0xa0b800
 #define SBP2_BROKEN_FIRMWARE_MAX_TRANSFER			0x20000
 
@@ -350,6 +340,8 @@
  * Information needed on a per scsi id basis (one for each sbp2 device)
  */
 struct scsi_id_instance_data {
+	/* SCSI ID */
+	int id;
 
 	/*
 	 * Various sbp2 specific structures
@@ -368,18 +360,15 @@
 	/*
 	 * Stuff we need to know about the sbp2 device itself
 	 */
-	u64 node_unique_id;
 	u64 sbp2_management_agent_addr;
 	u64 sbp2_command_block_agent_addr;
-	u32 node_id;
 	u32 speed_code;
 	u32 max_payload_size;
 
 	/*
 	 * Values pulled from the device's unit directory
 	 */
-	u32 sbp2_unit_spec_id;
-	u32 sbp2_unit_sw_version;
+	struct unit_directory *ud;
 	u32 sbp2_command_set_spec_id;
 	u32 sbp2_command_set;
 	u32 sbp2_unit_characteristics;
@@ -391,12 +380,6 @@
 	 */
 	wait_queue_head_t sbp2_login_wait;
 
-	/*
-	 * Flag noting whether the sbp2 device is currently validated (for use during
-	 * bus resets).
-	 */
-	u32 validated;
-
 	/* 
 	 * Pool of command orbs, so we can have more than overlapped command per id
 	 */
@@ -405,6 +388,8 @@
 	struct list_head sbp2_command_orb_completed;
 	u32 sbp2_total_command_orbs;
 
+	/* Node entry, as retrieved from NodeMgr entries */
+	struct node_entry *ne;
 };
 
 /*
@@ -425,22 +410,6 @@
 	spinlock_t sbp2_request_packet_lock;
 
 	/*
-	 * Flag indicating if a bus reset (or device detection) is in progress
-	 */
-	u32 bus_reset_in_progress;
-
-	/*
-	 * We currently use a kernel thread for dealing with bus resets and sbp2
-	 * device detection. We use this to wake up the thread when needed.
-	 */
-	wait_queue_head_t sbp2_detection_wait;
-
-	/* 
-	 * PID of sbp2 detection kernel thread 
-	 */
-	int sbp2_detection_pid;
-
-	/*
 	 * Lists keeping track of inuse/free sbp2_request_packets. These structures are
 	 * used for sending out sbp2 command and agent reset packets. We initially create
 	 * a pool of request packets so that we don't have to do any kmallocs while in critical
@@ -450,13 +419,6 @@
 	struct list_head sbp2_req_free;
 
 	/*
-	 * Stuff to keep track of the initial scsi bus scan (so that we don't miss it)
-	 */
-	u32 initial_scsi_bus_scan_complete;
-	Scsi_Cmnd *bus_scan_SCpnt;
-	void (*bus_scan_done)(Scsi_Cmnd *);
-
-	/*
 	 * Here is the pool of request packets. All the hpsb packets (for 1394 bus transactions)
 	 * are allocated at init and simply re-initialized when needed.
 	 */
@@ -476,9 +438,6 @@
 /*
  * Various utility prototypes
  */
-static int sbp2util_read_quadlet(struct sbp2scsi_host_info *hi, nodeid_t node, u64 addr,
-				 quadlet_t *buffer);
-static int sbp2util_unit_directory(struct sbp2scsi_host_info *hi, nodeid_t node, u64 *addr);
 static int sbp2util_create_request_packet_pool(struct sbp2scsi_host_info *hi);
 static void sbp2util_remove_request_packet_pool(struct sbp2scsi_host_info *hi);
 static struct sbp2_request_packet *sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
@@ -500,23 +459,19 @@
 /*
  * IEEE-1394 core driver related prototypes
  */
-static void sbp2_remove_unvalidated_devices(struct sbp2scsi_host_info *hi);
-static int sbp2_start_device(struct sbp2scsi_host_info *hi, int node_id);
-static int sbp2_check_device(struct sbp2scsi_host_info *hi, int node_id);
-static void sbp2_bus_reset_handler(void *context);
 static void sbp2_add_host(struct hpsb_host *host);
 static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host);
 static void sbp2_remove_host(struct hpsb_host *host);
-static void sbp2_host_reset(struct hpsb_host *host);
-static int sbp2_detection_thread(void *__sbp2);
 int sbp2_init(void);
 void sbp2_cleanup(void);
-#if 0
-static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, quadlet_t *data,
-				     u64 addr, unsigned int length);
-static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
-				    u64 addr, unsigned int length);
-#endif
+static int sbp2_probe(struct unit_directory *ud);
+static void sbp2_disconnect(struct unit_directory *ud);
+static void sbp2_update(struct unit_directory *ud);
+static int sbp2_start_device(struct sbp2scsi_host_info *hi, 
+			     struct unit_directory *ud);
+static void sbp2_remove_device(struct sbp2scsi_host_info *hi, 
+			       struct scsi_id_instance_data *scsi_id);
+
 /*
  * SBP-2 protocol related prototypes
  */
@@ -543,7 +498,7 @@
 static void sbp2_check_sbp2_command(unchar *cmd);
 static void sbp2_check_sbp2_response(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, 
 				     Scsi_Cmnd *SCpnt);
-static int sbp2_parse_unit_directory(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
+static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
 static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
 static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/ieee1394/video1394.c linux/drivers/ieee1394/video1394.c
--- v2.4.10/linux/drivers/ieee1394/video1394.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/ieee1394/video1394.c	Mon Oct  1 21:24:25 2001
@@ -103,7 +103,7 @@
 	int ctxMatch;
 	wait_queue_head_t waitq;
         spinlock_t lock;
-	unsigned int syt_offset;
+    unsigned int syt_offset;
 	int flags;
 };
 
@@ -488,24 +488,27 @@
 	int i;
 
 	/* the first descriptor will read only 4 bytes */
-	ir_prg[0].control = (0x280C << 16) | 4;
+	ir_prg[0].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
+		DMA_CTL_BRANCH | 4;
 
 	/* set the sync flag */
 	if (flags & VIDEO1394_SYNC_FRAMES)
-		ir_prg[0].control |= 0x00030000;
+		ir_prg[0].control |= DMA_CTL_WAIT;
 
 	ir_prg[0].address = kvirt_to_bus(buf);
 	ir_prg[0].branchAddress =  (virt_to_bus(&(ir_prg[1].control)) 
 				    & 0xfffffff0) | 0x1;
 
 	/* the second descriptor will read PAGE_SIZE-4 bytes */
-	ir_prg[1].control = (0x280C << 16) | (PAGE_SIZE-4);
+	ir_prg[1].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE |
+		DMA_CTL_BRANCH | (PAGE_SIZE-4);
 	ir_prg[1].address = kvirt_to_bus(buf+4);
 	ir_prg[1].branchAddress =  (virt_to_bus(&(ir_prg[2].control)) 
 				    & 0xfffffff0) | 0x1;
 	
 	for (i=2;i<d->nb_cmd-1;i++) {
-		ir_prg[i].control = (0x280C << 16) | PAGE_SIZE;
+		ir_prg[i].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | 
+			DMA_CTL_BRANCH | PAGE_SIZE;
 		ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
 
 		ir_prg[i].branchAddress =  
@@ -514,7 +517,8 @@
 	}
 
 	/* the last descriptor will generate an interrupt */
-	ir_prg[i].control = (0x283C << 16) | d->left_size;
+	ir_prg[i].control = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | 
+		DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size;
 	ir_prg[i].address = kvirt_to_bus(buf+(i-1)*PAGE_SIZE);
 }
 	
@@ -691,13 +695,14 @@
 	d->last_used_cmd[n] = d->nb_cmd - 1;
 	for (i=0;i<d->nb_cmd;i++) {
 				 
-		it_prg[i].begin.control = OUTPUT_MORE_IMMEDIATE | 8 ;
+		it_prg[i].begin.control = DMA_CTL_OUTPUT_MORE |
+			DMA_CTL_IMMEDIATE | 8 ;
 		it_prg[i].begin.address = 0;
 		
 		it_prg[i].begin.status = 0;
 		
 		it_prg[i].data[0] = 
-			(DMA_SPEED_100 << 16) 
+			(SPEED_100 << 16) 
 			| (/* tag */ 1 << 14)
 			| (d->channel << 8) 
 			| (TCODE_ISO_DATA << 4);
@@ -706,7 +711,7 @@
 		it_prg[i].data[2] = 0;
 		it_prg[i].data[3] = 0;
 		
-		it_prg[i].end.control = 0x100c0000;
+		it_prg[i].end.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
 		it_prg[i].end.address =
 			kvirt_to_bus(buf+i*d->packet_size);
 
@@ -721,7 +726,8 @@
 		}
 		else {
 			/* the last prg generates an interrupt */
-			it_prg[i].end.control |= 0x08300000 | d->left_size;
+			it_prg[i].end.control |= DMA_CTL_UPDATE | 
+				DMA_CTL_IRQ | d->left_size;
 			/* the last prg doesn't branch */
 			it_prg[i].begin.branchAddress = 0;
 			it_prg[i].end.branchAddress = 0;
@@ -761,7 +767,7 @@
 			size = packet_sizes[i];
 		}
 		it_prg[i].data[1] = size << 16; 
-		it_prg[i].end.control = 0x100c0000;
+		it_prg[i].end.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
 
 		if (i < d->nb_cmd-1 && packet_sizes[i+1] != 0) {
 			it_prg[i].end.control |= size;
@@ -773,7 +779,8 @@
 				 & 0xfffffff0) | 0x3;
 		} else {
 			/* the last prg generates an interrupt */
-			it_prg[i].end.control |= 0x08300000 | size;
+			it_prg[i].end.control |= DMA_CTL_UPDATE | 
+				DMA_CTL_IRQ | size;
 			/* the last prg doesn't branch */
 			it_prg[i].begin.branchAddress = 0;
 			it_prg[i].end.branchAddress = 0;
@@ -1560,7 +1567,6 @@
 static void remove_card(struct video_card *video)
 {
 	int i;
-	unsigned long flags;
 
 	ohci1394_unregister_video(video->ohci, &video_tmpl);
 
@@ -1581,9 +1587,7 @@
 		}
 		kfree(video->it_context);
 	}
-	spin_lock_irqsave(&video1394_cards_lock, flags);
 	list_del(&video->list);
-	spin_unlock_irqrestore(&video1394_cards_lock, flags);
 
 	kfree(video);
 }
@@ -1607,7 +1611,7 @@
 			p = list_entry(lh, struct video_card, list);
 			if (p ->ohci == ohci) {
 				remove_card(p);
-				return;
+				break;
 			}
 		}
 	}
@@ -1639,6 +1643,7 @@
 MODULE_AUTHOR("Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>");
 MODULE_DESCRIPTION("driver for digital video on OHCI board");
 MODULE_SUPPORTED_DEVICE(VIDEO1394_DRIVER_NAME);
+MODULE_LICENSE("GPL");
 
 static void __exit video1394_exit_module (void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/input/evdev.c linux/drivers/input/evdev.c
--- v2.4.10/linux/drivers/input/evdev.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/input/evdev.c	Sun Sep 30 12:26:05 2001
@@ -398,3 +398,5 @@
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Event character device driver");
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/input/input.c linux/drivers/input/input.c
--- v2.4.10/linux/drivers/input/input.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/input/input.c	Sun Sep 30 12:26:05 2001
@@ -37,6 +37,8 @@
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Input layer module");
+MODULE_LICENSE("GPL");
+
 
 EXPORT_SYMBOL(input_register_device);
 EXPORT_SYMBOL(input_unregister_device);
diff -u --recursive --new-file v2.4.10/linux/drivers/input/joydev.c linux/drivers/input/joydev.c
--- v2.4.10/linux/drivers/input/joydev.c	Wed Apr 11 19:02:30 2001
+++ linux/drivers/input/joydev.c	Sun Sep 30 12:26:05 2001
@@ -84,6 +84,7 @@
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Joystick device driver");
+MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("input/js");
 
 static int joydev_correct(int value, struct js_corr *corr)
diff -u --recursive --new-file v2.4.10/linux/drivers/input/mousedev.c linux/drivers/input/mousedev.c
--- v2.4.10/linux/drivers/input/mousedev.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/input/mousedev.c	Sun Sep 30 12:26:05 2001
@@ -314,9 +314,9 @@
 
 			case 0xf2: /* Get ID */
 				switch (list->mode) {
-					case 0: list->ps2[1] = 0;
-					case 1: list->ps2[1] = 3;
-					case 2: list->ps2[1] = 4;
+					case 0: list->ps2[1] = 0; break;
+					case 1: list->ps2[1] = 3; break;
+					case 2: list->ps2[1] = 4; break;
 				}
 				list->bufsiz = 2;
 				break;
@@ -497,6 +497,8 @@
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Input driver to PS/2 or ImPS/2 device driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(xres, "i");
 MODULE_PARM_DESC(xres, "Horizontal screen resolution");
 MODULE_PARM(yres, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/act2000/act2000.h linux/drivers/isdn/act2000/act2000.h
--- v2.4.10/linux/drivers/isdn/act2000/act2000.h	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/act2000/act2000.h	Sun Sep 30 12:26:05 2001
@@ -1,35 +1,19 @@
-/* $Id: act2000.h,v 1.8.6.2 2001/02/16 16:43:23 kai Exp $
+/* $Id: act2000.h,v 1.8.6.3 2001/09/23 22:24:32 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- * This program is free software; you can redistribute 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.
+ * Author       Fritz Elfert
+ * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * Thanks to Friedemann Baitinger and IBM Germany
  *
  */
 
 #ifndef act2000_h
 #define act2000_h
-
-#ifdef __KERNEL__
-/* Kernel includes */
-
-#include <linux/module.h>
-#include <linux/version.h>
-#endif
 
 #define ACT2000_IOCTL_SETPORT    1
 #define ACT2000_IOCTL_GETPORT    2
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/act2000/act2000_isa.c linux/drivers/isdn/act2000/act2000_isa.c
--- v2.4.10/linux/drivers/isdn/act2000/act2000_isa.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/act2000/act2000_isa.c	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,14 @@
-/* $Id: act2000_isa.c,v 1.11.6.2 2001/07/18 16:25:12 kai Exp $
+/* $Id: act2000_isa.c,v 1.11.6.3 2001/09/23 22:24:32 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
  *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- * This program is free software; you can redistribute 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.
+ * Author       Fritz Elfert
+ * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * Thanks to Friedemann Baitinger and IBM Germany
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/act2000/act2000_isa.h linux/drivers/isdn/act2000/act2000_isa.h
--- v2.4.10/linux/drivers/isdn/act2000/act2000_isa.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/act2000/act2000_isa.h	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,14 @@
-/* $Id: act2000_isa.h,v 1.4 2000/11/12 16:32:06 kai Exp $
+/* $Id: act2000_isa.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
  *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- * This program is free software; you can redistribute 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.
+ * Author       Fritz Elfert
+ * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * Thanks to Friedemann Baitinger and IBM Germany
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/act2000/capi.c linux/drivers/isdn/act2000/capi.c
--- v2.4.10/linux/drivers/isdn/act2000/capi.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/act2000/capi.c	Sun Sep 30 12:26:05 2001
@@ -1,24 +1,15 @@
-/* $Id: capi.c,v 1.9.6.1 2001/02/16 16:43:23 kai Exp $
+/* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
- *        CAPI encoder/decoder
+ * CAPI encoder/decoder
  *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- * This program is free software; you can redistribute 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.
+ * Author       Fritz Elfert
+ * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * Thanks to Friedemann Baitinger and IBM Germany
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/act2000/capi.h linux/drivers/isdn/act2000/capi.h
--- v2.4.10/linux/drivers/isdn/act2000/capi.h	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/act2000/capi.h	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,14 @@
-/* $Id: capi.h,v 1.6.6.1 2001/02/16 16:43:23 kai Exp $
+/* $Id: capi.h,v 1.6.6.2 2001/09/23 22:24:32 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- * This program is free software; you can redistribute 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.
+ * Author       Fritz Elfert
+ * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * Thanks to Friedemann Baitinger and IBM Germany
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/act2000/module.c linux/drivers/isdn/act2000/module.c
--- v2.4.10/linux/drivers/isdn/act2000/module.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/act2000/module.c	Sun Sep 30 12:26:05 2001
@@ -1,29 +1,21 @@
-/* $Id: module.c,v 1.14.6.3 2001/07/13 09:20:11 kai Exp $
+/* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
- * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- * This program is free software; you can redistribute 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.
+ * Author       Fritz Elfert
+ * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * Thanks to Friedemann Baitinger and IBM Germany
  *
  */
 
 #include "act2000.h"
 #include "act2000_isa.h"
 #include "capi.h"
+#include <linux/module.h>
 #include <linux/init.h>
 
 static unsigned short act2000_isa_ports[] =
@@ -41,9 +33,9 @@
 static int   act_irq  = -1;
 static char *act_id   = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 
-MODULE_DESCRIPTION(       "Driver for IBM Active 2000 ISDN card");
+MODULE_DESCRIPTION(       "ISDN4Linux: Driver for IBM Active 2000 ISDN card");
 MODULE_AUTHOR(            "Fritz Elfert");
-MODULE_SUPPORTED_DEVICE(  "ISDN subsystem");
+MODULE_LICENSE(           "GPL");
 MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA");
 MODULE_PARM_DESC(membase, "Base port address of first card");
 MODULE_PARM_DESC(act_irq, "IRQ of first card");
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/avm_cs.c linux/drivers/isdn/avmb1/avm_cs.c
--- v2.4.10/linux/drivers/isdn/avmb1/avm_cs.c	Fri Mar  2 11:12:07 2001
+++ linux/drivers/isdn/avmb1/avm_cs.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,13 @@
-/*======================================================================
-
-    A PCMCIA client driver for AVM B1/M1/M2
-
-    Written by Carsten Paeth, calle@calle.in-berlin.de
-    
-======================================================================*/
+/* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $
+ *
+ * A PCMCIA client driver for AVM B1/M1/M2
+ *
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -32,6 +35,12 @@
 #include <linux/capi.h>
 #include <linux/b1lli.h>
 #include <linux/b1pcmcia.h>
+
+/*====================================================================*/
+
+MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /*====================================================================*/
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/avmcard.h linux/drivers/isdn/avmb1/avmcard.h
--- v2.4.10/linux/drivers/isdn/avmb1/avmcard.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/avmcard.h	Sun Sep 30 12:26:05 2001
@@ -1,7 +1,9 @@
-/*
- * $Id: avmcard.h,v 1.8.6.3 2001/05/17 21:15:33 kai Exp $
+/* $Id: avmcard.h,v 1.8.6.4 2001/09/23 22:24:33 kai Exp $
  *
- * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c
--- v2.4.10/linux/drivers/isdn/avmb1/b1.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/b1.c	Sun Sep 30 12:26:05 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: b1.c,v 1.20.6.6 2001/05/17 21:15:33 kai Exp $
+/* $Id: b1.c,v 1.20.6.7 2001/09/23 22:24:33 kai Exp $
  * 
  * Common module for AVM B1 cards.
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -25,11 +27,13 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.20.6.6 $";
+static char *revision = "$Revision: 1.20.6.7 $";
 
 /* ------------------------------------------------------------- */
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Common support for active AVM cards");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- v2.4.10/linux/drivers/isdn/avmb1/b1dma.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/avmb1/b1dma.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: b1dma.c,v 1.11.6.7 2001/07/18 16:02:15 kai Exp $
+/* $Id: b1dma.c,v 1.11.6.8 2001/09/23 22:24:33 kai Exp $
  * 
  * Common module for AVM B1 cards that support dma with AMCC
  * 
- * (c) Copyright 2000 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 2000 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #include <linux/config.h>
@@ -30,11 +32,13 @@
 #error FIXME: driver requires 32-bit platform
 #endif
 
-static char *revision = "$Revision: 1.11.6.7 $";
+static char *revision = "$Revision: 1.11.6.8 $";
 
 /* ------------------------------------------------------------- */
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 static int suppress_pollack = 0;
 MODULE_PARM(suppress_pollack, "0-1i");
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c
--- v2.4.10/linux/drivers/isdn/avmb1/b1isa.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/b1isa.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: b1isa.c,v 1.10.6.5 2001/05/17 20:41:51 kai Exp $
+/* $Id: b1isa.c,v 1.10.6.6 2001/09/23 22:24:33 kai Exp $
  * 
  * Module for AVM B1 ISA-card.
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #include <linux/module.h>
@@ -22,11 +24,13 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.10.6.5 $";
+static char *revision = "$Revision: 1.10.6.6 $";
 
 /* ------------------------------------------------------------- */
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- v2.4.10/linux/drivers/isdn/avmb1/b1pci.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/b1pci.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: b1pci.c,v 1.29.6.4 2001/05/17 20:41:51 kai Exp $
+/* $Id: b1pci.c,v 1.29.6.5 2001/09/23 22:24:33 kai Exp $
  * 
  * Module for AVM B1 PCI-card.
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #include <linux/config.h>
@@ -24,7 +26,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.29.6.4 $";
+static char *revision = "$Revision: 1.29.6.5 $";
 
 /* ------------------------------------------------------------- */
 
@@ -34,7 +36,9 @@
 };
 
 MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl);
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c
--- v2.4.10/linux/drivers/isdn/avmb1/b1pcmcia.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/b1pcmcia.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: b1pcmcia.c,v 1.12.6.4 2001/05/17 20:41:51 kai Exp $
+/* $Id: b1pcmcia.c,v 1.12.6.5 2001/09/23 22:24:33 kai Exp $
  * 
  * Module for AVM B1/M1/M2 PCMCIA-card.
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #include <linux/module.h>
@@ -23,11 +25,13 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.12.6.4 $";
+static char *revision = "$Revision: 1.12.6.5 $";
 
 /* ------------------------------------------------------------- */
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM PCMCIA cards");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- v2.4.10/linux/drivers/isdn/avmb1/c4.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/c4.c	Sun Sep 30 12:26:05 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: c4.c,v 1.20.6.10 2001/06/09 15:14:15 kai Exp $
+/* $Id: c4.c,v 1.20.6.11 2001/09/23 22:24:33 kai Exp $
  * 
  * Module for AVM C4 & C2 card.
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -27,7 +29,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.20.6.10 $";
+static char *revision = "$Revision: 1.20.6.11 $";
 
 #undef CONFIG_C4_DEBUG
 #undef CONFIG_C4_POLLDEBUG
@@ -43,7 +45,9 @@
 };
 
 MODULE_DEVICE_TABLE(pci, c4_pci_tbl);
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 MODULE_PARM(suppress_pollack, "0-1i");
 
 /* ------------------------------------------------------------- */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- v2.4.10/linux/drivers/isdn/avmb1/capi.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/avmb1/capi.c	Sun Sep 30 12:26:05 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: capi.c,v 1.44.6.13 2001/08/13 07:46:15 kai Exp $
+/* $Id: capi.c,v 1.44.6.15 2001/09/28 08:05:29 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
- * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1996 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -43,9 +45,11 @@
 #include "capifs.h"
 #endif
 
-static char *revision = "$Revision: 1.44.6.13 $";
+static char *revision = "$Revision: 1.44.6.15 $";
 
-MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)");
+MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 #undef _DEBUG_REFCOUNT		/* alloc/free and open/close debug */
 #undef _DEBUG_TTYFUNCS		/* call to tty_driver */
@@ -768,7 +772,7 @@
 
 	if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {
 		kfree_skb(skb);
-		return retval;
+		return -EFAULT;
 	}
 	mlen = CAPIMSG_LEN(skb->data);
 	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
@@ -1182,7 +1186,7 @@
 	skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
 	if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {
 		kfree_skb(skb);
-		return retval;
+		return -EFAULT;
 	}
 
 	while (skb_queue_len(&mp->outqueue) > CAPINC_MAX_SENDQUEUE) {
@@ -1360,7 +1364,7 @@
 #ifdef _DEBUG_TTYFUNCS
 			printk(KERN_DEBUG "capinc_tty_write: copy_from_user=%d\n", retval);
 #endif
-			return retval;
+			return -EFAULT;
 		}
 	} else {
 		memcpy(skb_put(skb, count), buf, count);
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capicmd.h linux/drivers/isdn/avmb1/capicmd.h
--- v2.4.10/linux/drivers/isdn/avmb1/capicmd.h	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/capicmd.h	Sun Sep 30 12:26:05 2001
@@ -1,11 +1,14 @@
-/*
- * $Id: capicmd.h,v 1.2.6.1 2001/05/17 20:41:51 kai Exp $
+/* $Id: capicmd.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $
  * 
  * CAPI 2.0 Interface for Linux
  * 
- * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1997 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
+
 #ifndef __CAPICMD_H__
 #define __CAPICMD_H__
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h
--- v2.4.10/linux/drivers/isdn/avmb1/capidev.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capidev.h	Sun Sep 30 12:26:05 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: capidev.h,v 1.6.6.1 2001/05/17 20:41:51 kai Exp $
+/* $Id: capidev.h,v 1.6.6.2 2001/09/23 22:24:33 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
- * (c) Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1996 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- v2.4.10/linux/drivers/isdn/avmb1/capidrv.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capidrv.c	Sun Sep 30 12:26:05 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: capidrv.c,v 1.39.6.6 2001/05/17 20:41:51 kai Exp $
+/* $Id: capidrv.c,v 1.39.6.7 2001/09/23 22:24:33 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
- * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1997 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -33,10 +35,12 @@
 #include "capicmd.h"
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.39.6.6 $";
+static char *revision = "$Revision: 1.39.6.7 $";
 static int debugmode = 0;
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 MODULE_PARM(debugmode, "i");
 
 /* -------- type definitions ----------------------------------------- */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capidrv.h linux/drivers/isdn/avmb1/capidrv.h
--- v2.4.10/linux/drivers/isdn/avmb1/capidrv.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capidrv.h	Sun Sep 30 12:26:05 2001
@@ -1,11 +1,14 @@
-/*
- * $Id: capidrv.h,v 1.2.8.1 2001/05/17 20:41:51 kai Exp $
+/* $Id: capidrv.h,v 1.2.8.2 2001/09/23 22:24:33 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
- * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1997 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #ifndef __CAPIDRV_H__
 #define __CAPIDRV_H__
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capifs.c linux/drivers/isdn/avmb1/capifs.c
--- v2.4.10/linux/drivers/isdn/avmb1/capifs.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/capifs.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: capifs.c,v 1.14.6.7 2001/05/24 08:29:08 kai Exp $
+/* $Id: capifs.c,v 1.14.6.8 2001/09/23 22:24:33 kai Exp $
  * 
- * (c) Copyright 2000 by Carsten Paeth (calle@calle.de)
+ * Copyright 2000 by Carsten Paeth <calle@calle.de>
  *
  * Heavily based on devpts filesystem from H. Peter Anvin
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #include <linux/version.h>
@@ -26,9 +28,11 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.de>");
+MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
-static char *revision = "$Revision: 1.14.6.7 $";
+static char *revision = "$Revision: 1.14.6.8 $";
 
 struct capifs_ncci {
 	struct inode *inode;
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capifs.h linux/drivers/isdn/avmb1/capifs.h
--- v2.4.10/linux/drivers/isdn/avmb1/capifs.h	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/capifs.h	Sun Sep 30 12:26:05 2001
@@ -1,7 +1,9 @@
-/*
- * $Id: capifs.h,v 1.2.6.1 2001/05/17 20:41:51 kai Exp $
+/* $Id: capifs.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $
  * 
- * (c) Copyright 2000 by Carsten Paeth (calle@calle.de)
+ * Copyright 2000 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capilli.h linux/drivers/isdn/avmb1/capilli.h
--- v2.4.10/linux/drivers/isdn/avmb1/capilli.h	Thu Aug 12 09:42:33 1999
+++ linux/drivers/isdn/avmb1/capilli.h	Sun Sep 30 12:26:05 2001
@@ -1,11 +1,14 @@
-/*
- * $Id: capilli.h,v 1.4 1999/07/23 08:51:05 calle Exp $
+/* $Id: capilli.h,v 1.4.8.1 2001/09/23 22:24:33 kai Exp $
  * 
  * Kernel CAPI 2.0 Driver Interface for Linux
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
+
 #ifndef __CAPILLI_H__
 #define __CAPILLI_H__
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c
--- v2.4.10/linux/drivers/isdn/avmb1/capiutil.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capiutil.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,15 @@
-/*
- * $Id: capiutil.c,v 1.13.6.3 2001/05/17 20:41:51 kai Exp $
+/* $Id: capiutil.c,v 1.13.6.4 2001/09/23 22:24:33 kai Exp $
  *
  * CAPI 2.0 convert capi message to capi message struct
  *
  * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
- * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
@@ -17,6 +20,10 @@
 #include <asm/segment.h>
 #include <linux/config.h>
 #include "capiutil.h"
+
+MODULE_DESCRIPTION("CAPI4Linux: CAPI message conversion support");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /* from CAPI2.0 DDK AVM Berlin GmbH */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/capiutil.h linux/drivers/isdn/avmb1/capiutil.h
--- v2.4.10/linux/drivers/isdn/avmb1/capiutil.h	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/capiutil.h	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,15 @@
-/*
- * $Id: capiutil.h,v 1.5.6.1 2001/05/17 20:41:51 kai Exp $
- * 
+/* $Id: capiutil.h,v 1.5.6.2 2001/09/23 22:24:33 kai Exp $
+ *
  * CAPI 2.0 defines & types
- * 
- * From CAPI 2.0 Development Kit AVM 1995 (capi20.h)
- * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de)
- * 
+ *
+ * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
+ * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
+
 #ifndef __CAPIUTIL_H__
 #define __CAPIUTIL_H__
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- v2.4.10/linux/drivers/isdn/avmb1/kcapi.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/kcapi.c	Sun Sep 30 12:26:05 2001
@@ -1,11 +1,14 @@
-/*
- * $Id: kcapi.c,v 1.21.6.7 2001/06/09 15:14:15 kai Exp $
+/* $Id: kcapi.c,v 1.21.6.8 2001/09/23 22:24:33 kai Exp $
  * 
  * Kernel CAPI 2.0 Module
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
+
 #define CONFIG_AVMB1_COMPAT
 
 #include <linux/config.h>
@@ -30,7 +33,7 @@
 #include <linux/b1lli.h>
 #endif
 
-static char *revision = "$Revision: 1.21.6.7 $";
+static char *revision = "$Revision: 1.21.6.8 $";
 
 /* ------------------------------------------------------------- */
 
@@ -41,10 +44,12 @@
 
 /* ------------------------------------------------------------- */
 
-int showcapimsgs = 0;
+static int showcapimsgs = 0;
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
-MODULE_PARM(showcapimsgs, "0-4i");
+MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
+MODULE_PARM(showcapimsgs, "i");
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c
--- v2.4.10/linux/drivers/isdn/avmb1/t1isa.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/t1isa.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: t1isa.c,v 1.16.6.6 2001/05/17 21:15:33 kai Exp $
+/* $Id: t1isa.c,v 1.16.6.7 2001/09/23 22:24:34 kai Exp $
  * 
  * Module for AVM T1 HEMA-card.
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #include <linux/module.h>
@@ -23,11 +25,13 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.16.6.6 $";
+static char *revision = "$Revision: 1.16.6.7 $";
 
 /* ------------------------------------------------------------- */
 
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 HEMA ISA card");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c
--- v2.4.10/linux/drivers/isdn/avmb1/t1pci.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/avmb1/t1pci.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: t1pci.c,v 1.13.6.5 2001/05/17 20:41:51 kai Exp $
+/* $Id: t1pci.c,v 1.13.6.6 2001/09/23 22:24:34 kai Exp $
  * 
  * Module for AVM T1 PCI-card.
  * 
- * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
+ * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #include <linux/config.h>
@@ -24,7 +26,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.13.6.5 $";
+static char *revision = "$Revision: 1.13.6.6 $";
 
 #undef CONFIG_T1PCI_DEBUG
 #undef CONFIG_T1PCI_POLLDEBUG
@@ -37,7 +39,9 @@
 };
 
 MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl);
-MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 PCI card");
+MODULE_AUTHOR("Carsten Paeth");
+MODULE_LICENSE("GPL");
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/divert/divert_init.c linux/drivers/isdn/divert/divert_init.c
--- v2.4.10/linux/drivers/isdn/divert/divert_init.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/divert/divert_init.c	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,11 @@
-/* 
- * $Id: divert_init.c,v 1.5.6.2 2001/01/24 22:18:17 kai Exp $
+/* $Id divert_init.c,v 1.5.6.2 2001/01/24 22:18:17 kai Exp $
  *
  * Module init for DSS1 diversion services for i4l.
  *
  * Copyright 1999       by Werner Cornelius (werner@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -26,6 +14,10 @@
 #include <linux/init.h>
 #include "isdn_divert.h"
 
+MODULE_DESCRIPTION("ISDN4Linux: Call diversion support");
+MODULE_AUTHOR("Werner Cornelius");
+MODULE_LICENSE("GPL");
+
 /********************/
 /* needed externals */
 /********************/
@@ -70,7 +62,7 @@
 /* Module deinit code */
 /**********************/
 static void __exit divert_exit(void)
-{ long flags;
+{ unsigned long flags;
   int i;
 
   save_flags(flags);
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c
--- v2.4.10/linux/drivers/isdn/divert/divert_procfs.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/divert/divert_procfs.c	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,11 @@
-/*
- * $Id: divert_procfs.c,v 1.11.6.1 2001/08/13 07:46:15 kai Exp $
+/* $Id: divert_procfs.c,v 1.11.6.2 2001/09/23 22:24:36 kai Exp $
  *
  * Filesystem handling for the diversion supplementary services.
  *
  * Copyright 1998       by Werner Cornelius (werner@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -50,7 +38,7 @@
 put_info_buffer(char *cp)
 {
 	struct divert_info *ib;
-	long flags;
+	unsigned long flags;
 
 	if (if_used <= 0)
 		return;
@@ -145,7 +133,7 @@
 static int
 isdn_divert_open(struct inode *ino, struct file *filep)
 {
-	long flags;
+	unsigned long flags;
 
 	lock_kernel();
 	save_flags(flags);
@@ -168,7 +156,7 @@
 isdn_divert_close(struct inode *ino, struct file *filep)
 {
 	struct divert_info *inf;
-	long flags;
+	unsigned long flags;
 
 	lock_kernel();
 	save_flags(flags);
@@ -199,7 +187,7 @@
 {
 	divert_ioctl dioctl;
 	int i;
-	long flags;
+	unsigned long flags;
 	divert_rule *rulep;
 	char *cp;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/divert/isdn_divert.c linux/drivers/isdn/divert/isdn_divert.c
--- v2.4.10/linux/drivers/isdn/divert/isdn_divert.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/divert/isdn_divert.c	Sun Sep 30 12:26:05 2001
@@ -1,30 +1,14 @@
-/* 
- * $Id: isdn_divert.c,v 1.6.6.2 2001/02/16 16:43:25 kai Exp $
+/* $Id: isdn_divert.c,v 1.6.6.3 2001/09/23 22:24:36 kai Exp $
  *
  * DSS1 main diversion supplementary handling for i4l.
  *
  * Copyright 1999       by Werner Cornelius (werner@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-
-
-#define __NO_VERSION__
-#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/proc_fs.h>
 #include "isdn_divert.h"
@@ -67,7 +51,7 @@
 /* timer callback function */
 /***************************/
 static void deflect_timer_expire(ulong arg)
-{ long flags;
+{ unsigned long flags;
   struct call_struc *cs = (struct call_struc *) arg;
 
   save_flags(flags);
@@ -125,7 +109,7 @@
 int cf_command(int drvid, int mode, 
                u_char proc, char *msn, 
                u_char service, char *fwd_nr, ulong *procid)
-{ long flags;
+{ unsigned long flags;
   int retval,msnlen;
   int fwd_len;
   char *p,*ielenp,tmp[60];
@@ -221,7 +205,7 @@
 int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
 { struct call_struc *cs;
   isdn_ctrl ic;
-  long flags;
+  unsigned long flags;
   int i;
 
   if ((cmd & 0x7F) > 2) return(-EINVAL); /* invalid command */
@@ -292,7 +276,7 @@
 /********************************/
 int insertrule(int idx, divert_rule *newrule)
 { struct deflect_struc *ds,*ds1=NULL;
-  long flags;
+  unsigned long flags;
 
   if (!(ds = (struct deflect_struc *) kmalloc(sizeof(struct deflect_struc), 
                                               GFP_KERNEL))) 
@@ -338,7 +322,7 @@
 /***********************************/
 int deleterule(int idx)
 { struct deflect_struc *ds,*ds1;
-  long flags;
+  unsigned long flags;
   
   if (idx < 0) 
    { save_flags(flags);
@@ -406,7 +390,7 @@
 /*************************************************/
 int isdn_divert_icall(isdn_ctrl *ic)
 { int retval = 0;
-  long flags;
+  unsigned long flags;
   struct call_struc *cs = NULL; 
   struct deflect_struc *dv;
   char *p,*p1;
@@ -558,7 +542,7 @@
 
 void deleteprocs(void)
 { struct call_struc *cs, *cs1; 
-  long flags;
+  unsigned long flags;
 
   save_flags(flags);
   cli();
@@ -716,7 +700,7 @@
 int prot_stat_callback(isdn_ctrl *ic)
 { struct call_struc *cs, *cs1;
   int i;
-  long flags;
+  unsigned long flags;
 
   cs = divert_head; /* start of list */
   cs1 = NULL;
@@ -807,7 +791,7 @@
 /***************************/
 int isdn_divert_stat_callback(isdn_ctrl *ic)
 { struct call_struc *cs, *cs1;
-  long flags;
+  unsigned long flags;
   int retval;
 
   retval = -1;
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/divert/isdn_divert.h linux/drivers/isdn/divert/isdn_divert.h
--- v2.4.10/linux/drivers/isdn/divert/isdn_divert.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/divert/isdn_divert.h	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,13 @@
-/* 
- * $Id: isdn_divert.h,v 1.5 2000/11/13 22:51:47 kai Exp $
+/* $Id: isdn_divert.h,v 1.5.6.1 2001/09/23 22:24:36 kai Exp $
  *
  * Header for the diversion supplementary ioctl interface.
  *
  * Copyright 1998       by Werner Cornelius (werner@ikt.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #include <linux/ioctl.h>
 #include <linux/types.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/Divas_mod.c linux/drivers/isdn/eicon/Divas_mod.c
--- v2.4.10/linux/drivers/isdn/eicon/Divas_mod.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/eicon/Divas_mod.c	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,9 @@
-
 /*
- *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/fs.h>
@@ -35,6 +21,10 @@
 #include "uxio.h"
 
 
+MODULE_DESCRIPTION("ISDN4Linux: Driver for Eicon Diva Server cards");
+MODULE_AUTHOR("Armin Schindler");
+MODULE_LICENSE("GPL");
+
 #ifdef MODULE
 #include "idi.h"
 void DIVA_DIDD_Write(DESCRIPTOR *, int);
@@ -51,7 +41,6 @@
 	printk(KERN_DEBUG "DIVA Server Driver - initialising\n");
 	
 	printk(KERN_DEBUG "DIVA Server Driver - Version 2.0.16\n");
-
 
 #if !defined(CONFIG_PCI)
 	printk(KERN_WARNING "CONFIG_PCI is not defined!\n");
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/adapter.h linux/drivers/isdn/eicon/adapter.h
--- v2.4.10/linux/drivers/isdn/eicon/adapter.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/adapter.h	Sun Sep 30 12:26:05 2001
@@ -1,28 +1,14 @@
-
 /*
+ * Main internal include file for Diva Server driver
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
-
-/* Main internal include file for Diva Server driver */
 
 #if !defined(ADAPTER_H)
 #define ADAPTER_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/bri.c linux/drivers/isdn/eicon/bri.c
--- v2.4.10/linux/drivers/isdn/eicon/bri.c	Sat May 19 17:43:06 2001
+++ linux/drivers/isdn/eicon/bri.c	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,10 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.8  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/common.c linux/drivers/isdn/eicon/common.c
--- v2.4.10/linux/drivers/isdn/eicon/common.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/common.c	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.15  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #include "eicon.h"
 #include "sys.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/constant.h linux/drivers/isdn/eicon/constant.h
--- v2.4.10/linux/drivers/isdn/eicon/constant.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/constant.h	Sun Sep 30 12:26:05 2001
@@ -1,27 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
-
 
 /*------------------------------------------------------------------*/
 /* Q.931 information elements maximum length                        */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/divalog.h linux/drivers/isdn/eicon/divalog.h
--- v2.4.10/linux/drivers/isdn/eicon/divalog.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/divalog.h	Sun Sep 30 12:26:05 2001
@@ -1,31 +1,15 @@
-
 /*
+ * Include file for defining the kernel loggger messages
+ * These definitions are shared between the klog driver and the
+ * klogd daemon process
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- */
-
-
-/*
- * Include file for defining the kernel loggger messages
- * These definitions are shared between the klog driver and the
- * klogd daemon process
  */
 
 #if !defined(_KLOGMSG_H)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/divas.h linux/drivers/isdn/eicon/divas.h
--- v2.4.10/linux/drivers/isdn/eicon/divas.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/divas.h	Sun Sep 30 12:26:05 2001
@@ -1,28 +1,14 @@
-
 /*
+ * External Diva Server driver include file
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.5  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
-
-/* External Diva Server driver include file */
 
 #if !defined(DIVAS_H)
 #define DIVAS_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/dsp_defs.h linux/drivers/isdn/eicon/dsp_defs.h
--- v2.4.10/linux/drivers/isdn/eicon/dsp_defs.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/dsp_defs.h	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #ifndef DSP_DEFS_H_
 #define DSP_DEFS_H_
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/dspdids.h linux/drivers/isdn/eicon/dspdids.h
--- v2.4.10/linux/drivers/isdn/eicon/dspdids.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/dspdids.h	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #ifndef DSPDIDS_H_
 #define DSPDIDS_H_
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon.h linux/drivers/isdn/eicon/eicon.h
--- v2.4.10/linux/drivers/isdn/eicon/eicon.h	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/eicon/eicon.h	Sun Sep 30 12:26:05 2001
@@ -1,27 +1,15 @@
-/* $Id: eicon.h,v 1.23.6.4 2001/06/09 15:14:16 kai Exp $
+/* $Id: eicon.h,v 1.23.6.5 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  *
- * Copyright 1998    by Fritz Elfert (fritz@isdn4linux.de)
+ * Copyright 1998       by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1998-2000  by Armin Schindler (mac@melware.de) 
  * Copyright 1999,2000  Cytronics & Melware (info@melware.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #ifndef eicon_h
 #define eicon_h
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_dsp.h linux/drivers/isdn/eicon/eicon_dsp.h
--- v2.4.10/linux/drivers/isdn/eicon/eicon_dsp.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_dsp.h	Sun Sep 30 12:26:05 2001
@@ -1,25 +1,13 @@
-/* $Id: eicon_dsp.h,v 1.7 2000/05/07 08:51:04 armin Exp $
+/* $Id: eicon_dsp.h,v 1.7.6.1 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
- *        DSP definitions
+ * DSP definitions
  *
  * Copyright 1999,2000  by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000  Cytronics & Melware (info@melware.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_idi.c linux/drivers/isdn/eicon/eicon_idi.c
--- v2.4.10/linux/drivers/isdn/eicon/eicon_idi.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/eicon/eicon_idi.c	Sun Sep 30 12:26:05 2001
@@ -1,7 +1,7 @@
-/* $Id: eicon_idi.c,v 1.41.6.2 2001/04/07 21:41:44 armin Exp $
+/* $Id: eicon_idi.c,v 1.41.6.3 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
- *        IDI interface 
+ * IDI interface 
  *
  * Copyright 1998-2000  by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
@@ -11,19 +11,8 @@
  *		capabilities with Diva Server cards.
  *		(dor@deutschemailbox.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -36,7 +25,7 @@
 
 #undef EICON_FULL_SERVICE_OKTETT
 
-char *eicon_idi_revision = "$Revision: 1.41.6.2 $";
+char *eicon_idi_revision = "$Revision: 1.41.6.3 $";
 
 eicon_manifbuf *manbuf;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_idi.h linux/drivers/isdn/eicon/eicon_idi.h
--- v2.4.10/linux/drivers/isdn/eicon/eicon_idi.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_idi.h	Sun Sep 30 12:26:05 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon_idi.h,v 1.11 2000/05/07 08:51:04 armin Exp $
+/* $Id: eicon_idi.h,v 1.11.6.1 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN lowlevel-module for the Eicon active cards.
  * IDI-Interface
@@ -6,20 +6,8 @@
  * Copyright 1998-2000  by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000  Cytronics & Melware (info@melware.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_io.c linux/drivers/isdn/eicon/eicon_io.c
--- v2.4.10/linux/drivers/isdn/eicon/eicon_io.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/eicon_io.c	Sun Sep 30 12:26:05 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon_io.c,v 1.13.6.1 2001/02/16 09:09:50 armin Exp $
+/* $Id: eicon_io.c,v 1.13.6.2 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Code for communicating with hardware.
@@ -6,25 +6,13 @@
  * Copyright 1999,2000  by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
  *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  * Thanks to	Eicon Networks for 
  *		documents, informations and hardware. 
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA. 
- *
  */
-
 
 #include <linux/config.h>
 #include "eicon.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_isa.c linux/drivers/isdn/eicon/eicon_isa.c
--- v2.4.10/linux/drivers/isdn/eicon/eicon_isa.c	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_isa.c	Sun Sep 30 12:26:05 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon_isa.c,v 1.16 2000/06/12 12:44:02 armin Exp $
+/* $Id: eicon_isa.c,v 1.16.6.1 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Hardware-specific code for old ISA cards.
@@ -7,19 +7,8 @@
  * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000 Cytronics & Melware (info@melware.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -31,7 +20,7 @@
 #define release_shmem release_region
 #define request_shmem request_region
 
-char *eicon_isa_revision = "$Revision: 1.16 $";
+char *eicon_isa_revision = "$Revision: 1.16.6.1 $";
 
 #undef EICON_MCA_DEBUG
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_isa.h linux/drivers/isdn/eicon/eicon_isa.h
--- v2.4.10/linux/drivers/isdn/eicon/eicon_isa.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_isa.h	Sun Sep 30 12:26:05 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon_isa.h,v 1.10 2000/05/07 08:51:04 armin Exp $
+/* $Id: eicon_isa.h,v 1.10.6.1 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  *
@@ -6,19 +6,8 @@
  * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000 Cytronics & Melware (info@melware.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c
--- v2.4.10/linux/drivers/isdn/eicon/eicon_mod.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/eicon_mod.c	Sun Sep 30 12:26:05 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon_mod.c,v 1.37.6.5 2001/07/17 19:42:31 armin Exp $
+/* $Id: eicon_mod.c,v 1.37.6.6 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
  * 
@@ -6,6 +6,9 @@
  * Copyright 1998-2000 by Armin Schindler (mac@melware.de) 
  * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  * Thanks to    Eicon Networks for
  *              documents, informations and hardware.
  *
@@ -14,20 +17,6 @@
  *		capabilities with Diva Server cards.
  *		(dor@deutschemailbox.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 DRIVERNAME "Eicon active ISDN driver"
@@ -55,7 +44,7 @@
 static eicon_card *cards = (eicon_card *) NULL;   /* glob. var , contains
                                                      start of card-list   */
 
-static char *eicon_revision = "$Revision: 1.37.6.5 $";
+static char *eicon_revision = "$Revision: 1.37.6.6 $";
 
 extern char *eicon_pci_revision;
 extern char *eicon_isa_revision;
@@ -84,9 +73,9 @@
 #endif
 static char *id           = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 
-MODULE_DESCRIPTION(             "Driver for Eicon active ISDN cards");
+MODULE_DESCRIPTION(             "ISDN4Linux: Driver for Eicon active ISDN cards");
 MODULE_AUTHOR(                  "Armin Schindler");
-MODULE_SUPPORTED_DEVICE(        "ISDN subsystem");
+MODULE_LICENSE(                 "GPL");
 MODULE_PARM_DESC(id,   		"ID-String of first card");
 MODULE_PARM(id,           	"s");
 #ifdef CONFIG_ISDN_DRV_EICON_ISA
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_pci.c linux/drivers/isdn/eicon/eicon_pci.c
--- v2.4.10/linux/drivers/isdn/eicon/eicon_pci.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/eicon_pci.c	Sun Sep 30 12:26:05 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon_pci.c,v 1.15.6.2 2001/02/16 09:09:50 armin Exp $
+/* $Id: eicon_pci.c,v 1.15.6.3 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Hardware-specific code for PCI cards.
@@ -6,23 +6,12 @@
  * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  * Thanks to	Eicon Networks for 
  *		documents, informations and hardware. 
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA. 
- *
  */
 
 #include <linux/config.h>
@@ -35,7 +24,7 @@
 #include "adapter.h"
 #include "uxio.h"
 
-char *eicon_pci_revision = "$Revision: 1.15.6.2 $";
+char *eicon_pci_revision = "$Revision: 1.15.6.3 $";
 
 #if CONFIG_PCI	         /* intire stuff is only for PCI */
 #ifdef CONFIG_ISDN_DRV_EICON_PCI
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/eicon_pci.h linux/drivers/isdn/eicon/eicon_pci.h
--- v2.4.10/linux/drivers/isdn/eicon/eicon_pci.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_pci.h	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,12 @@
-/* $Id: eicon_pci.h,v 1.6 2000/05/07 08:51:04 armin Exp $
+/* $Id: eicon_pci.h,v 1.6.6.1 2001/09/23 22:24:37 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards (PCI part).
  *
  * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000 Cytronics & Melware (info@melware.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/fourbri.c linux/drivers/isdn/eicon/fourbri.c
--- v2.4.10/linux/drivers/isdn/eicon/fourbri.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/fourbri.c	Sun Sep 30 12:26:05 2001
@@ -1,28 +1,15 @@
-
 /*
+ * Diva Server 4BRI specific part of initialisation
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-
-/* Diva Server 4BRI specific part of initialisation */
 #include "sys.h"
 #include "idi.h"
 #include "divas.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/fpga.c linux/drivers/isdn/eicon/fpga.c
--- v2.4.10/linux/drivers/isdn/eicon/fpga.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/fpga.c	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.2  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #include "sys.h"
 #include "idi.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/idi.c linux/drivers/isdn/eicon/idi.c
--- v2.4.10/linux/drivers/isdn/eicon/idi.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/eicon/idi.c	Sun Sep 30 12:26:05 2001
@@ -1,30 +1,14 @@
-
 /*
+ * Core driver for Diva Server cards
+ * Implements the IDI interface
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.8  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- */
-
-
-/*
- * Core driver for Diva Server cards
- * Implements the IDI interface
  */
 
 #include "idi.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/idi.h linux/drivers/isdn/eicon/idi.h
--- v2.4.10/linux/drivers/isdn/eicon/idi.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/idi.h	Sun Sep 30 12:26:05 2001
@@ -1,28 +1,14 @@
-
 /*
+ * External IDI interface
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
-
-/* External IDI interface */
 
 #if !defined(IDI_H)
 #define IDI_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/kprintf.c linux/drivers/isdn/eicon/kprintf.c
--- v2.4.10/linux/drivers/isdn/eicon/kprintf.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/eicon/kprintf.c	Sun Sep 30 12:26:05 2001
@@ -1,31 +1,14 @@
-
 /*
+ * Source file for kernel interface to kernel log facility
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.3  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
-
-/*
- * Source file for kernel interface to kernel log facility
- */
-
 
 #include "eicon.h"
 #include "sys.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/lincfg.c linux/drivers/isdn/eicon/lincfg.c
--- v2.4.10/linux/drivers/isdn/eicon/lincfg.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/lincfg.c	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.9  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #include <linux/fs.h>
 #undef N_DATA   /* Because we have our own definition */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/linchr.c linux/drivers/isdn/eicon/linchr.c
--- v2.4.10/linux/drivers/isdn/eicon/linchr.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/linchr.c	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,10 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.12  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/linio.c linux/drivers/isdn/eicon/linio.c
--- v2.4.10/linux/drivers/isdn/eicon/linio.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/eicon/linio.c	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.16  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #define N_DATA
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/linsys.c linux/drivers/isdn/eicon/linsys.c
--- v2.4.10/linux/drivers/isdn/eicon/linsys.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/linsys.c	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #include <linux/sched.h>
 #undef N_DATA
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/log.c linux/drivers/isdn/eicon/log.c
--- v2.4.10/linux/drivers/isdn/eicon/log.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/log.c	Sun Sep 30 12:26:05 2001
@@ -1,29 +1,13 @@
-   
 /*
+ * Source file for diva log facility
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.5  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- */
-
-
-/*
- * Source file for diva log facility
  */
 
 #include "sys.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/pc.h linux/drivers/isdn/eicon/pc.h
--- v2.4.10/linux/drivers/isdn/eicon/pc.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/eicon/pc.h	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.2  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #ifndef PC_H_INCLUDED
 #define PC_H_INCLUDED
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/pc_maint.h linux/drivers/isdn/eicon/pc_maint.h
--- v2.4.10/linux/drivers/isdn/eicon/pc_maint.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/pc_maint.h	Sun Sep 30 12:26:05 2001
@@ -1,26 +1,12 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 #ifndef PC_MAINT_H
 #define PC_MAINT_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/pr_pc.h linux/drivers/isdn/eicon/pr_pc.h
--- v2.4.10/linux/drivers/isdn/eicon/pr_pc.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/pr_pc.h	Sun Sep 30 12:26:05 2001
@@ -1,23 +1,10 @@
-
 /*
- *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/pri.c linux/drivers/isdn/eicon/pri.c
--- v2.4.10/linux/drivers/isdn/eicon/pri.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/pri.c	Sun Sep 30 12:26:05 2001
@@ -1,28 +1,15 @@
-
 /*
+ * Diva Server PRI specific part of initialisation
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.5  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-
-/* Diva Server PRI specific part of initialisation */
 #include "sys.h"
 #include "idi.h"
 #include "divas.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/sys.h linux/drivers/isdn/eicon/sys.h
--- v2.4.10/linux/drivers/isdn/eicon/sys.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/eicon/sys.h	Sun Sep 30 12:26:05 2001
@@ -1,28 +1,14 @@
-
 /*
+ * Environment provided by system and miscellaneous definitions
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.2  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
-
-/* Environment provided by system and miscellaneous definitions */
 
 #if !defined(SYS_H)
 #define SYS_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/uxio.h linux/drivers/isdn/eicon/uxio.h
--- v2.4.10/linux/drivers/isdn/eicon/uxio.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/eicon/uxio.h	Sun Sep 30 12:26:05 2001
@@ -1,29 +1,13 @@
-
 /*
+ * Interface to Unix specific code for performing card I/O
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.6  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- */
-
-
-/*
- * Interface to Unix specific code for performing card I/O
  */
 
 #if !defined(UXIO_H)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/eicon/xlog.c linux/drivers/isdn/eicon/xlog.c
--- v2.4.10/linux/drivers/isdn/eicon/xlog.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/eicon/xlog.c	Sun Sep 30 12:26:05 2001
@@ -1,30 +1,14 @@
-
 /*
+ * Unix Eicon active card driver
+ * XLOG related functions
  *
  * Copyright (C) Eicon Technology Corporation, 2000.
  *
  * Eicon File Revision :    1.2  
  *
- * This program is free software; you can redistribute 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 OF ANY KIND WHATSOEVER INCLUDING ANY 
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- */
-
-
-/*
- * Unix Eicon active card driver
- * XLOG related functions
  */
 
 #include "sys.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/amd7930.c linux/drivers/isdn/hisax/amd7930.c
--- v2.4.10/linux/drivers/isdn/hisax/amd7930.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/amd7930.c	Sun Sep 30 12:26:05 2001
@@ -1,8 +1,12 @@
-/* $Id: amd7930.c,v 1.5.6.3 2001/06/11 22:08:37 kai Exp $
+/* $Id: amd7930.c,v 1.5.6.4 2001/09/23 22:24:46 kai Exp $
  *
  * HiSax ISDN driver - chip specific routines for AMD 7930
  *
- * Author       Brent Baccala (baccala@FreeSoft.org)
+ * Author       Brent Baccala
+ * Copyright    by Brent Baccala <baccala@FreeSoft.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  *    - Existing ISDN HiSax driver provides all the smarts
  *    - it compiles, runs, talks to an isolated phone switch, connects
@@ -94,7 +98,7 @@
 #include "rawhdlc.h"
 #include <linux/interrupt.h>
 
-static const char *amd7930_revision = "$Revision: 1.5.6.3 $";
+static const char *amd7930_revision = "$Revision: 1.5.6.4 $";
 
 #define RCV_BUFSIZE	1024	/* Size of raw receive buffer in bytes */
 #define RCV_BUFBLKS	4	/* Number of blocks to divide buffer into
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/arcofi.c linux/drivers/isdn/hisax/arcofi.c
--- v2.4.10/linux/drivers/isdn/hisax/arcofi.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/arcofi.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: arcofi.c,v 1.12.6.1 2001/02/16 16:43:25 kai Exp $
+/* $Id: arcofi.c,v 1.12.6.2 2001/09/23 22:24:46 kai Exp $
  *
- * arcofi.c   Ansteuerung ARCOFI 2165
+ * Ansteuerung ARCOFI 2165
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
  
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/arcofi.h linux/drivers/isdn/hisax/arcofi.h
--- v2.4.10/linux/drivers/isdn/hisax/arcofi.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/arcofi.h	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: arcofi.h,v 1.6.6.1 2001/02/16 16:43:25 kai Exp $
+/* $Id: arcofi.h,v 1.6.6.2 2001/09/23 22:24:46 kai Exp $
  *
- * arcofi.h   Ansteuerung ARCOFI 2165
+ * Ansteuerung ARCOFI 2165
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
  
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/asuscom.c linux/drivers/isdn/hisax/asuscom.c
--- v2.4.10/linux/drivers/isdn/hisax/asuscom.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/asuscom.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,14 @@
-/* $Id: asuscom.c,v 1.11.6.2 2001/07/13 09:20:12 kai Exp $
+/* $Id: asuscom.c,v 1.11.6.3 2001/09/23 22:24:46 kai Exp $
  *
- * asuscom.c     low level stuff for ASUSCOM NETWORK INC. ISDNLink cards
+ * low level stuff for ASUSCOM NETWORK INC. ISDNLink cards
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *
- * Thanks to  ASUSCOM NETWORK INC. Taiwan and  Dynalink NL for informations
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This file is (c) under GNU General Public License
+ * Thanks to  ASUSCOM NETWORK INC. Taiwan and  Dynalink NL for information
  *
  */
 
@@ -20,7 +22,7 @@
 
 extern const char *CardType[];
 
-const char *Asuscom_revision = "$Revision: 1.11.6.2 $";
+const char *Asuscom_revision = "$Revision: 1.11.6.3 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/avm_a1.c linux/drivers/isdn/hisax/avm_a1.c
--- v2.4.10/linux/drivers/isdn/hisax/avm_a1.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/avm_a1.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,15 @@
-/* $Id: avm_a1.c,v 2.13.6.1 2001/02/16 16:43:25 kai Exp $
+/* $Id: avm_a1.c,v 2.13.6.2 2001/09/23 22:24:46 kai Exp $
  *
- * avm_a1.c     low level stuff for AVM A1 (Fritz) isdn cards
+ * low level stuff for AVM A1 (Fritz) isdn cards
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
@@ -15,7 +18,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-static const char *avm_revision = "$Revision: 2.13.6.1 $";
+static const char *avm_revision = "$Revision: 2.13.6.2 $";
 
 #define	 AVM_A1_STAT_ISAC	0x01
 #define	 AVM_A1_STAT_HSCX	0x02
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/avm_a1p.c linux/drivers/isdn/hisax/avm_a1p.c
--- v2.4.10/linux/drivers/isdn/hisax/avm_a1p.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/avm_a1p.c	Sun Sep 30 12:26:05 2001
@@ -1,14 +1,18 @@
-/* $Id: avm_a1p.c,v 2.7.6.1 2001/02/16 16:43:25 kai Exp $
+/* $Id: avm_a1p.c,v 2.7.6.2 2001/09/23 22:24:46 kai Exp $
  *
- * avm_a1p.c    low level stuff for the following AVM cards:
- *              A1 PCMCIA
- *		FRITZ!Card PCMCIA
- *		FRITZ!Card PCMCIA 2.0
+ * low level stuff for the following AVM cards:
+ * A1 PCMCIA
+ * FRITZ!Card PCMCIA
+ * FRITZ!Card PCMCIA 2.0
  *
- * Author       Carsten Paeth (calle@calle.in-berlin.de)
+ * Author       Carsten Paeth
+ * Copyright    by Carsten Paeth     <calle@calle.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  This file is (c) under GNU General Public License
  */
+
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
@@ -53,7 +57,7 @@
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
 
-static const char *avm_revision = "$Revision: 2.7.6.1 $";
+static const char *avm_revision = "$Revision: 2.7.6.2 $";
 
 static inline u_char
 ReadISAC(struct IsdnCardState *cs, u_char offset)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/avm_pci.c linux/drivers/isdn/hisax/avm_pci.c
--- v2.4.10/linux/drivers/isdn/hisax/avm_pci.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/avm_pci.c	Sun Sep 30 12:26:05 2001
@@ -1,13 +1,17 @@
-/* $Id: avm_pci.c,v 1.22.6.5 2001/06/09 15:14:16 kai Exp $
+/* $Id: avm_pci.c,v 1.22.6.6 2001/09/23 22:24:46 kai Exp $
  *
- * avm_pci.c    low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
- *              Thanks to AVM, Berlin for informations
+ * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * Thanks to AVM, Berlin for information
  *
  */
+
 #define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/init.h>
@@ -18,7 +22,7 @@
 #include <linux/interrupt.h>
 
 extern const char *CardType[];
-static const char *avm_pci_rev = "$Revision: 1.22.6.5 $";
+static const char *avm_pci_rev = "$Revision: 1.22.6.6 $";
 
 #define  AVM_FRITZ_PCI		1
 #define  AVM_FRITZ_PNP		2
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/bkm_a4t.c linux/drivers/isdn/hisax/bkm_a4t.c
--- v2.4.10/linux/drivers/isdn/hisax/bkm_a4t.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/bkm_a4t.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,12 @@
-/* $Id: bkm_a4t.c,v 1.13.6.5 2001/07/18 16:02:15 kai Exp $
- * bkm_a4t.c    low level stuff for T-Berkom A4T
- *              derived from the original file sedlbauer.c
- *              derived from the original file niccy.c
- *              derived from the original file netjet.c
+/* $Id: bkm_a4t.c,v 1.13.6.6 2001/09/23 22:24:46 kai Exp $
  *
- * Author       Roland Klabunde (R.Klabunde@Berkom.de)
+ * low level stuff for T-Berkom A4T
  *
- * This file is (c) under GNU General Public License
+ * Author       Roland Klabunde
+ * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -24,7 +24,7 @@
 
 extern const char *CardType[];
 
-const char *bkm_a4t_revision = "$Revision: 1.13.6.5 $";
+const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $";
 
 
 static inline u_char
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/bkm_a8.c linux/drivers/isdn/hisax/bkm_a8.c
--- v2.4.10/linux/drivers/isdn/hisax/bkm_a8.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/bkm_a8.c	Sun Sep 30 12:26:05 2001
@@ -1,14 +1,15 @@
-/* $Id: bkm_a8.c,v 1.14.6.6 2001/07/18 16:02:15 kai Exp $
- * bkm_a8.c     low level stuff for Scitel Quadro (4*S0, passive)
- *              derived from the original file sedlbauer.c
- *              derived from the original file niccy.c
- *              derived from the original file netjet.c
+/* $Id: bkm_a8.c,v 1.14.6.7 2001/09/23 22:24:46 kai Exp $
  *
- * Author       Roland Klabunde (R.Klabunde@Berkom.de)
+ * low level stuff for Scitel Quadro (4*S0, passive)
  *
- * This file is (c) under GNU General Public License
+ * Author       Roland Klabunde
+ * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #define __NO_VERSION__
 
 #include <linux/config.h>
@@ -27,7 +28,7 @@
 
 extern const char *CardType[];
 
-const char sct_quadro_revision[] = "$Revision: 1.14.6.6 $";
+const char sct_quadro_revision[] = "$Revision: 1.14.6.7 $";
 
 static const char *sct_quadro_subtypes[] =
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/bkm_ax.h linux/drivers/isdn/hisax/bkm_ax.h
--- v2.4.10/linux/drivers/isdn/hisax/bkm_ax.h	Fri Mar  2 18:38:37 2001
+++ linux/drivers/isdn/hisax/bkm_ax.h	Sun Sep 30 12:26:05 2001
@@ -1,9 +1,12 @@
-/* $Id: bkm_ax.h,v 1.5.6.2 2001/02/16 16:43:25 kai Exp $
- * bkm_ax.h   low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive)
+/* $Id: bkm_ax.h,v 1.5.6.3 2001/09/23 22:24:46 kai Exp $
  *
- * Author     Roland Klabunde (R.Klabunde@Berkom.de)
+ * low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive)
  *
- * This file is (c) under GNU General Public License
+ * Author       Roland Klabunde
+ * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
--- v2.4.10/linux/drivers/isdn/hisax/callc.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/callc.c	Sun Sep 30 12:26:05 2001
@@ -1,17 +1,23 @@
-/* $Id: callc.c,v 2.51.6.5 2001/08/23 19:44:23 kai Exp $
+/* $Id: callc.c,v 2.51.6.6 2001/09/23 22:24:46 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *              based on the teles driver from Jan den Ouden
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
+ *
+ * based on the teles driver from Jan den Ouden
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
  *
  */
+
 #define __NO_VERSION__
+#include <linux/module.h>
 #include <linux/init.h>
 #include "hisax.h"
 #include "../avmb1/capicmd.h"  /* this should be moved in a common place */
@@ -20,7 +26,7 @@
 #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))
 #endif	/* MODULE */
 
-const char *lli_revision = "$Revision: 2.51.6.5 $";
+const char *lli_revision = "$Revision: 2.51.6.6 $";
 
 extern struct IsdnCard cards[];
 extern int nrcards;
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/cert.c linux/drivers/isdn/hisax/cert.c
--- v2.4.10/linux/drivers/isdn/hisax/cert.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/isdn/hisax/cert.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,13 @@
-/* $Id: cert.c,v 2.3.6.2 2001/07/27 09:08:27 kai Exp $
+/* $Id: cert.c,v 2.3.6.3 2001/09/23 22:24:47 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  */
  
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- v2.4.10/linux/drivers/isdn/hisax/config.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/config.c	Sun Sep 30 12:26:05 2001
@@ -1,11 +1,19 @@
-/* $Id: config.c,v 2.57.6.18 2001/08/27 22:19:05 kai Exp $
+/* $Id: config.c,v 2.57.6.20 2001/09/23 22:24:47 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *              based on the teles driver from Jan den Ouden
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ *              by Kai Germaschewski <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This file is (c) under GNU General Public License
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
+ *
+ * based on the teles driver from Jan den Ouden
  *
  */
+
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/timer.h>
@@ -365,7 +373,9 @@
 static int mem[8] __devinitdata = { 0, };
 static char *id __devinitdata = HiSaxID;
 
+MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards");
 MODULE_AUTHOR("Karsten Keil");
+MODULE_LICENSE("GPL");
 MODULE_PARM(type, "1-8i");
 MODULE_PARM(protocol, "1-8i");
 MODULE_PARM(io, "1-8i");
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c
--- v2.4.10/linux/drivers/isdn/hisax/diva.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/diva.c	Sun Sep 30 12:26:05 2001
@@ -1,14 +1,17 @@
-/* $Id: diva.c,v 1.25.6.4 2001/02/16 16:43:25 kai Exp $
+/* $Id: diva.c,v 1.25.6.5 2001/09/23 22:24:47 kai Exp $
  *
- * diva.c     low level stuff for Eicon.Diehl Diva Family ISDN cards
+ * low level stuff for Eicon.Diehl Diva Family ISDN cards
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
- * Thanks to Eicon Technology for documents and informations
+ * Thanks to Eicon Technology for documents and information
  *
  */
 
@@ -24,7 +27,7 @@
 
 extern const char *CardType[];
 
-const char *Diva_revision = "$Revision: 1.25.6.4 $";
+const char *Diva_revision = "$Revision: 1.25.6.5 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/elsa.c linux/drivers/isdn/hisax/elsa.c
--- v2.4.10/linux/drivers/isdn/hisax/elsa.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/elsa.c	Sun Sep 30 12:26:05 2001
@@ -1,14 +1,17 @@
-/* $Id: elsa.c,v 2.26.6.5 2001/07/18 16:25:12 kai Exp $
+/* $Id: elsa.c,v 2.26.6.6 2001/09/23 22:24:47 kai Exp $
  *
- * elsa.c     low level stuff for Elsa isdn cards
+ * low level stuff for Elsa isdn cards
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
- * Thanks to    Elsa GmbH for documents and informations
+ * Thanks to    Elsa GmbH for documents and information
  *
  *              Klaus Lichtenwalder (Klaus.Lichtenwalder@WebForum.DE)
  *              for ELSA PCMCIA support
@@ -30,7 +33,7 @@
 
 extern const char *CardType[];
 
-const char *Elsa_revision = "$Revision: 2.26.6.5 $";
+const char *Elsa_revision = "$Revision: 2.26.6.6 $";
 const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
  "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/elsa_cs.c linux/drivers/isdn/hisax/elsa_cs.c
--- v2.4.10/linux/drivers/isdn/hisax/elsa_cs.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/hisax/elsa_cs.c	Sun Sep 30 12:26:05 2001
@@ -4,6 +4,7 @@
 
     This driver is for the Elsa PCM ISDN Cards, i.e. the MicroLink
 
+
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     except in compliance with the License. You may obtain a copy of
@@ -21,6 +22,17 @@
     Modifications from dummy_cs.c are Copyright (C) 1999-2001 Klaus
     Lichtenwalder <Lichtenwalder@ACM.org>. All Rights Reserved.
 
+    Alternatively, the contents of this file may be used under the
+    terms of the GNU General Public License version 2 (the "GPL"), in
+    which case the provisions of the GPL are applicable instead of the
+    above.  If you wish to allow the use of your version of this file
+    only under the terms of the GPL and not to allow others to use
+    your version of this file under the MPL, indicate your decision
+    by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL.  If you do not delete
+    the provisions above, a recipient may use your version of this
+    file under either the MPL or the GPL.
+
 ======================================================================*/
 
 #include <linux/module.h>
@@ -43,6 +55,10 @@
 #include <pcmcia/ds.h>
 #include <pcmcia/bus_ops.h>
 
+MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
+MODULE_AUTHOR("Klaus Lichtenwalder");
+MODULE_LICENSE("Dual MPL/GPL");
+
 /*
    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
    you do not define PCMCIA_DEBUG at all, all the debug code will be
@@ -56,7 +72,7 @@
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 static char *version =
-"elsa_cs.c $Revision: 1.1.2.1 $ $Date: 2001/04/15 08:01:34 $ (K.Lichtenwalder)";
+"elsa_cs.c $Revision: 1.1.2.2 $ $Date: 2001/09/23 22:24:47 $ (K.Lichtenwalder)";
 #else
 #define DEBUG(n, args...)
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/elsa_ser.c linux/drivers/isdn/hisax/elsa_ser.c
--- v2.4.10/linux/drivers/isdn/hisax/elsa_ser.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/elsa_ser.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: elsa_ser.c,v 2.10.6.3 2001/08/17 12:34:26 kai Exp $
+/* $Id: elsa_ser.c,v 2.10.6.4 2001/09/23 22:24:47 kai Exp $
  *
  * stuff for the serial modem on ELSA cards
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #include <linux/config.h>
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/fsm.c linux/drivers/isdn/hisax/fsm.c
--- v2.4.10/linux/drivers/isdn/hisax/fsm.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/fsm.c	Sun Sep 30 12:26:05 2001
@@ -1,15 +1,21 @@
-/* $Id: fsm.c,v 1.14.6.3 2001/08/23 19:44:23 kai Exp $
+/* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *              based on the teles driver from Jan den Ouden
+ * Finite state machine
+ *
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ *              by Kai Germaschewski <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
  *
- * This file is (c) under GNU General Public License
- *
  */
+
 #define __NO_VERSION__
+#include <linux/module.h>
 #include <linux/init.h>
 #include "hisax.h"
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/fsm.h linux/drivers/isdn/hisax/fsm.h
--- v2.4.10/linux/drivers/isdn/hisax/fsm.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/fsm.h	Sun Sep 30 12:26:05 2001
@@ -1,3 +1,16 @@
+/* $Id: fsm.h,v 1.3.2.2 2001/09/23 22:24:47 kai Exp $
+ *
+ * Finite state machine
+ *
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ *              by Kai Germaschewski <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
 #ifndef __FSM_H__
 #define __FSM_H__
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/gazel.c linux/drivers/isdn/hisax/gazel.c
--- v2.4.10/linux/drivers/isdn/hisax/gazel.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/gazel.c	Sun Sep 30 12:26:05 2001
@@ -1,13 +1,16 @@
-/* $Id: gazel.c,v 2.11.6.6 2001/06/08 08:48:46 kai Exp $
+/* $Id: gazel.c,v 2.11.6.7 2001/09/23 22:24:47 kai Exp $
  *
- * gazel.c     low level stuff for Gazel isdn cards
+ * low level stuff for Gazel isdn cards
  *
  * Author       BeWan Systems
  *              based on source code from Karsten Keil
- *
- * This file is (c) under GNU General Public License
+ * Copyright    by BeWan Systems
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #include <linux/config.h>
 #include <linux/init.h>
 #define __NO_VERSION__
@@ -19,7 +22,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *gazel_revision = "$Revision: 2.11.6.6 $";
+const char *gazel_revision = "$Revision: 2.11.6.7 $";
 
 #define R647      1
 #define R685      2
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_2bds0.c linux/drivers/isdn/hisax/hfc_2bds0.c
--- v2.4.10/linux/drivers/isdn/hisax/hfc_2bds0.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/hfc_2bds0.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,15 @@
-/* $Id: hfc_2bds0.c,v 1.15.6.2 2001/06/09 15:14:17 kai Exp $
+/* $Id: hfc_2bds0.c,v 1.15.6.3 2001/09/23 22:24:47 kai Exp $
  *
- *  specific routines for CCD's HFC 2BDS0
+ * specific routines for CCD's HFC 2BDS0
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_2bds0.h linux/drivers/isdn/hisax/hfc_2bds0.h
--- v2.4.10/linux/drivers/isdn/hisax/hfc_2bds0.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hfc_2bds0.h	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: hfc_2bds0.h,v 1.4.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: hfc_2bds0.h,v 1.4.6.2 2001/09/23 22:24:47 kai Exp $
  *
- *  specific defines for CCD's HFC 2BDS0
+ * specific defines for CCD's HFC 2BDS0
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_2bs0.c linux/drivers/isdn/hisax/hfc_2bs0.c
--- v2.4.10/linux/drivers/isdn/hisax/hfc_2bs0.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/hfc_2bs0.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: hfc_2bs0.c,v 1.17.6.2 2001/06/09 15:14:17 kai Exp $
+/* $Id: hfc_2bs0.c,v 1.17.6.3 2001/09/23 22:24:47 kai Exp $
  *
- *  specific routines for CCD's HFC 2BS0
+ * specific routines for CCD's HFC 2BS0
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_2bs0.h linux/drivers/isdn/hisax/hfc_2bs0.h
--- v2.4.10/linux/drivers/isdn/hisax/hfc_2bs0.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hfc_2bs0.h	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: hfc_2bs0.h,v 1.3.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: hfc_2bs0.h,v 1.3.6.2 2001/09/23 22:24:47 kai Exp $
  *
- *  specific defines for CCD's HFC 2BS0
+ * specific defines for CCD's HFC 2BS0
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- v2.4.10/linux/drivers/isdn/hisax/hfc_pci.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/hfc_pci.c	Sun Sep 30 12:26:05 2001
@@ -1,27 +1,17 @@
-/* $Id: hfc_pci.c,v 1.34.6.7 2001/07/27 09:08:27 kai Exp $
-
- * hfc_pci.c     low level driver for CCD´s hfc-pci based cards
- *
- * Author     Werner Cornelius (werner@isdn4linux.de)
- *            based on existing driver for CCD hfc ISA cards
- *            type approval valid for HFC-S PCI A based card 
- *
- * Copyright 1999  by Werner Cornelius (werner@isdn-development.de)
- * Copyright 1999  by Karsten Keil (keil@isdn4linux.de)
+/* $Id: hfc_pci.c,v 1.34.6.8 2001/09/23 22:24:47 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * low level driver for CCD´s hfc-pci based cards
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author       Werner Cornelius
+ *              based on existing driver for CCD hfc ISA cards
+ * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
+ *              by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  */
 
@@ -36,7 +26,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcpci_revision = "$Revision: 1.34.6.7 $";
+static const char *hfcpci_revision = "$Revision: 1.34.6.8 $";
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -84,7 +74,7 @@
 void
 release_io_hfcpci(struct IsdnCardState *cs)
 {
-	long flags;
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
@@ -299,7 +289,7 @@
 	u_char *ptr, *ptr1, new_f2;
 	struct sk_buff *skb;
 	struct IsdnCardState *cs = bcs->cs;
-	long flags;
+	unsigned long flags;
 	int total, maxlen, new_z2;
 	z_type *zp;
 
@@ -634,7 +624,7 @@
 hfcpci_fill_fifo(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
-	long flags;
+	unsigned long flags;
 	int maxlen, fcnt;
 	int count, new_z1;
 	bzfifo_type *bz;
@@ -812,7 +802,7 @@
 static int
 hfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic)
 {
-	long flags;
+	unsigned long flags;
 	int i = *(unsigned int *) ic->parm.num;
 
 	if ((ic->arg == 98) &&
@@ -1162,7 +1152,7 @@
 {
 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 	struct sk_buff *skb = arg;
-	long flags;
+	unsigned long flags;
 
 	switch (pr) {
 		case (PH_DATA | REQUEST):
@@ -1316,7 +1306,7 @@
 mode_hfcpci(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
-	long flags;
+	unsigned long flags;
 	int fifo2;
 
 	if (cs->debug & L1_DEB_HSCX)
@@ -1551,7 +1541,7 @@
 static void
 hfcpci_bh(struct IsdnCardState *cs)
 {
-	long flags;
+	unsigned long flags;
 /*      struct PStack *stptr;
  */
 	if (!cs)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_pci.h linux/drivers/isdn/hisax/hfc_pci.h
--- v2.4.10/linux/drivers/isdn/hisax/hfc_pci.h	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hisax/hfc_pci.h	Sun Sep 30 12:26:05 2001
@@ -1,24 +1,12 @@
-/* $Id: hfc_pci.h,v 1.8.6.1 2001/04/08 19:32:26 kai Exp $
+/* $Id: hfc_pci.h,v 1.8.6.2 2001/09/23 22:24:48 kai Exp $
  *
- *  specific defines for CCD's HFC 2BDS0 PCI chips
+ * specific defines for CCD's HFC 2BDS0 PCI chips
  *
- * Author     Werner Cornelius (werner@isdn4linux.de)      
- *
- * Copyright 1999  by Werner Cornelius (werner@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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       Werner Cornelius
+ * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_sx.c linux/drivers/isdn/hisax/hfc_sx.c
--- v2.4.10/linux/drivers/isdn/hisax/hfc_sx.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/hfc_sx.c	Sun Sep 30 12:26:05 2001
@@ -1,25 +1,13 @@
-/* $Id: hfc_sx.c,v 1.9.6.2 2001/07/18 16:25:12 kai Exp $
-
- * hfc_sx.c     low level driver for CCD´s hfc-s+/sp based cards
- *
- * Author     Werner Cornelius (werner@isdn4linux.de)
- *            based on existing driver for CCD HFC PCI cards
- *
- * Copyright 1999  by Werner Cornelius (werner@isdn4linux.de)
+/* $Id: hfc_sx.c,v 1.9.6.3 2001/09/23 22:24:48 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * level driver for CCD´s hfc-s+/sp based cards
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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       Werner Cornelius
+ *              based on existing driver for CCD HFC PCI cards
+ * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -32,7 +20,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcsx_revision = "$Revision: 1.9.6.2 $";
+static const char *hfcsx_revision = "$Revision: 1.9.6.3 $";
 
 /***************************************/
 /* IRQ-table for CCDs demo board       */
@@ -73,7 +61,7 @@
 /******************************/
 static inline void
 Write_hfc(struct IsdnCardState *cs, u_char regnum, u_char val)
-{       long flags;
+{       unsigned long flags;
 
         save_flags(flags);
 	cli();
@@ -84,7 +72,7 @@
 
 static inline u_char
 Read_hfc(struct IsdnCardState *cs, u_char regnum)
-{       long flags;
+{       unsigned long flags;
         u_char ret; 
 
         save_flags(flags);
@@ -101,7 +89,7 @@
 /**************************************************/
 static void
 fifo_select(struct IsdnCardState *cs, u_char fifo)
-{       long flags;
+{       unsigned long flags;
 
         if (fifo == cs->hw.hfcsx.last_fifo) 
 	  return; /* still valid */
@@ -123,7 +111,7 @@
 /******************************************/
 static void
 reset_fifo(struct IsdnCardState *cs, u_char fifo)
-{       long flags;
+{       unsigned long flags;
 
         save_flags(flags); 
 	cli();
@@ -337,7 +325,7 @@
 void
 release_io_hfcsx(struct IsdnCardState *cs)
 {
-	long flags;
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
@@ -599,7 +587,7 @@
 hfcsx_fill_fifo(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
-	long flags;
+	unsigned long flags;
 
 	if (!bcs->tx_skb)
 		return;
@@ -670,7 +658,7 @@
 static int
 hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic)
 {
-	long flags;
+	unsigned long flags;
 	int i = *(unsigned int *) ic->parm.num;
 
 	if ((ic->arg == 98) &&
@@ -729,7 +717,7 @@
 static void
 receive_emsg(struct IsdnCardState *cs)
 {
-	long flags;
+	unsigned long flags;
 	int count = 5;
 	u_char *ptr;
 	struct sk_buff *skb;
@@ -961,7 +949,7 @@
 {
 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 	struct sk_buff *skb = arg;
-	long flags;
+	unsigned long flags;
 
 	switch (pr) {
 		case (PH_DATA | REQUEST):
@@ -1115,7 +1103,7 @@
 mode_hfcsx(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
-	long flags;
+	unsigned long flags;
 	int fifo2;
 
 	if (cs->debug & L1_DEB_HSCX)
@@ -1339,7 +1327,7 @@
 static void
 hfcsx_bh(struct IsdnCardState *cs)
 {
-	long flags;
+	unsigned long flags;
 /*      struct PStack *stptr;
  */
 	if (!cs)
@@ -1479,7 +1467,7 @@
 {
 	struct IsdnCardState *cs = card->cs;
 	char tmp[64];
-	long flags;
+	unsigned long flags;
 
 	strcpy(tmp, hfcsx_revision);
 	printk(KERN_INFO "HiSax: HFC-SX driver Rev. %s\n", HiSax_getrev(tmp));
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfc_sx.h linux/drivers/isdn/hisax/hfc_sx.h
--- v2.4.10/linux/drivers/isdn/hisax/hfc_sx.h	Sun Aug  6 12:43:41 2000
+++ linux/drivers/isdn/hisax/hfc_sx.h	Sun Sep 30 12:26:05 2001
@@ -1,24 +1,13 @@
-/* $Id: hfc_sx.h,v 1.2 2000/06/26 08:59:13 keil Exp $
+/* $Id: hfc_sx.h,v 1.2.6.1 2001/09/23 22:24:48 kai Exp $
  *
- *  specific defines for CCD's HFC 2BDS0 S+,SP chips
+ * specific defines for CCD's HFC 2BDS0 S+,SP chips
  *
- * Author     Werner Cornelius (werner@isdn4linux.de)      
- *
- * Copyright 1999  by Werner Cornelius (werner@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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       Werner Cornelius
+ *              based on existing driver for CCD HFC PCI cards
+ * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hfcscard.c linux/drivers/isdn/hisax/hfcscard.c
--- v2.4.10/linux/drivers/isdn/hisax/hfcscard.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hfcscard.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: hfcscard.c,v 1.8.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: hfcscard.c,v 1.8.6.2 2001/09/23 22:24:48 kai Exp $
  *
- * hfcscard.c     low level stuff for hfcs based cards (Teles3c, ACER P10)
+ * low level stuff for hfcs based cards (Teles3c, ACER P10)
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -16,7 +18,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcs_revision = "$Revision: 1.8.6.1 $";
+static const char *hfcs_revision = "$Revision: 1.8.6.2 $";
 
 static void
 hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- v2.4.10/linux/drivers/isdn/hisax/hisax.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/hisax.h	Sun Sep 30 12:26:05 2001
@@ -1,13 +1,12 @@
-/* $Id: hisax.h,v 2.52.6.8 2001/08/23 19:44:23 kai Exp $
+/* $Id: hisax.h,v 2.52.6.9 2001/09/23 22:24:48 kai Exp $
  *
- *   Basic declarations, defines and prototypes
+ * Basic declarations, defines and prototypes
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 #include <linux/config.h>
-#include <linux/module.h>
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/major.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hisax_debug.h linux/drivers/isdn/hisax/hisax_debug.h
--- v2.4.10/linux/drivers/isdn/hisax/hisax_debug.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/hisax_debug.h	Sun Sep 30 12:26:05 2001
@@ -3,13 +3,11 @@
  *
  * Author       Frode Isaksen
  * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
+ *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
  * 
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- */
-
-/* 
  * How to use:
  * 
  * Before including this file, you need to
@@ -18,10 +16,13 @@
  * determines the debug bitmask.
  *
  * If CONFIG_HISAX_DEBUG is not set, all macros evaluate to nothing
+ *
  */
 
 #ifndef __HISAX_DEBUG_H__
 #define __HISAX_DEBUG_H__
+
+#include <linux/config.h>
 
 #ifdef CONFIG_HISAX_DEBUG
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hisax_if.h linux/drivers/isdn/hisax/hisax_if.h
--- v2.4.10/linux/drivers/isdn/hisax/hisax_if.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/hisax_if.h	Sun Sep 30 12:26:05 2001
@@ -1,3 +1,15 @@
+/*
+ * Interface between low level (hardware) drivers and 
+ * HiSax protocol stack
+ *
+ * Author       Kai Germaschewski
+ * Copyright    2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
 #ifndef __HISAX_IF_H__
 #define __HISAX_IF_H__
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hscx.c linux/drivers/isdn/hisax/hscx.c
--- v2.4.10/linux/drivers/isdn/hisax/hscx.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/hscx.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: hscx.c,v 1.21.6.2 2001/06/09 15:14:17 kai Exp $
+/* $Id: hscx.c,v 1.21.6.3 2001/09/23 22:24:48 kai Exp $
  *
- * hscx.c   HSCX specific routines
+ * HSCX specific routines
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hscx.h linux/drivers/isdn/hisax/hscx.h
--- v2.4.10/linux/drivers/isdn/hisax/hscx.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hscx.h	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: hscx.h,v 1.6.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: hscx.h,v 1.6.6.2 2001/09/23 22:24:48 kai Exp $
  *
- * hscx.h   HSCX specific defines
+ * HSCX specific defines
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/hscx_irq.c linux/drivers/isdn/hisax/hscx_irq.c
--- v2.4.10/linux/drivers/isdn/hisax/hscx_irq.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hscx_irq.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,14 @@
-/* $Id: hscx_irq.c,v 1.16.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: hscx_irq.c,v 1.16.6.2 2001/09/23 22:24:48 kai Exp $
  *
- * hscx_irq.c     low level b-channel stuff for Siemens HSCX
+ * low level b-channel stuff for Siemens HSCX
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * This is an include file for fast inline IRQ stuff
- *
- * This file is (c) under GNU General Public License
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/icc.c linux/drivers/isdn/hisax/icc.c
--- v2.4.10/linux/drivers/isdn/hisax/icc.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/icc.c	Sun Sep 30 12:26:05 2001
@@ -1,18 +1,18 @@
-// $Id: icc.c,v 1.5.6.3 2001/06/09 15:14:17 kai Exp $
-//-----------------------------------------------------------------------------
-//
-// ICC specific routines
-//
-// Author       Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd
-//              www.traverse.com.au
-//
-// 1999.6.25 Initial implementation of routines for Siemens ISDN
-// Communication Controller PEB 2070 based on the ISAC routines
-// written by Karsten Keil.
-//
-// This file is (c) under GNU General Public License
-//
-//-----------------------------------------------------------------------------
+/* $Id: icc.c,v 1.5.6.4 2001/09/23 22:24:48 kai Exp $
+ *
+ * ICC specific routines
+ *
+ * Author       Matt Henderson & Guy Ellis
+ * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * 1999.6.25 Initial implementation of routines for Siemens ISDN
+ * Communication Controller PEB 2070 based on the ISAC routines
+ * written by Karsten Keil.
+ *
+ */
 
 #define __NO_VERSION__
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/icc.h linux/drivers/isdn/hisax/icc.h
--- v2.4.10/linux/drivers/isdn/hisax/icc.h	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hisax/icc.h	Sun Sep 30 12:26:05 2001
@@ -1,19 +1,17 @@
-// $Id: icc.h,v 1.2.6.2 2001/03/13 16:17:08 kai Exp $
-//-----------------------------------------------------------------------------
-//
-// ICC specific routines
-//
-// Author       Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd
-//              www.traverse.com.au
-//
-// 1999.7.14 Initial implementation of routines for Siemens ISDN 
-// Communication Controller PEB 2070 based on the ISAC routines 
-// written by Karsten Keil.
-//
-// This file is (c) under GNU General Public License
-//
-//-----------------------------------------------------------------------------
-
+/* $Id: icc.h,v 1.2.6.3 2001/09/23 22:24:48 kai Exp $
+ *
+ * ICC specific routines
+ *
+ * Author       Matt Henderson & Guy Ellis
+ * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * 1999.7.14 Initial implementation of routines for Siemens ISDN 
+ * Communication Controller PEB 2070 based on the ISAC routines 
+ * written by Karsten Keil.
+ */
 
 /* All Registers original Siemens Spec  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/ipac.h linux/drivers/isdn/hisax/ipac.h
--- v2.4.10/linux/drivers/isdn/hisax/ipac.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/ipac.h	Sun Sep 30 12:26:05 2001
@@ -1,13 +1,14 @@
-/* $Id: ipac.h,v 1.5.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: ipac.h,v 1.5.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * ipac.h   IPAC specific defines
+ * IPAC specific defines
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 /* All Registers original Siemens Spec  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isac.c linux/drivers/isdn/hisax/isac.c
--- v2.4.10/linux/drivers/isdn/hisax/isac.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/isac.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,16 @@
-/* $Id: isac.c,v 1.28.6.2 2001/06/09 15:14:17 kai Exp $
+/* $Id: isac.c,v 1.28.6.3 2001/09/23 22:24:49 kai Exp $
  *
- * isac.c   ISAC specific routines
+ * ISAC specific routines
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
  */
 
 #define __NO_VERSION__
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isac.h linux/drivers/isdn/hisax/isac.h
--- v2.4.10/linux/drivers/isdn/hisax/isac.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isac.h	Sun Sep 30 12:26:05 2001
@@ -1,13 +1,14 @@
-/* $Id: isac.h,v 1.7.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isac.h,v 1.7.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * isac.h   ISAC specific defines
+ * ISAC specific defines
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
-
 
 /* All Registers original Siemens Spec  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c
--- v2.4.10/linux/drivers/isdn/hisax/isar.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/isar.c	Sun Sep 30 12:26:06 2001
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.17.6.4 2001/08/17 12:34:26 kai Exp $
+/* $Id: isar.c,v 1.17.6.5 2001/09/23 11:51:33 keil Exp $
  *
  * isar.c   ISAR (Siemens PSB 7110) specific routines
  *
@@ -270,9 +270,10 @@
 			ret = 1;goto reterror;
 		}
 		while (left>0) {
-			noc = left;
-			if (noc > 126)
+			if (left > 126)
 				noc = 126;
+			else
+				noc = left;
 			nom = 2*noc;
 			mp  = msg;
 			*mp++ = sadr / 256;
@@ -288,8 +289,8 @@
 			nom += 3;
 			sp = (u_short *)tmpmsg;
 #if DBG_LOADFIRM
-			printk(KERN_DEBUG"isar: load %3d words at %04x\n",
-				 noc, sadr);
+			printk(KERN_DEBUG"isar: load %3d words at %04x left %d\n",
+				 noc, sadr, left);
 #endif
 			sadr += noc;
 			while(noc) {
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isar.h linux/drivers/isdn/hisax/isar.h
--- v2.4.10/linux/drivers/isdn/hisax/isar.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isar.h	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: isar.h,v 1.9.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isar.h,v 1.9.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * isar.h   ISAR (Siemens PSB 7110) specific defines
+ * ISAR (Siemens PSB 7110) specific defines
  *
- * Author Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
  
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c
--- v2.4.10/linux/drivers/isdn/hisax/isdnl1.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/isdnl1.c	Sun Sep 30 12:26:05 2001
@@ -1,13 +1,16 @@
-/* $Id: isdnl1.c,v 2.41.6.4 2001/08/23 19:44:23 kai Exp $
+/* $Id: isdnl1.c,v 2.41.6.5 2001/09/23 22:24:49 kai Exp $
  *
- * isdnl1.c     common low level stuff for Siemens Chipsetbased isdn cards
- *              based on the teles driver from Jan den Ouden
+ * common low level stuff for Siemens Chipsetbased isdn cards
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ *              based on the teles driver from Jan den Ouden
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
@@ -15,7 +18,7 @@
  *
  */
 
-const char *l1_revision = "$Revision: 2.41.6.4 $";
+const char *l1_revision = "$Revision: 2.41.6.5 $";
 
 #define __NO_VERSION__
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isdnl1.h linux/drivers/isdn/hisax/isdnl1.h
--- v2.4.10/linux/drivers/isdn/hisax/isdnl1.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/isdnl1.h	Sun Sep 30 12:26:05 2001
@@ -1,8 +1,9 @@
-/* $Id: isdnl1.h,v 2.9.6.2 2001/08/23 19:44:23 kai Exp $
+/* $Id: isdnl1.h,v 2.9.6.3 2001/09/23 22:24:49 kai Exp $
  *
  * Layer 1 defines
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isdnl2.c linux/drivers/isdn/hisax/isdnl2.c
--- v2.4.10/linux/drivers/isdn/hisax/isdnl2.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/isdnl2.c	Sun Sep 30 12:26:05 2001
@@ -1,22 +1,26 @@
-/* $Id: isdnl2.c,v 2.25.6.3 2001/06/09 15:14:17 kai Exp $
+/* $Id: isdnl2.c,v 2.25.6.4 2001/09/23 22:24:49 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
  *
  */
+
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
 #include "isdnl2.h"
 
-const char *l2_revision = "$Revision: 2.25.6.3 $";
+const char *l2_revision = "$Revision: 2.25.6.4 $";
 
 static void l2m_debug(struct FsmInst *fi, char *fmt, ...);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isdnl2.h linux/drivers/isdn/hisax/isdnl2.h
--- v2.4.10/linux/drivers/isdn/hisax/isdnl2.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl2.h	Sun Sep 30 12:26:05 2001
@@ -1,8 +1,9 @@
-/* $Id: isdnl2.h,v 1.3.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isdnl2.h,v 1.3.6.2 2001/09/23 22:24:49 kai Exp $
  *
  * Layer 2 defines
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isdnl3.c linux/drivers/isdn/hisax/isdnl3.c
--- v2.4.10/linux/drivers/isdn/hisax/isdnl3.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/isdnl3.c	Sun Sep 30 12:26:05 2001
@@ -1,11 +1,14 @@
-/* $Id: isdnl3.c,v 2.17.6.4 2001/06/09 15:14:17 kai Exp $
+/* $Id: isdnl3.c,v 2.17.6.5 2001/09/23 22:24:49 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
@@ -18,7 +21,7 @@
 #include "isdnl3.h"
 #include <linux/config.h>
 
-const char *l3_revision = "$Revision: 2.17.6.4 $";
+const char *l3_revision = "$Revision: 2.17.6.5 $";
 
 static struct Fsm l3fsm;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isdnl3.h linux/drivers/isdn/hisax/isdnl3.h
--- v2.4.10/linux/drivers/isdn/hisax/isdnl3.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl3.h	Sun Sep 30 12:26:05 2001
@@ -1,6 +1,7 @@
-/* $Id: isdnl3.h,v 2.6.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isdnl3.h,v 2.6.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/isurf.c linux/drivers/isdn/hisax/isurf.c
--- v2.4.10/linux/drivers/isdn/hisax/isurf.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isurf.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: isurf.c,v 1.10.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: isurf.c,v 1.10.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * isurf.c  low level stuff for Siemens I-Surf/I-Talk cards
+ * low level stuff for Siemens I-Surf/I-Talk cards
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -17,7 +19,7 @@
 
 extern const char *CardType[];
 
-static const char *ISurf_revision = "$Revision: 1.10.6.1 $";
+static const char *ISurf_revision = "$Revision: 1.10.6.2 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/ix1_micro.c linux/drivers/isdn/hisax/ix1_micro.c
--- v2.4.10/linux/drivers/isdn/hisax/ix1_micro.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/ix1_micro.c	Sun Sep 30 12:26:05 2001
@@ -1,47 +1,22 @@
-/* $Id: ix1_micro.c,v 2.10.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: ix1_micro.c,v 2.10.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * ix1_micro.c  low level stuff for ITK ix1-micro Rev.2 isdn cards
- *              derived from the original file teles3.c from Karsten Keil
+ * low level stuff for ITK ix1-micro Rev.2 isdn cards
+ * derived from the original file teles3.c from Karsten Keil
  *
- * Copyright (C) 1997 Klaus-Peter Nischke (ITK AG) (for the modifications to
- *                                                  the original file teles.c)
- *
- * Thanks to    Jan den Ouden
- *              Fritz Elfert
- *              Beat Doebeli
+ * Author       Klaus-Peter Nischke
+ * Copyright    by Klaus-Peter Nischke, ITK AG
+ *                                   <klaus@nischke.do.eunet.de>
+ *              by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
+ * Klaus-Peter Nischke
+ * Deusener Str. 287
+ * 44369 Dortmund
+ * Germany
  */
 
-/*
-   For the modification done by the author the following terms and conditions
-   apply (GNU General Public License)
-
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-   You may contact Klaus-Peter Nischke by email: klaus@nischke.do.eunet.de
-   or by conventional mail:
-
-   Klaus-Peter Nischke
-   Deusener Str. 287
-   44369 Dortmund
-   Germany
- */
-
-
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
@@ -50,7 +25,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *ix1_revision = "$Revision: 2.10.6.1 $";
+const char *ix1_revision = "$Revision: 2.10.6.2 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/jade.c linux/drivers/isdn/hisax/jade.c
--- v2.4.10/linux/drivers/isdn/hisax/jade.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/jade.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: jade.c,v 1.6.6.2 2001/06/09 15:14:18 kai Exp $
+/* $Id: jade.c,v 1.6.6.3 2001/09/23 22:24:49 kai Exp $
  *
- * jade.c   JADE stuff (derived from original hscx.c)
+ * JADE stuff (derived from original hscx.c)
  *
- * Author   Roland Klabunde (R.Klabunde@Berkom.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Roland Klabunde
+ * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/jade.h linux/drivers/isdn/hisax/jade.h
--- v2.4.10/linux/drivers/isdn/hisax/jade.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/jade.h	Sun Sep 30 12:26:05 2001
@@ -1,9 +1,12 @@
-/* $Id: jade.h,v 1.3.6.1 2001/02/16 16:43:27 kai Exp $
- * jade.h   JADE specific defines
+/* $Id: jade.h,v 1.3.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * Author   Roland Klabunde (R.Klabunde@Berkom.de)
+ * JADE specific defines
  *
- * This file is (c) under GNU General Public License
+ * Author       Roland Klabunde
+ * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/jade_irq.c linux/drivers/isdn/hisax/jade_irq.c
--- v2.4.10/linux/drivers/isdn/hisax/jade_irq.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/jade_irq.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: jade_irq.c,v 1.5.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: jade_irq.c,v 1.5.6.2 2001/09/23 22:24:49 kai Exp $
  *
- * jade_irq.c   Low level JADE IRQ stuff (derived from original hscx_irq.c)
+ * Low level JADE IRQ stuff (derived from original hscx_irq.c)
  *
- * Author   Roland Klabunde (R.Klabunde@Berkom.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Roland Klabunde
+ * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/l3_1tr6.c linux/drivers/isdn/hisax/l3_1tr6.c
--- v2.4.10/linux/drivers/isdn/hisax/l3_1tr6.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3_1tr6.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,15 @@
-/* $Id: l3_1tr6.c,v 2.13.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: l3_1tr6.c,v 2.13.6.2 2001/09/23 22:24:49 kai Exp $
  *
- *  German 1TR6 D-channel protocol
+ * German 1TR6 D-channel protocol
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  */
 
@@ -17,7 +20,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 2.13.6.1 $";
+const char *l3_1tr6_revision = "$Revision: 2.13.6.2 $";
 
 #define MsgHead(ptr, cref, mty, dis) \
 	*ptr++ = dis; \
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/l3_1tr6.h linux/drivers/isdn/hisax/l3_1tr6.h
--- v2.4.10/linux/drivers/isdn/hisax/l3_1tr6.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3_1tr6.h	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: l3_1tr6.h,v 2.2.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: l3_1tr6.h,v 2.2.6.2 2001/09/23 22:24:49 kai Exp $
  *
- *  German 1TR6 D-channel protocol defines
+ * German 1TR6 D-channel protocol defines
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #ifndef l3_1tr6
 #define l3_1tr6
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/l3dss1.c linux/drivers/isdn/hisax/l3dss1.c
--- v2.4.10/linux/drivers/isdn/hisax/l3dss1.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/l3dss1.c	Sun Sep 30 12:26:05 2001
@@ -1,13 +1,18 @@
-/* $Id: l3dss1.c,v 2.30.6.1 2001/02/16 16:43:27 kai Exp $
+/* $Id: l3dss1.c,v 2.30.6.2 2001/09/23 22:24:49 kai Exp $
  *
  * EURO/DSS1 D-channel protocol
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * German 1TR6 D-channel protocol
+ *
+ * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
@@ -22,7 +27,7 @@
 #include <linux/config.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.30.6.1 $";
+const char *dss1_revision = "$Revision: 2.30.6.2 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -44,7 +49,7 @@
 static unsigned char new_invoke_id(struct PStack *p)
 {
 	unsigned char retval;
-	long flags;
+	unsigned long flags;
 	int i;
   
 	i = 32; /* maximum search depth */
@@ -73,7 +78,7 @@
 /* free a used invoke id */
 /*************************/
 static void free_invoke_id(struct PStack *p, unsigned char id)
-{ long flags;
+{ unsigned long flags;
 
   if (!id) return; /* 0 = invalid value */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/l3dss1.h linux/drivers/isdn/hisax/l3dss1.h
--- v2.4.10/linux/drivers/isdn/hisax/l3dss1.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3dss1.h	Sun Sep 30 12:26:05 2001
@@ -1,8 +1,9 @@
-/* $Id: l3dss1.h,v 1.10.6.1 2001/02/16 16:43:28 kai Exp $
+/* $Id: l3dss1.h,v 1.10.6.2 2001/09/23 22:24:50 kai Exp $
  *
- *  DSS1 (Euro) D-channel protocol defines
+ * DSS1 (Euro) D-channel protocol defines
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/l3ni1.c linux/drivers/isdn/hisax/l3ni1.c
--- v2.4.10/linux/drivers/isdn/hisax/l3ni1.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/l3ni1.c	Sun Sep 30 12:26:05 2001
@@ -1,24 +1,23 @@
-// $Id: l3ni1.c,v 2.5.6.2 2001/02/16 16:43:28 kai Exp $
-//
-//-----------------------------------------------------------------------------
-//
-// NI1 D-channel protocol
-//
-// Authors:
-// Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd
-// www.traverse.com.au
-//
-// 2000.6.6 Initial implementation of routines for US NI1 
-// Layer 3 protocol based on the EURO/DSS1 D-channel protocol 
-// driver written by Karsten Keil et al.  
-// NI-1 Hall of Fame - Thanks to.... 
-// Ragnar Paulson - for some handy code fragments
-// Will Scales - beta tester extraordinaire
-// Brett Whittacre - beta tester and remote devel system in Vegas
-//
-// This file is (c) under GNU General Public License
-//
-//-----------------------------------------------------------------------------
+/* $Id: l3ni1.c,v 2.5.6.3 2001/09/23 22:24:50 kai Exp $
+ *
+ * NI1 D-channel protocol
+ *
+ * Author       Matt Henderson & Guy Ellis
+ * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * 2000.6.6 Initial implementation of routines for US NI1 
+ * Layer 3 protocol based on the EURO/DSS1 D-channel protocol 
+ * driver written by Karsten Keil et al.  
+ * NI-1 Hall of Fame - Thanks to.... 
+ * Ragnar Paulson - for some handy code fragments
+ * Will Scales - beta tester extraordinaire
+ * Brett Whittacre - beta tester and remote devel system in Vegas
+ *
+ */
+
 #define __NO_VERSION__
 #include "hisax.h"
 #include "isdnl3.h"
@@ -26,7 +25,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *ni1_revision = "$Revision: 2.5.6.2 $";
+const char *ni1_revision = "$Revision: 2.5.6.3 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -48,7 +47,7 @@
 static unsigned char new_invoke_id(struct PStack *p)
 {
 	unsigned char retval;
-	long flags;
+	unsigned long flags;
 	int i;
   
 	i = 32; /* maximum search depth */
@@ -77,7 +76,7 @@
 /* free a used invoke id */
 /*************************/
 static void free_invoke_id(struct PStack *p, unsigned char id)
-{ long flags;
+{ unsigned long flags;
 
   if (!id) return; /* 0 = invalid value */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/l3ni1.h linux/drivers/isdn/hisax/l3ni1.h
--- v2.4.10/linux/drivers/isdn/hisax/l3ni1.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3ni1.h	Sun Sep 30 12:26:05 2001
@@ -1,20 +1,19 @@
-// $Id: l3ni1.h,v 2.3.6.1 2001/02/16 16:43:28 kai Exp $
-//-----------------------------------------------------------------------------
-//
-// NI1 D-channel protocol
-//
-// Author       Matt Henderson & Guy Ellis - Traverse Tecnologies Pty Ltd
-//              www.traverse.com.au
-//
-// 2000.6.6 Initial implementation of routines for US NI1 
-// Layer 3 protocol based on the EURO/DSS1 D-channel protocol 
-// driver written by Karsten Keil et al.  Thanks also for the 
-// code provided by Ragnar Paulson.
-//
-//
-// This file is (c) under GNU General Public License
-//
-//-----------------------------------------------------------------------------
+/* $Id: l3ni1.h,v 2.3.6.2 2001/09/23 22:24:50 kai Exp $
+ *
+ * NI1 D-channel protocol
+ *
+ * Author       Matt Henderson & Guy Ellis
+ * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * 2000.6.6 Initial implementation of routines for US NI1 
+ * Layer 3 protocol based on the EURO/DSS1 D-channel protocol 
+ * driver written by Karsten Keil et al.  Thanks also for the 
+ * code provided by Ragnar Paulson.
+ *
+ */
 
 #ifndef l3ni1_process
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/lmgr.c linux/drivers/isdn/hisax/lmgr.c
--- v2.4.10/linux/drivers/isdn/hisax/lmgr.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/lmgr.c	Sun Sep 30 12:26:05 2001
@@ -1,10 +1,12 @@
-/* $Id: lmgr.c,v 1.7.6.1 2001/02/16 16:43:28 kai Exp $
+/* $Id: lmgr.c,v 1.7.6.2 2001/09/23 22:24:50 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Layermanagement module
  *
- *  Layermanagement module
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/mic.c linux/drivers/isdn/hisax/mic.c
--- v2.4.10/linux/drivers/isdn/hisax/mic.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/mic.c	Sun Sep 30 12:26:05 2001
@@ -1,12 +1,12 @@
-/* $Id: mic.c,v 1.10.6.1 2001/02/16 16:43:28 kai Exp $
+/* $Id: mic.c,v 1.10.6.2 2001/09/23 22:24:50 kai Exp $
  *
- * mic.c  low level stuff for mic cards
+ * low level stuff for mic cards
  *
- * Copyright (C) 1997 
- *
- * Author  Stephan von Krawczynski <skraw@ithnet.com>
- *
- * This file is (c) under GNU General Public License
+ * Author       Stephan von Krawczynski
+ * Copyright    by Stephan von Krawczynski <skraw@ithnet.com>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -19,7 +19,7 @@
 
 extern const char *CardType[];
 
-const char *mic_revision = "$Revision: 1.10.6.1 $";
+const char *mic_revision = "$Revision: 1.10.6.2 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c
--- v2.4.10/linux/drivers/isdn/hisax/netjet.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/netjet.c	Sun Sep 30 12:26:06 2001
@@ -1,12 +1,14 @@
-/* $Id: netjet.c,v 1.24.6.5 2001/06/09 15:14:18 kai Exp $
+/* $Id: netjet.c,v 1.24.6.6 2001/09/23 22:24:50 kai Exp $
  *
- * netjet.c     low level stuff for Traverse Technologie NETJet ISDN cards
+ * low level stuff for Traverse Technologie NETJet ISDN cards
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * Thanks to Traverse Technologie Australia for documents and informations
- *
- * This file is (c) under GNU General Public License
+ * Thanks to Traverse Technologie Australia for documents and information
  *
  */
 
@@ -22,7 +24,7 @@
 #include <asm/io.h>
 #include "netjet.h"
 
-const char *NETjet_revision = "$Revision: 1.24.6.5 $";
+const char *NETjet_revision = "$Revision: 1.24.6.6 $";
 
 /* Interface functions */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/netjet.h linux/drivers/isdn/hisax/netjet.h
--- v2.4.10/linux/drivers/isdn/hisax/netjet.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/netjet.h	Sun Sep 30 12:26:06 2001
@@ -1,14 +1,16 @@
-// $Id: netjet.h,v 2.5.6.2 2001/02/16 16:43:28 kai Exp $
-//-----------------------------------------------------------------------------
-//
-// NETjet common header file
-//
-// Author       Kerstern Keil repackaged by
-//              Matt Henderson - Traverse Technologies P/L www.traverse.com.au
-//
-// This file is (c) under GNU General Public License
-//
-//-----------------------------------------------------------------------------
+/* $Id: netjet.h,v 2.5.6.3 2001/09/23 22:24:50 kai Exp $
+ *
+ * NETjet common header file
+ *
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ *              by Matt Henderson,
+ *                 Traverse Technologies P/L www.traverse.com.au
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
 
 extern const char *CardType[];
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/niccy.c linux/drivers/isdn/hisax/niccy.c
--- v2.4.10/linux/drivers/isdn/hisax/niccy.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/niccy.c	Sun Sep 30 12:26:06 2001
@@ -1,13 +1,15 @@
-/* $Id: niccy.c,v 1.15.6.4 2001/02/16 16:43:28 kai Exp $
+/* $Id: niccy.c,v 1.15.6.5 2001/09/23 22:24:50 kai Exp $
  *
- * niccy.c  low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and
- *          compatible (SAGEM cybermodem)
+ * low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and
+ * compatible (SAGEM cybermodem)
  *
- * Author   Karsten Keil
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  * 
- * Thanks to Dr. Neuhaus and SAGEM for informations
- *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ * 
+ * Thanks to Dr. Neuhaus and SAGEM for information
  *
  */
 
@@ -22,7 +24,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *niccy_revision = "$Revision: 1.15.6.4 $";
+const char *niccy_revision = "$Revision: 1.15.6.5 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/nj_s.c linux/drivers/isdn/hisax/nj_s.c
--- v2.4.10/linux/drivers/isdn/hisax/nj_s.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/nj_s.c	Sun Sep 30 12:26:06 2001
@@ -1,7 +1,9 @@
-// $Id: nj_s.c,v 2.7.6.5 2001/07/18 16:25:12 kai Exp $
-//
-// This file is (c) under GNU General Public License
-//
+/* $Id: nj_s.c,v 2.7.6.6 2001/09/23 22:24:50 kai Exp $
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
 
 #define __NO_VERSION__
 #include <linux/config.h>
@@ -14,7 +16,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_S_revision = "$Revision: 2.7.6.5 $";
+const char *NETjet_S_revision = "$Revision: 2.7.6.6 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/nj_u.c linux/drivers/isdn/hisax/nj_u.c
--- v2.4.10/linux/drivers/isdn/hisax/nj_u.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/nj_u.c	Sun Sep 30 12:26:06 2001
@@ -1,6 +1,7 @@
-/* $Id: nj_u.c,v 2.8.6.5 2001/07/18 16:25:12 kai Exp $ 
+/* $Id: nj_u.c,v 2.8.6.6 2001/09/23 22:24:50 kai Exp $ 
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -15,7 +16,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_U_revision = "$Revision: 2.8.6.5 $";
+const char *NETjet_U_revision = "$Revision: 2.8.6.6 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/q931.c linux/drivers/isdn/hisax/q931.c
--- v2.4.10/linux/drivers/isdn/hisax/q931.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hisax/q931.c	Sun Sep 30 12:26:06 2001
@@ -1,17 +1,17 @@
-/* $Id: q931.c,v 1.10.6.2 2001/03/13 16:17:08 kai Exp $
+/* $Id: q931.c,v 1.10.6.3 2001/09/23 22:24:50 kai Exp $
  *
- * q931.c       code to decode ITU Q.931 call control messages
+ * code to decode ITU Q.931 call control messages
  *
  * Author       Jan den Ouden
+ * Copyright    by Jan den Ouden
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * Changelog
+ * Changelog:
  *
  * Pauline Middelink    general improvements
- *
  * Beat Doebeli         cause texts, display information element
- *
  * Karsten Keil         cause texts, display information element for 1TR6
  *
  */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/rawhdlc.c linux/drivers/isdn/hisax/rawhdlc.c
--- v2.4.10/linux/drivers/isdn/hisax/rawhdlc.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/rawhdlc.c	Sun Sep 30 12:26:06 2001
@@ -1,11 +1,14 @@
-/* $Id: rawhdlc.c,v 1.5.6.1 2001/02/16 16:43:28 kai Exp $
+/* $Id: rawhdlc.c,v 1.5.6.2 2001/09/23 22:24:51 kai Exp $
  *
- * rawhdlc.c     support routines for cards that don't support HDLC
+ * support routines for cards that don't support HDLC
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
- *            Brent Baccala <baccala@FreeSoft.org>
+ * Author     Brent Baccala
+ * Copyright  by Karsten Keil <keil@isdn4linux.de>
+ *            by Brent Baccala <baccala@FreeSoft.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This file is (c) under GNU General Public License
  *
  * Some passive ISDN cards, such as the Traverse NETJet and the AMD 7930,
  * don't perform HDLC encapsulation over the B channel.  Drivers for
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/rawhdlc.h linux/drivers/isdn/hisax/rawhdlc.h
--- v2.4.10/linux/drivers/isdn/hisax/rawhdlc.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/rawhdlc.h	Sun Sep 30 12:26:06 2001
@@ -1,10 +1,10 @@
-/* $Id: rawhdlc.h,v 1.3.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: rawhdlc.h,v 1.3.6.2 2001/09/23 22:24:51 kai Exp $
  *
- * rawhdlc.h     support routines for cards that don't support HDLC
+ * Author     Brent Baccala
+ * Copyright  by Brent Baccala <baccala@FreeSoft.org>
  *
- * Author     Brent Baccala <baccala@FreeSoft.org>
- *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/s0box.c linux/drivers/isdn/hisax/s0box.c
--- v2.4.10/linux/drivers/isdn/hisax/s0box.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/s0box.c	Sun Sep 30 12:26:06 2001
@@ -1,12 +1,15 @@
-/* $Id: s0box.c,v 2.4.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: s0box.c,v 2.4.6.2 2001/09/23 22:24:51 kai Exp $
  *
- * s0box.c      low level stuff for Creatix S0BOX
+ * low level stuff for Creatix S0BOX
  *
- * Author       S0BOX specific stuff: Enrik Berkhan (enrik@starfleet.inka.de)
+ * Author       Enrik Berkhan
+ * Copyright    by Enrik Berkhan <enrik@starfleet.inka.de>
  *
- * This file is (c) under GNU General Public License
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
@@ -15,7 +18,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *s0box_revision = "$Revision: 2.4.6.1 $";
+const char *s0box_revision = "$Revision: 2.4.6.2 $";
 
 static inline void
 writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/saphir.c linux/drivers/isdn/hisax/saphir.c
--- v2.4.10/linux/drivers/isdn/hisax/saphir.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/saphir.c	Sun Sep 30 12:26:06 2001
@@ -1,16 +1,17 @@
-/* $Id: saphir.c,v 1.8.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: saphir.c,v 1.8.6.2 2001/09/23 22:24:51 kai Exp $
  *
- * saphir.c low level stuff for HST Saphir 1
+ * low level stuff for HST Saphir 1
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * Thanks to    HST High Soft Tech GmbH
  *
- * This file is (c) under GNU General Public License
- *
  */
 
-
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
@@ -19,7 +20,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-static char *saphir_rev = "$Revision: 1.8.6.1 $";
+static char *saphir_rev = "$Revision: 1.8.6.2 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/sedlbauer.c linux/drivers/isdn/hisax/sedlbauer.c
--- v2.4.10/linux/drivers/isdn/hisax/sedlbauer.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hisax/sedlbauer.c	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,22 @@
-/* $Id: sedlbauer.c,v 1.25.6.5 2001/07/13 09:20:12 kai Exp $
+/* $Id: sedlbauer.c,v 1.25.6.6 2001/09/23 22:24:51 kai Exp $
  *
- * sedlbauer.c  low level stuff for Sedlbauer cards
- *              includes support for the Sedlbauer speed star (speed star II),
- *              support for the Sedlbauer speed fax+,
- *              support for the Sedlbauer ISDN-Controller PC/104 and
- *              support for the Sedlbauer speed pci
- *              derived from the original file asuscom.c from Karsten Keil
- *
- * Copyright (C) 1997,1998 Marcus Niemann (for the modifications to
- *                                         the original file asuscom.c)
- *
- * Author     Marcus Niemann (niemann@www-bib.fh-bielefeld.de)
+ * low level stuff for Sedlbauer cards
+ * includes support for the Sedlbauer speed star (speed star II),
+ * support for the Sedlbauer speed fax+,
+ * support for the Sedlbauer ISDN-Controller PC/104 and
+ * support for the Sedlbauer speed pci
+ * derived from the original file asuscom.c from Karsten Keil
+ *
+ * Author       Marcus Niemann
+ * Copyright    by Marcus Niemann    <niemann@www-bib.fh-bielefeld.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * Thanks to  Karsten Keil
  *            Sedlbauer AG for informations
  *            Edgar Toernig
  *
- * This file is (c) under GNU General Public License
- *
  */
 
 /* Supported cards:
@@ -52,7 +51,7 @@
 
 extern const char *CardType[];
 
-const char *Sedlbauer_revision = "$Revision: 1.25.6.5 $";
+const char *Sedlbauer_revision = "$Revision: 1.25.6.6 $";
 
 const char *Sedlbauer_Types[] =
 	{"None", "speed card/win", "speed star", "speed fax+",
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/sedlbauer_cs.c linux/drivers/isdn/hisax/sedlbauer_cs.c
--- v2.4.10/linux/drivers/isdn/hisax/sedlbauer_cs.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/hisax/sedlbauer_cs.c	Sun Sep 30 12:26:06 2001
@@ -5,8 +5,6 @@
     This driver is for the Sedlbauer Speed Star and Speed Star II, 
     which are ISDN PCMCIA Cards.
     
-    sedlbauer_cs.c 1.1a 2001/01/28 15:04:04
-
     The contents of this file are subject to the Mozilla Public
     License Version 1.1 (the "License"); you may not use this file
     except in compliance with the License. You may obtain a copy of
@@ -56,6 +54,10 @@
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 #include <pcmcia/bus_ops.h>
+
+MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
+MODULE_AUTHOR("Marcus Niemann");
+MODULE_LICENSE("Dual MPL/GPL");
 
 /*
    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/sportster.c linux/drivers/isdn/hisax/sportster.c
--- v2.4.10/linux/drivers/isdn/hisax/sportster.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/sportster.c	Sun Sep 30 12:26:06 2001
@@ -1,12 +1,15 @@
-/* $Id: sportster.c,v 1.14.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: sportster.c,v 1.14.6.2 2001/09/23 22:24:51 kai Exp $
  *
- * sportster.c     low level stuff for USR Sportster internal TA
+ * low level stuff for USR Sportster internal TA
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation
  *
- * This file is (c) under GNU General Public License
  *
  */
 #define __NO_VERSION__
@@ -17,7 +20,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *sportster_revision = "$Revision: 1.14.6.1 $";
+const char *sportster_revision = "$Revision: 1.14.6.2 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/st5481.h linux/drivers/isdn/hisax/st5481.h
--- v2.4.10/linux/drivers/isdn/hisax/st5481.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/st5481.h	Sun Sep 30 12:26:06 2001
@@ -13,6 +13,8 @@
 #ifndef _ST5481_H_
 #define _ST5481_H_
 
+#include <linux/config.h>
+
 // USB IDs, the Product Id is in the range 0x4810-0x481F
 
 #define ST_VENDOR_ID 0x0483
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/st5481_b.c linux/drivers/isdn/hisax/st5481_b.c
--- v2.4.10/linux/drivers/isdn/hisax/st5481_b.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/st5481_b.c	Sun Sep 30 12:26:06 2001
@@ -10,8 +10,6 @@
  *
  */
 
-#include <linux/version.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/slab.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/st5481_d.c linux/drivers/isdn/hisax/st5481_d.c
--- v2.4.10/linux/drivers/isdn/hisax/st5481_d.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/st5481_d.c	Sun Sep 30 12:26:06 2001
@@ -10,8 +10,6 @@
  *
  */
 
-#include <linux/version.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/slab.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/st5481_init.c linux/drivers/isdn/hisax/st5481_init.c
--- v2.4.10/linux/drivers/isdn/hisax/st5481_init.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/st5481_init.c	Sun Sep 30 12:26:06 2001
@@ -25,6 +25,7 @@
  * clean up debug
  */
 
+#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -32,8 +33,9 @@
 #include <linux/slab.h>
 #include "st5481.h"
 
-MODULE_AUTHOR("Frode Isaksen <fisaksen@bewan.com>");
-MODULE_DESCRIPTION("ST5481 USB ISDN modem driver");
+MODULE_DESCRIPTION("ISDN4Linux: driver for ST5481 USB ISDN adapter");
+MODULE_AUTHOR("Frode Isaksen");
+MODULE_LICENSE("GPL");
 
 static int protocol = 2;       /* EURO-ISDN Default */
 MODULE_PARM(protocol, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/st5481_usb.c linux/drivers/isdn/hisax/st5481_usb.c
--- v2.4.10/linux/drivers/isdn/hisax/st5481_usb.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/hisax/st5481_usb.c	Sun Sep 30 12:26:06 2001
@@ -10,8 +10,6 @@
  *
  */
 
-#include <linux/version.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/slab.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/tei.c linux/drivers/isdn/hisax/tei.c
--- v2.4.10/linux/drivers/isdn/hisax/tei.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/tei.c	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,27 @@
-/* $Id: tei.c,v 2.17.6.2 2001/05/26 15:19:57 kai Exp $
+/* $Id: tei.c,v 2.17.6.3 2001/09/23 22:24:51 kai Exp $
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *		This file is (c) under GNU General Public License
- *		For changes and modifications please read
- *		../../../Documentation/isdn/HiSax.cert
+ * For changes and modifications please read
+ * ../../../Documentation/isdn/HiSax.cert
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
  *
  */
+
 #define __NO_VERSION__
 #include "hisax.h"
 #include "isdnl2.h"
 #include <linux/init.h>
 #include <linux/random.h>
 
-const char *tei_revision = "$Revision: 2.17.6.2 $";
+const char *tei_revision = "$Revision: 2.17.6.3 $";
 
 #define ID_REQUEST	1
 #define ID_ASSIGNED	2
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/teleint.c linux/drivers/isdn/hisax/teleint.c
--- v2.4.10/linux/drivers/isdn/hisax/teleint.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/teleint.c	Sun Sep 30 12:26:06 2001
@@ -1,10 +1,12 @@
-/* $Id: teleint.c,v 1.14.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: teleint.c,v 1.14.6.2 2001/09/23 22:24:52 kai Exp $
  *
- * teleint.c     low level stuff for TeleInt isdn cards
+ * low level stuff for TeleInt isdn cards
  *
- * Author     Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -17,7 +19,7 @@
 
 extern const char *CardType[];
 
-const char *TeleInt_revision = "$Revision: 1.14.6.1 $";
+const char *TeleInt_revision = "$Revision: 1.14.6.2 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/teles0.c linux/drivers/isdn/hisax/teles0.c
--- v2.4.10/linux/drivers/isdn/hisax/teles0.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/teles0.c	Sun Sep 30 12:26:06 2001
@@ -1,17 +1,20 @@
-/* $Id: teles0.c,v 2.13.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: teles0.c,v 2.13.6.2 2001/09/23 22:24:52 kai Exp $
  *
- * teles0.c     low level stuff for Teles Memory IO isdn cards
- *              based on the teles driver from Jan den Ouden
+ * low level stuff for Teles Memory IO isdn cards
  *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ *              based on the teles driver from Jan den Ouden
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
  *              Beat Doebeli
  *
- * This file is (c) under GNU General Public License
- *
  */
+
 #define __NO_VERSION__
 #include <linux/init.h>
 #include "hisax.h"
@@ -21,7 +24,7 @@
 
 extern const char *CardType[];
 
-const char *teles0_revision = "$Revision: 2.13.6.1 $";
+const char *teles0_revision = "$Revision: 2.13.6.2 $";
 
 #define TELES_IOMEM_SIZE	0x400
 #define byteout(addr,val) outb(val,addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/teles3.c linux/drivers/isdn/hisax/teles3.c
--- v2.4.10/linux/drivers/isdn/hisax/teles3.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/teles3.c	Sun Sep 30 12:26:06 2001
@@ -1,17 +1,17 @@
-/* $Id: teles3.c,v 2.17.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: teles3.c,v 2.17.6.2 2001/09/23 22:24:52 kai Exp $
  *
- * teles3.c     low level stuff for Teles 16.3 & PNP isdn cards
+ * low level stuff for Teles 16.3 & PNP isdn cards
  *
- *              based on the teles driver from Jan den Ouden
- *
- * Author       Karsten Keil (keil@isdn4linux.de)
+ * Author       Karsten Keil
+ * Copyright    by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * Thanks to    Jan den Ouden
  *              Fritz Elfert
  *              Beat Doebeli
  *
- * This file is (c) under GNU General Public License
- *
  */
 #define __NO_VERSION__
 #include <linux/init.h>
@@ -21,7 +21,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *teles3_revision = "$Revision: 2.17.6.1 $";
+const char *teles3_revision = "$Revision: 2.17.6.2 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/telespci.c linux/drivers/isdn/hisax/telespci.c
--- v2.4.10/linux/drivers/isdn/hisax/telespci.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/telespci.c	Sun Sep 30 12:26:06 2001
@@ -1,13 +1,17 @@
-/* $Id: telespci.c,v 2.16.6.4 2001/02/16 16:43:29 kai Exp $
+/* $Id: telespci.c,v 2.16.6.5 2001/09/23 22:24:52 kai Exp $
  *
- * telespci.c     low level stuff for Teles PCI isdn cards
+ * low level stuff for Teles PCI isdn cards
  *
- * Author       Ton van Rosmalen 
- *              Karsten Keil (keil@isdn4linux.de)
- *
- * This file is (c) under GNU General Public License
+ * Author       Ton van Rosmalen
+ *              Karsten Keil
+ * Copyright    by Ton van Rosmalen
+ *              by Karsten Keil      <keil@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #define __NO_VERSION__
 #include <linux/init.h>
 #include <linux/config.h>
@@ -18,7 +22,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *telespci_revision = "$Revision: 2.16.6.4 $";
+const char *telespci_revision = "$Revision: 2.16.6.5 $";
 
 #define ZORAN_PO_RQ_PEN	0x02000000
 #define ZORAN_PO_WR	0x00800000
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/w6692.c linux/drivers/isdn/hisax/w6692.c
--- v2.4.10/linux/drivers/isdn/hisax/w6692.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hisax/w6692.c	Sun Sep 30 12:26:06 2001
@@ -1,11 +1,12 @@
-/* $Id: w6692.c,v 1.12.6.5 2001/06/09 15:14:18 kai Exp $
+/* $Id: w6692.c,v 1.12.6.6 2001/09/23 22:24:52 kai Exp $
  *
- * w6692.c   Winbond W6692 specific routines
+ * Winbond W6692 specific routines
  *
- * Author       Petr Novak <petr.novak@i.cz>
- *              (based on HiSax driver by Karsten Keil)
- *
- *              This file is (c) under GNU General Public License
+ * Author       Petr Novak
+ * Copyright    by Petr Novak        <petr.novak@i.cz>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -35,7 +36,7 @@
 
 extern const char *CardType[];
 
-const char *w6692_revision = "$Revision: 1.12.6.5 $";
+const char *w6692_revision = "$Revision: 1.12.6.6 $";
 
 #define DBUSY_TIMER_VALUE 80
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hisax/w6692.h linux/drivers/isdn/hisax/w6692.h
--- v2.4.10/linux/drivers/isdn/hisax/w6692.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/w6692.h	Sun Sep 30 12:26:06 2001
@@ -1,10 +1,12 @@
-/* $Id: w6692.h,v 1.2.6.1 2001/02/16 16:43:29 kai Exp $
+/* $Id: w6692.h,v 1.2.6.2 2001/09/23 22:24:52 kai Exp $
  *
- * w6692.h   Winbond W6692 specific defines
+ * Winbond W6692 specific defines
  *
- * Author       Petr Novak <petr.novak@i.cz>
- *
- * This file is (c) under GNU General Public License
+ * Author       Petr Novak
+ * Copyright    by Petr Novak        <petr.novak@i.cz>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/boardergo.c linux/drivers/isdn/hysdn/boardergo.c
--- v2.4.10/linux/drivers/isdn/hysdn/boardergo.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/hysdn/boardergo.c	Sun Sep 30 12:26:06 2001
@@ -1,41 +1,27 @@
-/* $Id: boardergo.c,v 1.5.6.5 2001/07/18 16:02:16 kai Exp $
-
+/* $Id: boardergo.c,v 1.5.6.6 2001/09/23 22:24:54 kai Exp $
+ *
  * Linux driver for HYSDN cards, specific routines for ergo type boards.
  *
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  * As all Linux supported cards Champ2, Ergo and Metro2/4 use the same
  * DPRAM interface and layout with only minor differences all related
  * stuff is done here, not in separate modules.
  *
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999  by Werner Cornelius (werner@titro.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 __NO_VERSION__
 #include <linux/config.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <asm/io.h>
+#include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
+#include <asm/io.h>
 
 #include "hysdn_defs.h"
 #include "boardergo.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/boardergo.h linux/drivers/isdn/hysdn/boardergo.h
--- v2.4.10/linux/drivers/isdn/hysdn/boardergo.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/hysdn/boardergo.h	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,12 @@
-/* $Id: boardergo.h,v 1.2 2000/11/13 22:51:47 kai Exp $
-
- * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..).
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+/* $Id: boardergo.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..).
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hycapi.c linux/drivers/isdn/hysdn/hycapi.c
--- v2.4.10/linux/drivers/isdn/hysdn/hycapi.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hysdn/hycapi.c	Sun Sep 30 12:26:06 2001
@@ -1,27 +1,15 @@
-/* $Id: hycapi.c,v 1.8.6.3 2001/05/26 15:19:58 kai Exp $
+/* $Id: hycapi.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
  *
  * Linux driver for HYSDN cards, CAPI2.0-Interface.
- * written by Ulrich Albrecht (u.albrecht@hypercope.de) for Hypercope GmbH
  *
+ * Author    Ulrich Albrecht <u.albrecht@hypercope.de> for Hypercope GmbH
  * Copyright 2000 by Hypercope GmbH
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/signal.h>
@@ -41,7 +29,7 @@
 #include "hysdn_defs.h"
 #include <linux/kernelcapi.h>
 
-static char hycapi_revision[]="$Revision: 1.8.6.3 $";
+static char hycapi_revision[]="$Revision: 1.8.6.4 $";
 
 unsigned int hycapi_enable = 0xffffffff; 
 MODULE_PARM(hycapi_enable, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_boot.c linux/drivers/isdn/hysdn/hysdn_boot.c
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_boot.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hysdn/hysdn_boot.c	Sun Sep 30 12:26:06 2001
@@ -1,30 +1,16 @@
-/* $Id: hysdn_boot.c,v 1.4.6.3 2001/03/13 16:17:09 kai Exp $
-
- * Linux driver for HYSDN cards, specific routines for booting and pof handling.
- *
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+/* $Id: hysdn_boot.c,v 1.4.6.4 2001/09/23 22:24:54 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * Linux driver for HYSDN cards
+ * specific routines for booting and pof handling
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-#define __NO_VERSION__
-#include <linux/module.h>
-#include <linux/version.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_defs.h linux/drivers/isdn/hysdn/hysdn_defs.h
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_defs.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_defs.h	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,13 @@
-/* $Id: hysdn_defs.h,v 1.5.6.2 2001/04/20 02:42:00 keil Exp $
-
- * Linux driver for HYSDN cards, global definitions and exported vars and functions.
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+/* $Id: hysdn_defs.h,v 1.5.6.3 2001/09/23 22:24:54 kai Exp $
  *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ * Linux driver for HYSDN cards
+ * global definitions and exported vars and functions.
  *
- * This program is free software; you can redistribute 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.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_init.c linux/drivers/isdn/hysdn/hysdn_init.c
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_init.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/hysdn/hysdn_init.c	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,12 @@
-/* $Id: hysdn_init.c,v 1.6.6.5 2001/02/16 16:43:30 kai Exp $
-
- * Linux driver for HYSDN cards, init functions.
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+/* $Id: hysdn_init.c,v 1.6.6.6 2001/09/23 22:24:54 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * Linux driver for HYSDN cards, init functions.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -32,7 +21,19 @@
 
 #include "hysdn_defs.h"
 
-static char *hysdn_init_revision = "$Revision: 1.6.6.5 $";
+static struct pci_device_id hysdn_pci_tbl[] __initdata = {
+	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO},
+	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2},
+	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO},
+	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO},
+	{ }				/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl);
+MODULE_DESCRIPTION("ISDN4Linux: Driver for HYSDN cards");
+MODULE_AUTHOR("Werner Cornelius");
+MODULE_LICENSE("GPL");
+
+static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
 int cardmax;			/* number of found cards */
 hysdn_card *card_root = NULL;	/* pointer to first card */
 
@@ -62,14 +63,6 @@
 	}			/* terminating entry */
 };
 
-static struct pci_device_id hysdn_pci_tbl[] __initdata = {
-	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO},
-	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2},
-	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO},
-	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO},
-	{ }				/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl);
 
 /*********************************************************************/
 /* search_cards searches for available cards in the pci config data. */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_net.c linux/drivers/isdn/hysdn/hysdn_net.c
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_net.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/hysdn/hysdn_net.c	Sun Sep 30 12:26:06 2001
@@ -1,28 +1,16 @@
-/* $Id: hysdn_net.c,v 1.8.6.3 2001/06/05 19:45:37 kai Exp $
-
+/* $Id: hysdn_net.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
+ *
  * Linux driver for HYSDN cards, net (ethernet type) handling routines.
  *
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * This net module has been inspired by the skeleton driver from
  * Donald Becker (becker@CESDIS.gsfc.nasa.gov)
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #define __NO_VERSION__
@@ -41,7 +29,7 @@
 MODULE_PARM(hynet_enable, "i");
 
 /* store the actual version for log reporting */
-char *hysdn_net_revision = "$Revision: 1.8.6.3 $";
+char *hysdn_net_revision = "$Revision: 1.8.6.4 $";
 
 #define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_pof.h linux/drivers/isdn/hysdn/hysdn_pof.h
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_pof.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/hysdn/hysdn_pof.h	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,12 @@
-/* $Id: hysdn_pof.h,v 1.2 2000/11/13 22:51:47 kai Exp $
-
- * Linux driver for HYSDN cards, definitions used for handling pof-files.
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+/* $Id: hysdn_pof.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * Linux driver for HYSDN cards, definitions used for handling pof-files.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_procconf.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/isdn/hysdn/hysdn_procconf.c	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,13 @@
-/* $Id: hysdn_procconf.c,v 1.8.6.3 2001/08/13 07:46:15 kai Exp $
-
+/* $Id: hysdn_procconf.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
+ *
  * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions.
+ *
  * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
  *
  * Copyright 1999  by Werner Cornelius (werner@titro.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -31,7 +21,7 @@
 
 #include "hysdn_defs.h"
 
-static char *hysdn_procconf_revision = "$Revision: 1.8.6.3 $";
+static char *hysdn_procconf_revision = "$Revision: 1.8.6.4 $";
 
 #define INFO_OUT_LEN 80		/* length of info line including lf */
 
@@ -456,4 +446,4 @@
 	}
 
 	remove_proc_entry(PROC_SUBDIR_NAME, proc_net);
-}				/* hysdn_procfs_release */
+}
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_proclog.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/isdn/hysdn/hysdn_proclog.c	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,12 @@
-/* $Id: hysdn_proclog.c,v 1.9.6.2 2001/08/13 07:46:15 kai Exp $
-
- * Linux driver for HYSDN cards, /proc/net filesystem log functions.
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+/* $Id: hysdn_proclog.c,v 1.9.6.3 2001/09/23 22:24:54 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * Linux driver for HYSDN cards, /proc/net filesystem log functions.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/hysdn_sched.c linux/drivers/isdn/hysdn/hysdn_sched.c
--- v2.4.10/linux/drivers/isdn/hysdn/hysdn_sched.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_sched.c	Sun Sep 30 12:26:06 2001
@@ -1,36 +1,23 @@
-/* $Id: hysdn_sched.c,v 1.5.6.2 2001/04/20 02:42:00 keil Exp $
-
- * Linux driver for HYSDN cards, scheduler routines for handling exchange card <-> pc.
- *
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
- *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+/* $Id: hysdn_sched.c,v 1.5.6.3 2001/09/23 22:24:54 kai Exp $
  *
- * This program is free software; you can redistribute 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.
+ * Linux driver for HYSDN cards
+ * scheduler routines for handling exchange card <-> pc.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-#define __NO_VERSION__
 #include <linux/config.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <asm/io.h>
+#include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
+#include <asm/io.h>
 
 #include "hysdn_defs.h"
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/hysdn/ince1pc.h linux/drivers/isdn/hysdn/ince1pc.h
--- v2.4.10/linux/drivers/isdn/hysdn/ince1pc.h	Mon Aug 21 07:49:03 2000
+++ linux/drivers/isdn/hysdn/ince1pc.h	Sun Sep 30 12:26:06 2001
@@ -1,17 +1,19 @@
+/*
+ * Linux driver for HYSDN cards
+ * common definitions for both sides of the bus:
+ * - conventions both spoolers must know
+ * - channel numbers agreed upon
+ *
+ * Author    M. Steinkopf
+ * Copyright 1999 by M. Steinkopf
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
 #ifndef __INCE1PC_H__
 #define __INCE1PC_H__
-
-/****************************************************************************
-
-    FILE:       ince1pc.h
-
-    AUTHOR:     M.Steinkopf
-
-    PURPOSE:    common definitions for both sides of the bus:
-		- conventions both spoolers must know
-		- channel numbers agreed upon
-
-*****************************************************************************/ 
 
 /*  basic scalar definitions have same meanning,
  *  but their declaration location depends on environment
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
--- v2.4.10/linux/drivers/isdn/icn/icn.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/icn/icn.c	Sun Sep 30 12:26:06 2001
@@ -1,28 +1,35 @@
-/* $Id: icn.c,v 1.65.6.7 2001/08/17 12:34:27 kai Exp $
-
+/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $
+ *
  * ISDN low-level module for the ICN active ISDN-Card.
  *
  * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
 #include "icn.h"
+#include <linux/module.h>
 #include <linux/init.h>
 
+static int portbase = ICN_BASEADDR;
+static unsigned long membase = ICN_MEMADDR;
+static char *icn_id = "\0";
+static char *icn_id2 = "\0";
+
+MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
+MODULE_AUTHOR("Fritz Elfert");
+MODULE_LICENSE("GPL");
+MODULE_PARM(portbase, "i");
+MODULE_PARM_DESC(portbase, "Port address of first card");
+MODULE_PARM(membase, "l");
+MODULE_PARM_DESC(membase, "Shared memory address of all cards");
+MODULE_PARM(icn_id, "s");
+MODULE_PARM_DESC(icn_id, "ID-String of first card");
+MODULE_PARM(icn_id2, "s");
+MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
+
 /*
  * Verbose bootcode- and protocol-downloading.
  */
@@ -34,7 +41,7 @@
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.65.6.7 $";
+*revision = "$Revision: 1.65.6.8 $";
 
 static int icn_addcard(int, char *, char *);
 
@@ -607,7 +614,7 @@
 	int left;
 	u_char c;
 	int ch;
-	long flags;
+	unsigned long flags;
 	int i;
 	u_char *p;
 	isdn_ctrl cmd;
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/icn/icn.h linux/drivers/isdn/icn/icn.h
--- v2.4.10/linux/drivers/isdn/icn/icn.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/icn/icn.h	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/* $Id: icn.h,v 1.30.6.4 2001/08/17 12:34:27 kai Exp $
-
+/* $Id: icn.h,v 1.30.6.5 2001/09/23 22:24:55 kai Exp $
+ *
  * ISDN lowlevel-module for the ICN active ISDN-Card.
  *
  * Copyright 1994 by Fritz Elfert (fritz@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -46,7 +35,6 @@
 #ifdef __KERNEL__
 /* Kernel includes */
 
-#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -205,27 +193,6 @@
 {0, 4, 8, 12};                  /* for icn_map_channel() */
 
 static icn_dev dev;
-
-/* With modutils >= 1.1.67 Integers can be changed while loading a
- * module. For this reason define the Port-Base an Shmem-Base as
- * integers.
- */
-static int portbase = ICN_BASEADDR;
-static unsigned long membase = ICN_MEMADDR;
-static char *icn_id = "\0";
-static char *icn_id2 = "\0";
-
-#ifdef MODULE
-MODULE_AUTHOR("Fritz Elfert");
-MODULE_PARM(portbase, "i");
-MODULE_PARM_DESC(portbase, "Port address of first card");
-MODULE_PARM(membase, "l");
-MODULE_PARM_DESC(membase, "Shared memory address of all cards");
-MODULE_PARM(icn_id, "s");
-MODULE_PARM_DESC(icn_id, "ID-String of first card");
-MODULE_PARM(icn_id2, "s");
-MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
-#endif
 
 #endif                          /* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_audio.c linux/drivers/isdn/isdn_audio.c
--- v2.4.10/linux/drivers/isdn/isdn_audio.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdn_audio.c	Sun Sep 30 12:26:06 2001
@@ -1,34 +1,21 @@
-/* $Id: isdn_audio.c,v 1.21.6.1 2001/08/17 12:34:25 kai Exp $
-
+/* $Id: isdn_audio.c,v 1.21.6.2 2001/09/23 22:24:31 kai Exp $
+ *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
  * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
  * DTMF code (c) 1996 by Christian Mock (cm@kukuruz.ping.at)
  * Silence detection (c) 1998 by Armin Schindler (mac@gismo.telekom.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-#define __NO_VERSION__
-#include <linux/module.h>
 #include <linux/isdn.h>
 #include "isdn_audio.h"
 #include "isdn_common.h"
 
-char *isdn_audio_revision = "$Revision: 1.21.6.1 $";
+char *isdn_audio_revision = "$Revision: 1.21.6.2 $";
 
 /*
  * Misc. lookup-tables.
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_audio.h linux/drivers/isdn/isdn_audio.h
--- v2.4.10/linux/drivers/isdn/isdn_audio.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_audio.h	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/* $Id: isdn_audio.h,v 1.9 2000/05/11 22:29:20 kai Exp $
-
+/* $Id: isdn_audio.h,v 1.9.6.1 2001/09/23 22:24:31 kai Exp $
+ *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
  * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_bsdcomp.c linux/drivers/isdn/isdn_bsdcomp.c
--- v2.4.10/linux/drivers/isdn/isdn_bsdcomp.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/isdn_bsdcomp.c	Sun Sep 30 12:26:06 2001
@@ -4,8 +4,14 @@
  * Patched version for ISDN syncPPP written 1997/1998 by Michael Hipp
  * The whole module is now SKB based.
  *
- * Compile with:
- *  gcc -O2 -I/usr/src/linux/include -D__KERNEL__ -DMODULE -c isdn_bsdcomp.c
+ */
+
+/*
+ * Update: The Berkeley copyright was changed, and the change 
+ * is retroactive to all "true" BSD software (ie everything
+ * from UCB as opposed to other peoples code that just carried
+ * the same license). The new copyright doesn't clash with the
+ * GPL, so the module-only restriction has been removed..
  */
 
 /*
@@ -82,13 +88,15 @@
 
 #include <linux/isdn.h>
 #include <linux/isdn_ppp.h>
-/* #include <linux/netprotocol.h> */
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/if_arp.h>
 #include <linux/ppp-comp.h>
 
 #include "isdn_ppp.h"
+
+MODULE_DESCRIPTION("ISDN4Linux: BSD Compression for PPP over ISDN");
+MODULE_LICENSE("Dual BSD/GPL");
 
 #define BSD_VERSION(x)	((x) >> 5)
 #define BSD_NBITS(x)	((x) & 0x1F)
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- v2.4.10/linux/drivers/isdn/isdn_common.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdn_common.c	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,13 @@
-/* $Id: isdn_common.c,v 1.114.6.14 2001/08/17 12:34:25 kai Exp $
-
+/* $Id: isdn_common.c,v 1.114.6.15 2001/09/23 22:24:31 kai Exp $
+ *
  * Linux ISDN subsystem, common used functions (linklevel).
  *
  * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    Thinking Objects Software GmbH Wuerzburg
  * Copyright 1995,96    by Michael Hipp (Michael.Hipp@student.uni-tuebingen.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -49,9 +38,13 @@
 /* Debugflags */
 #undef ISDN_DEBUG_STATCALLB
 
+MODULE_DESCRIPTION("ISDN4Linux: link layer");
+MODULE_AUTHOR("Fritz Elfert");
+MODULE_LICENSE("GPL");
+
 isdn_dev *dev;
 
-static char *isdn_revision = "$Revision: 1.114.6.14 $";
+static char *isdn_revision = "$Revision: 1.114.6.15 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -280,7 +273,7 @@
 	}
 	if (tf) 
 	{
-		long flags;
+		unsigned long flags;
 
 		save_flags(flags);
 		cli();
@@ -292,7 +285,7 @@
 void
 isdn_timer_ctrl(int tf, int onoff)
 {
-	long flags;
+	unsigned long flags;
 	int old_tflags;
 
 	save_flags(flags);
@@ -2397,7 +2390,7 @@
  */
 static void __exit isdn_exit(void)
 {
-	long flags;
+	unsigned long flags;
 	int i;
 
 #ifdef CONFIG_ISDN_PPP
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_common.h linux/drivers/isdn/isdn_common.h
--- v2.4.10/linux/drivers/isdn/isdn_common.h	Mon Nov 27 16:53:43 2000
+++ linux/drivers/isdn/isdn_common.h	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,14 @@
-/* $Id: isdn_common.h,v 1.21 2000/11/25 17:00:59 kai Exp $
-
- * header for Linux ISDN subsystem, common used functions and debugging-switches (linklevel).
+/* $Id: isdn_common.h,v 1.21.6.1 2001/09/23 22:24:31 kai Exp $
+ *
+ * header for Linux ISDN subsystem
+ * common used functions and debugging-switches (linklevel).
  *
  * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
  * Copyright 1995,96    by Michael Hipp (Michael.Hipp@student.uni-tuebingen.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_concap.c linux/drivers/isdn/isdn_concap.c
--- v2.4.10/linux/drivers/isdn/isdn_concap.c	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_concap.c	Sun Sep 30 12:26:06 2001
@@ -1,20 +1,9 @@
-/* $Id: isdn_concap.c,v 1.8 2000/05/11 22:29:20 kai Exp $
- 
+/* $Id: isdn_concap.c,v 1.8.6.1 2001/09/23 22:24:31 kai Exp $
+ * 
  * Linux ISDN subsystem, protocol encapsulation
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_concap.h linux/drivers/isdn/isdn_concap.h
--- v2.4.10/linux/drivers/isdn/isdn_concap.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_concap.h	Sun Sep 30 12:26:06 2001
@@ -1,20 +1,9 @@
-/* $Id: isdn_concap.h,v 1.3 2000/05/11 22:29:20 kai Exp $
+/* $Id: isdn_concap.h,v 1.3.6.1 2001/09/23 22:24:31 kai Exp $
  *
  * Linux ISDN subsystem, protocol encapsulation
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- v2.4.10/linux/drivers/isdn/isdn_net.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdn_net.c	Sun Sep 30 12:26:06 2001
@@ -1,35 +1,20 @@
-/* $Id: isdn_net.c,v 1.140.6.8 2001/08/14 14:04:21 kai Exp $
-
+/* $Id: isdn_net.c,v 1.140.6.10 2001/09/28 08:05:29 kai Exp $
+ *
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
  * Copyright 1994-1998  by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
  * Copyright 1995,96    by Michael Hipp (Michael.Hipp@student.uni-tuebingen.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* Jan 2001: fix CISCO HDLC      Bjoern A. Zeeb <i4l@zabbadoz.net>
+ * Jan 2001: fix CISCO HDLC      Bjoern A. Zeeb <i4l@zabbadoz.net>
  *           for info on the protocol, see 
  *           http://i4l.zabbadoz.net/i4l/cisco-hdlc.txt
  */
 
 #include <linux/config.h>
-#define __NO_VERSION__
-#include <linux/module.h>
 #include <linux/isdn.h>
 #include <net/arp.h>
 #include <net/dst.h>
@@ -190,7 +175,7 @@
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
 
-char *isdn_net_revision = "$Revision: 1.140.6.8 $";
+char *isdn_net_revision = "$Revision: 1.140.6.10 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -583,7 +568,7 @@
 	isdn_net_dev *p = dev->netdev;
 	int anymore = 0;
 	int i;
-	ulong flags;
+	unsigned long flags;
 	isdn_ctrl cmd;
 
 	while (p) {
@@ -1673,10 +1658,11 @@
 {
 	unsigned char *p;
 	int period;
-	__u32 code;
-	__u32 my_seq, addr;
-	__u32 your_seq, mask;
-	__u16 unused;
+	u32 code;
+	u32 my_seq, addr;
+	u32 your_seq, mask;
+	u32 local;
+	u16 unused;
 
 	if (skb->len < 14)
 		return;
@@ -1690,14 +1676,27 @@
 		isdn_net_ciscohdlck_slarp_send_reply(lp);
 		break;
 	case CISCO_SLARP_REPLY:
-		/* Ignore replies - at least for now */
-		if (lp->cisco_debserint) {
-			p += get_u32(p, &addr);
-			p += get_u32(p, &mask);
-			p += get_u16(p, &unused);
-			printk(KERN_DEBUG "%s: got slarp reply (%ul/%ul) - "
-				"ignored\n", lp->name, addr, mask);
-		}
+		addr = ntohl(*(u32 *)p);
+		mask = ntohl(*(u32 *)(p+4));
+		if (mask != 0xfffffffc)
+			goto slarp_reply_out;
+		if ((addr & 3) == 0 || (addr & 3) == 3)
+			goto slarp_reply_out;
+		local = addr ^ 3;
+		printk(KERN_INFO "%s: got slarp reply: "
+			"remote ip: %d.%d.%d.%d, "
+			"local ip: %d.%d.%d.%d "
+			"mask: %d.%d.%d.%d\n",
+		       lp->name,
+		       HIPQUAD(addr),
+		       HIPQUAD(local),
+		       HIPQUAD(mask));
+		break;
+  slarp_reply_out:
+		 printk(KERN_INFO "%s: got invalid slarp "
+				 "reply (%d.%d.%d.%d/%d.%d.%d.%d) "
+				 "- ignored\n", lp->name,
+				 HIPQUAD(addr), HIPQUAD(mask));
 		break;
 	case CISCO_SLARP_KEEPALIVE:
 		period = (int)((jiffies - lp->cisco_last_slarp_in
@@ -1723,9 +1722,9 @@
 isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
 {
 	unsigned char *p;
-	__u8 addr;
-	__u8 ctrl;
-	__u16 type;
+ 	u8 addr;
+ 	u8 ctrl;
+ 	u16 type;
 	
 	if (skb->len < 4)
 		goto out_free;
@@ -2792,7 +2791,7 @@
 			chidx = lp->pre_channel;
 		}
 		if (cfg->exclusive > 0) {
-			ulong flags;
+			unsigned long flags;
 
 			/* If binding is exclusive, try to grab the channel */
 			save_flags(flags);
@@ -3048,7 +3047,7 @@
 	int inout = phone->outgoing & 1;
 	isdn_net_phone *n;
 	isdn_net_phone *m;
-	ulong flags;
+	unsigned long flags;
 
 	if (p) {
 		save_flags(flags);
@@ -3084,7 +3083,7 @@
 {
 	isdn_net_phone *n;
 	isdn_net_phone *m;
-	ulong flags;
+	unsigned long flags;
 	int i;
 
 	save_flags(flags);
@@ -3133,7 +3132,7 @@
 static int
 isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
 {
-	ulong flags;
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
@@ -3219,7 +3218,7 @@
 int
 isdn_net_rmall(void)
 {
-	ulong flags;
+	unsigned long flags;
 	int ret;
 
 	/* Walk through netdev-chain */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h
--- v2.4.10/linux/drivers/isdn/isdn_net.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdn_net.h	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,13 @@
-/* $Id: isdn_net.h,v 1.19.6.2 2001/08/14 14:04:21 kai Exp $
-
+/* $Id: isdn_net.h,v 1.19.6.4 2001/09/28 08:05:29 kai Exp $
+ *
  * header for Linux ISDN subsystem, network related functions (linklevel).
  *
  * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
  * Copyright 1995,96    by Michael Hipp (Michael.Hipp@student.uni-tuebingen.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -39,8 +28,8 @@
 #define CISCO_TYPE_CDP        0x2000
 #define CISCO_TYPE_INET       0x0800
 #define CISCO_TYPE_SLARP      0x8035
-#define CISCO_SLARP_REPLY     0
-#define CISCO_SLARP_REQUEST   1
+#define CISCO_SLARP_REQUEST   0
+#define CISCO_SLARP_REPLY     1
 #define CISCO_SLARP_KEEPALIVE 2
 
 extern char *isdn_net_new(char *, struct net_device *);
@@ -147,48 +136,44 @@
 }
 
 static inline int
-put_u8(unsigned char *p, __u8 x)
+put_u8(unsigned char *p, u8 x)
 {
-	p[0] = x;
+	*p = x;
 	return 1;
 }
 
 static inline int
-put_u16(unsigned char *p, __u16 x)
+put_u16(unsigned char *p, u16 x)
 {
-	p[0] = x >> 8;
-	p[1] = x;
+	*((u16 *)p) = htons(x);
 	return 2;
 }
 
 static inline int
-put_u32(unsigned char *p, __u32 x)
+put_u32(unsigned char *p, u32 x)
 {
-	p[0] = x >> 24;
-	p[1] = x >> 16;
-	p[2] = x >> 8;
-	p[3] = x;
+	*((u32 *)p) = htonl(x);
 	return 4;
 }
 
 static inline int
-get_u8(unsigned char *p, __u8 *x)
+get_u8(unsigned char *p, u8 *x)
 {
-	*x = p[0];
+	*x = *p;
 	return 1;
 }
 
 static inline int
-get_u16(unsigned char *p, __u16 *x)
+get_u16(unsigned char *p, u16 *x)
 {
-	*x = (p[0] << 8) + p[1];
+	*x = ntohs(*((u16 *)p));
 	return 2;
 }
 
 static inline int
-get_u32(unsigned char *p, __u32 *x)
+get_u32(unsigned char *p, u32 *x)
 {
-	*x = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
+	*x = ntohl(*((u32 *)p));
 	return 4;
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- v2.4.10/linux/drivers/isdn/isdn_ppp.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/isdn/isdn_ppp.c	Sun Sep 30 12:26:06 2001
@@ -1,31 +1,17 @@
-/* $Id: isdn_ppp.c,v 1.85.6.6 2001/07/27 09:08:27 kai Exp $
+/* $Id: isdn_ppp.c,v 1.85.6.7 2001/09/23 22:24:31 kai Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
  * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
 #include <linux/config.h>
-#define __NO_VERSION__
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/poll.h>
 #include <linux/isdn.h>
+#include <linux/poll.h>
 #include <linux/ppp-comp.h>
 
 #include "isdn_common.h"
@@ -83,7 +69,7 @@
 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
 #endif	/* CONFIG_ISDN_MPP */
   
-char *isdn_ppp_revision = "$Revision: 1.85.6.6 $";
+char *isdn_ppp_revision = "$Revision: 1.85.6.7 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_ppp.h linux/drivers/isdn/isdn_ppp.h
--- v2.4.10/linux/drivers/isdn/isdn_ppp.h	Mon Dec 11 13:21:44 2000
+++ linux/drivers/isdn/isdn_ppp.h	Sun Sep 30 12:26:06 2001
@@ -1,27 +1,17 @@
-/* $Id: isdn_ppp.h,v 1.17 2000/08/10 22:52:46 kai Exp $
-
+/* $Id: isdn_ppp.h,v 1.17.6.1 2001/09/23 22:24:32 kai Exp $
+ *
  * header for Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
  * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
 #include <linux/ppp_defs.h>     /* for PPP_PROTOCOL */
 #include <linux/isdn_ppp.h>	/* for isdn_ppp info */
+
 extern int isdn_ppp_read(int, struct file *, char *, int);
 extern int isdn_ppp_write(int, struct file *, const char *, int);
 extern int isdn_ppp_open(int, struct file *);
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c
--- v2.4.10/linux/drivers/isdn/isdn_tty.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdn_tty.c	Sun Sep 30 12:26:06 2001
@@ -1,30 +1,17 @@
-/* $Id: isdn_tty.c,v 1.94.6.7 2001/08/27 22:19:04 kai Exp $
-
+/* $Id: isdn_tty.c,v 1.94.6.8 2001/09/23 22:24:32 kai Exp $
+ *
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
  * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 #undef ISDN_TTY_STAT_DEBUG
 
-#define __NO_VERSION__
 #include <linux/config.h>
-#include <linux/module.h>
 #include <linux/isdn.h>
 #include "isdn_common.h"
 #include "isdn_tty.h"
@@ -66,7 +53,7 @@
 static int si2bit[8] =
 {4, 1, 4, 4, 4, 4, 4, 4};
 
-char *isdn_tty_revision = "$Revision: 1.94.6.7 $";
+char *isdn_tty_revision = "$Revision: 1.94.6.8 $";
 
 
 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_tty.h linux/drivers/isdn/isdn_tty.h
--- v2.4.10/linux/drivers/isdn/isdn_tty.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdn_tty.h	Sun Sep 30 12:26:06 2001
@@ -1,23 +1,12 @@
-/* $Id: isdn_tty.h,v 1.22.6.1 2001/08/14 14:12:18 kai Exp $
-
+/* $Id: isdn_tty.h,v 1.22.6.2 2001/09/23 22:24:32 kai Exp $
+ *
  * header for Linux ISDN subsystem, tty related functions (linklevel).
  *
  * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_ttyfax.c linux/drivers/isdn/isdn_ttyfax.c
--- v2.4.10/linux/drivers/isdn/isdn_ttyfax.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdn_ttyfax.c	Sun Sep 30 12:26:06 2001
@@ -1,39 +1,26 @@
-/* $Id: isdn_ttyfax.c,v 1.7.6.1 2001/08/14 14:12:18 kai Exp $
-
+/* $Id: isdn_ttyfax.c,v 1.7.6.2 2001/09/23 22:24:32 kai Exp $
+ *
  * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel).
  *
  * Copyright 1999    by Armin Schindler (mac@melware.de)
  * Copyright 1999    by Ralf Spachmann (mel@melware.de)
  * Copyright 1999    by Cytronics & Melware
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
 #undef ISDN_TTY_FAX_STAT_DEBUG
 #undef ISDN_TTY_FAX_CMD_DEBUG
 
-#define __NO_VERSION__
-#include <linux/module.h>
 #include <linux/isdn.h>
 #include "isdn_common.h"
 #include "isdn_tty.h"
 #include "isdn_ttyfax.h"
 
 
-static char *isdn_tty_fax_revision = "$Revision: 1.7.6.1 $";
+static char *isdn_tty_fax_revision = "$Revision: 1.7.6.2 $";
 
 #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_ttyfax.h linux/drivers/isdn/isdn_ttyfax.h
--- v2.4.10/linux/drivers/isdn/isdn_ttyfax.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_ttyfax.h	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,13 @@
-/* $Id: isdn_ttyfax.h,v 1.2 2000/05/11 22:29:21 kai Exp $
-
+/* $Id: isdn_ttyfax.h,v 1.2.6.1 2001/09/23 22:24:32 kai Exp $
+ *
  * header for Linux ISDN subsystem, tty_fax related functions (linklevel).
  *
  * Copyright 1999   by Armin Schindler (mac@melware.de)
  * Copyright 1999   by Ralf Spachmann (mel@melware.de)
  * Copyright 1999   by Cytronics & Melware
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_v110.c linux/drivers/isdn/isdn_v110.c
--- v2.4.10/linux/drivers/isdn/isdn_v110.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/isdn_v110.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/* $Id: isdn_v110.c,v 1.5.6.3 2001/02/16 16:43:23 kai Exp $
-
+/* $Id: isdn_v110.c,v 1.5.6.4 2001/09/23 22:24:32 kai Exp $
+ *
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
  * Copyright by Thomas Pfeiffer (pfeiffer@pds.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -30,7 +19,7 @@
 
 #undef ISDN_V110_DEBUG
 
-char *isdn_v110_revision = "$Revision: 1.5.6.3 $";
+char *isdn_v110_revision = "$Revision: 1.5.6.4 $";
 
 #define V110_38400 255
 #define V110_19200  15
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_v110.h linux/drivers/isdn/isdn_v110.h
--- v2.4.10/linux/drivers/isdn/isdn_v110.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_v110.h	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,14 @@
-/* $Id: isdn_v110.h,v 1.4 2000/05/11 22:29:21 kai Exp $
-
+/* $Id: isdn_v110.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $
+ *
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
  * Copyright by Thomas Pfeiffer (pfeiffer@pds.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
+
 #ifndef _isdn_v110_h_
 #define _isdn_v110_h_
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_x25iface.c linux/drivers/isdn/isdn_x25iface.c
--- v2.4.10/linux/drivers/isdn/isdn_x25iface.c	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_x25iface.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,9 @@
-/* $Id: isdn_x25iface.c,v 1.9 2000/05/16 20:52:10 keil Exp $
-
+/* $Id: isdn_x25iface.c,v 1.9.6.1 2001/09/23 22:24:32 kai Exp $
  *
  * Linux ISDN subsystem, X.25 related functions
  *
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  * stuff needed to support the Linux X.25 PLP code on top of devices that
  * can provide a lab_b service using the concap_proto mechanism.
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdn_x25iface.h linux/drivers/isdn/isdn_x25iface.h
--- v2.4.10/linux/drivers/isdn/isdn_x25iface.h	Mon Dec 11 13:21:52 2000
+++ linux/drivers/isdn/isdn_x25iface.h	Sun Sep 30 12:26:06 2001
@@ -1,20 +1,9 @@
-/* $Id: isdn_x25iface.h,v 1.3 2000/05/11 22:29:21 kai Exp $
-
- * header for Linux ISDN subsystem, x.25 related functions
- *
- * This program is free software; you can redistribute 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.
+/* $Id: isdn_x25iface.h,v 1.3.6.1 2001/09/23 22:24:32 kai Exp $
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * header for Linux ISDN subsystem, x.25 related functions
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdnloop/isdnloop.c linux/drivers/isdn/isdnloop/isdnloop.c
--- v2.4.10/linux/drivers/isdn/isdnloop/isdnloop.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/* $Id: isdnloop.c,v 1.11.6.5 2001/08/17 12:34:27 kai Exp $
-
+/* $Id: isdnloop.c,v 1.11.6.6 2001/09/23 22:24:56 kai Exp $
+ *
  * ISDN low-level module implementing a dummy loop driver.
  *
  * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -25,8 +14,14 @@
 #include <linux/init.h>
 #include "isdnloop.h"
 
-static char
-*revision = "$Revision: 1.11.6.5 $";
+static char *revision = "$Revision: 1.11.6.6 $";
+static char *isdnloop_id;
+
+MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card");
+MODULE_AUTHOR("Fritz Elfert");
+MODULE_LICENSE("GPL");
+MODULE_PARM(isdnloop_id, "s");
+MODULE_PARM_DESC(isdnloop_id, "ID-String of first card");
 
 static int isdnloop_addcard(char *);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/isdnloop/isdnloop.h linux/drivers/isdn/isdnloop/isdnloop.h
--- v2.4.10/linux/drivers/isdn/isdnloop/isdnloop.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.h	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/* $Id: isdnloop.h,v 1.5.6.2 2001/08/17 12:34:27 kai Exp $
-
+/* $Id: isdnloop.h,v 1.5.6.3 2001/09/23 22:24:56 kai Exp $
+ *
  * Loopback lowlevel module for testing of linklevel.
  *
  * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
@@ -44,7 +33,6 @@
 #ifdef __KERNEL__
 /* Kernel includes */
 
-#include <linux/module.h>
 #include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -115,14 +103,6 @@
  */
 #ifdef __KERNEL__
 static isdnloop_card *cards = (isdnloop_card *) 0;
-static char *isdnloop_id = "\0";
-
-#ifdef MODULE
-MODULE_AUTHOR("Fritz Elfert");
-MODULE_PARM(isdnloop_id, "s");
-MODULE_PARM_DESC(isdnloop_id, "ID-String of first card");
-#endif
-
 #endif                          /* __KERNEL__ */
 
 /* Utility-Macros */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/callbacks.c linux/drivers/isdn/pcbit/callbacks.c
--- v2.4.10/linux/drivers/isdn/pcbit/callbacks.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/callbacks.c	Sun Sep 30 12:26:06 2001
@@ -1,4 +1,6 @@
 /*
+ * Callbacks for the FSM
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
@@ -7,20 +9,11 @@
  * the GNU General Public License, incorporated herein by reference.
  */
 
-/*        
- *        callbacks for the FSM
- */
-
 /*
  * Fix: 19981230 - Carlos Morgado <chbm@techie.com>
  * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN 
  * NULL pointer dereference in cb_in_1 (originally fixed in 2.0)
  */
-
-
-#define __NO_VERSION__
-
-#include <linux/module.h>
 
 #include <linux/sched.h>
 #include <linux/string.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/callbacks.h linux/drivers/isdn/pcbit/callbacks.h
--- v2.4.10/linux/drivers/isdn/pcbit/callbacks.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/callbacks.h	Sun Sep 30 12:26:06 2001
@@ -1,15 +1,12 @@
 /*
+ * Callbacks prototypes for FSM
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
- */
-
-/*
- *        Callbacks prototypes for FSM
- *
  */
 
 #ifndef CALLBACKS_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/capi.c linux/drivers/isdn/pcbit/capi.c
--- v2.4.10/linux/drivers/isdn/pcbit/capi.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/capi.c	Sun Sep 30 12:26:06 2001
@@ -1,17 +1,16 @@
 /*
+ * CAPI encoder/decoder for
+ * Portugal Telecom CAPI 2.0
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
- */
-
-/*        
- *        CAPI encoder/decoder for
- *        Portugal Telecom CAPI 2.0
  *
- *        Not compatible with the AVM Gmbh. CAPI 2.0
+ * Not compatible with the AVM Gmbh. CAPI 2.0
+ *
  */
 
 /*
@@ -27,10 +26,6 @@
  *              for debug purposes mainly
  *              encode our number in CallerPN and ConnectedPN
  */
-
-#define __NO_VERSION__
-
-#include <linux/module.h>
 
 #include <linux/sched.h>
 #include <linux/string.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/capi.h linux/drivers/isdn/pcbit/capi.h
--- v2.4.10/linux/drivers/isdn/pcbit/capi.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/capi.h	Sun Sep 30 12:26:06 2001
@@ -1,14 +1,12 @@
 /*
+ * CAPI encode/decode prototypes and defines
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
- */
-
-/*        
- *        CAPI encode/decode prototypes and defines
  */
 
 #ifndef CAPI_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/drv.c linux/drivers/isdn/pcbit/drv.c
--- v2.4.10/linux/drivers/isdn/pcbit/drv.c	Wed Apr 11 19:02:36 2001
+++ linux/drivers/isdn/pcbit/drv.c	Sun Sep 30 12:26:06 2001
@@ -1,14 +1,12 @@
 /*
+ * PCBIT-D interface with isdn4linux
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
- */
-
-/*        
- *        PCBIT-D interface with isdn4linux
  */
 
 /*
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/edss1.c linux/drivers/isdn/pcbit/edss1.c
--- v2.4.10/linux/drivers/isdn/pcbit/edss1.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/edss1.c	Sun Sep 30 12:26:06 2001
@@ -1,4 +1,7 @@
 /*
+ * DSS.1 Finite State Machine
+ * base: ITU-T Rec Q.931
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
@@ -7,19 +10,10 @@
  * the GNU General Public License, incorporated herein by reference.
  */
 
-/*        
- *        DSS.1 Finite State Machine
- *        base: ITU-T Rec Q.931
- */
-
 /*
  *        TODO: complete the FSM
  *              move state/event descriptions to a user space logger
  */
-
-#define __NO_VERSION__
-
-#include <linux/module.h>
 
 #include <linux/sched.h>
 #include <linux/string.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/edss1.h linux/drivers/isdn/pcbit/edss1.h
--- v2.4.10/linux/drivers/isdn/pcbit/edss1.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/edss1.h	Sun Sep 30 12:26:06 2001
@@ -1,14 +1,12 @@
 /*
+ * DSS.1 module definitions
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
- */
-
-/*        
- *        DSS.1 module definitions
  */
 
 #ifndef EDSS1_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/layer2.c linux/drivers/isdn/pcbit/layer2.c
--- v2.4.10/linux/drivers/isdn/pcbit/layer2.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/pcbit/layer2.c	Sun Sep 30 12:26:06 2001
@@ -1,4 +1,6 @@
 /*
+ * PCBIT-D low-layer interface
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
@@ -13,10 +15,6 @@
 */
 
 /*
- *        PCBIT-D low-layer interface
- */
-
-/*
  *        Based on documentation provided by Inesc:
  *        - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93
  */
@@ -25,16 +23,6 @@
  *        TODO: better handling of errors
  *              re-write/remove debug printks
  */
-
-#define __NO_VERSION__
-
-
-#ifdef MODULE
-#define INCLUDE_INLINE_FUNCS
-#endif
-
-
-#include <linux/module.h>
 
 #include <linux/sched.h>
 #include <linux/string.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/layer2.h linux/drivers/isdn/pcbit/layer2.h
--- v2.4.10/linux/drivers/isdn/pcbit/layer2.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/pcbit/layer2.h	Sun Sep 30 12:26:06 2001
@@ -1,4 +1,6 @@
 /*
+ * PCBIT-D low-layer interface definitions
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
@@ -11,10 +13,6 @@
  * 19991203 - Fernando Carvalho - takion@superbofh.org
  * Hacked to compile with egcs and run with current version of isdn modules
 */
-
-/*        
- *        PCBIT-D low-layer interface definitions
- */
 
 #ifndef LAYER2_H
 #define LAYER2_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/module.c linux/drivers/isdn/pcbit/module.c
--- v2.4.10/linux/drivers/isdn/pcbit/module.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/module.c	Sun Sep 30 12:26:06 2001
@@ -1,4 +1,6 @@
 /*
+ * PCBIT-D module support
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
@@ -7,10 +9,6 @@
  * the GNU General Public License, incorporated herein by reference.
  */
 
-/*        
- *        PCBIT-D module support
- */
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
@@ -22,6 +20,12 @@
 #include <linux/isdnif.h>
 #include "pcbit.h"
 
+MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card");
+MODULE_AUTHOR("Pedro Roque Marques");
+MODULE_LICENSE("GPL");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
+
 static int mem[MAX_PCBIT_CARDS] = {0, };
 static int irq[MAX_PCBIT_CARDS] = {0, };
 
@@ -118,9 +122,6 @@
 }
 __setup("pcbit=", pcbit_setup);
 #endif
-
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
 
 module_init(pcbit_init);
 module_exit(pcbit_exit);
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/pcbit/pcbit.h linux/drivers/isdn/pcbit/pcbit.h
--- v2.4.10/linux/drivers/isdn/pcbit/pcbit.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/pcbit.h	Sun Sep 30 12:26:06 2001
@@ -1,14 +1,12 @@
 /*
+ * PCBIT-D device driver definitions
+ *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
- */
-
-/*        
- *        PCBIT-D device driver definitions
  */
 
 #ifndef PCBIT_H
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/card.h linux/drivers/isdn/sc/card.h
--- v2.4.10/linux/drivers/isdn/sc/card.h	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/card.h	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,13 @@
-/*
- *  $Id: card.h,v 1.1 1996/11/07 13:07:40 fritz Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: card.h,v 1.1.10.1 2001/09/23 22:24:59 kai Exp $
  *
- *  card.h - Driver parameters for SpellCaster ISA ISDN adapters
+ * Driver parameters for SpellCaster ISA ISDN adapters
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/command.c linux/drivers/isdn/sc/command.c
--- v2.4.10/linux/drivers/isdn/sc/command.c	Thu May 29 21:53:06 1997
+++ linux/drivers/isdn/sc/command.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/*
- *  $Id: command.c,v 1.4 1997/03/30 16:51:34 calle Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: command.c,v 1.4.10.1 2001/09/23 22:24:59 kai Exp $
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
@@ -27,6 +16,7 @@
  */
 
 #define __NO_VERSION__
+#include <linux/module.h>
 #include "includes.h"		/* This must be first */
 #include "hardware.h"
 #include "message.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/debug.c linux/drivers/isdn/sc/debug.c
--- v2.4.10/linux/drivers/isdn/sc/debug.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/isdn/sc/debug.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/*
- *  $Id: debug.c,v 1.5 2000/11/12 15:29:37 kai Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: debug.c,v 1.5.6.1 2001/09/23 22:24:59 kai Exp $
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
@@ -25,6 +14,7 @@
  *     +1 (416) 297-8565
  *     +1 (416) 297-6433 Facsimile
  */
+
 #include <linux/kernel.h>
 #include <linux/string.h>
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/debug.h linux/drivers/isdn/sc/debug.h
--- v2.4.10/linux/drivers/isdn/sc/debug.h	Sat Feb 26 20:20:13 2000
+++ linux/drivers/isdn/sc/debug.h	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/*
- *  $Id: debug.h,v 1.2 2000/02/26 01:00:53 keil Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: debug.h,v 1.2.8.1 2001/09/23 22:24:59 kai Exp $
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/event.c linux/drivers/isdn/sc/event.c
--- v2.4.10/linux/drivers/isdn/sc/event.c	Wed Apr  1 16:21:04 1998
+++ linux/drivers/isdn/sc/event.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/*
- *  $Id: event.c,v 1.4 1997/10/09 22:30:58 fritz Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: event.c,v 1.4.8.1 2001/09/23 22:24:59 kai Exp $
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/hardware.h linux/drivers/isdn/sc/hardware.h
--- v2.4.10/linux/drivers/isdn/sc/hardware.h	Wed Apr  1 16:21:04 1998
+++ linux/drivers/isdn/sc/hardware.h	Sun Sep 30 12:26:06 2001
@@ -1,5 +1,9 @@
 /*
  * Hardware specific macros, defines and structures
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #ifndef HARDWARE_H
@@ -12,15 +16,7 @@
  */
 
 #define MAX_CARDS	4		/* The maximum number of cards to
-					   control or probe for. If you change
-					   this, you must also change the number
-					   of elements in io, irq, and ram to
-					   match. Initialized in init.c */
-/*
-extern unsigned int io[];
-extern unsigned char irq[];
-extern unsigned long ram[];
-*/
+					   control or probe for. */
 
 #define SIGNATURE	0x87654321	/* Board reset signature */
 #define SIG_OFFSET	0x1004		/* Where to find signature in shared RAM */
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/includes.h linux/drivers/isdn/sc/includes.h
--- v2.4.10/linux/drivers/isdn/sc/includes.h	Fri Feb  9 11:30:23 2001
+++ linux/drivers/isdn/sc/includes.h	Sun Sep 30 12:26:06 2001
@@ -1,4 +1,9 @@
-#include <linux/module.h>
+/*
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
 #include <linux/version.h>
 #include <linux/errno.h>
 #include <asm/segment.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/init.c linux/drivers/isdn/sc/init.c
--- v2.4.10/linux/drivers/isdn/sc/init.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/sc/init.c	Sun Sep 30 12:26:06 2001
@@ -1,9 +1,23 @@
+/*
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include "includes.h"
 #include "hardware.h"
 #include "card.h"
 
+MODULE_DESCRIPTION("ISDN4Linux: Driver for Spellcaster card");
+MODULE_AUTHOR("Spellcaster Telecommunications Inc.");
+MODULE_LICENSE("GPL");
+MODULE_PARM( io, "1-" __MODULE_STRING(MAX_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
+MODULE_PARM(ram, "1-" __MODULE_STRING(MAX_CARDS) "i");
+MODULE_PARM(do_reset, "i");
+
 board *adapter[MAX_CARDS];
 int cinst;
 
@@ -38,11 +52,6 @@
 	}
 	return 0;
 }
-
-MODULE_PARM(io, "1-4i");
-MODULE_PARM(irq, "1-4i");
-MODULE_PARM(ram, "1-4i");
-MODULE_PARM(do_reset, "i");
 
 static int __init sc_init(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/interrupt.c linux/drivers/isdn/sc/interrupt.c
--- v2.4.10/linux/drivers/isdn/sc/interrupt.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/sc/interrupt.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/*
- *  $Id: interrupt.c,v 1.4.8.2 2001/04/08 17:51:43 kai Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: interrupt.c,v 1.4.8.3 2001/09/23 22:24:59 kai Exp $
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/ioctl.c linux/drivers/isdn/sc/ioctl.c
--- v2.4.10/linux/drivers/isdn/sc/ioctl.c	Sun Nov  7 16:34:00 1999
+++ linux/drivers/isdn/sc/ioctl.c	Sun Sep 30 12:26:06 2001
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 1996  SpellCaster Telecommunications Inc.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
 #define __NO_VERSION__
 #include "includes.h"
 #include "hardware.h"
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/message.c linux/drivers/isdn/sc/message.c
--- v2.4.10/linux/drivers/isdn/sc/message.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/sc/message.c	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,13 @@
-/*
- *  $Id: message.c,v 1.5.8.1 2001/04/08 17:51:43 kai Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: message.c,v 1.5.8.2 2001/09/23 22:24:59 kai Exp $
  *
- *  message.c - functions for sending and receiving control messages
+ * functions for sending and receiving control messages
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/message.h linux/drivers/isdn/sc/message.h
--- v2.4.10/linux/drivers/isdn/sc/message.h	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/message.h	Sun Sep 30 12:26:06 2001
@@ -1,25 +1,14 @@
-/*
- *  $Id: message.h,v 1.1 1996/11/07 13:07:47 fritz Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: message.h,v 1.1.10.1 2001/09/23 22:24:59 kai Exp $
  *
- *  message.h - structures, macros and defines useful for sending
- *              messages to the adapter
+ * Copyright (C) 1996  SpellCaster Telecommunications 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.
+ * structures, macros and defines useful for sending
+ * messages to the adapter
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/packet.c linux/drivers/isdn/sc/packet.c
--- v2.4.10/linux/drivers/isdn/sc/packet.c	Sun Nov  7 16:34:00 1999
+++ linux/drivers/isdn/sc/packet.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/*
- *  $Id: packet.c,v 1.5 1999/08/31 11:20:41 paul Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: packet.c,v 1.5.8.1 2001/09/23 22:24:59 kai Exp $
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/scioc.h linux/drivers/isdn/sc/scioc.h
--- v2.4.10/linux/drivers/isdn/sc/scioc.h	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/scioc.h	Sun Sep 30 12:26:06 2001
@@ -1,3 +1,7 @@
+/*
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
 
 /*
  * IOCTL Command Codes
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/shmem.c linux/drivers/isdn/sc/shmem.c
--- v2.4.10/linux/drivers/isdn/sc/shmem.c	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/shmem.c	Sun Sep 30 12:26:06 2001
@@ -1,24 +1,13 @@
-/*
- *  $Id: shmem.c,v 1.2 1996/11/20 17:49:56 fritz Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: shmem.c,v 1.2.10.1 2001/09/23 22:24:59 kai Exp $
  *
- *  card.c - Card functions implementing ISDN4Linux functionality
+ * Copyright (C) 1996  SpellCaster Telecommunications 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.
+ * Card functions implementing ISDN4Linux functionality
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/sc/timer.c linux/drivers/isdn/sc/timer.c
--- v2.4.10/linux/drivers/isdn/sc/timer.c	Mon Aug 21 07:49:03 2000
+++ linux/drivers/isdn/sc/timer.c	Sun Sep 30 12:26:06 2001
@@ -1,22 +1,11 @@
-/*
- *  $Id: timer.c,v 1.3 2000/05/06 00:52:39 kai Exp $
- *  Copyright (C) 1996  SpellCaster Telecommunications Inc.
+/* $Id: timer.c,v 1.3.6.1 2001/09/23 22:24:59 kai Exp $
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the 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) 1996  SpellCaster Telecommunications Inc.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  For more information, please contact gpl-info@spellcast.com or write:
+ * For more information, please contact gpl-info@spellcast.com or write:
  *
  *     SpellCaster Telecommunications Inc.
  *     5621 Finch Avenue East, Unit #3
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam.h linux/drivers/isdn/tpam/tpam.h
--- v2.4.10/linux/drivers/isdn/tpam/tpam.h	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/tpam/tpam.h	Sun Sep 30 12:26:06 2001
@@ -1,31 +1,19 @@
-/* $Id: tpam.h,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $
+/* $Id: tpam.h,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
 
 #ifndef _TPAM_PRIV_H_
 #define _TPAM_PRIV_H_
 
-#include <linux/module.h>
 #include <linux/isdnif.h>
 #include <linux/init.h>
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam_commands.c linux/drivers/isdn/tpam/tpam_commands.c
--- v2.4.10/linux/drivers/isdn/tpam/tpam_commands.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/tpam/tpam_commands.c	Sun Sep 30 12:26:06 2001
@@ -1,27 +1,16 @@
-/* $Id: tpam_commands.c,v 1.1.2.2 2001/06/08 08:23:46 kai Exp $
+/* $Id: tpam_commands.c,v 1.1.2.3 2001/09/23 22:25:03 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - ISDN commands)
  *
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
-#include <linux/config.h>
+
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam_crcpc.c linux/drivers/isdn/tpam/tpam_crcpc.c
--- v2.4.10/linux/drivers/isdn/tpam/tpam_crcpc.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/tpam/tpam_crcpc.c	Sun Sep 30 12:26:06 2001
@@ -1,25 +1,14 @@
-/* $Id: tpam_crcpc.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $
+/* $Id: tpam_crcpc.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - CRC encoding)
  *
  * Copyright 1998-2000 AUVERTECH Télécom
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam_hdlc.c linux/drivers/isdn/tpam/tpam_hdlc.c
--- v2.4.10/linux/drivers/isdn/tpam/tpam_hdlc.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/tpam/tpam_hdlc.c	Sun Sep 30 12:26:06 2001
@@ -1,25 +1,14 @@
-/* $Id: tpam_hdlc.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $
+/* $Id: tpam_hdlc.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - HDLC encoding)
  *
  * Copyright 1998-2000 AUVERTECH Télécom
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam_main.c linux/drivers/isdn/tpam/tpam_main.c
--- v2.4.10/linux/drivers/isdn/tpam/tpam_main.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/isdn/tpam/tpam_main.c	Sun Sep 30 12:26:06 2001
@@ -1,27 +1,16 @@
-/* $Id: tpam_main.c,v 1.1.2.2 2001/07/11 12:22:59 kai Exp $
+/* $Id: tpam_main.c,v 1.1.2.3 2001/09/23 22:25:03 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - main routines)
  *
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
-#include <linux/config.h>
+
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
@@ -46,9 +35,9 @@
 /* Configurable id of the driver */
 static char *id = "tpam\0\0\0\0\0\0\0\0\0\0\0\0";
 
-MODULE_DESCRIPTION("Driver for TurboPAM cards");
-MODULE_AUTHOR("Stelian Pop, Alcove");
-MODULE_SUPPORTED_DEVICE("ISDN subsystem");
+MODULE_DESCRIPTION("ISDN4Linux: Driver for TurboPAM ISDN cards");
+MODULE_AUTHOR("Stelian Pop");
+MODULE_LICENSE("GPL");
 MODULE_PARM_DESC(id,"ID-String of the driver");
 MODULE_PARM(id,"s");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam_memory.c linux/drivers/isdn/tpam/tpam_memory.c
--- v2.4.10/linux/drivers/isdn/tpam/tpam_memory.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/tpam/tpam_memory.c	Sun Sep 30 12:26:06 2001
@@ -1,27 +1,16 @@
-/* $Id: tpam_memory.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $
+/* $Id: tpam_memory.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access)
  *
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
-#include <linux/config.h>
+
 #include <linux/pci.h>
 #include <asm/io.h>
 
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam_nco.c linux/drivers/isdn/tpam/tpam_nco.c
--- v2.4.10/linux/drivers/isdn/tpam/tpam_nco.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/tpam/tpam_nco.c	Sun Sep 30 12:26:06 2001
@@ -1,27 +1,17 @@
-/* $Id: tpam_nco.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $
+/* $Id: tpam_nco.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
  *
- * Turbo PAM ISDN driver for Linux. (Kernel Driver - Low Level NCO Manipulation)
+ * Turbo PAM ISDN driver for Linux. 
+ * (Kernel Driver - Low Level NCO Manipulation)
  *
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
-#include <linux/config.h>
+
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/tqueue.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/isdn/tpam/tpam_queues.c linux/drivers/isdn/tpam/tpam_queues.c
--- v2.4.10/linux/drivers/isdn/tpam/tpam_queues.c	Tue Jul  3 17:08:19 2001
+++ linux/drivers/isdn/tpam/tpam_queues.c	Sun Sep 30 12:26:06 2001
@@ -1,28 +1,16 @@
-/* $Id: tpam_queues.c,v 1.1.2.1 2001/06/05 19:45:37 kai Exp $
+/* $Id: tpam_queues.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
  * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
  *
- * For all support questions please contact: <support@auvertech.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * For all support questions please contact: <support@auvertech.fr>
  *
  */
-#include <linux/config.h>
-#include <linux/module.h>
+
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/tqueue.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/md/linear.c linux/drivers/md/linear.c
--- v2.4.10/linux/drivers/md/linear.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/md/linear.c	Sun Sep 30 12:26:06 2001
@@ -203,3 +203,4 @@
 
 module_init(linear_init);
 module_exit(linear_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/md/md.c linux/drivers/md/md.c
--- v2.4.10/linux/drivers/md/md.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/md/md.c	Wed Oct  3 22:27:48 2001
@@ -140,7 +140,7 @@
  */
 dev_mapping_t mddev_map[MAX_MD_DEVS];
 
-void add_mddev_mapping (mddev_t * mddev, kdev_t dev, void *data)
+void add_mddev_mapping(mddev_t * mddev, kdev_t dev, void *data)
 {
 	unsigned int minor = MINOR(dev);
 
@@ -148,7 +148,7 @@
 		MD_BUG();
 		return;
 	}
-	if (mddev_map[minor].mddev != NULL) {
+	if (mddev_map[minor].mddev) {
 		MD_BUG();
 		return;
 	}
@@ -156,7 +156,7 @@
 	mddev_map[minor].data = data;
 }
 
-void del_mddev_mapping (mddev_t * mddev, kdev_t dev)
+void del_mddev_mapping(mddev_t * mddev, kdev_t dev)
 {
 	unsigned int minor = MINOR(dev);
 
@@ -172,7 +172,7 @@
 	mddev_map[minor].data = NULL;
 }
 
-static int md_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+static int md_make_request(request_queue_t *q, int rw, struct buffer_head * bh)
 {
 	mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
 
@@ -184,7 +184,7 @@
 	}
 }
 
-static mddev_t * alloc_mddev (kdev_t dev)
+static mddev_t * alloc_mddev(kdev_t dev)
 {
 	mddev_t *mddev;
 
@@ -195,7 +195,7 @@
 	mddev = (mddev_t *) kmalloc(sizeof(*mddev), GFP_KERNEL);
 	if (!mddev)
 		return NULL;
-		
+
 	memset(mddev, 0, sizeof(*mddev));
 
 	mddev->__minor = MINOR(dev);
@@ -245,7 +245,7 @@
 
 static MD_LIST_HEAD(device_names);
 
-char * partition_name (kdev_t dev)
+char * partition_name(kdev_t dev)
 {
 	struct gendisk *hd;
 	static char nomem [] = "<nomem>";
@@ -282,7 +282,7 @@
 	return dname->name;
 }
 
-static unsigned int calc_dev_sboffset (kdev_t dev, mddev_t *mddev,
+static unsigned int calc_dev_sboffset(kdev_t dev, mddev_t *mddev,
 						int persistent)
 {
 	unsigned int size = 0;
@@ -294,7 +294,7 @@
 	return size;
 }
 
-static unsigned int calc_dev_size (kdev_t dev, mddev_t *mddev, int persistent)
+static unsigned int calc_dev_size(kdev_t dev, mddev_t *mddev, int persistent)
 {
 	unsigned int size;
 
@@ -308,7 +308,7 @@
 	return size;
 }
 
-static unsigned int zoned_raid_size (mddev_t *mddev)
+static unsigned int zoned_raid_size(mddev_t *mddev)
 {
 	unsigned int mask;
 	mdk_rdev_t * rdev;
@@ -338,7 +338,7 @@
  * provide data have to be able to deal with loss of individual
  * disks, so they do their checking themselves.
  */
-int md_check_ordering (mddev_t *mddev)
+int md_check_ordering(mddev_t *mddev)
 {
 	int i, c;
 	mdk_rdev_t *rdev;
@@ -349,8 +349,8 @@
 	 */
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		if (rdev->faulty) {
-			printk("md: md%d's device %s faulty, aborting.\n",
-				mdidx(mddev), partition_name(rdev->dev));
+			printk(KERN_ERR "md: md%d's device %s faulty, aborting.\n",
+			       mdidx(mddev), partition_name(rdev->dev));
 			goto abort;
 		}
 	}
@@ -364,7 +364,7 @@
 		goto abort;
 	}
 	if (mddev->nb_dev != mddev->sb->raid_disks) {
-		printk("md: md%d, array needs %d disks, has %d, aborting.\n",
+		printk(KERN_ERR "md: md%d, array needs %d disks, has %d, aborting.\n",
 			mdidx(mddev), mddev->sb->raid_disks, mddev->nb_dev);
 		goto abort;
 	}
@@ -378,13 +378,13 @@
 				c++;
 		}
 		if (!c) {
-			printk("md: md%d, missing disk #%d, aborting.\n",
-				mdidx(mddev), i);
+			printk(KERN_ERR "md: md%d, missing disk #%d, aborting.\n",
+			       mdidx(mddev), i);
 			goto abort;
 		}
 		if (c > 1) {
-			printk("md: md%d, too many disks #%d, aborting.\n",
-				mdidx(mddev), i);
+			printk(KERN_ERR "md: md%d, too many disks #%d, aborting.\n",
+			       mdidx(mddev), i);
 			goto abort;
 		}
 	}
@@ -393,7 +393,7 @@
 	return 1;
 }
 
-static void remove_descriptor (mdp_disk_t *disk, mdp_super_t *sb)
+static void remove_descriptor(mdp_disk_t *disk, mdp_super_t *sb)
 {
 	if (disk_active(disk)) {
 		sb->working_disks--;
@@ -426,7 +426,7 @@
 #define BAD_CSUM KERN_WARNING \
 "md: invalid superblock checksum on %s\n"
 
-static int alloc_array_sb (mddev_t * mddev)
+static int alloc_array_sb(mddev_t * mddev)
 {
 	if (mddev->sb) {
 		MD_BUG();
@@ -440,14 +440,14 @@
 	return 0;
 }
 
-static int alloc_disk_sb (mdk_rdev_t * rdev)
+static int alloc_disk_sb(mdk_rdev_t * rdev)
 {
 	if (rdev->sb)
 		MD_BUG();
 
 	rdev->sb = (mdp_super_t *) __get_free_page(GFP_KERNEL);
 	if (!rdev->sb) {
-		printk (OUT_OF_MEM);
+		printk(OUT_OF_MEM);
 		return -EINVAL;
 	}
 	md_clear_page(rdev->sb);
@@ -455,7 +455,7 @@
 	return 0;
 }
 
-static void free_disk_sb (mdk_rdev_t * rdev)
+static void free_disk_sb(mdk_rdev_t * rdev)
 {
 	if (rdev->sb) {
 		free_page((unsigned long) rdev->sb);
@@ -468,7 +468,7 @@
 	}
 }
 
-static int read_disk_sb (mdk_rdev_t * rdev)
+static int read_disk_sb(mdk_rdev_t * rdev)
 {
 	int ret = -EINVAL;
 	struct buffer_head *bh = NULL;
@@ -479,15 +479,14 @@
 	if (!rdev->sb) {
 		MD_BUG();
 		goto abort;
-	}	
-	
+	}
+
 	/*
 	 * Calculate the position of the superblock,
 	 * it's at the end of the disk
 	 */
 	sb_offset = calc_dev_sboffset(rdev->dev, rdev->mddev, 1);
 	rdev->sb_offset = sb_offset;
-	printk("(read) %s's sb offset: %ld", partition_name(dev), sb_offset);
 	fsync_dev(dev);
 	set_blocksize (dev, MD_SB_BYTES);
 	bh = bread (dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
@@ -496,10 +495,10 @@
 		sb = (mdp_super_t *) bh->b_data;
 		memcpy (rdev->sb, sb, MD_SB_BYTES);
 	} else {
-		printk (NO_SB,partition_name(rdev->dev));
+		printk(NO_SB,partition_name(rdev->dev));
 		goto abort;
 	}
-	printk(" [events: %08lx]\n", (unsigned long)rdev->sb->events_lo);
+	printk(KERN_INFO " [events: %08lx]\n", (unsigned long)rdev->sb->events_lo);
 	ret = 0;
 abort:
 	if (bh)
@@ -507,7 +506,7 @@
 	return ret;
 }
 
-static unsigned int calc_sb_csum (mdp_super_t * sb)
+static unsigned int calc_sb_csum(mdp_super_t * sb)
 {
 	unsigned int disk_csum, csum;
 
@@ -522,7 +521,7 @@
  * Check one RAID superblock for generic plausibility
  */
 
-static int check_disk_sb (mdk_rdev_t * rdev)
+static int check_disk_sb(mdk_rdev_t * rdev)
 {
 	mdp_super_t *sb;
 	int ret = -EINVAL;
@@ -534,13 +533,12 @@
 	}
 
 	if (sb->md_magic != MD_SB_MAGIC) {
-		printk (BAD_MAGIC, partition_name(rdev->dev));
+		printk(BAD_MAGIC, partition_name(rdev->dev));
 		goto abort;
 	}
 
 	if (sb->md_minor >= MAX_MD_DEVS) {
-		printk (BAD_MINOR, partition_name(rdev->dev),
-							sb->md_minor);
+		printk(BAD_MINOR, partition_name(rdev->dev), sb->md_minor);
 		goto abort;
 	}
 
@@ -590,7 +588,7 @@
 static MD_LIST_HEAD(all_raid_disks);
 static MD_LIST_HEAD(pending_raid_disks);
 
-static void bind_rdev_to_array (mdk_rdev_t * rdev, mddev_t * mddev)
+static void bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 {
 	mdk_rdev_t *same_pdev;
 
@@ -603,16 +601,16 @@
 		printk( KERN_WARNING
 "md%d: WARNING: %s appears to be on the same physical disk as %s. True\n"
 "     protection against single-disk failure might be compromised.\n",
- 			mdidx(mddev), partition_name(rdev->dev),
+			mdidx(mddev), partition_name(rdev->dev),
 				partition_name(same_pdev->dev));
-		
+
 	md_list_add(&rdev->same_set, &mddev->disks);
 	rdev->mddev = mddev;
 	mddev->nb_dev++;
-	printk("md: bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
+	printk(KERN_INFO "md: bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
 }
 
-static void unbind_rdev_from_array (mdk_rdev_t * rdev)
+static void unbind_rdev_from_array(mdk_rdev_t * rdev)
 {
 	if (!rdev->mddev) {
 		MD_BUG();
@@ -621,7 +619,7 @@
 	md_list_del(&rdev->same_set);
 	MD_INIT_LIST_HEAD(&rdev->same_set);
 	rdev->mddev->nb_dev--;
-	printk("md: unbind<%s,%d>\n", partition_name(rdev->dev),
+	printk(KERN_INFO "md: unbind<%s,%d>\n", partition_name(rdev->dev),
 						 rdev->mddev->nb_dev);
 	rdev->mddev = NULL;
 }
@@ -633,13 +631,13 @@
  * inode is not enough, the SCSI module usage code needs
  * an explicit open() on the device]
  */
-static int lock_rdev (mdk_rdev_t *rdev)
+static int lock_rdev(mdk_rdev_t *rdev)
 {
 	int err = 0;
 	struct block_device *bdev;
 
 	bdev = bdget(rdev->dev);
-	if (bdev == NULL)
+	if (!bdev)
 		return -ENOMEM;
 	err = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_RAW);
 	if (!err)
@@ -647,7 +645,7 @@
 	return err;
 }
 
-static void unlock_rdev (mdk_rdev_t *rdev)
+static void unlock_rdev(mdk_rdev_t *rdev)
 {
 	struct block_device *bdev = rdev->bdev;
 	rdev->bdev = NULL;
@@ -656,11 +654,11 @@
 	blkdev_put(bdev, BDEV_RAW);
 }
 
-void md_autodetect_dev (kdev_t dev);
+void md_autodetect_dev(kdev_t dev);
 
-static void export_rdev (mdk_rdev_t * rdev)
+static void export_rdev(mdk_rdev_t * rdev)
 {
-	printk("md: export_rdev(%s)\n",partition_name(rdev->dev));
+	printk(KERN_INFO "md: export_rdev(%s)\n",partition_name(rdev->dev));
 	if (rdev->mddev)
 		MD_BUG();
 	unlock_rdev(rdev);
@@ -668,7 +666,8 @@
 	md_list_del(&rdev->all);
 	MD_INIT_LIST_HEAD(&rdev->all);
 	if (rdev->pending.next != &rdev->pending) {
-		printk("md: (%s was pending)\n",partition_name(rdev->dev));
+		printk(KERN_INFO "md: (%s was pending)\n",
+			partition_name(rdev->dev));
 		md_list_del(&rdev->pending);
 		MD_INIT_LIST_HEAD(&rdev->pending);
 	}
@@ -680,13 +679,13 @@
 	kfree(rdev);
 }
 
-static void kick_rdev_from_array (mdk_rdev_t * rdev)
+static void kick_rdev_from_array(mdk_rdev_t * rdev)
 {
 	unbind_rdev_from_array(rdev);
 	export_rdev(rdev);
 }
 
-static void export_array (mddev_t *mddev)
+static void export_array(mddev_t *mddev)
 {
 	struct md_list_head *tmp;
 	mdk_rdev_t *rdev;
@@ -708,7 +707,7 @@
 		MD_BUG();
 }
 
-static void free_mddev (mddev_t *mddev)
+static void free_mddev(mddev_t *mddev)
 {
 	if (!mddev) {
 		MD_BUG();
@@ -751,45 +750,47 @@
 {
 	int i;
 
-	printk("md:  SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n",
+	printk(KERN_INFO "md:  SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n",
 		sb->major_version, sb->minor_version, sb->patch_version,
 		sb->set_uuid0, sb->set_uuid1, sb->set_uuid2, sb->set_uuid3,
 		sb->ctime);
-	printk("md:     L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level,
+	printk(KERN_INFO "md:     L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level,
 		sb->size, sb->nr_disks, sb->raid_disks, sb->md_minor,
 		sb->layout, sb->chunk_size);
-	printk("md:     UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n",
+	printk(KERN_INFO "md:     UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n",
 		sb->utime, sb->state, sb->active_disks, sb->working_disks,
 		sb->failed_disks, sb->spare_disks,
 		sb->sb_csum, (unsigned long)sb->events_lo);
 
+	printk(KERN_INFO);
 	for (i = 0; i < MD_SB_DISKS; i++) {
 		mdp_disk_t *desc;
 
 		desc = sb->disks + i;
-		if (desc->number || desc->major || desc->minor || desc->raid_disk || (desc->state && (desc->state != 4))) {
+		if (desc->number || desc->major || desc->minor ||
+		    desc->raid_disk || (desc->state && (desc->state != 4))) {
 			printk("     D %2d: ", i);
 			print_desc(desc);
 		}
 	}
-	printk("md:     THIS: ");
+	printk(KERN_INFO "md:     THIS: ");
 	print_desc(&sb->this_disk);
 
 }
 
 static void print_rdev(mdk_rdev_t *rdev)
 {
-	printk("md: rdev %s: O:%s, SZ:%08ld F:%d DN:%d ",
+	printk(KERN_INFO "md: rdev %s: O:%s, SZ:%08ld F:%d DN:%d ",
 		partition_name(rdev->dev), partition_name(rdev->old_dev),
 		rdev->size, rdev->faulty, rdev->desc_nr);
 	if (rdev->sb) {
-		printk("md: rdev superblock:\n");
+		printk(KERN_INFO "md: rdev superblock:\n");
 		print_sb(rdev->sb);
 	} else
-		printk("md: no rdev superblock!\n");
+		printk(KERN_INFO "md: no rdev superblock!\n");
 }
 
-void md_print_devices (void)
+void md_print_devices(void)
 {
 	struct md_list_head *tmp, *tmp2;
 	mdk_rdev_t *rdev;
@@ -818,7 +819,7 @@
 	printk("\n");
 }
 
-static int sb_equal ( mdp_super_t *sb1, mdp_super_t *sb2)
+static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2)
 {
 	int ret;
 	mdp_super_t *tmp1, *tmp2;
@@ -867,7 +868,7 @@
 	return 0;
 }
 
-static mdk_rdev_t * find_rdev_all (kdev_t dev)
+static mdk_rdev_t * find_rdev_all(kdev_t dev)
 {
 	struct md_list_head *tmp;
 	mdk_rdev_t *rdev;
@@ -908,8 +909,8 @@
 	dev = rdev->dev;
 	sb_offset = calc_dev_sboffset(dev, rdev->mddev, 1);
 	if (rdev->sb_offset != sb_offset) {
-		printk("%s's sb offset has changed from %ld to %ld, skipping\n",
-			partition_name(dev), rdev->sb_offset, sb_offset);
+		printk(KERN_INFO "%s's sb offset has changed from %ld to %ld, skipping\n",
+		       partition_name(dev), rdev->sb_offset, sb_offset);
 		goto skip;
 	}
 	/*
@@ -919,12 +920,12 @@
 	 */
 	size = calc_dev_size(dev, rdev->mddev, 1);
 	if (size != rdev->size) {
-		printk("%s's size has changed from %ld to %ld since import, skipping\n",
-			partition_name(dev), rdev->size, size);
+		printk(KERN_INFO "%s's size has changed from %ld to %ld since import, skipping\n",
+		       partition_name(dev), rdev->size, size);
 		goto skip;
 	}
 
-	printk("(write) %s's sb offset: %ld\n", partition_name(dev), sb_offset);
+	printk(KERN_INFO "(write) %s's sb offset: %ld\n", partition_name(dev), sb_offset);
 	fsync_dev(dev);
 	set_blocksize(dev, MD_SB_BYTES);
 	bh = getblk(dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
@@ -945,7 +946,7 @@
 skip:
 	return 0;
 }
-#undef GETBLK_FAILED 
+#undef GETBLK_FAILED
 
 static void set_this_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 {
@@ -1025,7 +1026,7 @@
 
 	err = 0;
 	ITERATE_RDEV(mddev,rdev,tmp) {
-		printk("md: ");
+		printk(KERN_INFO "md: ");
 		if (rdev->faulty)
 			printk("(skipping faulty ");
 		if (rdev->alias_device)
@@ -1041,10 +1042,10 @@
 	}
 	if (err) {
 		if (--count) {
-			printk("md: errors occurred during superblock update, repeating\n");
+			printk(KERN_ERR "md: errors occurred during superblock update, repeating\n");
 			goto repeat;
 		}
-		printk("md: excessive errors occurred during superblock update, exiting\n");
+		printk(KERN_ERR "md: excessive errors occurred during superblock update, exiting\n");
 	}
 	return 0;
 }
@@ -1059,7 +1060,7 @@
  *
  * a faulty rdev _never_ has rdev->sb set.
  */
-static int md_import_device (kdev_t newdev, int on_disk)
+static int md_import_device(kdev_t newdev, int on_disk)
 {
 	int err;
 	mdk_rdev_t *rdev;
@@ -1070,13 +1071,13 @@
 
 	rdev = (mdk_rdev_t *) kmalloc(sizeof(*rdev), GFP_KERNEL);
 	if (!rdev) {
-		printk("md: could not alloc mem for %s!\n", partition_name(newdev));
+		printk(KERN_ERR "md: could not alloc mem for %s!\n", partition_name(newdev));
 		return -ENOMEM;
 	}
 	memset(rdev, 0, sizeof(*rdev));
 
 	if (is_mounted(newdev)) {
-		printk("md: can not import %s, has active inodes!\n",
+		printk(KERN_WARNING "md: can not import %s, has active inodes!\n",
 			partition_name(newdev));
 		err = -EBUSY;
 		goto abort_free;
@@ -1087,7 +1088,7 @@
 
 	rdev->dev = newdev;
 	if (lock_rdev(rdev)) {
-		printk("md: could not lock %s, zero-size? Marking faulty.\n",
+		printk(KERN_ERR "md: could not lock %s, zero-size? Marking faulty.\n",
 			partition_name(newdev));
 		err = -EINVAL;
 		goto abort_free;
@@ -1099,7 +1100,7 @@
 	if (blk_size[MAJOR(newdev)])
 		size = blk_size[MAJOR(newdev)][MINOR(newdev)];
 	if (!size) {
-		printk("md: %s has zero size, marking faulty!\n",
+		printk(KERN_WARNING "md: %s has zero size, marking faulty!\n",
 				partition_name(newdev));
 		err = -EINVAL;
 		goto abort_free;
@@ -1107,13 +1108,13 @@
 
 	if (on_disk) {
 		if ((err = read_disk_sb(rdev))) {
-			printk("md: could not read %s's sb, not importing!\n",
-					partition_name(newdev));
+			printk(KERN_WARNING "md: could not read %s's sb, not importing!\n",
+			       partition_name(newdev));
 			goto abort_free;
 		}
 		if ((err = check_disk_sb(rdev))) {
-			printk("md: %s has invalid sb, not importing!\n",
-					partition_name(newdev));
+			printk(KERN_WARNING "md: %s has invalid sb, not importing!\n",
+			       partition_name(newdev));
 			goto abort_free;
 		}
 
@@ -1162,7 +1163,7 @@
 #define UNKNOWN_LEVEL KERN_ERR \
 "md: md%d: unsupported raid level %d\n"
 
-static int analyze_sbs (mddev_t * mddev)
+static int analyze_sbs(mddev_t * mddev)
 {
 	int out_of_date = 0, i, first;
 	struct md_list_head *tmp, *tmp2;
@@ -1197,7 +1198,7 @@
 			continue;
 		}
 		if (!sb_equal(sb, rdev->sb)) {
-			printk (INCONSISTENT, partition_name(rdev->dev));
+			printk(INCONSISTENT, partition_name(rdev->dev));
 			kick_rdev_from_array(rdev);
 			continue;
 		}
@@ -1227,7 +1228,8 @@
 					rdev->sb->events_hi--;
 		}
 
-		printk("md: %s's event counter: %08lx\n", partition_name(rdev->dev),
+		printk(KERN_INFO "md: %s's event counter: %08lx\n",
+		       partition_name(rdev->dev),
 			(unsigned long)rdev->sb->events_lo);
 		if (!freshest) {
 			freshest = rdev;
@@ -1246,7 +1248,7 @@
 	}
 	if (out_of_date) {
 		printk(OUT_OF_DATE);
-		printk("md: freshest: %s\n", partition_name(freshest->dev));
+		printk(KERN_INFO "md: freshest: %s\n", partition_name(freshest->dev));
 	}
 	memcpy (sb, freshest->sb, sizeof(*sb));
 
@@ -1265,7 +1267,7 @@
 		ev2 = md_event(sb);
 		++ev1;
 		if (ev1 < ev2) {
-			printk("md: kicking non-fresh %s from array!\n",
+			printk(KERN_WARNING "md: kicking non-fresh %s from array!\n",
 						partition_name(rdev->dev));
 			kick_rdev_from_array(rdev);
 			continue;
@@ -1291,7 +1293,8 @@
 			((ev1 == ev2) || (ev1 == ev3))) {
 			mdp_disk_t *desc;
 
-			printk("md: device name has changed from %s to %s since last import!\n", partition_name(rdev->old_dev), partition_name(rdev->dev));
+			printk(KERN_WARNING "md: device name has changed from %s to %s since last import!\n",
+			       partition_name(rdev->old_dev), partition_name(rdev->dev));
 			if (rdev->desc_nr == -1) {
 				MD_BUG();
 				goto abort;
@@ -1338,7 +1341,7 @@
 			ITERATE_RDEV(mddev,rdev,tmp) {
 				if (rdev->desc_nr != desc->number)
 					continue;
-				printk("md%d: kicking faulty %s!\n",
+				printk(KERN_WARNING "md%d: kicking faulty %s!\n",
 					mdidx(mddev),partition_name(rdev->dev));
 				kick_rdev_from_array(rdev);
 				found = 1;
@@ -1347,7 +1350,7 @@
 			if (!found) {
 				if (dev == MKDEV(0,0))
 					continue;
-				printk("md%d: removing former faulty %s!\n",
+				printk(KERN_WARNING "md%d: removing former faulty %s!\n",
 					mdidx(mddev), partition_name(dev));
 			}
 			remove_descriptor(desc, sb);
@@ -1389,7 +1392,8 @@
 		if (found)
 			continue;
 
-		printk("md%d: former device %s is unavailable, removing from array!\n", mdidx(mddev), partition_name(dev));
+		printk(KERN_WARNING "md%d: former device %s is unavailable, removing from array!\n",
+		       mdidx(mddev), partition_name(dev));
 		remove_descriptor(desc, sb);
 	}
 
@@ -1436,7 +1440,7 @@
 				first = 0;
 		}
 	}
- 
+
 	/*
 	 * Kick all rdevs that are not in the
 	 * descriptor array:
@@ -1445,7 +1449,7 @@
 		if (rdev->desc_nr == -1)
 			kick_rdev_from_array(rdev);
 	}
- 
+
 	/*
 	 * Do a final reality check.
 	 */
@@ -1484,14 +1488,14 @@
 	if (sb->major_version != MD_MAJOR_VERSION ||
 			sb->minor_version > MD_MINOR_VERSION) {
 
-		printk (OLD_VERSION, mdidx(mddev), sb->major_version,
+		printk(OLD_VERSION, mdidx(mddev), sb->major_version,
 				sb->minor_version, sb->patch_version);
 		goto abort;
 	}
 
 	if ((sb->state != (1 << MD_SB_CLEAN)) && ((sb->level == 1) ||
 			(sb->level == 4) || (sb->level == 5)))
-		printk (NOT_CLEAN_IGNORE, mdidx(mddev));
+		printk(NOT_CLEAN_IGNORE, mdidx(mddev));
 
 	return 0;
 abort:
@@ -1503,7 +1507,7 @@
 #undef OLD_VERSION
 #undef OLD_LEVEL
 
-static int device_size_calculation (mddev_t * mddev)
+static int device_size_calculation(mddev_t * mddev)
 {
 	int data_disks = 0, persistent;
 	unsigned int readahead;
@@ -1526,7 +1530,7 @@
 		}
 		rdev->size = calc_dev_size(rdev->dev, mddev, persistent);
 		if (rdev->size < sb->chunk_size / 1024) {
-			printk (KERN_WARNING
+			printk(KERN_WARNING
 				"md: Dev %s smaller than chunk_size: %ldk < %dk\n",
 				partition_name(rdev->dev),
 				rdev->size, sb->chunk_size / 1024);
@@ -1560,7 +1564,7 @@
 			data_disks = sb->raid_disks-1;
 			break;
 		default:
-			printk (UNKNOWN_LEVEL, mdidx(mddev), sb->level);
+			printk(UNKNOWN_LEVEL, mdidx(mddev), sb->level);
 			goto abort;
 	}
 	if (!md_size[mdidx(mddev)])
@@ -1599,7 +1603,7 @@
 #define BAD_CHUNKSIZE KERN_ERR \
 "no chunksize specified, see 'man raidtab'\n"
 
-static int do_md_run (mddev_t * mddev)
+static int do_md_run(mddev_t * mddev)
 {
 	int pnum, err;
 	int chunk_size;
@@ -1663,7 +1667,8 @@
 		}
 	} else
 		if (chunk_size)
-			printk(KERN_INFO "md: RAID level %d does not need chunksize! Continuing anyway.\n", mddev->sb->level);
+			printk(KERN_INFO "md: RAID level %d does not need chunksize! Continuing anyway.\n",
+			       mddev->sb->level);
 
 	if (pnum >= MAX_PERSONALITY) {
 		MD_BUG();
@@ -1700,7 +1705,7 @@
 			continue;
 		invalidate_device(rdev->dev, 1);
 		if (get_hardsect_size(rdev->dev)
-			> md_hardsect_sizes[mdidx(mddev)]) 
+			> md_hardsect_sizes[mdidx(mddev)])
 			md_hardsect_sizes[mdidx(mddev)] =
 				get_hardsect_size(rdev->dev);
 	}
@@ -1711,7 +1716,7 @@
 
 	err = mddev->pers->run(mddev);
 	if (err) {
-		printk("md: pers->run() failed ...\n");
+		printk(KERN_ERR "md: pers->run() failed ...\n");
 		mddev->pers = NULL;
 		return -EINVAL;
 	}
@@ -1736,7 +1741,7 @@
 
 #define OUT(x) do { err = (x); goto out; } while (0)
 
-static int restart_array (mddev_t *mddev)
+static int restart_array(mddev_t *mddev)
 {
 	int err = 0;
 
@@ -1753,7 +1758,7 @@
 		mddev->ro = 0;
 		set_device_ro(mddev_to_kdev(mddev), 0);
 
-		printk (KERN_INFO
+		printk(KERN_INFO
 			"md: md%d switched to read-write mode.\n", mdidx(mddev));
 		/*
 		 * Kick recovery or resync if necessary
@@ -1762,7 +1767,7 @@
 		if (mddev->pers->restart_resync)
 			mddev->pers->restart_resync(mddev);
 	} else {
-		printk (KERN_ERR "md: md%d has no personality assigned.\n",
+		printk(KERN_ERR "md: md%d has no personality assigned.\n",
 			mdidx(mddev));
 		err = -EINVAL;
 	}
@@ -1776,15 +1781,15 @@
 #define	STILL_IN_USE \
 "md: md%d still in use.\n"
 
-static int do_md_stop (mddev_t * mddev, int ro)
+static int do_md_stop(mddev_t * mddev, int ro)
 {
 	int err = 0, resync_interrupted = 0;
 	kdev_t dev = mddev_to_kdev(mddev);
 
- 	if (atomic_read(&mddev->active)>1) {
- 		printk(STILL_IN_USE, mdidx(mddev));
- 		OUT(-EBUSY);
- 	}
+	if (atomic_read(&mddev->active)>1) {
+		printk(STILL_IN_USE, mdidx(mddev));
+		OUT(-EBUSY);
+	}
 
 	if (mddev->pers) {
 		/*
@@ -1831,7 +1836,7 @@
 			 * interrupted.
 			 */
 			if (!mddev->recovery_running && !resync_interrupted) {
-				printk("md: marking sb clean...\n");
+				printk(KERN_INFO "md: marking sb clean...\n");
 				mddev->sb->state |= 1 << MD_SB_CLEAN;
 			}
 			md_update_sb(mddev);
@@ -1844,12 +1849,11 @@
 	 * Free resources if final stop
 	 */
 	if (!ro) {
-		printk (KERN_INFO "md: md%d stopped.\n", mdidx(mddev));
+		printk(KERN_INFO "md: md%d stopped.\n", mdidx(mddev));
 		free_mddev(mddev);
 
 	} else
-		printk (KERN_INFO
-			"md: md%d switched to read-only mode.\n", mdidx(mddev));
+		printk(KERN_INFO "md: md%d switched to read-only mode.\n", mdidx(mddev));
 out:
 	return err;
 }
@@ -1859,7 +1863,7 @@
 /*
  * We have to safely support old arrays too.
  */
-int detect_old_array (mdp_super_t *sb)
+int detect_old_array(mdp_super_t *sb)
 {
 	if (sb->major_version > 0)
 		return 0;
@@ -1870,7 +1874,7 @@
 }
 
 
-static void autorun_array (mddev_t *mddev)
+static void autorun_array(mddev_t *mddev)
 {
 	mdk_rdev_t *rdev;
 	struct md_list_head *tmp;
@@ -1881,7 +1885,7 @@
 		return;
 	}
 
-	printk("md: running: ");
+	printk(KERN_INFO "md: running: ");
 
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		printk("<%s>", partition_name(rdev->dev));
@@ -1890,7 +1894,7 @@
 
 	err = do_md_run (mddev);
 	if (err) {
-		printk("md :do_md_run() returned %d\n", err);
+		printk(KERN_WARNING "md :do_md_run() returned %d\n", err);
 		/*
 		 * prevent the writeback of an unrunnable array
 		 */
@@ -1911,7 +1915,7 @@
  *
  * If "unit" is allocated, then bump its reference count
  */
-static void autorun_devices (kdev_t countdev)
+static void autorun_devices(kdev_t countdev)
 {
 	struct md_list_head candidates;
 	struct md_list_head *tmp;
@@ -1920,20 +1924,22 @@
 	kdev_t md_kdev;
 
 
-	printk("md: autorun ...\n");
+	printk(KERN_INFO "md: autorun ...\n");
 	while (pending_raid_disks.next != &pending_raid_disks) {
 		rdev0 = md_list_entry(pending_raid_disks.next,
 					 mdk_rdev_t, pending);
 
-		printk("md: considering %s ...\n", partition_name(rdev0->dev));
+		printk(KERN_INFO "md: considering %s ...\n", partition_name(rdev0->dev));
 		MD_INIT_LIST_HEAD(&candidates);
 		ITERATE_RDEV_PENDING(rdev,tmp) {
 			if (uuid_equal(rdev0, rdev)) {
 				if (!sb_equal(rdev0->sb, rdev->sb)) {
-					printk("md: %s has same UUID as %s, but superblocks differ ...\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+					printk(KERN_WARNING
+					       "md: %s has same UUID as %s, but superblocks differ ...\n",
+					       partition_name(rdev->dev), partition_name(rdev0->dev));
 					continue;
 				}
-				printk("md:  adding %s ...\n", partition_name(rdev->dev));
+				printk(KERN_INFO "md:  adding %s ...\n", partition_name(rdev->dev));
 				md_list_del(&rdev->pending);
 				md_list_add(&rdev->pending, &candidates);
 			}
@@ -1946,20 +1952,20 @@
 		md_kdev = MKDEV(MD_MAJOR, rdev0->sb->md_minor);
 		mddev = kdev_to_mddev(md_kdev);
 		if (mddev) {
-			printk("md: md%d already running, cannot run %s\n",
-				 mdidx(mddev), partition_name(rdev0->dev));
+			printk(KERN_WARNING "md: md%d already running, cannot run %s\n",
+			       mdidx(mddev), partition_name(rdev0->dev));
 			ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp)
 				export_rdev(rdev);
 			continue;
 		}
 		mddev = alloc_mddev(md_kdev);
- 		if (mddev == NULL) {
- 			printk("md: cannot allocate memory for md drive.\n");
- 			break;
- 		}
- 		if (md_kdev == countdev)
- 			atomic_inc(&mddev->active);
-		printk("md: created md%d\n", mdidx(mddev));
+		if (!mddev) {
+			printk(KERN_ERR "md: cannot allocate memory for md drive.\n");
+			break;
+		}
+		if (md_kdev == countdev)
+			atomic_inc(&mddev->active);
+		printk(KERN_INFO "md: created md%d\n", mdidx(mddev));
 		ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp) {
 			bind_rdev_to_array(rdev, mddev);
 			md_list_del(&rdev->pending);
@@ -1967,7 +1973,7 @@
 		}
 		autorun_array(mddev);
 	}
-	printk("md: ... autorun DONE.\n");
+	printk(KERN_INFO "md: ... autorun DONE.\n");
 }
 
 /*
@@ -2002,14 +2008,14 @@
 #define AUTORUNNING KERN_INFO \
 "md: auto-running md%d.\n"
 
-static int autostart_array (kdev_t startdev, kdev_t countdev)
+static int autostart_array(kdev_t startdev, kdev_t countdev)
 {
 	int err = -EINVAL, i;
 	mdp_super_t *sb = NULL;
 	mdk_rdev_t *start_rdev = NULL, *rdev;
 
 	if (md_import_device(startdev, 1)) {
-		printk("md: could not import %s!\n", partition_name(startdev));
+		printk(KERN_WARNING "md: could not import %s!\n", partition_name(startdev));
 		goto abort;
 	}
 
@@ -2019,7 +2025,7 @@
 		goto abort;
 	}
 	if (start_rdev->faulty) {
-		printk("md: can not autostart based on faulty %s!\n",
+		printk(KERN_WARNING "md: can not autostart based on faulty %s!\n",
 						partition_name(startdev));
 		goto abort;
 	}
@@ -2029,7 +2035,9 @@
 
 	err = detect_old_array(sb);
 	if (err) {
-		printk("md: array version is too old to be autostarted, use raidtools 0.90 mkraid --upgrade\nto upgrade the array without data loss!\n");
+		printk(KERN_WARNING "md: array version is too old to be autostarted ,"
+		       "use raidtools 0.90 mkraid --upgrade to upgrade the array "
+		       "without data loss!\n");
 		goto abort;
 	}
 
@@ -2045,7 +2053,8 @@
 		if (dev == startdev)
 			continue;
 		if (md_import_device(dev, 1)) {
-			printk("md: could not import %s, trying to run array nevertheless.\n", partition_name(dev));
+			printk(KERN_WARNING "md: could not import %s, trying to run array nevertheless.\n",
+			       partition_name(dev));
 			continue;
 		}
 		rdev = find_rdev_all(dev);
@@ -2078,7 +2087,7 @@
 #undef AUTORUNNING
 
 
-static int get_version (void * arg)
+static int get_version(void * arg)
 {
 	mdu_version_t ver;
 
@@ -2093,7 +2102,7 @@
 }
 
 #define SET_FROM_SB(x) info.x = mddev->sb->x
-static int get_array_info (mddev_t * mddev, void * arg)
+static int get_array_info(mddev_t * mddev, void * arg)
 {
 	mdu_array_info_t info;
 
@@ -2131,7 +2140,7 @@
 #undef SET_FROM_SB
 
 #define SET_FROM_SB(x) info.x = mddev->sb->disks[nr].x
-static int get_disk_info (mddev_t * mddev, void * arg)
+static int get_disk_info(mddev_t * mddev, void * arg)
 {
 	mdu_disk_info_t info;
 	unsigned int nr;
@@ -2160,7 +2169,7 @@
 
 #define SET_SB(x) mddev->sb->disks[nr].x = info->x
 
-static int add_new_disk (mddev_t * mddev, mdu_disk_info_t *info)
+static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
 {
 	int err, size, persistent;
 	mdk_rdev_t *rdev;
@@ -2169,15 +2178,15 @@
 	dev = MKDEV(info->major,info->minor);
 
 	if (find_rdev_all(dev)) {
-		printk("md: device %s already used in a RAID array!\n",
-				partition_name(dev));
+		printk(KERN_WARNING "md: device %s already used in a RAID array!\n",
+		       partition_name(dev));
 		return -EBUSY;
 	}
 	if (!mddev->sb) {
 		/* expecting a device which has a superblock */
 		err = md_import_device(dev, 1);
 		if (err) {
-			printk("md: md_import_device returned %d\n", err);
+			printk(KERN_WARNING "md: md_import_device returned %d\n", err);
 			return -EINVAL;
 		}
 		rdev = find_rdev_all(dev);
@@ -2189,12 +2198,14 @@
 			mdk_rdev_t *rdev0 = md_list_entry(mddev->disks.next,
 							mdk_rdev_t, same_set);
 			if (!uuid_equal(rdev0, rdev)) {
-				printk("md: %s has different UUID to %s\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+				printk(KERN_WARNING "md: %s has different UUID to %s\n",
+				       partition_name(rdev->dev), partition_name(rdev0->dev));
 				export_rdev(rdev);
 				return -EINVAL;
 			}
 			if (!sb_equal(rdev0->sb, rdev->sb)) {
-				printk("md: %s has same UUID but different superblock to %s\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+				printk(KERN_WARNING "md: %s has same UUID but different superblock to %s\n",
+				       partition_name(rdev->dev), partition_name(rdev0->dev));
 				export_rdev(rdev);
 				return -EINVAL;
 			}
@@ -2219,7 +2230,7 @@
 	if ((info->state & (1<<MD_DISK_FAULTY))==0) {
 		err = md_import_device (dev, 0);
 		if (err) {
-			printk("md: error, md_import_device() returned %d\n", err);
+			printk(KERN_WARNING "md: error, md_import_device() returned %d\n", err);
 			return -EINVAL;
 		}
 		rdev = find_rdev_all(dev);
@@ -2235,7 +2246,7 @@
 
 		persistent = !mddev->sb->not_persistent;
 		if (!persistent)
-			printk("md: nonpersistent superblock ...\n");
+			printk(KERN_INFO "md: nonpersistent superblock ...\n");
 
 		size = calc_dev_size(dev, mddev, persistent);
 		rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
@@ -2253,24 +2264,24 @@
 }
 #undef SET_SB
 
-static int hot_generate_error (mddev_t * mddev, kdev_t dev)
+static int hot_generate_error(mddev_t * mddev, kdev_t dev)
 {
 	struct request_queue *q;
 	mdk_rdev_t *rdev;
 	mdp_disk_t *disk;
- 
+
 	if (!mddev->pers)
 		return -ENODEV;
- 
-	printk("md: trying to generate %s error in md%d ... \n",
+
+	printk(KERN_INFO "md: trying to generate %s error in md%d ... \n",
 		partition_name(dev), mdidx(mddev));
- 
+
 	rdev = find_rdev(mddev, dev);
 	if (!rdev) {
 		MD_BUG();
 		return -ENXIO;
 	}
- 
+
 	if (rdev->desc_nr == -1) {
 		MD_BUG();
 		return -EINVAL;
@@ -2278,19 +2289,19 @@
 	disk = &mddev->sb->disks[rdev->desc_nr];
 	if (!disk_active(disk))
 		return -ENODEV;
- 
+
 	q = blk_get_queue(rdev->dev);
 	if (!q) {
 		MD_BUG();
 		return -ENODEV;
 	}
-	printk("md: okay, generating error!\n");
+	printk(KERN_INFO "md: okay, generating error!\n");
 //	q->oneshot_error = 1; // disabled for now
- 
+
 	return 0;
 }
 
-static int hot_remove_disk (mddev_t * mddev, kdev_t dev)
+static int hot_remove_disk(mddev_t * mddev, kdev_t dev)
 {
 	int err;
 	mdk_rdev_t *rdev;
@@ -2299,12 +2310,12 @@
 	if (!mddev->pers)
 		return -ENODEV;
 
-	printk("md: trying to remove %s from md%d ... \n",
+	printk(KERN_INFO "md: trying to remove %s from md%d ... \n",
 		partition_name(dev), mdidx(mddev));
 
 	if (!mddev->pers->diskop) {
-		printk("md%d: personality does not support diskops!\n",
-								 mdidx(mddev));
+		printk(KERN_WARNING "md%d: personality does not support diskops!\n",
+		       mdidx(mddev));
 		return -EINVAL;
 	}
 
@@ -2325,7 +2336,7 @@
 		MD_BUG();
 		return -EINVAL;
 	}
-	
+
 	err = mddev->pers->diskop(mddev, &disk, DISKOP_HOT_REMOVE_DISK);
 	if (err == -EBUSY) {
 		MD_BUG();
@@ -2343,12 +2354,12 @@
 
 	return 0;
 busy:
-	printk("md: cannot remove active disk %s from md%d ... \n",
+	printk(KERN_WARNING "md: cannot remove active disk %s from md%d ... \n",
 		partition_name(dev), mdidx(mddev));
 	return -EBUSY;
 }
 
-static int hot_add_disk (mddev_t * mddev, kdev_t dev)
+static int hot_add_disk(mddev_t * mddev, kdev_t dev)
 {
 	int i, err, persistent;
 	unsigned int size;
@@ -2358,12 +2369,12 @@
 	if (!mddev->pers)
 		return -ENODEV;
 
-	printk("md: trying to hot-add %s to md%d ... \n",
+	printk(KERN_INFO "md: trying to hot-add %s to md%d ... \n",
 		partition_name(dev), mdidx(mddev));
 
 	if (!mddev->pers->diskop) {
-		printk("md%d: personality does not support diskops!\n",
-								 mdidx(mddev));
+		printk(KERN_WARNING "md%d: personality does not support diskops!\n",
+		       mdidx(mddev));
 		return -EINVAL;
 	}
 
@@ -2371,7 +2382,7 @@
 	size = calc_dev_size(dev, mddev, persistent);
 
 	if (size < mddev->sb->size) {
-		printk("md%d: disk size %d blocks < array size %d\n",
+		printk(KERN_WARNING "md%d: disk size %d blocks < array size %d\n",
 				mdidx(mddev), size, mddev->sb->size);
 		return -ENOSPC;
 	}
@@ -2382,7 +2393,7 @@
 
 	err = md_import_device (dev, 0);
 	if (err) {
-		printk("md: error, md_import_device() returned %d\n", err);
+		printk(KERN_WARNING "md: error, md_import_device() returned %d\n", err);
 		return -EINVAL;
 	}
 	rdev = find_rdev_all(dev);
@@ -2391,7 +2402,7 @@
 		return -EINVAL;
 	}
 	if (rdev->faulty) {
-		printk("md: can not hot-add faulty %s disk to md%d!\n",
+		printk(KERN_WARNING "md: can not hot-add faulty %s disk to md%d!\n",
 				partition_name(dev), mdidx(mddev));
 		err = -EINVAL;
 		goto abort_export;
@@ -2416,7 +2427,8 @@
 			break;
 	}
 	if (i == MD_SB_DISKS) {
-		printk("md%d: can not hot-add to full array!\n", mdidx(mddev));
+		printk(KERN_WARNING "md%d: can not hot-add to full array!\n",
+		       mdidx(mddev));
 		err = -EBUSY;
 		goto abort_unbind_export;
 	}
@@ -2470,7 +2482,7 @@
 }
 
 #define SET_SB(x) mddev->sb->x = info->x
-static int set_array_info (mddev_t * mddev, mdu_array_info_t *info)
+static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
 {
 
 	if (alloc_array_sb(mddev))
@@ -2511,37 +2523,37 @@
 }
 #undef SET_SB
 
-static int set_disk_info (mddev_t * mddev, void * arg)
+static int set_disk_info(mddev_t * mddev, void * arg)
 {
-	printk("md: not yet");
+	printk(KERN_INFO "md: not yet");
 	return -EINVAL;
 }
 
-static int clear_array (mddev_t * mddev)
+static int clear_array(mddev_t * mddev)
 {
-	printk("md: not yet");
+	printk(KERN_INFO "md: not yet");
 	return -EINVAL;
 }
 
-static int write_raid_info (mddev_t * mddev)
+static int write_raid_info(mddev_t * mddev)
 {
-	printk("md: not yet");
+	printk(KERN_INFO "md: not yet");
 	return -EINVAL;
 }
 
-static int protect_array (mddev_t * mddev)
+static int protect_array(mddev_t * mddev)
 {
-	printk("md: not yet");
+	printk(KERN_INFO "md: not yet");
 	return -EINVAL;
 }
 
-static int unprotect_array (mddev_t * mddev)
+static int unprotect_array(mddev_t * mddev)
 {
-	printk("md: not yet");
+	printk(KERN_INFO "md: not yet");
 	return -EINVAL;
 }
 
-static int set_disk_faulty (mddev_t *mddev, kdev_t dev)
+static int set_disk_faulty(mddev_t *mddev, kdev_t dev)
 {
 	int ret;
 
@@ -2549,7 +2561,7 @@
 	return ret;
 }
 
-static int md_ioctl (struct inode *inode, struct file *file,
+static int md_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
 	unsigned int minor;
@@ -2627,7 +2639,7 @@
 		case SET_ARRAY_INFO:
 		case START_ARRAY:
 			if (mddev) {
-				printk("md: array md%d already exists!\n",
+				printk(KERN_WARNING "md: array md%d already exists!\n",
 								mdidx(mddev));
 				err = -EEXIST;
 				goto abort;
@@ -2649,12 +2661,13 @@
 			 */
 			err = lock_mddev(mddev);
 			if (err) {
-				printk("md: ioctl, reason %d, cmd %d\n", err, cmd);
+				printk(KERN_WARNING "md: ioctl, reason %d, cmd %d\n",
+				       err, cmd);
 				goto abort;
 			}
 
 			if (mddev->sb) {
-				printk("md: array md%d already has a superblock!\n",
+				printk(KERN_WARNING "md: array md%d already has a superblock!\n",
 					mdidx(mddev));
 				err = -EBUSY;
 				goto abort_unlock;
@@ -2667,7 +2680,7 @@
 				}
 				err = set_array_info(mddev, &info);
 				if (err) {
-					printk("md: couldnt set array info. %d\n", err);
+					printk(KERN_WARNING "md: couldnt set array info. %d\n", err);
 					goto abort_unlock;
 				}
 			}
@@ -2679,7 +2692,7 @@
 			 */
 			err = autostart_array((kdev_t)arg, dev);
 			if (err) {
-				printk("md: autostart %s failed!\n",
+				printk(KERN_WARNING "md: autostart %s failed!\n",
 					partition_name((kdev_t)arg));
 				goto abort;
 			}
@@ -2698,7 +2711,7 @@
 	}
 	err = lock_mddev(mddev);
 	if (err) {
-		printk("md: ioctl lock interrupted, reason %d, cmd %d\n",err, cmd);
+		printk(KERN_INFO "md: ioctl lock interrupted, reason %d, cmd %d\n",err, cmd);
 		goto abort;
 	}
 	/* if we don't have a superblock yet, only ADD_NEW_DISK or STOP_ARRAY is allowed */
@@ -2839,7 +2852,9 @@
 		}
 
 		default:
-			printk(KERN_WARNING "md: %s(pid %d) used obsolete MD ioctl, upgrade your software to use new ictls.\n", current->comm, current->pid);
+			printk(KERN_WARNING "md: %s(pid %d) used obsolete MD ioctl, "
+			       "upgrade your software to use new ictls.\n",
+			       current->comm, current->pid);
 			err = -EINVAL;
 			goto abort_unlock;
 	}
@@ -2852,12 +2867,12 @@
 	return err;
 done:
 	if (err)
-		printk("md: huh12?\n");
+		MD_BUG();
 abort:
 	return err;
 }
 
-static int md_open (struct inode *inode, struct file *file)
+static int md_open(struct inode *inode, struct file *file)
 {
 	/*
 	 * Always succeed, but increment the usage count
@@ -2868,7 +2883,7 @@
 	return (0);
 }
 
-static int md_release (struct inode *inode, struct file * file)
+static int md_release(struct inode *inode, struct file * file)
 {
 	mddev_t *mddev = kdev_to_mddev(inode->i_rdev);
 	if (mddev)
@@ -2937,11 +2952,8 @@
 			run(thread->data);
 			run_task_queue(&tq_disk);
 		}
-		if (md_signal_pending(current)) {
-			printk("md: %8s(%d) flushing signals.\n", current->comm,
-				current->pid);
+		if (md_signal_pending(current))
 			md_flush_signals();
-		}
 	}
 	complete(thread->event);
 	return 0;
@@ -2954,22 +2966,22 @@
 	wake_up(&thread->wqueue);
 }
 
-mdk_thread_t *md_register_thread (void (*run) (void *),
+mdk_thread_t *md_register_thread(void (*run) (void *),
 						void *data, const char *name)
 {
 	mdk_thread_t *thread;
 	int ret;
 	struct completion event;
-	
+
 	thread = (mdk_thread_t *) kmalloc
 				(sizeof(mdk_thread_t), GFP_KERNEL);
 	if (!thread)
 		return NULL;
-	
+
 	memset(thread, 0, sizeof(mdk_thread_t));
 	md_init_waitqueue_head(&thread->wqueue);
 
-	init_completion(&event);	
+	init_completion(&event);
 	thread->event = &event;
 	thread->run = run;
 	thread->data = data;
@@ -2983,22 +2995,22 @@
 	return thread;
 }
 
-void md_interrupt_thread (mdk_thread_t *thread)
+void md_interrupt_thread(mdk_thread_t *thread)
 {
 	if (!thread->tsk) {
 		MD_BUG();
 		return;
 	}
-	printk("md: interrupting MD-thread pid %d\n", thread->tsk->pid);
+	dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
 	send_sig(SIGKILL, thread->tsk, 1);
 }
 
-void md_unregister_thread (mdk_thread_t *thread)
+void md_unregister_thread(mdk_thread_t *thread)
 {
 	struct completion event;
 
 	init_completion(&event);
-	
+
 	thread->event = &event;
 	thread->run = NULL;
 	thread->name = NULL;
@@ -3007,7 +3019,7 @@
 	kfree(thread);
 }
 
-void md_recover_arrays (void)
+void md_recover_arrays(void)
 {
 	if (!md_recovery_thread) {
 		MD_BUG();
@@ -3017,12 +3029,15 @@
 }
 
 
-int md_error (mddev_t *mddev, kdev_t rdev)
+int md_error(mddev_t *mddev, kdev_t rdev)
 {
 	mdk_rdev_t * rrdev;
 
-/*	printk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev), __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2),__builtin_return_address(3));
- */
+	dprintk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
+		MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev),
+		__builtin_return_address(0),__builtin_return_address(1),
+		__builtin_return_address(2),__builtin_return_address(3));
+
 	if (!mddev) {
 		MD_BUG();
 		return 0;
@@ -3030,7 +3045,7 @@
 	rrdev = find_rdev(mddev, rdev);
 	if (!rrdev || rrdev->faulty)
 		return 0;
-	if (mddev->pers->error_handler == NULL
+	if (!mddev->pers->error_handler
 			|| mddev->pers->error_handler(mddev,rdev) <= 0) {
 		free_disk_sb(rrdev);
 		rrdev->faulty = 1;
@@ -3048,7 +3063,7 @@
 	return 0;
 }
 
-static int status_unused (char * page)
+static int status_unused(char * page)
 {
 	int sz = 0, i = 0;
 	mdk_rdev_t *rdev;
@@ -3074,7 +3089,7 @@
 }
 
 
-static int status_resync (char * page, mddev_t * mddev)
+static int status_resync(char * page, mddev_t * mddev)
 {
 	int sz = 0;
 	unsigned long max_blocks, resync, res, dt, db, rt;
@@ -3084,7 +3099,7 @@
 
 	/*
 	 * Should not happen.
-	 */		
+	 */
 	if (!max_blocks) {
 		MD_BUG();
 		return 0;
@@ -3126,7 +3141,7 @@
 	if (!dt) dt++;
 	db = resync - (mddev->resync_mark_cnt/2);
 	rt = (dt * ((max_blocks-resync) / (db/100+1)))/100;
-	
+
 	sz += sprintf(page + sz, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
 
 	sz += sprintf(page + sz, " speed=%ldK/sec", db/dt);
@@ -3160,7 +3175,7 @@
 		sz += sprintf(page + sz, "md%d : %sactive", mdidx(mddev),
 						mddev->pers ? "" : "in");
 		if (mddev->pers) {
-			if (mddev->ro)	
+			if (mddev->ro)
 				sz += sprintf(page + sz, " (read-only)");
 			sz += sprintf(page + sz, " %s", mddev->pers->name);
 		}
@@ -3200,12 +3215,12 @@
 		}
 		sz += sprintf(page + sz, "\n");
 	}
-	sz += status_unused (page + sz);
+	sz += status_unused(page + sz);
 
 	return sz;
 }
 
-int register_md_personality (int pnum, mdk_personality_t *p)
+int register_md_personality(int pnum, mdk_personality_t *p)
 {
 	if (pnum >= MAX_PERSONALITY) {
 		MD_BUG();
@@ -3222,7 +3237,7 @@
 	return 0;
 }
 
-int unregister_md_personality (int pnum)
+int unregister_md_personality(int pnum)
 {
 	if (pnum >= MAX_PERSONALITY) {
 		MD_BUG();
@@ -3273,7 +3288,7 @@
 	sync_io[major][index] += nr_sectors;
 }
 
-static int is_mddev_idle (mddev_t *mddev)
+static int is_mddev_idle(mddev_t *mddev)
 {
 	mdk_rdev_t * rdev;
 	struct md_list_head *tmp;
@@ -3291,9 +3306,7 @@
 		curr_events = kstat.dk_drive_rblk[major][idx] +
 						kstat.dk_drive_wblk[major][idx] ;
 		curr_events -= sync_io[major][idx];
-//		printk("md: events(major: %d, idx: %d): %ld\n", major, idx, curr_events);
 		if ((curr_events - rdev->last_events) > 32) {
-//			printk("!I(%ld)%x", curr_events - rdev->last_events, rdev->dev);
 			rdev->last_events = curr_events;
 			idle = 0;
 		}
@@ -3321,7 +3334,7 @@
 	unsigned int max_sectors, currspeed,
 		j, window, err, serialize;
 	unsigned long mark[SYNC_MARKS];
-	unsigned long mark_cnt[SYNC_MARKS];	
+	unsigned long mark_cnt[SYNC_MARKS];
 	int last_mark,m;
 	struct md_list_head *tmp;
 	unsigned long last_check;
@@ -3337,7 +3350,9 @@
 		if (mddev2 == mddev)
 			continue;
 		if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
-			printk(KERN_INFO "md: delaying resync of md%d until md%d has finished resync (they share one or more physical units)\n", mdidx(mddev), mdidx(mddev2));
+			printk(KERN_INFO "md: delaying resync of md%d until md%d "
+			       "has finished resync (they share one or more physical units)\n",
+			       mdidx(mddev), mdidx(mddev2));
 			serialize = 1;
 			break;
 		}
@@ -3359,7 +3374,9 @@
 	printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
 	printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec/disc.\n",
 						sysctl_speed_limit_min);
-	printk(KERN_INFO "md: using maximum available idle IO bandwith (but not more than %d KB/sec) for reconstruction.\n", sysctl_speed_limit_max);
+	printk(KERN_INFO "md: using maximum available idle IO bandwith "
+	       "(but not more than %d KB/sec) for reconstruction.\n",
+	       sysctl_speed_limit_max);
 
 	/*
 	 * Resync has low priority.
@@ -3379,7 +3396,8 @@
 	 * Tune reconstruction:
 	 */
 	window = MAX_READAHEAD*(PAGE_SIZE/512);
-	printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n",window/2,max_sectors/2);
+	printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n",
+	       window/2,max_sectors/2);
 
 	atomic_set(&mddev->recovery_active, 0);
 	init_waitqueue_head(&mddev->recovery_wait);
@@ -3401,14 +3419,14 @@
 			continue;
 
 		last_check = j;
-		
+
 		run_task_queue(&tq_disk);
 
 	repeat:
 		if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
 			/* step marks */
 			int next = (last_mark+1) % SYNC_MARKS;
-			
+
 			mddev->resync_mark = mark[next];
 			mddev->resync_mark_cnt = mark_cnt[next];
 			mark[next] = jiffies;
@@ -3422,7 +3440,7 @@
 			 * got a signal, exit.
 			 */
 			mddev->curr_resync = 0;
-			printk("md: md_do_sync() got signal ... exiting\n");
+			printk(KERN_INFO "md: md_do_sync() got signal ... exiting\n");
 			md_flush_signals();
 			err = -EINTR;
 			goto out;
@@ -3476,7 +3494,7 @@
  * of my root partition with the first 0.5 gigs of my /home partition ... so
  * i'm a bit nervous ;)
  */
-void md_do_recovery (void *data)
+void md_do_recovery(void *data)
 {
 	int err;
 	mddev_t *mddev;
@@ -3495,15 +3513,18 @@
 		if (sb->active_disks == sb->raid_disks)
 			continue;
 		if (!sb->spare_disks) {
-			printk(KERN_ERR "md%d: no spare disk to reconstruct array! -- continuing in degraded mode\n", mdidx(mddev));
+			printk(KERN_ERR "md%d: no spare disk to reconstruct array! "
+			       "-- continuing in degraded mode\n", mdidx(mddev));
 			continue;
 		}
 		/*
 		 * now here we get the spare and resync it.
 		 */
-		if ((spare = get_spare(mddev)) == NULL)
+		spare = get_spare(mddev);
+		if (!spare)
 			continue;
-		printk(KERN_INFO "md%d: resyncing spare disk %s to replace failed disk\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+		printk(KERN_INFO "md%d: resyncing spare disk %s to replace failed disk\n",
+		       mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
 		if (!mddev->pers->diskop)
 			continue;
 		if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE))
@@ -3512,7 +3533,8 @@
 		mddev->recovery_running = 1;
 		err = md_do_sync(mddev, spare);
 		if (err == -EIO) {
-			printk(KERN_INFO "md%d: spare disk %s failed, skipping to next spare.\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+			printk(KERN_INFO "md%d: spare disk %s failed, skipping to next spare.\n",
+			       mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
 			if (!disk_faulty(spare)) {
 				mddev->pers->diskop(mddev,&spare,DISKOP_SPARE_INACTIVE);
 				mark_disk_faulty(spare);
@@ -3556,7 +3578,7 @@
 		goto restart;
 	}
 	printk(KERN_INFO "md: recovery thread finished ...\n");
-	
+
 }
 
 int md_notify_reboot(struct notifier_block *this,
@@ -3589,7 +3611,7 @@
 	priority:	INT_MAX, /* before any real devices */
 };
 
-static void md_geninit (void)
+static void md_geninit(void)
 {
 	int i;
 
@@ -3611,18 +3633,18 @@
 #endif
 }
 
-int md__init md_init (void)
+int md__init md_init(void)
 {
 	static char * name = "mdrecoveryd";
 	int minor;
-	
-	printk (KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d, MD_SB_DISKS=%d\n",
+
+	printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d, MD_SB_DISKS=%d\n",
 			MD_MAJOR_VERSION, MD_MINOR_VERSION,
 			MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
 
 	if (devfs_register_blkdev (MAJOR_NR, "md", &md_fops))
 	{
-		printk (KERN_ALERT "md: Unable to get major %d for md\n", MAJOR_NR);
+		printk(KERN_ALERT "md: Unable to get major %d for md\n", MAJOR_NR);
 		return (-1);
 	}
 	devfs_handle = devfs_mk_dir (NULL, "md", NULL);
@@ -3637,7 +3659,7 @@
 
 	/* forward all md request to md_make_request */
 	blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), md_make_request);
-	
+
 
 	read_ahead[MAJOR_NR] = INT_MAX;
 
@@ -3678,14 +3700,14 @@
 static int detected_devices[128];
 static int dev_cnt;
 
-void md_autodetect_dev (kdev_t dev)
+void md_autodetect_dev(kdev_t dev)
 {
 	if (dev_cnt >= 0 && dev_cnt < 127)
 		detected_devices[dev_cnt++] = dev;
 }
 
 
-static void autostart_arrays (void)
+static void autostart_arrays(void)
 {
 	mdk_rdev_t *rdev;
 	int i;
@@ -3753,21 +3775,22 @@
 	char *str1 = str;
 
 	if (get_option(&str, &minor) != 2) {	/* MD Number */
-		printk("md: Too few arguments supplied to md=.\n");
+		printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
 		return 0;
 	}
 	if (minor >= MAX_MD_DEVS) {
-		printk ("md: md=%d, Minor device number too high.\n", minor);
+		printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
 		return 0;
 	} else if (md_setup_args.device_names[minor]) {
-		printk ("md: md=%d, Specified more then once. Replacing previous definition.\n", minor);
+		printk(KERN_WARNING "md: md=%d, Specified more then once. "
+		       "Replacing previous definition.\n", minor);
 	}
 	switch (get_option(&str, &level)) {	/* RAID Personality */
 	case 2: /* could be 0 or -1.. */
 		if (level == 0 || level == -1) {
 			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
 					get_option(&str, &fault) != 2) {
-				printk("md: Too few arguments supplied to md=.\n");
+				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
 				return 0;
 			}
 			md_setup_args.pers[minor] = level;
@@ -3782,8 +3805,9 @@
 				pername = "raid0";
 				break;
 			default:
-				printk ("md: The kernel has not been configured for raid%d"
-					" support!\n", level);
+				printk(KERN_WARNING
+				       "md: The kernel has not been configured for raid%d support!\n",
+				       level);
 				return 0;
 			}
 			md_setup_args.pers[minor] = level;
@@ -3797,11 +3821,11 @@
 		md_setup_args.pers[minor] = 0;
 		pername="super-block";
 	}
-	
-	printk ("md: Will configure md%d (%s) from %s, below.\n",
+
+	printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
 		minor, pername, str);
 	md_setup_args.device_names[minor] = str;
-			
+
 	return 1;
 }
 
@@ -3819,13 +3843,14 @@
 		mdu_disk_info_t dinfo;
 
 		if ((devname = md_setup_args.device_names[minor]) == 0)	continue;
-	
+
 		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
 
 			char *p;
 			void *handle;
-	
-			if ((p = strchr(devname, ',')) != NULL)
+
+			p = strchr(devname, ',');
+			if (p)
 				*p++ = 0;
 
 			dev = name_to_kdev_t(devname);
@@ -3837,29 +3862,31 @@
 				dev = MKDEV(major, minor);
 			}
 			if (dev == 0) {
-				printk ("md: Unknown device name: %s\n", devname);
+				printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
 				break;
 			}
-			
+
 			devices[i] = dev;
 			md_setup_args.device_set[minor] = 1;
-			
+
 			devname = p;
 		}
 		devices[i] = 0;
-		
+
 		if (md_setup_args.device_set[minor] == 0)
 			continue;
-		
+
 		if (mddev_map[minor].mddev) {
-			printk("md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", minor);
+			printk(KERN_WARNING
+			       "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
+			       minor);
 			continue;
 		}
-		printk("md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
-		
+		printk(KERN_INFO "md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
+
 		mddev = alloc_mddev(MKDEV(MD_MAJOR,minor));
-		if (mddev == NULL) {
-			printk("md: kmalloc failed - cannot start array %d\n", minor);
+		if (!mddev) {
+			printk(KERN_ERR "md: kmalloc failed - cannot start array %d\n", minor);
 			continue;
 		}
 		if (md_setup_args.pers[minor]) {
@@ -3905,7 +3932,7 @@
 		if (err) {
 			mddev->sb_dirty = 0;
 			do_md_stop(mddev, 0);
-			printk("md: starting md%d failed\n", minor);
+			printk(KERN_WARNING "md: starting md%d failed\n", minor);
 		}
 	}
 }
@@ -3950,7 +3977,7 @@
 
 #else /* It is a MODULE */
 
-int init_module (void)
+int init_module(void)
 {
 	return md_init();
 }
@@ -3965,7 +3992,7 @@
 }
 
 
-void cleanup_module (void)
+void cleanup_module(void)
 {
 	md_unregister_thread(md_recovery_thread);
 	devfs_unregister(devfs_handle);
@@ -3984,7 +4011,7 @@
 	blk_size[MAJOR_NR] = NULL;
 	max_readahead[MAJOR_NR] = NULL;
 	hardsect_size[MAJOR_NR] = NULL;
-	
+
 	free_device_names();
 
 }
diff -u --recursive --new-file v2.4.10/linux/drivers/md/multipath.c linux/drivers/md/multipath.c
--- v2.4.10/linux/drivers/md/multipath.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/md/multipath.c	Sun Sep 30 12:26:06 2001
@@ -1258,4 +1258,4 @@
 
 module_init(multipath_init);
 module_exit(multipath_exit);
-
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/md/raid0.c linux/drivers/md/raid0.c
--- v2.4.10/linux/drivers/md/raid0.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/md/raid0.c	Sun Sep 30 12:26:06 2001
@@ -347,5 +347,4 @@
 
 module_init(raid0_init);
 module_exit(raid0_exit);
-
-
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/md/raid1.c linux/drivers/md/raid1.c
--- v2.4.10/linux/drivers/md/raid1.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/md/raid1.c	Sun Sep 30 12:26:06 2001
@@ -1826,4 +1826,4 @@
 
 module_init(raid1_init);
 module_exit(raid1_exit);
-
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/md/raid5.c linux/drivers/md/raid5.c
--- v2.4.10/linux/drivers/md/raid5.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/md/raid5.c	Sun Sep 30 12:26:06 2001
@@ -2026,4 +2026,4 @@
 
 module_init(raid5_init);
 module_exit(raid5_exit);
-
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/md/xor.c linux/drivers/md/xor.c
--- v2.4.10/linux/drivers/md/xor.c	Mon Jan 22 14:49:36 2001
+++ linux/drivers/md/xor.c	Sun Sep 30 12:26:06 2001
@@ -137,5 +137,6 @@
 }
 
 MD_EXPORT_SYMBOL(xor_block);
+MODULE_LICENSE("GPL");
 
 module_init(calibrate_xor_block);
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/miropcm20-radio.c linux/drivers/media/radio/miropcm20-radio.c
--- v2.4.10/linux/drivers/media/radio/miropcm20-radio.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/media/radio/miropcm20-radio.c	Sun Sep 30 12:26:06 2001
@@ -273,6 +273,7 @@
 
 MODULE_AUTHOR("Ruurd Reitsma");
 MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
+MODULE_LICENSE("GPL");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/miropcm20-rds-core.c linux/drivers/media/radio/miropcm20-rds-core.c
--- v2.4.10/linux/drivers/media/radio/miropcm20-rds-core.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/media/radio/miropcm20-rds-core.c	Sun Sep 30 12:26:06 2001
@@ -208,3 +208,4 @@
 void __exit unload_aci_rds(void)
 {
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/miropcm20-rds.c linux/drivers/media/radio/miropcm20-rds.c
--- v2.4.10/linux/drivers/media/radio/miropcm20-rds.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/media/radio/miropcm20-rds.c	Sun Sep 30 12:26:06 2001
@@ -138,3 +138,4 @@
 
 module_init(miropcm20_rds_init);
 module_exit(miropcm20_rds_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-aimslab.c linux/drivers/media/radio/radio-aimslab.c
--- v2.4.10/linux/drivers/media/radio/radio-aimslab.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-aimslab.c	Sun Sep 30 12:26:06 2001
@@ -370,6 +370,8 @@
 
 MODULE_AUTHOR("M.Kirkwood");
 MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-aztech.c linux/drivers/media/radio/radio-aztech.c
--- v2.4.10/linux/drivers/media/radio/radio-aztech.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-aztech.c	Sun Sep 30 12:26:06 2001
@@ -312,6 +312,8 @@
 
 MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
 MODULE_DESCRIPTION("A driver for the Aztech radio card.");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM(radio_nr, "i");
 MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-cadet.c linux/drivers/media/radio/radio-cadet.c
--- v2.4.10/linux/drivers/media/radio/radio-cadet.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-cadet.c	Sun Sep 30 12:26:06 2001
@@ -629,6 +629,8 @@
 
 MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
 MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-gemtek-pci.c linux/drivers/media/radio/radio-gemtek-pci.c
--- v2.4.10/linux/drivers/media/radio/radio-gemtek-pci.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/radio/radio-gemtek-pci.c	Sun Sep 30 12:26:06 2001
@@ -439,6 +439,8 @@
 
 MODULE_AUTHOR( "Vladimir Shebordaev <vshebordaev@mail.ru>" );
 MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" );
+MODULE_LICENSE("GPL");
+
 MODULE_PARM( mx, "b" );
 MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" );
 MODULE_PARM( nr_radio, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-gemtek.c linux/drivers/media/radio/radio-gemtek.c
--- v2.4.10/linux/drivers/media/radio/radio-gemtek.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-gemtek.c	Sun Sep 30 12:26:06 2001
@@ -294,6 +294,8 @@
 
 MODULE_AUTHOR("Jonas Munsin");
 MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (0x20c or 0x248 have been reported to work for the combined sound/radiocard)).");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-maestro.c linux/drivers/media/radio/radio-maestro.c
--- v2.4.10/linux/drivers/media/radio/radio-maestro.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-maestro.c	Sun Sep 30 12:26:06 2001
@@ -298,6 +298,7 @@
 
 MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
 MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
+MODULE_LICENSE("GPL");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-maxiradio.c linux/drivers/media/radio/radio-maxiradio.c
--- v2.4.10/linux/drivers/media/radio/radio-maxiradio.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-maxiradio.c	Sun Sep 30 12:26:06 2001
@@ -316,6 +316,8 @@
 
 MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
 MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
+MODULE_LICENSE("GPL");
+
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-rtrack2.c linux/drivers/media/radio/radio-rtrack2.c
--- v2.4.10/linux/drivers/media/radio/radio-rtrack2.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-rtrack2.c	Sun Sep 30 12:26:06 2001
@@ -256,6 +256,8 @@
 
 MODULE_AUTHOR("Ben Pfaff");
 MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-sf16fmi.c linux/drivers/media/radio/radio-sf16fmi.c
--- v2.4.10/linux/drivers/media/radio/radio-sf16fmi.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/media/radio/radio-sf16fmi.c	Sun Sep 30 12:26:06 2001
@@ -352,6 +352,8 @@
 
 MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
 MODULE_DESCRIPTION("A driver for the SF16MI radio.");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-terratec.c linux/drivers/media/radio/radio-terratec.c
--- v2.4.10/linux/drivers/media/radio/radio-terratec.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-terratec.c	Sun Sep 30 12:26:06 2001
@@ -338,6 +338,7 @@
 
 MODULE_AUTHOR("R.OFFERMANNS & others");
 MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
+MODULE_LICENSE("GPL");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-trust.c linux/drivers/media/radio/radio-trust.c
--- v2.4.10/linux/drivers/media/radio/radio-trust.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-trust.c	Sun Sep 30 12:26:06 2001
@@ -331,6 +331,8 @@
 
 MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
 MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-typhoon.c linux/drivers/media/radio/radio-typhoon.c
--- v2.4.10/linux/drivers/media/radio/radio-typhoon.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-typhoon.c	Sun Sep 30 12:26:06 2001
@@ -317,6 +317,8 @@
 
 MODULE_AUTHOR("Dr. Henrik Seidel");
 MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
 MODULE_PARM(mutefreq, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/radio/radio-zoltrix.c linux/drivers/media/radio/radio-zoltrix.c
--- v2.4.10/linux/drivers/media/radio/radio-zoltrix.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-zoltrix.c	Sun Sep 30 12:26:06 2001
@@ -393,6 +393,8 @@
 
 MODULE_AUTHOR("C.van Schaik");
 MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
 MODULE_PARM(radio_nr, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/adv7175.c linux/drivers/media/video/adv7175.c
--- v2.4.10/linux/drivers/media/video/adv7175.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/adv7175.c	Sun Sep 30 12:26:06 2001
@@ -476,3 +476,4 @@
 
 module_init(adv7175_init);
 module_exit(adv7175_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/bt819.c linux/drivers/media/video/bt819.c
--- v2.4.10/linux/drivers/media/video/bt819.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/bt819.c	Sun Sep 30 12:26:06 2001
@@ -494,3 +494,4 @@
 
 module_init(bt819_setup);
 module_exit(bt819_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/bt856.c linux/drivers/media/video/bt856.c
--- v2.4.10/linux/drivers/media/video/bt856.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/bt856.c	Sun Sep 30 12:26:06 2001
@@ -301,3 +301,4 @@
 
 module_init(bt856_init);
 module_exit(bt856_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/bttv-cards.c linux/drivers/media/video/bttv-cards.c
--- v2.4.10/linux/drivers/media/video/bttv-cards.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/bttv-cards.c	Sun Sep 30 12:26:06 2001
@@ -83,6 +83,7 @@
 MODULE_PARM(gpiomask,"i");
 MODULE_PARM(audioall,"i");
 MODULE_PARM(audiomux,"1-5i");
+MODULE_LICENSE("GPL");
 
 /* kernel args */
 #ifndef MODULE
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- v2.4.10/linux/drivers/media/video/bttv-driver.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/bttv-driver.c	Sun Sep 30 12:26:06 2001
@@ -105,6 +105,7 @@
 
 MODULE_DESCRIPTION("bttv - v4l driver module for bt848/878 based cards");
 MODULE_AUTHOR("Ralph  Metzler & Marcus Metzler & Gerd Knorr");
+MODULE_LICENSE("GPL");
 
 /* kernel args */
 #ifndef MODULE
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/bttv-if.c linux/drivers/media/video/bttv-if.c
--- v2.4.10/linux/drivers/media/video/bttv-if.c	Mon Feb 19 14:43:36 2001
+++ linux/drivers/media/video/bttv-if.c	Sun Sep 30 12:26:06 2001
@@ -351,6 +351,7 @@
 	btv->i2c_rc = i2c_bit_add_bus(&btv->i2c_adap);
 	return btv->i2c_rc;
 }
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/bw-qcam.c linux/drivers/media/video/bw-qcam.c
--- v2.4.10/linux/drivers/media/video/bw-qcam.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/bw-qcam.c	Sun Sep 30 12:26:06 2001
@@ -1051,3 +1051,4 @@
 	return 0;
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/c-qcam.c linux/drivers/media/video/c-qcam.c
--- v2.4.10/linux/drivers/media/video/c-qcam.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/c-qcam.c	Sun Sep 30 12:26:06 2001
@@ -876,6 +876,8 @@
 
 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
 MODULE_DESCRIPTION(BANNER);
+MODULE_LICENSE("GPL");
+
 MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
 probe=<0|1|2> for camera detection method\n\
 force_rgb=<0|1> for RGB data format (default BGR)");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/cpia.c linux/drivers/media/video/cpia.c
--- v2.4.10/linux/drivers/media/video/cpia.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/cpia.c	Fri Oct  5 12:04:50 2001
@@ -3,9 +3,9 @@
  *
  * Supports CPiA based Video Camera's.
  *
- * (C) Copyright 1999-2000 Peter Pregler,
- * (C) Copyright 1999-2000 Scott J. Bertin,
- * (C) Copyright 1999-2000 Johannes Erdfelt, jerdfelt@valinux.com
+ * (C) Copyright 1999-2000 Peter Pregler
+ * (C) Copyright 1999-2000 Scott J. Bertin
+ * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.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
@@ -56,7 +56,7 @@
 
 #ifdef MODULE
 MODULE_PARM(video_nr,"i");
-MODULE_AUTHOR("Scott J. Bertin <sbertin@mindspring.com> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <jerdfelt@valinux.com>");
+MODULE_AUTHOR("Scott J. Bertin <sbertin@mindspring.com> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfelt.com>");
 MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
 MODULE_SUPPORTED_DEVICE("video");
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/cpia_usb.c linux/drivers/media/video/cpia_usb.c
--- v2.4.10/linux/drivers/media/video/cpia_usb.c	Mon Feb 19 10:18:18 2001
+++ linux/drivers/media/video/cpia_usb.c	Fri Oct  5 12:04:50 2001
@@ -4,7 +4,7 @@
  * Supports CPiA based parallel port Video Camera's.
  *
  * Copyright (C) 1999        Jochen Scharrlach <Jochen.Scharrlach@schwaben.de>
- * Copyright (C) 1999, 2000  Johannes Erdfelt <jerdfelt@valinux.com>
+ * Copyright (C) 1999, 2000  Johannes Erdfelt <johannes@erdfelt.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
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/i2c-old.c linux/drivers/media/video/i2c-old.c
--- v2.4.10/linux/drivers/media/video/i2c-old.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/media/video/i2c-old.c	Sun Sep 30 12:26:06 2001
@@ -448,3 +448,4 @@
 {
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/i2c-parport.c linux/drivers/media/video/i2c-parport.c
--- v2.4.10/linux/drivers/media/video/i2c-parport.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/media/video/i2c-parport.c	Sun Sep 30 12:26:06 2001
@@ -149,3 +149,4 @@
   parport_unregister_driver(&parport_i2c_driver);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/meye.c linux/drivers/media/video/meye.c
--- v2.4.10/linux/drivers/media/video/meye.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/meye.c	Sun Sep 30 12:26:06 2001
@@ -1480,6 +1480,8 @@
 
 MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>");
 MODULE_DESCRIPTION("video4linux driver for the MotionEye camera");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(gbuffers,"i");
 MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (32 max)");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/msp3400.c linux/drivers/media/video/msp3400.c
--- v2.4.10/linux/drivers/media/video/msp3400.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/msp3400.c	Sun Sep 30 12:26:06 2001
@@ -131,6 +131,8 @@
 MODULE_PARM(simple,"i");
 MODULE_PARM(amsound,"i");
 MODULE_PARM(dolby,"i");
+MODULE_LICENSE("GPL");
+
 
 /* ---------------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- v2.4.10/linux/drivers/media/video/planb.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/media/video/planb.c	Sun Sep 30 12:26:06 2001
@@ -75,6 +75,8 @@
 MODULE_PARM(def_norm, "i");
 MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
 MODULE_PARM(video_nr,"i");
+MODULE_LICENSE("GPL");
+
 
 /* ------------------ PlanB Exported Functions ------------------ */
 static long planb_write(struct video_device *, const char *, unsigned long, int);
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/pms.c linux/drivers/media/video/pms.c
--- v2.4.10/linux/drivers/media/video/pms.c	Thu May 24 15:14:08 2001
+++ linux/drivers/media/video/pms.c	Sun Sep 30 12:26:06 2001
@@ -1058,6 +1058,8 @@
 MODULE_PARM(io_port,"i");
 MODULE_PARM(mem_base,"i");
 MODULE_PARM(video_nr,"i");
+MODULE_LICENSE("GPL");
+
 
 static void __exit shutdown_mediavision(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/saa5249.c linux/drivers/media/video/saa5249.c
--- v2.4.10/linux/drivers/media/video/saa5249.c	Wed Jul 25 17:10:20 2001
+++ linux/drivers/media/video/saa5249.c	Sun Sep 30 12:26:06 2001
@@ -694,3 +694,4 @@
 	ioctl:		saa5249_ioctl,
 };
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/saa7110.c linux/drivers/media/video/saa7110.c
--- v2.4.10/linux/drivers/media/video/saa7110.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/saa7110.c	Sun Sep 30 12:26:06 2001
@@ -426,3 +426,4 @@
 
 module_init(saa7110_init);
 module_exit(saa7110_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/saa7111.c linux/drivers/media/video/saa7111.c
--- v2.4.10/linux/drivers/media/video/saa7111.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/media/video/saa7111.c	Sun Sep 30 12:26:06 2001
@@ -448,3 +448,4 @@
 
 module_init(saa7111_init);
 module_exit(saa7111_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/saa7185.c linux/drivers/media/video/saa7185.c
--- v2.4.10/linux/drivers/media/video/saa7185.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/media/video/saa7185.c	Sun Sep 30 12:26:06 2001
@@ -406,3 +406,4 @@
 
 module_init(saa7185_init);
 module_exit(saa7185_exit);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c
--- v2.4.10/linux/drivers/media/video/stradis.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/stradis.c	Sun Sep 30 12:26:06 2001
@@ -65,6 +65,8 @@
 
 static int video_nr = -1;
 MODULE_PARM(video_nr,"i");
+MODULE_LICENSE("GPL");
+
 
 #define nDebNormal	0x00480000
 #define nDebNoInc	0x00480000
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/tda7432.c linux/drivers/media/video/tda7432.c
--- v2.4.10/linux/drivers/media/video/tda7432.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/tda7432.c	Sun Sep 30 12:26:06 2001
@@ -50,6 +50,8 @@
 
 MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>");
 MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(debug,"i");
 MODULE_PARM(loudness,"i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/tda9875.c linux/drivers/media/video/tda9875.c
--- v2.4.10/linux/drivers/media/video/tda9875.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/tda9875.c	Sun Sep 30 12:26:06 2001
@@ -34,6 +34,8 @@
 #include "id.h"
 
 MODULE_PARM(debug,"i");
+MODULE_LICENSE("GPL");
+
 
 static int debug = 0;	/* insmod parameter */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/tuner-3036.c linux/drivers/media/video/tuner-3036.c
--- v2.4.10/linux/drivers/media/video/tuner-3036.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/media/video/tuner-3036.c	Sun Sep 30 12:26:06 2001
@@ -220,6 +220,8 @@
 
 MODULE_DESCRIPTION("SAB3036 tuner driver");
 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug,"i");
 MODULE_PARM_DESC(debug,"Enable debugging output");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/tuner.c linux/drivers/media/video/tuner.c
--- v2.4.10/linux/drivers/media/video/tuner.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/tuner.c	Sun Sep 30 12:26:06 2001
@@ -47,6 +47,7 @@
 MODULE_PARM(tv_range,"2i");
 MODULE_PARM(radio_range,"2i");
 MODULE_PARM(pal,"s");
+MODULE_LICENSE("GPL");
 
 struct tuner
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/tvaudio.c linux/drivers/media/video/tvaudio.c
--- v2.4.10/linux/drivers/media/video/tvaudio.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/media/video/tvaudio.c	Sun Sep 30 12:26:06 2001
@@ -1168,6 +1168,7 @@
 
 module_init(audiochip_init_module);
 module_exit(audiochip_cleanup_module);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/tvmixer.c linux/drivers/media/video/tvmixer.c
--- v2.4.10/linux/drivers/media/video/tvmixer.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/media/video/tvmixer.c	Sun Sep 30 12:26:06 2001
@@ -355,3 +355,4 @@
  * c-basic-offset: 8
  * End:
  */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- v2.4.10/linux/drivers/media/video/videodev.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/media/video/videodev.c	Sun Sep 30 12:26:06 2001
@@ -592,6 +592,8 @@
 
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/w9966.c linux/drivers/media/video/w9966.c
--- v2.4.10/linux/drivers/media/video/w9966.c	Thu May 24 15:14:08 2001
+++ linux/drivers/media/video/w9966.c	Sun Sep 30 12:26:06 2001
@@ -119,6 +119,8 @@
 
 MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
 MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
+MODULE_LICENSE("GPL");
+
 
 #ifdef MODULE
 static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""};
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/zr36067.c linux/drivers/media/video/zr36067.c
--- v2.4.10/linux/drivers/media/video/zr36067.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/media/video/zr36067.c	Sun Sep 30 12:26:06 2001
@@ -4901,3 +4901,4 @@
 
 module_init(init_dc10_cards);
 module_exit(unload_dc10_cards);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/zr36120.c linux/drivers/media/video/zr36120.c
--- v2.4.10/linux/drivers/media/video/zr36120.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/media/video/zr36120.c	Sun Sep 30 12:26:06 2001
@@ -62,6 +62,8 @@
 
 MODULE_AUTHOR("Pauline Middelink <middelin@polyware.nl>");
 MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(triton1,"i");
 MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i");
 MODULE_PARM(video_nr,"i");
diff -u --recursive --new-file v2.4.10/linux/drivers/media/video/zr36120_mem.c linux/drivers/media/video/zr36120_mem.c
--- v2.4.10/linux/drivers/media/video/zr36120_mem.c	Mon Aug  7 21:01:36 2000
+++ linux/drivers/media/video/zr36120_mem.c	Sun Sep 30 12:26:06 2001
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/wrapper.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #ifdef CONFIG_BIGPHYS_AREA
 #include <linux/bigphysarea.h>
@@ -75,3 +76,5 @@
 #endif
 	}
 }
+
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/message/fusion/mptbase.c linux/drivers/message/fusion/mptbase.c
--- v2.4.10/linux/drivers/message/fusion/mptbase.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/message/fusion/mptbase.c	Sun Sep 30 12:26:06 2001
@@ -42,7 +42,7 @@
  *  Originally By: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptbase.c,v 1.53.4.1 2001/08/24 20:07:05 sralston Exp $
+ *  $Id: mptbase.c,v 1.53.4.3 2001/09/18 03:54:54 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -108,6 +108,8 @@
 
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
 
 /*
  *  cmd line parameters
@@ -1435,10 +1437,14 @@
 {
 	if (this != NULL) {
 		int sz;
+		u32 state;
 
 		/* Disable the FW */
-		if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0)
-			(void) KickStart(this, 1);
+		state = GetIocState(this, 1);
+		if (state == MPI_IOC_STATE_OPERATIONAL) {
+			if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0)
+				(void) KickStart(this, 1);
+		}
 
 		/* Disable adapter interrupts! */
 		CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
diff -u --recursive --new-file v2.4.10/linux/drivers/message/fusion/mptbase.h linux/drivers/message/fusion/mptbase.h
--- v2.4.10/linux/drivers/message/fusion/mptbase.h	Sun Sep 23 11:40:58 2001
+++ linux/drivers/message/fusion/mptbase.h	Sun Sep 30 12:26:06 2001
@@ -12,7 +12,7 @@
  *  Originally By: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptbase.h,v 1.46.2.2.2.1 2001/08/24 20:07:05 sralston Exp $
+ *  $Id: mptbase.h,v 1.46.2.2.2.2 2001/09/18 03:22:29 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -77,8 +77,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2001 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"1.02.01"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-1.02.01"
+#define MPT_LINUX_VERSION_COMMON	"1.02.02"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-1.02.02"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
diff -u --recursive --new-file v2.4.10/linux/drivers/message/fusion/mptctl.c linux/drivers/message/fusion/mptctl.c
--- v2.4.10/linux/drivers/message/fusion/mptctl.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/message/fusion/mptctl.c	Sun Sep 30 12:26:06 2001
@@ -93,6 +93,8 @@
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
diff -u --recursive --new-file v2.4.10/linux/drivers/message/fusion/mptlan.c linux/drivers/message/fusion/mptlan.c
--- v2.4.10/linux/drivers/message/fusion/mptlan.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/message/fusion/mptlan.c	Sun Sep 30 12:26:06 2001
@@ -1508,6 +1508,8 @@
 MODULE_PARM(tx_max_out_p, "i");
 MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
 
+MODULE_LICENSE("GPL");
+
 module_init(mpt_lan_init);
 module_exit(mpt_lan_exit);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/message/fusion/mptscsih.c linux/drivers/message/fusion/mptscsih.c
--- v2.4.10/linux/drivers/message/fusion/mptscsih.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/message/fusion/mptscsih.c	Sun Sep 30 12:26:06 2001
@@ -19,7 +19,7 @@
  *  Original author: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptscsih.c,v 1.29 2001/06/18 18:59:05 sralston Exp $
+ *  $Id: mptscsih.c,v 1.29.4.1 2001/09/18 03:22:30 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -81,6 +81,8 @@
 
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
@@ -324,14 +326,10 @@
 			dprintk((KERN_NOTICE MYNAM ": SET sc->resid=%02xh\n", sc->resid));
 #endif
 
-#if 0
-			if (sc->underflow && (le32_to_cpu(pScsiReply->TransferCount) < sc->underflow)) {
-				sc->result = DID_ERROR << 16;
-				sc->resid = sc->request_bufflen - le32_to_cpu(pScsiReply->TransferCount);
-			} else {
-				sc->result = 0;
+			if (pScsiReq->CDB[0] == INQUIRY) {
+				sc->result = (DID_OK << 16);
+				break;
 			}
-#endif
 
 			/* workaround attempts... */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/Config.in linux/drivers/mtd/Config.in
--- v2.4.10/linux/drivers/mtd/Config.in	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/Config.in	Fri Oct  5 12:05:47 2001
@@ -1,5 +1,5 @@
 
-# $Id: Config.in,v 1.66 2001/05/07 21:00:43 dwmw2 Exp $
+# $Id: Config.in,v 1.71 2001/10/03 11:38:38 dwmw2 Exp $
 
 mainmenu_option next_comment
 comment 'Memory Technology Devices (MTD)'
@@ -13,7 +13,10 @@
    fi
    dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
    dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
+if [ "$CONFIG_ARM" = "y" ]; then
    dep_tristate '  Compaq bootldr partition table parsing' CONFIG_MTD_BOOTLDR_PARTS $CONFIG_MTD_PARTITIONS
+   dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS
+fi
 
 comment 'User Modules And Translation Layers'
    dep_tristate '  Direct char device access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/Makefile linux/drivers/mtd/Makefile
--- v2.4.10/linux/drivers/mtd/Makefile	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/Makefile	Thu Oct  4 15:13:18 2001
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now inherited from the
 # parent makes..
 #
-# $Id: Makefile,v 1.60 2001/05/31 20:43:18 dwmw2 Exp $
+# $Id: Makefile,v 1.63 2001/06/13 09:43:07 dwmw2 Exp $
 
 
 obj-y           += chips/chipslink.o maps/mapslink.o \
@@ -19,7 +19,7 @@
 
 O_TARGET	:= mtdlink.o
 
-export-objs	:= mtdcore.o mtdpart.o redboot.o bootldr.o
+export-objs	:= mtdcore.o mtdpart.o redboot.o bootldr.o afs.o
 list-multi	:= nftl.o
 
 mod-subdirs	:= 
@@ -47,6 +47,7 @@
 obj-$(CONFIG_MTD_PARTITIONS)	+= mtdpart.o
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
 obj-$(CONFIG_MTD_BOOTLDR_PARTS) += bootldr.o
+obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/afs.c linux/drivers/mtd/afs.c
--- v2.4.10/linux/drivers/mtd/afs.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/afs.c	Thu Oct  4 15:14:41 2001
@@ -0,0 +1,227 @@
+/*======================================================================
+
+    drivers/mtd/afs.c: ARM Flash Layout/Partitioning
+  
+    Copyright (C) 2000 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
+  
+   This is access code for flashes using ARM's flash partitioning 
+   standards.
+
+   $Id: afs.c,v 1.6 2001/10/02 10:04:51 rmk Exp $
+
+======================================================================*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+struct footer_struct {
+	u32 image_info_base;	/* Address of first word of ImageFooter  */
+	u32 image_start;	/* Start of area reserved by this footer */
+	u32 signature;		/* 'Magic' number proves it's a footer   */
+	u32 type;		/* Area type: ARM Image, SIB, customer   */
+	u32 checksum;		/* Just this structure                   */
+};
+
+struct image_info_struct {
+	u32 bootFlags;		/* Boot flags, compression etc.          */
+	u32 imageNumber;	/* Unique number, selects for boot etc.  */
+	u32 loadAddress;	/* Address program should be loaded to   */
+	u32 length;		/* Actual size of image                  */
+	u32 address;		/* Image is executed from here           */
+	char name[16];		/* Null terminated                       */
+	u32 headerBase;		/* Flash Address of any stripped header  */
+	u32 header_length;	/* Length of header in memory            */
+	u32 headerType;		/* AIF, RLF, s-record etc.               */
+	u32 checksum;		/* Image checksum (inc. this struct)     */
+};
+
+static int
+afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
+		u_int off, u_int mask)
+{
+	struct footer_struct fs;
+	u_int ptr = off + mtd->erasesize - sizeof(fs);
+	size_t sz;
+	int ret;
+
+	ret = mtd->read(mtd, ptr, sizeof(fs), &sz, (u_char *) &fs);
+	if (ret >= 0 && sz != sizeof(fs))
+		ret = -EINVAL;
+
+	if (ret < 0) {
+		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
+			ptr, ret);
+		return ret;
+	}
+
+	/*
+	 * Does it contain the magic number?
+	 */
+	if (fs.signature != 0xa0ffff9f)
+		ret = 1;
+
+	*iis_start = fs.image_info_base & mask;
+	*img_start = fs.image_start & mask;
+
+	/*
+	 * Check the image info base.  This can not
+	 * be located after the footer structure.
+	 */
+	if (*iis_start >= ptr)
+		ret = 1;
+
+	/*
+	 * Check the start of this image.  The image
+	 * data can not be located after this block.
+	 */
+	if (*img_start > off)
+		ret = 1;
+
+	return ret;
+}
+
+static int
+afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
+{
+	size_t sz;
+	int ret;
+
+	memset(iis, 0, sizeof(*iis));
+	ret = mtd->read(mtd, ptr, sizeof(*iis), &sz, (u_char *) iis);
+	if (ret >= 0 && sz != sizeof(*iis))
+		ret = -EINVAL;
+	if (ret < 0)
+		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
+			ptr, ret);
+
+	return ret;
+}
+
+int parse_afs_partitions(struct mtd_info *mtd, struct mtd_partition **pparts)
+{
+	struct mtd_partition *parts;
+	u_int mask, off, idx, sz;
+	int ret = 0;
+	char *str;
+
+	/*
+	 * This is the address mask; we use this to mask off out of
+	 * range address bits.
+	 */
+	mask = mtd->size - 1;
+
+	/*
+	 * First, calculate the size of the array we need for the
+	 * partition information.  We include in this the size of
+	 * the strings.
+	 */
+	for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
+		struct image_info_struct iis;
+		u_int iis_ptr, img_ptr;
+
+		ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
+		if (ret < 0)
+			break;
+		if (ret == 1)
+			continue;
+
+		ret = afs_read_iis(mtd, &iis, iis_ptr);
+		if (ret < 0)
+			break;
+
+		sz += sizeof(struct mtd_partition);
+		sz += strlen(iis.name) + 1;
+		idx += 1;
+	}
+
+	if (!sz)
+		return ret;
+
+	parts = kmalloc(sz, GFP_KERNEL);
+	if (!parts)
+		return -ENOMEM;
+
+	str = (char *)(parts + idx);
+
+	/*
+	 * Identify the partitions
+	 */
+	for (idx = off = 0; off < mtd->size; off += mtd->erasesize) {
+		struct image_info_struct iis;
+		u_int iis_ptr, img_ptr, size;
+
+		/* Read the footer. */
+		ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
+		if (ret < 0)
+			break;
+		if (ret == 1)
+			continue;
+
+		/* Read the image info block */
+		ret = afs_read_iis(mtd, &iis, iis_ptr);
+		if (ret < 0)
+			break;
+
+		strcpy(str, iis.name);
+		size = mtd->erasesize + off - img_ptr;
+
+		/*
+		 * In order to support JFFS2 partitions on this layout,
+		 * we must lie to MTD about the real size of JFFS2
+		 * partitions; this ensures that the AFS flash footer
+		 * won't be erased by JFFS2.  Please ensure that your
+		 * JFFS2 partitions are given image numbers between
+		 * 1000 and 2000 inclusive.
+		 */
+		if (iis.imageNumber >= 1000 && iis.imageNumber < 2000)
+			size -= mtd->erasesize;
+
+		parts[idx].name		= str;
+		parts[idx].size		= size;
+		parts[idx].offset	= img_ptr;
+		parts[idx].mask_flags	= 0;
+
+		printk("  mtd%d: at 0x%08x, %5dKB, %8u, %s\n",
+			idx, img_ptr, parts[idx].size / 1024,
+			iis.imageNumber, str);
+
+		idx += 1;
+		str = str + strlen(iis.name) + 1;
+	}
+
+	if (!idx) {
+		kfree(parts);
+		parts = NULL;
+	}
+
+	*pparts = parts;
+	return idx ? idx : ret;
+}
+
+EXPORT_SYMBOL(parse_afs_partitions);
+
+MODULE_AUTHOR("ARM Ltd");
+MODULE_DESCRIPTION("ARM Firmware Suite partition parser");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/bootldr.c linux/drivers/mtd/bootldr.c
--- v2.4.10/linux/drivers/mtd/bootldr.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/bootldr.c	Thu Oct  4 15:14:44 2001
@@ -3,7 +3,7 @@
  *
  * Copyright 2001 Compaq Computer Corporation.
  *
- * $Id: bootldr.c,v 1.4 2001/06/02 18:24:27 nico Exp $
+ * $Id: bootldr.c,v 1.6 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * Use consistent with the GNU GPL is permitted,
  * provided that this copyright notice is
@@ -24,6 +24,8 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <asm/setup.h>
+#include <linux/bootmem.h>
 
 #define FLASH_PARTITION_NAMELEN 32
 enum LFR_FLAGS {
@@ -33,6 +35,9 @@
    LFR_EXPAND = 8               /* expand partition size to fit rest of flash */
 };
 
+// the tags are parsed too early to malloc or alloc_bootmem so we'll fix it
+// for now
+#define MAX_NUM_PARTITIONS 8
 typedef struct FlashRegion {
    char name[FLASH_PARTITION_NAMELEN];
    unsigned long base;
@@ -43,7 +48,7 @@
 typedef struct BootldrFlashPartitionTable {
   int magic; /* should be filled with 0x646c7470 (btlp) BOOTLDR_PARTITION_MAGIC */
   int npartitions;
-  struct FlashRegion partition[0];
+  struct FlashRegion partition[8];
 } BootldrFlashPartitionTable;
 
 #define BOOTLDR_MAGIC      0x646c7462        /* btld: marks a valid bootldr image */
@@ -56,6 +61,10 @@
 #define BOOTCAP_PARTITIONS (1<<1) /* partition table stored in params sector */
 #define BOOTCAP_PARAMS_AFTER_BOOTLDR (1<<2) /* params sector right after bootldr sector(s), else in last sector */
 
+static struct BootldrFlashPartitionTable Table;
+static struct BootldrFlashPartitionTable *partition_table = NULL;
+
+
 int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts)
 {
 	struct mtd_partition *parts;
@@ -65,9 +74,10 @@
 	long bootmagic = 0;
 	long bootcap = 0;
 	int namelen = 0;
-	struct BootldrFlashPartitionTable *partition_table = NULL; 
+
 	char *names; 
 
+#if 0
 	/* verify bootldr magic */
 	ret = master->read(master, BOOTLDR_MAGIC_OFFSET, sizeof(long), &retlen, (void *)&bootmagic);
 	if (ret) 
@@ -87,22 +97,33 @@
 		partition_table_offset = master->size - master->erasesize;
 
 	printk(__FUNCTION__ ": partition_table_offset=%#lx\n", partition_table_offset);
+	printk(__FUNCTION__ ": ptable_addr=%#lx\n", ptable_addr);
+
 
 	/* Read the partition table */
 	partition_table = (struct BootldrFlashPartitionTable *)kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!partition_table)
 		return -ENOMEM;
+
 	ret = master->read(master, partition_table_offset,
 			   PAGE_SIZE, &retlen, (void *)partition_table);
 	if (ret)
-		goto out;
+	    goto out;
+
+#endif
+	if (!partition_table)
+	    return -ENOMEM;
 
+	
 	printk(__FUNCTION__ ": magic=%#x\n", partition_table->magic);
+	printk(__FUNCTION__ ": numPartitions=%#x\n", partition_table->npartitions);
+
 
 	/* check for partition table magic number */
 	if (partition_table->magic != BOOTLDR_PARTITION_MAGIC) 
 		goto out;
-	npartitions = partition_table->npartitions;
+	npartitions = (partition_table->npartitions > MAX_NUM_PARTITIONS)?
+	    MAX_NUM_PARTITIONS:partition_table->npartitions;	
 
 	printk(__FUNCTION__ ": npartitions=%#x\n", npartitions);
 
@@ -118,6 +139,9 @@
 	names = (char *)&parts[npartitions];
 	memset(parts, 0, sizeof(*parts)*npartitions + namelen);
 
+
+
+	// from here we use the partition table
 	for (i = 0; i < npartitions; i++) {
                 struct FlashRegion *partition = &partition_table->partition[i];
 		const char *name = partition->name;
@@ -141,9 +165,50 @@
 	*pparts = parts;
 
  out:
+#if 0
 	if (partition_table)
 		kfree(partition_table);
+#endif
+	
 	return ret;
 }
 
+
+static int __init parse_tag_ptable(const struct tag *tag)
+{
+    char buf[128];
+    int i;
+    int j;
+    
+    partition_table = &Table;
+
+#ifdef CONFIG_DEBUG_LL    
+    sprintf(buf,"ptable: magic = = 0x%lx  npartitions= %d \n",
+	    tag->u.ptable.magic,tag->u.ptable.npartitions);
+    printascii(buf);
+    
+    for (i=0; i<tag->u.ptable.npartitions; i++){
+	sprintf(buf,"ptable: partition name = %s base= 0x%lx  size= 0x%lx flags= 0x%lx\n",
+	    (char *) (&tag->u.ptable.partition[i].name[0]),
+		tag->u.ptable.partition[i].base,
+		tag->u.ptable.partition[i].size,
+		tag->u.ptable.partition[i].flags);
+	printascii(buf);
+    }
+#endif
+
+    memcpy((void *)partition_table,(void *) (&(tag->u.ptable)),sizeof(partition_table) +
+	sizeof(struct FlashRegion)*tag->u.ptable.npartitions);
+
+    
+    return 0;
+}
+
+__tagtable(ATAG_PTABLE, parse_tag_ptable);
+
 EXPORT_SYMBOL(parse_bootldr_partitions);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Compaq Computer Corporation");
+MODULE_DESCRIPTION("Parsing code for Compaq bootldr partitions");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/Config.in linux/drivers/mtd/chips/Config.in
--- v2.4.10/linux/drivers/mtd/chips/Config.in	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/Config.in	Thu Oct  4 15:13:18 2001
@@ -1,21 +1,31 @@
 # drivers/mtd/chips/Config.in
 
-# $Id: Config.in,v 1.4 2001/05/14 09:48:12 dwmw2 Exp $
+# $Id: Config.in,v 1.12 2001/09/23 15:35:21 dwmw2 Exp $
 
 mainmenu_option next_comment
 
 comment 'RAM/ROM/Flash chip drivers'
 
-dep_tristate '  Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD
-if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_CFI" = "m" ]; then
-   bool '  CFI Virtual erase regions (EXPERIMENTAL)' CONFIG_MTD_CFI_VIRTUAL_ER 
-   bool '  CFI Advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS
+dep_tristate '  Detect flash chips by Common Flash Interface (CFI) probe' CONFIG_MTD_CFI $CONFIG_MTD
+#dep_tristate '  Detect non-CFI Intel-compatible flash chips' CONFIG_MTD_INTELPROBE $CONFIG_MTD
+dep_tristate '  Detect non-CFI AMD/JEDEC-compatible flash chips' CONFIG_MTD_JEDECPROBE $CONFIG_MTD
+
+if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_INTELPROBE" = "y" -o "$CONFIG_MTD_JEDECPROBE" = "y" ]; then
+   define_bool CONFIG_MTD_GEN_PROBE y
+else
+   if [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_INTELPROBE" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then
+      define_bool CONFIG_MTD_GEN_PROBE m
+   else
+      define_bool CONFIG_MTD_GEN_PROBE n
+   fi
+fi
+if [ "$CONFIG_MTD_GEN_PROBE" = "y" -o "$CONFIG_MTD_GEN_PROBE" = "m" ]; then
+   bool '  Flash chip driver advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS
    if [ "$CONFIG_MTD_CFI_ADV_OPTIONS" = "y" ]; then
      choice 'Flash cmd/query data swapping'			\
 	"NO			CONFIG_MTD_CFI_NOSWAP		\
 	 BIG_ENDIAN_BYTE	CONFIG_MTD_CFI_BE_BYTE_SWAP	\
-	 LITTLE_ENDIAN_BYTE	CONFIG_MTD_CFI_LE_BYTE_SWAP	\
-	 LART_ENDIAN_BYTE	CONFIG_MTD_CFI_LART_BIT_SWAP"	NO
+	 LITTLE_ENDIAN_BYTE	CONFIG_MTD_CFI_LE_BYTE_SWAP"	NO
      bool '  Specific CFI Flash geometry selection' CONFIG_MTD_CFI_GEOMETRY
      if [ "$CONFIG_MTD_CFI_GEOMETRY" = "y" ]; then
        bool '    Support  8-bit buswidth' CONFIG_MTD_CFI_B1
@@ -31,12 +41,17 @@
      fi
   fi
 fi
-dep_tristate '    CFI support for Intel/Sharp Basic/Extended Commands' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI
-dep_tristate '    CFI support for AMD/Fujitsu Standard Commands' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_CFI
-dep_tristate '  AMD compatible flash chip support (non-CFI)' CONFIG_MTD_AMDSTD $CONFIG_MTD
-dep_tristate '  pre-CFI Sharp chip support' CONFIG_MTD_SHARP $CONFIG_MTD
+dep_tristate '  Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
+dep_tristate '  Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
+
 dep_tristate '  Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
 dep_tristate '  Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
-dep_tristate '  JEDEC device support' CONFIG_MTD_JEDEC $CONFIG_MTD
+dep_tristate '  Support for absent chips in bus mapping' CONFIG_MTD_ABSENT $CONFIG_MTD
+
+bool '  Older (theoretically obsoleted now) drivers for non-CFI chips' CONFIG_MTD_OBSOLETE_CHIPS
+dep_tristate '  AMD compatible flash chip support (non-CFI)' CONFIG_MTD_AMDSTD $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS
+dep_tristate '  pre-CFI Sharp chip support' CONFIG_MTD_SHARP $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS
+dep_tristate '  JEDEC device support' CONFIG_MTD_JEDEC $CONFIG_MTD $CONFIG_MTD_OBSOLETE_CHIPS
+
 
 endmenu
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/Makefile linux/drivers/mtd/chips/Makefile
--- v2.4.10/linux/drivers/mtd/chips/Makefile	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/Makefile	Fri Oct  5 12:05:47 2001
@@ -1,11 +1,11 @@
 #
 # linux/drivers/chips/Makefile
 #
-# $Id: Makefile,v 1.4 2001/06/09 19:57:57 dwmw2 Exp $
+# $Id: Makefile,v 1.7 2001/10/05 06:53:51 dwmw2 Exp $
 
 O_TARGET	:= chipslink.o
 
-export-objs	:= chipreg.o
+export-objs	:= chipreg.o gen_probe.o
 
 #                       *** BIG UGLY NOTE ***
 #
@@ -16,12 +16,16 @@
 
 obj-$(CONFIG_MTD)		+= chipreg.o
 obj-$(CONFIG_MTD_AMDSTD)	+= amd_flash.o 
-obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o cfi_jedec.o
+obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o
 obj-$(CONFIG_MTD_CFI_AMDSTD)	+= cfi_cmdset_0002.o
 obj-$(CONFIG_MTD_CFI_INTELEXT)	+= cfi_cmdset_0001.o
+obj-$(CONFIG_MTD_GEN_PROBE)	+= gen_probe.o
+obj-$(CONFIG_MTD_INTELPROBE)	+= intel_probe.o
 obj-$(CONFIG_MTD_JEDEC)		+= jedec.o
+obj-$(CONFIG_MTD_JEDECPROBE)	+= jedec_probe.o
 obj-$(CONFIG_MTD_RAM)		+= map_ram.o
 obj-$(CONFIG_MTD_ROM)		+= map_rom.o
 obj-$(CONFIG_MTD_SHARP)		+= sharp.o
+obj-$(CONFIG_MTD_ABSENT)	+= map_absent.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/amd_flash.c linux/drivers/mtd/chips/amd_flash.c
--- v2.4.10/linux/drivers/mtd/chips/amd_flash.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/chips/amd_flash.c	Thu Oct  4 15:14:59 2001
@@ -3,7 +3,7 @@
  *
  * Author: Jonas Holmberg <jonas.holmberg@axis.com>
  *
- * $Id: amd_flash.c,v 1.8 2001/06/02 14:47:16 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.15 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * Copyright (c) 2001 Axis Communications AB
  *
@@ -33,6 +33,8 @@
 /* Addresses */
 #define ADDR_MANUFACTURER		0x0000
 #define ADDR_DEVICE_ID			0x0001
+#define ADDR_SECTOR_LOCK		0x0002
+#define ADDR_HANDSHAKE			0x0003
 #define ADDR_UNLOCK_1			0x0555
 #define ADDR_UNLOCK_2			0x02AA
 
@@ -46,6 +48,8 @@
 #define CMD_SECTOR_ERASE_UNLOCK_DATA	0x0080
 #define CMD_SECTOR_ERASE_UNLOCK_DATA_2	0x0030
 
+#define CMD_UNLOCK_SECTOR		0x0060
+
 /* Manufacturers */
 #define MANUFACTURER_AMD	0x0001
 #define MANUFACTURER_FUJITSU	0x0004
@@ -60,6 +64,9 @@
 #define AM29LV800BT	0x22DA
 #define AM29LV160DT	0x22C4
 #define AM29LV160DB	0x2249
+#define AM29BDS323D     0x22D1
+#define AM29BDS643D	0x227E
+
 
 /* Fujitsu */
 #define MBM29LV160TE	0x22C4
@@ -202,6 +209,92 @@
 		(wide_read(map, addr) & D6_MASK));
 }
 
+static inline void unlock_sector(struct map_info *map, unsigned long sect_addr,
+				 int unlock)
+{
+	/* Sector lock address. A6 = 1 for unlock, A6 = 0 for lock */
+	int SLA = unlock ?
+		(sect_addr |  (0x40 * map->buswidth)) :
+		(sect_addr & ~(0x40 * map->buswidth)) ;
+
+	__u32 cmd = make_cmd(map, CMD_UNLOCK_SECTOR);
+
+	wide_write(map, make_cmd(map, CMD_RESET_DATA), 0);
+	wide_write(map, cmd, SLA); /* 1st cycle: write cmd to any address */
+	wide_write(map, cmd, SLA); /* 2nd cycle: write cmd to any address */
+	wide_write(map, cmd, SLA); /* 3rd cycle: write cmd to SLA */
+}
+
+static inline int is_sector_locked(struct map_info *map,
+				   unsigned long sect_addr)
+{
+	int status;
+
+	wide_write(map, CMD_RESET_DATA, 0);
+	send_cmd(map, sect_addr, CMD_MANUFACTURER_UNLOCK_DATA);
+
+	/* status is 0x0000 for unlocked and 0x0001 for locked */
+	status = wide_read(map, sect_addr + (map->buswidth * ADDR_SECTOR_LOCK));
+	wide_write(map, CMD_RESET_DATA, 0);
+	return status;
+}
+
+static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
+			       int is_unlock)
+{
+	struct map_info *map;
+	struct mtd_erase_region_info *merip;
+	int eraseoffset, erasesize, eraseblocks;
+	int i;
+	int retval = 0;
+	int lock_status;
+      
+	map = mtd->priv;
+
+	/* Pass the whole chip through sector by sector and check for each
+	   sector if the sector and the given interval overlap */
+	for(i = 0; i < mtd->numeraseregions; i++) {
+		merip = &mtd->eraseregions[i];
+
+		eraseoffset = merip->offset;
+		erasesize = merip->erasesize;
+		eraseblocks = merip->numblocks;
+
+		if (ofs > eraseoffset + erasesize)
+			continue;
+
+		while (eraseblocks > 0) {
+			if (ofs < eraseoffset + erasesize && ofs + len > eraseoffset) {
+				unlock_sector(map, eraseoffset, is_unlock);
+
+				lock_status = is_sector_locked(map, eraseoffset);
+				
+				if (is_unlock && lock_status) {
+					printk("Cannot unlock sector at address %x length %xx\n",
+					       eraseoffset, merip->erasesize);
+					retval = -1;
+				} else if (!is_unlock && !lock_status) {
+					printk("Cannot lock sector at address %x length %x\n",
+					       eraseoffset, merip->erasesize);
+					retval = -1;
+				}
+			}
+			eraseoffset += erasesize;
+			eraseblocks --;
+		}
+	}
+	return retval;
+}
+
+static int amd_flash_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	return amd_flash_do_unlock(mtd, ofs, len, 1);
+}
+
+static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	return amd_flash_do_unlock(mtd, ofs, len, 0);
+}
 
 
 /*
@@ -213,7 +306,8 @@
 			  struct amd_flash_private *private,
 			  const struct amd_flash_info *table, int table_size)
 {
-	__u32 mfr_id, dev_id;
+	__u32 mfr_id;
+	__u32 dev_id;
 	struct map_info *map = mtd->priv;
 	struct amd_flash_private temp;
 	int i;
@@ -231,8 +325,8 @@
 
 	if ((map->buswidth == 4) && ((mfr_id >> 16) == (mfr_id & 0xffff)) &&
 	    ((dev_id >> 16) == (dev_id & 0xffff))) {
-		mfr_id = mfr_id & 0xffff;
-		dev_id = dev_id & 0xffff;
+		mfr_id &= 0xffff;
+		dev_id &= 0xffff;
 	} else {
 		temp.interleave = 1;
 	}
@@ -248,15 +342,24 @@
 				 * autoselect mode now.
 				 */
 				for (j = 0; j < private->numchips; j++) {
-					if ((wide_read(map, chips[j].start +
-							    (map->buswidth *
-							     ADDR_MANUFACTURER))
-					     == mfr_id)
-					    &&
-					    (wide_read(map, chips[j].start +
-					    		    (map->buswidth *
-							     ADDR_DEVICE_ID))
-					     == dev_id)) {
+					__u32 mfr_id_other;
+					__u32 dev_id_other;
+
+					mfr_id_other =
+						wide_read(map, chips[j].start +
+							       (map->buswidth *
+								ADDR_MANUFACTURER
+							       ));
+					dev_id_other =
+						wide_read(map, chips[j].start +
+					    		       (map->buswidth *
+							        ADDR_DEVICE_ID));
+					if (temp.interleave == 2) {
+						mfr_id_other &= 0xffff;
+						dev_id_other &= 0xffff;
+					}
+					if ((mfr_id_other == mfr_id) &&
+					    (dev_id_other == dev_id)) {
 
 						/* Exit autoselect mode. */
 						send_cmd(map, base,
@@ -488,6 +591,28 @@
 			{ offset: 0x008000, erasesize: 0x08000, numblocks:  1 },
 			{ offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
 		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29BDS323D,
+		name: "AMD AM29BDS323D",
+		size: 0x00400000,
+		numeraseregions: 3,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 48 },
+			{ offset: 0x300000, erasesize: 0x10000, numblocks: 15 },
+			{ offset: 0x3f0000, erasesize: 0x02000, numblocks:  8 },
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29BDS643D,
+		name: "AMD AM29BDS643D",
+		size: 0x00800000,
+		numeraseregions: 3,
+		regions: {
+			{ offset: 0x000000, erasesize: 0x10000, numblocks: 96 },
+			{ offset: 0x600000, erasesize: 0x10000, numblocks: 31 },
+			{ offset: 0x7f0000, erasesize: 0x02000, numblocks:  8 },
+		}
 	} 
 	};
 
@@ -597,6 +722,8 @@
 	mtd->sync = amd_flash_sync;	
 	mtd->suspend = amd_flash_suspend;	
 	mtd->resume = amd_flash_resume;	
+	mtd->lock = amd_flash_lock;
+	mtd->unlock = amd_flash_unlock;
 
 	private = kmalloc(sizeof(*private) + (sizeof(struct flchip) *
 					      temp.numchips), GFP_KERNEL);
@@ -761,8 +888,7 @@
 	wide_write(map, datum, adr);
 
 	times_left = 500000;
-	while (times_left-- && flash_is_busy(map, chip->start,
-					     private->interleave)) {
+	while (times_left-- && flash_is_busy(map, adr, private->interleave)) { 
 		if (current->need_resched) {
 			spin_unlock_bh(chip->mutex);
 			schedule();
@@ -964,7 +1090,7 @@
 	schedule_timeout(HZ);
 	spin_lock_bh(chip->mutex);
 	
-	while (flash_is_busy(map, chip->start, private->interleave)) {
+	while (flash_is_busy(map, adr, private->interleave)) {
 
 		if (chip->state != FL_ERASING) {
 			/* Someone's suspended the erase. Sleep */
@@ -1250,3 +1376,7 @@
 
 module_init(amd_flash_init);
 module_exit(amd_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonas Holmberg <jonas.holmberg@axis.com>");
+MODULE_DESCRIPTION("Old MTD chip driver for AMD flash chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/cfi_cmdset_0001.c linux/drivers/mtd/chips/cfi_cmdset_0001.c
--- v2.4.10/linux/drivers/mtd/chips/cfi_cmdset_0001.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/cfi_cmdset_0001.c	Thu Oct  4 15:14:59 2001
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0001.c,v 1.80 2001/06/03 01:32:57 nico Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.87 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * 
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/compatmac.h>
@@ -41,80 +42,23 @@
 
 static void cfi_intelext_destroy(struct mtd_info *);
 
-void cfi_cmdset_0001(struct map_info *, int, unsigned long);
+struct mtd_info *cfi_cmdset_0001(struct map_info *, int);
 
 static struct mtd_info *cfi_intelext_setup (struct map_info *);
 
 static struct mtd_chip_driver cfi_intelext_chipdrv = {
-	probe: cfi_intelext_setup,
+	probe: NULL, /* Not usable directly */
 	destroy: cfi_intelext_destroy,
-	name: "cfi_intel",
+	name: "cfi_cmdset_0001",
 	module: THIS_MODULE
 };
 
 /* #define DEBUG_LOCK_BITS */
+/* #define DEBUG_CFI_FEATURES */
 
-/* This routine is made available to other mtd code via
- * inter_module_register.  It must only be accessed through
- * inter_module_get which will bump the use count of this module.  The
- * addresses passed back in cfi are valid as long as the use count of
- * this module is non-zero, i.e. between inter_module_get and
- * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
- */
-void cfi_cmdset_0001(struct map_info *map, int primary, unsigned long base)
+#ifdef DEBUG_CFI_FEATURES
+static void cfi_tell_features(struct cfi_pri_intelext *extp)
 {
-	struct cfi_private *cfi = map->fldrv_priv;
-	int i;
-	struct cfi_pri_intelext *extp;
-	int ofs_factor = cfi->interleave * cfi->device_type;
-
-	__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
-
-	//printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
-
-	if (!adr)
-		return;
-
-	/* Switch it into Query Mode */
-	switch(CFIDEV_BUSWIDTH) {
-	case 1:
-		map->write8(map, 0x98, 0x55);
-		break;
-	case 2:
-		map->write16(map, 0x9898, 0xaa);
-		break;
-	case 4:
-		map->write32(map, 0x98989898, 0x154);
-		break;
-	}
-
-	extp = kmalloc(sizeof(*extp), GFP_KERNEL);
-	if (!extp) {
-		printk("Failed to allocate memory\n");
-		return;
-	}
-
-	/* Read in the Extended Query Table */
-	for (i=0; i<sizeof(*extp); i++) {
-		((unsigned char *)extp)[i] = 
-		    cfi_read_query(map, (base+((adr+i)*cfi->interleave*cfi->device_type)));
-	}
-
-	if (extp->MajorVersion != '1' || 
-	    (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
-		printk("  Unknown IntelExt Extended Query version %c.%c.\n",
-		       extp->MajorVersion, extp->MinorVersion);
-		kfree(extp);
-		return;
-	}
-
-	/* Do some byteswapping if necessary */
-	extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
-	extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
-
-	
-	/* Tell the user about it in lots of lovely detail */
-#if 0  
 	printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);
 	printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");
 	printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");
@@ -150,54 +94,85 @@
 	if (extp->VppOptimal)
 		printk("  Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 
 		       extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
-#endif	
-	/* OK. We like it. Take over the control of it. */
+}
+#endif
 
-	/* Switch it into Read Mode */
-	switch(CFIDEV_BUSWIDTH) {
-	case 1:
-		map->write8(map, 0xff, 0x55);
-		break;
-	case 2:
-		map->write16(map, 0xffff, 0xaa);
-		break;
-	case 4:
-		map->write32(map, 0xffffffff, 0x154);
-		break;
-	}
+/* This routine is made available to other mtd code via
+ * inter_module_register.  It must only be accessed through
+ * inter_module_get which will bump the use count of this module.  The
+ * addresses passed back in cfi are valid as long as the use count of
+ * this module is non-zero, i.e. between inter_module_get and
+ * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
+ */
+struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i;
+	__u32 base = cfi->chips[0].start;
 
+	if (cfi->cfi_mode) {
+		/* 
+		 * It's a real CFI chip, not one for which the probe
+		 * routine faked a CFI structure. So we read the feature
+		 * table from it.
+		 */
+		__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
+		struct cfi_pri_intelext *extp;
+		int ofs_factor = cfi->interleave * cfi->device_type;
 
-	/* If there was an old setup function, decrease its use count */
-	if (map->fldrv)
-	  if(map->fldrv->module)
-	    __MOD_DEC_USE_COUNT(map->fldrv->module);
-	
-	if (cfi->cmdset_priv)
-		kfree(cfi->cmdset_priv);
+		//printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
+		if (!adr)
+			return NULL;
+
+		/* Switch it into Query Mode */
+		cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
+
+		extp = kmalloc(sizeof(*extp), GFP_KERNEL);
+		if (!extp) {
+			printk(KERN_ERR "Failed to allocate memory\n");
+			return NULL;
+		}
+		
+		/* Read in the Extended Query Table */
+		for (i=0; i<sizeof(*extp); i++) {
+			((unsigned char *)extp)[i] = 
+				cfi_read_query(map, (base+((adr+i)*ofs_factor)));
+		}
+		
+		if (extp->MajorVersion != '1' || 
+		    (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
+			printk(KERN_WARNING "  Unknown IntelExt Extended Query "
+			       "version %c.%c.\n",  extp->MajorVersion,
+			       extp->MinorVersion);
+			kfree(extp);
+			return NULL;
+		}
+		
+		/* Do some byteswapping if necessary */
+		extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
+		extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
+		
+#ifdef DEBUG_CFI_FEATURES
+		/* Tell the user about it in lots of lovely detail */
+		cfi_tell_features(extp);
+#endif	
+
+		/* Install our own private info structure */
+		cfi->cmdset_priv = extp;
+	}	
 
 	for (i=0; i< cfi->numchips; i++) {
 		cfi->chips[i].word_write_time = 128;
 		cfi->chips[i].buffer_write_time = 128;
 		cfi->chips[i].erase_time = 1024;
 	}		
-		
 
 	map->fldrv = &cfi_intelext_chipdrv;
 	MOD_INC_USE_COUNT;
-
-	cfi->cmdset_priv = extp;
-
-#if 1 /* Does this work? */
-	cfi_send_gen_cmd(0x90, 0x55, base, map, cfi, cfi->device_type, NULL);
-
-	cfi->mfr = cfi_read_query(map, base);
-	cfi->id = cfi_read_query(map, base + ofs_factor);
-
-	printk("JEDEC ID: %2.2X %2.2X\n", cfi->mfr, cfi->id);
-#endif
-
-        cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
-	return;
+	
+	/* Make sure it's in read mode */
+	cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL);
+	return cfi_intelext_setup(map);
 }
 
 static struct mtd_info *cfi_intelext_setup(struct map_info *map)
@@ -209,12 +184,12 @@
 	unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
 
 	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
-	//printk("number of CFI chips: %d\n", cfi->numchips);
+	//printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips);
 
 	if (!mtd) {
-	  printk("Failed to allocate memory for MTD device\n");
-	  kfree(cfi->cmdset_priv);
-	  return NULL;
+		printk(KERN_ERR "Failed to allocate memory for MTD device\n");
+		kfree(cfi->cmdset_priv);
+		return NULL;
 	}
 
 	memset(mtd, 0, sizeof(*mtd));
@@ -226,9 +201,9 @@
 	mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 
 			* mtd->numeraseregions, GFP_KERNEL);
 	if (!mtd->eraseregions) { 
-			printk("Failed to allocate memory for MTD erase region info\n");
-			kfree(cfi->cmdset_priv);
-			return NULL;
+		printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
+		kfree(cfi->cmdset_priv);
+		return NULL;
 	}
 	
 	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
@@ -249,14 +224,14 @@
 
 		if (offset != devsize) {
 			/* Argh */
-			printk("Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
+			printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
 			kfree(mtd->eraseregions);
 			kfree(cfi->cmdset_priv);
 			return NULL;
 		}
 
 		for (i=0; i<mtd->numeraseregions;i++){
-			printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
+			printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n",
 			       i,mtd->eraseregions[i].offset,
 			       mtd->eraseregions[i].erasesize,
 			       mtd->eraseregions[i].numblocks);
@@ -266,10 +241,10 @@
 		mtd->erase = cfi_intelext_erase_varsize;
 	mtd->read = cfi_intelext_read;
 	if ( cfi->cfiq->BufWriteTimeoutTyp ) {
-		//printk( KERN_INFO"Using buffer write method\n" );
+		//printk(KERN_INFO "Using buffer write method\n" );
 		mtd->write = cfi_intelext_write_buffers;
 	} else {
-		//printk( KERN_INFO"Using word write method\n" );
+		//printk(KERN_INFO "Using word write method\n" );
 		mtd->write = cfi_intelext_write_words;
 	}
 	mtd->sync = cfi_intelext_sync;
@@ -311,10 +286,19 @@
 	 */
 	switch (chip->state) {
 	case FL_ERASING:
+		if (!((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)
+			goto sleep; /* We don't support erase suspend */
+		
 		cfi_write (map, CMD(0xb0), cmd_addr);
+		/* If the flash has finished erasing, then 'erase suspend'
+		 * appears to make some (28F320) flash devices switch to
+		 * 'read' mode.  Make sure that we switch to 'read status'
+		 * mode so we get the right data. --rmk
+		 */
+		cfi_write(map, CMD(0x70), cmd_addr);
 		chip->oldstate = FL_ERASING;
 		chip->state = FL_ERASE_SUSPENDING;
-//		printk("Erase suspending at 0x%lx\n", cmd_addr);
+		//		printk("Erase suspending at 0x%lx\n", cmd_addr);
 		for (;;) {
 			status = cfi_read(map, cmd_addr);
 			if ((status & status_OK) == status_OK)
@@ -323,22 +307,25 @@
 			if (time_after(jiffies, timeo)) {
 				/* Urgh */
 				cfi_write(map, CMD(0xd0), cmd_addr);
+				/* make sure we're in 'read status' mode */
+				cfi_write(map, CMD(0x70), cmd_addr);
 				chip->state = FL_ERASING;
 				spin_unlock_bh(chip->mutex);
-				printk("Chip not ready after erase suspended\n");
+				printk(KERN_ERR "Chip not ready after erase "
+				       "suspended: status = 0x%x\n", status);
 				return -EIO;
 			}
-
+			
 			spin_unlock_bh(chip->mutex);
 			cfi_udelay(1);
 			spin_lock_bh(chip->mutex);
 		}
-
+		
 		suspended = 1;
 		cfi_write(map, CMD(0xff), cmd_addr);
 		chip->state = FL_READY;
 		break;
-
+	
 #if 0
 	case FL_WRITING:
 		/* Not quite yet */
@@ -363,7 +350,7 @@
 		/* Urgh. Chip not yet ready to talk to us. */
 		if (time_after(jiffies, timeo)) {
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in read. WSM status = %x\n", status);
+			printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %x\n", status);
 			return -EIO;
 		}
 
@@ -373,6 +360,7 @@
 		goto retry;
 
 	default:
+	sleep:
 		/* Stick ourselves on a wait queue to be woken when
 		   someone changes the status */
 		set_current_state(TASK_UNINTERRUPTIBLE);
@@ -484,7 +472,7 @@
 		/* Urgh. Chip not yet ready to talk to us. */
 		if (time_after(jiffies, timeo)) {
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in read\n");
+			printk(KERN_ERR "waiting for chip to be ready timed out in read\n");
 			return -EIO;
 		}
 
@@ -538,7 +526,7 @@
 			chip->state = FL_STATUS;
 			DISABLE_VPP(map);
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in word write\n");
+			printk(KERN_ERR "waiting for chip to be ready timed out in word write\n");
 			return -EIO;
 		}
 
@@ -732,7 +720,7 @@
 		/* Urgh. Chip not yet ready to talk to us. */
 		if (time_after(jiffies, timeo)) {
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in buffer write\n");
+			printk(KERN_ERR "waiting for chip to be ready timed out in buffer write\n");
 			return -EIO;
 		}
 
@@ -773,7 +761,7 @@
 			chip->state = FL_STATUS;
 			DISABLE_VPP(map);
 			spin_unlock_bh(chip->mutex);
-			printk("Chip not ready for buffer write. Xstatus = %x, status = %x\n", status, cfi_read(map, cmd_adr));
+			printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %x, status = %x\n", status, cfi_read(map, cmd_adr));
 			return -EIO;
 		}
 	}
@@ -826,7 +814,7 @@
 			chip->state = FL_STATUS;
 			DISABLE_VPP(map);
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in bufwrite\n");
+			printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
 			return -EIO;
 		}
 		
@@ -973,7 +961,7 @@
 		/* Urgh. Chip not yet ready to talk to us. */
 		if (time_after(jiffies, timeo)) {
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in erase\n");
+			printk(KERN_ERR "waiting for chip to be ready timed out in erase\n");
 			return -EIO;
 		}
 
@@ -1019,7 +1007,7 @@
 			spin_unlock_bh(chip->mutex);
 			schedule();
 			remove_wait_queue(&chip->wq, &wait);
-			timeo = jiffies + (HZ*2); /* FIXME */
+			timeo = jiffies + (HZ*20); /* FIXME */
 			spin_lock_bh(chip->mutex);
 			continue;
 		}
@@ -1032,7 +1020,7 @@
 		if (time_after(jiffies, timeo)) {
 			cfi_write(map, CMD(0x70), adr);
 			chip->state = FL_STATUS;
-			printk("waiting for erase to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
+			printk(KERN_ERR "waiting for erase to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
 			DISABLE_VPP(map);
 			spin_unlock_bh(chip->mutex);
 			return -EIO;
@@ -1274,7 +1262,7 @@
 		/* Urgh. Chip not yet ready to talk to us. */
 		if (time_after(jiffies, timeo)) {
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in lock\n");
+			printk(KERN_ERR "waiting for chip to be ready timed out in lock\n");
 			return -EIO;
 		}
 
@@ -1318,7 +1306,7 @@
 		if (time_after(jiffies, timeo)) {
 			cfi_write(map, CMD(0x70), adr);
 			chip->state = FL_STATUS;
-			printk("waiting for lock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
+			printk(KERN_ERR "waiting for lock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
 			DISABLE_VPP(map);
 			spin_unlock_bh(chip->mutex);
 			return -EIO;
@@ -1423,7 +1411,7 @@
 		/* Urgh. Chip not yet ready to talk to us. */
 		if (time_after(jiffies, timeo)) {
 			spin_unlock_bh(chip->mutex);
-			printk("waiting for chip to be ready timed out in unlock\n");
+			printk(KERN_ERR "waiting for chip to be ready timed out in unlock\n");
 			return -EIO;
 		}
 
@@ -1467,7 +1455,7 @@
 		if (time_after(jiffies, timeo)) {
 			cfi_write(map, CMD(0x70), adr);
 			chip->state = FL_STATUS;
-			printk("waiting for unlock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
+			printk(KERN_ERR "waiting for unlock to complete timed out. Xstatus = %x, status = %x.\n", status, cfi_read(map, adr));
 			DISABLE_VPP(map);
 			spin_unlock_bh(chip->mutex);
 			return -EIO;
@@ -1568,6 +1556,9 @@
 			spin_lock_bh(chip->mutex);
 			
 			if (chip->state == FL_PM_SUSPENDED) {
+				/* No need to force it into a known state here,
+				   because we're returning failure, and it didn't
+				   get power cycled */
 				chip->state = chip->oldstate;
 				wake_up(&chip->wq);
 			}
@@ -1591,9 +1582,9 @@
 
 		spin_lock_bh(chip->mutex);
 		
+		/* Go to known state. Chip may have been power cycled */
 		if (chip->state == FL_PM_SUSPENDED) {
-			/* We need to force it back to a known state. */
-			cfi_write(map, CMD(0xff), 0);
+			cfi_write(map, CMD(0xFF), 0);
 			chip->state = FL_READY;
 			wake_up(&chip->wq);
 		}
@@ -1610,23 +1601,17 @@
 	kfree(cfi);
 }
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define cfi_intelext_init init_module
-#define cfi_intelext_exit cleanup_module
-#endif
-
 static char im_name_1[]="cfi_cmdset_0001";
 static char im_name_3[]="cfi_cmdset_0003";
 
-
-mod_init_t cfi_intelext_init(void)
+int __init cfi_intelext_init(void)
 {
 	inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001);
 	inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001);
 	return 0;
 }
 
-mod_exit_t cfi_intelext_exit(void)
+static void __exit cfi_intelext_exit(void)
 {
 	inter_module_unregister(im_name_1);
 	inter_module_unregister(im_name_3);
@@ -1634,3 +1619,7 @@
 
 module_init(cfi_intelext_init);
 module_exit(cfi_intelext_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
+MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/cfi_cmdset_0002.c linux/drivers/mtd/chips/cfi_cmdset_0002.c
--- v2.4.10/linux/drivers/mtd/chips/cfi_cmdset_0002.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/cfi_cmdset_0002.c	Thu Oct  4 15:14:59 2001
@@ -8,7 +8,7 @@
  *
  * This code is GPL
  *
- * $Id: cfi_cmdset_0002.c,v 1.48 2001/06/03 01:32:57 nico Exp $
+ * $Id: cfi_cmdset_0002.c,v 1.51 2001/10/02 15:05:12 dwmw2 Exp $
  *
  */
 
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 
@@ -37,93 +38,107 @@
 
 static void cfi_amdstd_destroy(struct mtd_info *);
 
-void cfi_cmdset_0002(struct map_info *, int, unsigned long);
+struct mtd_info *cfi_cmdset_0002(struct map_info *, int);
 static struct mtd_info *cfi_amdstd_setup (struct map_info *);
 
 
 static struct mtd_chip_driver cfi_amdstd_chipdrv = {
-	probe: cfi_amdstd_setup,
+	probe: NULL, /* Not usable directly */
 	destroy: cfi_amdstd_destroy,
 	name: "cfi_cmdset_0002",
 	module: THIS_MODULE
 };
 
-void cfi_cmdset_0002(struct map_info *map, int primary, unsigned long base)
+struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned char bootloc;
 	int ofs_factor = cfi->interleave * cfi->device_type;
 	int i;
 	__u8 major, minor;
-//	struct cfi_pri_intelext *extp;
+	__u32 base = cfi->chips[0].start;
 
-    if (cfi->cfi_mode==0){
-	__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
+	if (cfi->cfi_mode==1){
+		__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
 
-	cfi_send_gen_cmd(0x98, 0x55, 0, map, cfi, cfi->device_type, NULL);
-
-	major = cfi_read_query(map, (adr+3)*ofs_factor);
-	minor = cfi_read_query(map, (adr+4)*ofs_factor);
-
-	printk(" Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n",
-	       major, minor, adr);
-
-	cfi_send_gen_cmd(0xf0, 0x55, 0, map, cfi, cfi->device_type, NULL);
-
-	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-	cfi->mfr = cfi_read_query(map, base);
-	cfi->id = cfi_read_query(map, base + ofs_factor);
+		cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
+		
+		major = cfi_read_query(map, base + (adr+3)*ofs_factor);
+		minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
+		
+		printk(" Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n",
+		       major, minor, adr);
+				cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
+		
+		cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
+		cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
+		cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
+		cfi->mfr = cfi_read_query(map, base);
+		cfi->id = cfi_read_query(map, base + ofs_factor);
 
-	/* Wheee. Bring me the head of someone at AMD. */
+		/* Wheee. Bring me the head of someone at AMD. */
 #ifdef AMD_BOOTLOC_BUG
-	if (((major << 8) | minor) < 0x3131) {
-		/* CFI version 1.0 => don't trust bootloc */
-		if (cfi->id & 0x80) {
-			printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
-			bootloc = 3;	/* top boot */
-		} else {
-			bootloc = 2;	/* bottom boot */
-		}
-	} else
+		if (((major << 8) | minor) < 0x3131) {
+			/* CFI version 1.0 => don't trust bootloc */
+			if (cfi->id & 0x80) {
+				printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
+				bootloc = 3;	/* top boot */
+			} else {
+				bootloc = 2;	/* bottom boot */
+			}
+		} else
 #endif
-	{
-		cfi_send_gen_cmd(0x98, 0x55, 0, map, cfi, cfi->device_type, NULL);
-		bootloc = cfi_read_query(map, (adr+15)*ofs_factor);
-	}
-	if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
-		printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
-
-		for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
-			int j = (cfi->cfiq->NumEraseRegions-1)-i;
-			__u32 swap;
-
-			swap = cfi->cfiq->EraseRegionInfo[i];
-			cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
-			cfi->cfiq->EraseRegionInfo[j] = swap;
+			{
+				cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
+				bootloc = cfi_read_query(map, base + (adr+15)*ofs_factor);
+			}
+		if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
+			printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
+			
+			for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
+				int j = (cfi->cfiq->NumEraseRegions-1)-i;
+				__u32 swap;
+				
+				swap = cfi->cfiq->EraseRegionInfo[i];
+				cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
+				cfi->cfiq->EraseRegionInfo[j] = swap;
+			}
 		}
-	}
-    }
-
-    /* If there was an old setup function, decrease its use count */
-    if (map->fldrv)
-      if(map->fldrv->module)
-	__MOD_DEC_USE_COUNT(map->fldrv->module);
-    
-    if (cfi->cmdset_priv)
-		kfree(cfi->cmdset_priv);
+		switch (cfi->device_type) {
+		case CFI_DEVICETYPE_X8:
+			cfi->addr_unlock1 = 0x555; 
+			cfi->addr_unlock2 = 0x2aa; 
+			break;
+		case CFI_DEVICETYPE_X16:
+			cfi->addr_unlock1 = 0xaaa;
+			if (map->buswidth == cfi->interleave) {
+				/* X16 chip(s) in X8 mode */
+				cfi->addr_unlock2 = 0x555;
+			} else {
+				cfi->addr_unlock2 = 0x554;
+			}
+			break;
+		case CFI_DEVICETYPE_X32:
+			cfi->addr_unlock1 = 0x1555; 
+			cfi->addr_unlock2 = 0xaaa; 
+			break;
+		default:
+			printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0002 device type %d\n", cfi->device_type);
+			return NULL;
+		}
+	} /* CFI mode */
 
-    for (i=0; i< cfi->numchips; i++) {
+	for (i=0; i< cfi->numchips; i++) {
 		cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
 		cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
 		cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
-    }		
+	}		
+	
+	map->fldrv = &cfi_amdstd_chipdrv;
+	MOD_INC_USE_COUNT;
 
-    map->fldrv = &cfi_amdstd_chipdrv;
-    MOD_INC_USE_COUNT;
-    cfi_send_gen_cmd(0xf0, 0x55, 0, map, cfi, cfi->device_type, NULL);
-    return;
+	cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
+	return cfi_amdstd_setup(map);
 }
 
 static struct mtd_info *cfi_amdstd_setup(struct map_info *map)
@@ -913,20 +928,15 @@
 	kfree(cfi);
 }
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define cfi_amdstd_init init_module
-#define cfi_amdstd_exit cleanup_module
-#endif
-
 static char im_name[]="cfi_cmdset_0002";
 
-mod_init_t cfi_amdstd_init(void)
+int __init cfi_amdstd_init(void)
 {
 	inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
 	return 0;
 }
 
-mod_exit_t cfi_amdstd_exit(void)
+static void __exit cfi_amdstd_exit(void)
 {
 	inter_module_unregister(im_name);
 }
@@ -934,3 +944,6 @@
 module_init(cfi_amdstd_init);
 module_exit(cfi_amdstd_exit);
 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
+MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/cfi_jedec.c linux/drivers/mtd/chips/cfi_jedec.c
--- v2.4.10/linux/drivers/mtd/chips/cfi_jedec.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/cfi_jedec.c	Wed Dec 31 16:00:00 1969
@@ -1,289 +0,0 @@
-/* $Id: cfi_jedec.c,v 1.5 2001/06/02 14:52:23 dwmw2 Exp $ */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/map.h>
-#include <linux/mtd/cfi.h>
-
-/* Manufacturers */
-#define MANUFACTURER_AMD	0x0001
-#define MANUFACTURER_FUJITSU	0x0004
-#define MANUFACTURER_ATMEL	0x001f
-#define MANUFACTURER_ST		0x0020
-#define MANUFACTURER_SST	0x00BF
-#define MANUFACTURER_TOSHIBA	0x0098
-
-/* AMD */
-#define AM29F800BB	0x2258
-#define AM29F800BT	0x22D6
-#define AM29LV800BB	0x225B
-#define AM29LV800BT	0x22DA
-#define AM29LV160DT	0x22C4
-#define AM29LV160DB	0x2249
-
-/* Atmel */
-#define AT49BV16X4	0x00c0
-#define AT49BV16X4T	0x00c2
-
-/* Fujitsu */
-#define MBM29LV160TE	0x22C4
-#define MBM29LV160BE	0x2249
-
-/* ST - www.st.com */
-#define M29W800T	0x00D7
-#define M29W160DT	0x22C4
-#define M29W160DB	0x2249
-
-/* SST */
-#define SST39LF800	0x2781
-#define SST39LF160	0x2782
-
-/* Toshiba */
-#define TC58FVT160	0x00C2
-#define TC58FVB160	0x0043
-
-
-struct amd_flash_info {
-	const __u16 mfr_id;
-	const __u16 dev_id;
-	const char *name;
-	const int DevSize;
-	const int InterfaceDesc;
-	const int NumEraseRegions;
-	const ulong regions[4];
-};
-
-#define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
-
-#define SIZE_1MiB 20
-#define SIZE_2MiB 21
-#define SIZE_4MiB 22
-
-static const struct amd_flash_info jedec_table[] = {
-	{
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV160DT,
-		name: "AMD AM29LV160DT",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV160DB,
-		name: "AMD AM29LV160DB",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x10000,31)
-		}
-	}, {
-		mfr_id: MANUFACTURER_TOSHIBA,
-		dev_id: TC58FVT160,
-		name: "Toshiba TC58FVT160",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_FUJITSU,
-		dev_id: MBM29LV160TE,
-		name: "Fujitsu MBM29LV160TE",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_TOSHIBA,
-		dev_id: TC58FVB160,
-		name: "Toshiba TC58FVB160",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x10000,31)
-		}
-	}, {
-		mfr_id: MANUFACTURER_FUJITSU,
-		dev_id: MBM29LV160BE,
-		name: "Fujitsu MBM29LV160BE",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x10000,31)
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BB,
-		name: "AMD AM29LV800BB",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x10000,15),
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29F800BB,
-		name: "AMD AM29F800BB",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x10000,15),
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BT,
-		name: "AMD AM29LV800BT",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29F800BT,
-		name: "AMD AM29F800BT",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_AMD,
-		dev_id: AM29LV800BB,
-		name: "AMD AM29LV800BB",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W800T,
-		name: "ST M29W800T",
-		DevSize: SIZE_1MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,15),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W160DT,
-		name: "ST M29W160DT",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x10000,31),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x04000,1)
-		}
-	}, {
-		mfr_id: MANUFACTURER_ST,
-		dev_id: M29W160DB,
-		name: "ST M29W160DB",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 4,
-		regions: {ERASEINFO(0x04000,1),
-			  ERASEINFO(0x02000,2),
-			  ERASEINFO(0x08000,1),
-			  ERASEINFO(0x10000,31)
-		}
-	}, {
-		mfr_id: MANUFACTURER_ATMEL,
-		dev_id: AT49BV16X4,
-		name: "Atmel AT49BV16X4",
-		DevSize: SIZE_2MiB,
-		NumEraseRegions: 3,
-		regions: {ERASEINFO(0x02000,8),
-			  ERASEINFO(0x08000,2),
-			  ERASEINFO(0x10000,30)
-		}
-	}, {
-                mfr_id: MANUFACTURER_ATMEL,
-                dev_id: AT49BV16X4T,
-                name: "Atmel AT49BV16X4T",
-                DevSize: SIZE_2MiB,
-                NumEraseRegions: 3,
-                regions: {ERASEINFO(0x10000,30),
-                          ERASEINFO(0x08000,2),
-			  ERASEINFO(0x02000,8)
-                }
-        }, {
-		0
-	} 
-};
-
-int cfi_jedec_lookup(int index, int mfr_id, int dev_id)
-{
-  	if (index>=0){
-		if (jedec_table[index].mfr_id == mfr_id &&
-		    jedec_table[index].dev_id == dev_id) return index;
-  	}
-  	else{
-		for (index=0; jedec_table[index].mfr_id; index++){
-		    if (jedec_table[index].mfr_id == mfr_id &&
-		        jedec_table[index].dev_id == dev_id) return index;
-		}
-  	}
-	return -1;
-}
-
-int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
-{
-int i,num_erase_regions;
-
-	printk("Found: %s\n",jedec_table[index].name);
-
-	num_erase_regions = jedec_table[index].NumEraseRegions;
-	
-	p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
-	if (!p_cfi->cfiq) {
-		//xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
-		return -1;
-	}
-
-	memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));	
-	
-	p_cfi->cfiq->P_ID = P_ID_AMD_STD;
-	p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
-	p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
-
-	for (i=0; i<num_erase_regions; i++){
-		p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
-	}	
-	return 0; 	/* ok */
-}
-
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/cfi_probe.c linux/drivers/mtd/chips/cfi_probe.c
--- v2.4.10/linux/drivers/mtd/chips/cfi_probe.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/cfi_probe.c	Thu Oct  4 15:14:59 2001
@@ -1,7 +1,7 @@
 /* 
    Common Flash Interface probe code.
    (C) 2000 Red Hat. GPL'd.
-   $Id: cfi_probe.c,v 1.60 2001/06/03 01:32:57 nico Exp $
+   $Id: cfi_probe.c,v 1.66 2001/10/02 15:05:12 dwmw2 Exp $
 */
 
 #include <linux/config.h>
@@ -12,11 +12,13 @@
 #include <asm/byteorder.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
+#include <linux/interrupt.h>
 
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
+#include <linux/mtd/gen_probe.h>
 
-/* #define DEBUG_CFI */
+//#define DEBUG_CFI 
 
 #ifdef DEBUG_CFI
 static void print_cfi_ident(struct cfi_ident *);
@@ -25,430 +27,153 @@
 int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
 int cfi_jedec_lookup(int index, int mfr_id, int dev_id);
 
-static void check_cmd_set(struct map_info *, int, unsigned long);
-static struct cfi_private *cfi_cfi_probe(struct map_info *);
-struct mtd_info *cfi_probe(struct map_info *map);
-
-
-static struct mtd_chip_driver cfi_chipdrv = {
-	probe: cfi_probe,
-	name: "cfi",
-	module: THIS_MODULE
-};
-
-
-struct mtd_info *cfi_probe(struct map_info *map)
-{
-	struct mtd_info *mtd = NULL;
-	struct cfi_private *cfi;
-
-	/* First probe the map to see if we have CFI stuff there. */
-	cfi = cfi_cfi_probe(map);
-	
-	if (!cfi)
-		return NULL;
-
-	map->fldrv_priv = cfi;
-	/* OK we liked it. Now find a driver for the command set it talks */
-
-	check_cmd_set(map, 1, cfi->chips[0].start); /* First the primary cmdset */
-	if (!map->fldrv)
-		check_cmd_set(map, 0, cfi->chips[0].start); /* Then the secondary */
-	
-	/* check_cmd_set() will have used inter_module_get to increase
-	   the use count of the module which provides the command set 
-	   driver. If we're quitting, we have to decrease it again.
-	*/
-
-	if(map->fldrv) {
-		mtd = map->fldrv->probe(map);
-		/* Undo the use count we held onto from inter_module_get */
-#ifdef MODULE
-		if(map->fldrv->module)
-		  __MOD_DEC_USE_COUNT(map->fldrv->module);
-#endif
-		if (mtd)
-			return mtd;
-	}
-	printk(KERN_WARNING"cfi_probe: No supported Vendor Command Set found\n");
-	
-	kfree(cfi->cfiq);
-	kfree(cfi);
-	map->fldrv_priv = NULL;
-	return NULL;
-}
+static int cfi_probe_chip(struct map_info *map, __u32 base,
+			  struct flchip *chips, struct cfi_private *cfi);
+static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi);
 
-static __u32 cfi_send_cmd(u_char cmd, __u32 base, struct map_info *map, struct cfi_private *cfi)
-{
-	return cfi_send_gen_cmd(cmd, 0x55, base, map, cfi, cfi->device_type, NULL);
-}
+struct mtd_info *cfi_probe(struct map_info *map);
 
 /* check for QRY, or search for jedec id.
    in: interleave,type,mode
    ret: table index, <0 for error
  */
-static int cfi_check_qry_or_id(struct map_info *map, __u32 base, int index,
+static inline int qry_present(struct map_info *map, __u32 base,
 				struct cfi_private *cfi)
 {
-	__u32 manufacturer_id, device_id;
 	int osf = cfi->interleave * cfi->device_type;	// scale factor
 
-	//printk("cfi_check_qry_or_id: base=0x%08lx interl=%d type=%d index=%d\n",base,cfi->interleave,cfi->device_type,index);
+	if (cfi_read(map,base+osf*0x10)==cfi_build_cmd('Q',map,cfi) &&
+	    cfi_read(map,base+osf*0x11)==cfi_build_cmd('R',map,cfi) &&
+	    cfi_read(map,base+osf*0x12)==cfi_build_cmd('Y',map,cfi))
+		return 1;	// ok !
 
-	switch(cfi->cfi_mode){
-	case 0:
-		if (cfi_read(map,base+osf*0x10)==cfi_build_cmd('Q',map,cfi) &&
-		    cfi_read(map,base+osf*0x11)==cfi_build_cmd('R',map,cfi) &&
-		    cfi_read(map,base+osf*0x12)==cfi_build_cmd('Y',map,cfi))
-			return 0;	// ok !
-		break;
-		
-	case 1:
-		manufacturer_id = cfi_read(map,base+0*osf);
-		device_id 	= cfi_read(map,base+1*osf);
-		//printk("cfi_check_qry_or_id: man=0x%lx,id=0x%lx\n",manufacturer_id, device_id);
-		
-		return cfi_jedec_lookup(index,manufacturer_id,device_id);	
-	}
-	
-	return -1; 	// nothing found
-}
-
-static void cfi_qry_mode(struct map_info *map, __u32 base, struct cfi_private *cfi)
-{
-	switch(cfi->cfi_mode){
-	case 0:
-		/* Query */
-		cfi_send_cmd(0x98, base, map, cfi);
-		break;
-		
-	case 1:
-		
-		/* Autoselect */
-		cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		break;
-	}
+	return 0; 	// nothing found
 }
 
-static int cfi_probe_chip_1(struct map_info *map, __u32 base,
+static int cfi_probe_chip(struct map_info *map, __u32 base,
 			  struct flchip *chips, struct cfi_private *cfi)
 {
-	int index;
-	__u32 tmp,ofs;
-	
-	ofs = cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, &tmp);
+	int i;
 	
-	cfi_qry_mode(map,base,cfi);
-	
-	index=cfi_check_qry_or_id(map,base,-1,cfi);
-	if (index<0) return -1;
-	
-	if (chips){
-		int i;
-
-		for (i=0; i<cfi->numchips; i++){
-			/* This chip should be in read mode if it's one
-			   we've already touched. */
-			if (cfi_check_qry_or_id(map,chips[i].start,index,cfi) >= 0){
-				cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
-				if (cfi_check_qry_or_id(map,chips[i].start,index,cfi) >= 0){
-					/* Yes it's got QRY for data. Most unfortunate.
-					   Stick the old one in read mode too. */
-					cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
-					if (cfi_check_qry_or_id(map,base,index,cfi) >= 0){
-						/* OK, so has the new one. Assume it's an alias */
-						printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-						       map->name, base, chips[i].start);
-						return -1;
-					}
-				} else {
-					/* 
-					 * FIXME: Is this supposed to work?
-					 * The third argument is already
-					 * multiplied as this within the
-					 * function definition. (Nicolas Pitre)
-					 */
-					cfi_send_gen_cmd(0xF0, 0, base+0xaa*cfi->interleave * cfi->device_type, map, cfi, cfi->device_type, NULL);
-					cfi_send_gen_cmd(0xF0, 0, chips[i].start+0xaa*cfi->interleave * cfi->device_type, map, cfi, cfi->device_type, NULL);
-					return -1;
-				}
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
+
+	if (!qry_present(map,base,cfi))
+		return 0;
+
+	if (!cfi->numchips) {
+		/* This is the first time we're called. Set up the CFI 
+		   stuff accordingly and return */
+		return cfi_chip_setup(map, cfi);
+	}
+
+	/* Check each previous chip to see if it's an alias */
+	for (i=0; i<cfi->numchips; i++) {
+		/* This chip should be in read mode if it's one
+		   we've already touched. */
+		if (qry_present(map,chips[i].start,cfi)) {
+			/* Eep. This chip also had the QRY marker. 
+			 * Is it an alias for the new one? */
+			cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
+
+			/* If the QRY marker goes away, it's an alias */
+			if (!qry_present(map, chips[i].start, cfi)) {
+				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
+				       map->name, base, chips[i].start);
+				return 0;
+			}
+			/* Yes, it's actually got QRY for data. Most 
+			 * unfortunate. Stick the new chip in read mode
+			 * too and if it's the same, assume it's an alias. */
+			/* FIXME: Use other modes to do a proper check */
+			cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+			
+			if (qry_present(map, base, cfi)) {
+				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
+				       map->name, base, chips[i].start);
+				return 0;
 			}
-		} /* for i */
-		
-		/* OK, if we got to here, then none of the previous chips appear to
-		   be aliases for the current one. */
-		if (cfi->numchips == MAX_CFI_CHIPS) {
-			printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
-			/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
-			return -1;
 		}
-		chips[cfi->numchips].start = base;
-		chips[cfi->numchips].state = FL_READY;
-		chips[cfi->numchips].mutex = &chips[cfi->numchips]._spinlock;
-		cfi->numchips++;
-		
-		/* Put it back into Read Mode */
-		cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 	}
-	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n", map->name, 
-	       cfi->interleave, cfi->device_type*8, base, map->buswidth*8);
 	
-	return index;
-}
-
-/*  put dev into qry mode, and try cfi and jedec modes for the given type/interleave
- */
-static int cfi_probe_chip(struct map_info *map, __u32 base,
-			  struct flchip *chips, struct cfi_private *cfi)
-{
-	int index;
-	cfi->cfi_mode=0;	/* cfi mode */
-	
-	switch (cfi->device_type) {
-	case CFI_DEVICETYPE_X8:
-		cfi->addr_unlock1 = 0x555; 
-		cfi->addr_unlock2 = 0x2aa; 
-		break;
-	case CFI_DEVICETYPE_X16:
-		cfi->addr_unlock1 = 0xaaa;
-		if (map->buswidth == cfi->interleave) {
-			/* X16 chip(s) in X8 mode */
-			cfi->addr_unlock2 = 0x555;
-		} else {
-			cfi->addr_unlock2 = 0x554;
-		}
-		break;
-	case CFI_DEVICETYPE_X32:
-		cfi->addr_unlock1 = 0x1555; 
-		cfi->addr_unlock2 = 0xaaa; 
-		break;
-	default:
-		return 0;
+	/* OK, if we got to here, then none of the previous chips appear to
+	   be aliases for the current one. */
+	if (cfi->numchips == MAX_CFI_CHIPS) {
+		printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
+		/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
+		return -1;
 	}
-	index = cfi_probe_chip_1(map,base,chips,cfi);
-	if (index>=0) return index;
+	chips[cfi->numchips].start = base;
+	chips[cfi->numchips].state = FL_READY;
+	cfi->numchips++;
 	
-	cfi->cfi_mode=1;	/* jedec mode */
-	index = cfi_probe_chip_1(map,base,chips,cfi);
-	if (index>=0) return index;
-	
-	cfi->addr_unlock1 = 0x5555;
-	cfi->addr_unlock2 = 0x2aaa; 
-	index = cfi_probe_chip_1(map,base,chips,cfi);
-	
-	return index;
-}
+	/* Put it back into Read Mode */
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 
-/*
- * Since probeing for CFI chips requires writing to the device problems may
- * occur if the flash is not present and RAM is accessed instead.  For now we
- * assume that the flash is present so we don't check for RAM or replace
- * possibly overwritten data.
- */
-static int cfi_probe_new_chip(struct map_info *map, unsigned long base,
-			      struct flchip *chips, struct cfi_private *cfi)
-{
-int index;
-	switch (map->buswidth) {
-#ifdef CFIDEV_BUSWIDTH_1		
-	case CFIDEV_BUSWIDTH_1:
-		cfi->interleave = CFIDEV_INTERLEAVE_1;
-		cfi->device_type = CFI_DEVICETYPE_X8;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-
-		cfi->device_type = CFI_DEVICETYPE_X16;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-		break;			
-#endif
-
-#ifdef CFIDEV_BUSWIDTH_2		
-	case CFIDEV_BUSWIDTH_2:
-#ifdef CFIDEV_INTERLEAVE_1
-		cfi->interleave = CFIDEV_INTERLEAVE_1;
-		cfi->device_type = CFI_DEVICETYPE_X16;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-#endif
-#ifdef CFIDEV_INTERLEAVE_2
-		cfi->interleave = CFIDEV_INTERLEAVE_2;
-		cfi->device_type = CFI_DEVICETYPE_X8;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-
-		cfi->device_type = CFI_DEVICETYPE_X16;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-
-#endif
-		break;			
-#endif
-
-#ifdef CFIDEV_BUSWIDTH_4
-	case CFIDEV_BUSWIDTH_4:
-#ifdef CFIDEV_INTERLEAVE_4
-		cfi->interleave = CFIDEV_INTERLEAVE_4;
-		cfi->device_type = CFI_DEVICETYPE_X16;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-
-		cfi->device_type = CFI_DEVICETYPE_X32;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-
-		cfi->device_type = CFI_DEVICETYPE_X8;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-#endif
-#ifdef CFIDEV_INTERLEAVE_2
-		cfi->interleave = CFIDEV_INTERLEAVE_2;
-		cfi->device_type = CFI_DEVICETYPE_X16;
-		index = cfi_probe_chip(map,base,chips,cfi);
-		if (index>=0) return index;
-#endif
-#ifdef CFIDEV_INTERLEAVE_1
-                cfi->interleave = CFIDEV_INTERLEAVE_1;
-                cfi->device_type = CFI_DEVICETYPE_X32;
-                index = cfi_probe_chip(map,base,chips,cfi);
-                if (index>=0) return index;
-#endif
-		break;
-#endif
-	default:
-		printk(KERN_WARNING "cfi_probe called with unsupported buswidth %d\n", map->buswidth);
-		return -1;
-	} // switch
-	return -1;
+	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
+	       map->name, cfi->interleave, cfi->device_type*8, base,
+	       map->buswidth*8);
+	
+	return 1;
 }
 
-static struct cfi_private *cfi_cfi_probe(struct map_info *map)
+static int cfi_chip_setup(struct map_info *map, 
+		   struct cfi_private *cfi)
 {
-	unsigned long base=0;
-	struct cfi_private cfi;
-	struct cfi_private *retcfi;
-	struct flchip chip[MAX_CFI_CHIPS];
-	int i,index; 
-	char num_erase_regions;
- 	int ofs_factor;
-
-	memset(&cfi, 0, sizeof(cfi));
-
-	/* The first invocation (with chips == NULL) leaves the device in Query Mode */
-	index = cfi_probe_new_chip(map, 0, NULL, &cfi);
-
-	if (index<0) {
-		printk(KERN_WARNING"%s: Found no CFI device at location zero\n", map->name);
-		/* Doesn't appear to be CFI-compliant at all */
-		return NULL;
-	}
-
-	/* Read the Basic Query Structure from the device */
-
- 	ofs_factor = cfi.interleave*cfi.device_type;
-
-	/* First, work out the amount of space to allocate */
-	if (cfi.cfi_mode==0){
-		num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
+	int ofs_factor = cfi->interleave*cfi->device_type;
+	__u32 base = 0;
+	int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor);
+	int i;
 
 #ifdef DEBUG_CFI
-		printk("Number of erase regions: %d\n", num_erase_regions);
+	printk("Number of erase regions: %d\n", num_erase_regions);
 #endif
+	if (!num_erase_regions)
+		return 0;
 
-		cfi.cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
-		if (!cfi.cfiq) {
-			printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
-			return NULL;
-		}
-
-		memset(cfi.cfiq,0,sizeof(struct cfi_ident));	
-
-		cfi.fast_prog=1;		/* CFI supports fast programming */
-
-			/* CFI flash */
-		for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
-			((unsigned char *)cfi.cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
-		}
-
-		/* Do any necessary byteswapping */
-		cfi.cfiq->P_ID = le16_to_cpu(cfi.cfiq->P_ID);
-
-		cfi.cfiq->P_ADR = le16_to_cpu(cfi.cfiq->P_ADR);
-		cfi.cfiq->A_ID = le16_to_cpu(cfi.cfiq->A_ID);
-		cfi.cfiq->A_ADR = le16_to_cpu(cfi.cfiq->A_ADR);
-		cfi.cfiq->InterfaceDesc = le16_to_cpu(cfi.cfiq->InterfaceDesc);
-		cfi.cfiq->MaxBufWriteSize = le16_to_cpu(cfi.cfiq->MaxBufWriteSize);
-
-		for (i=0; i<cfi.cfiq->NumEraseRegions; i++) {
-			cfi.cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi.cfiq->EraseRegionInfo[i]);
-
-#ifdef DEBUG_CFI		
-			printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
-		       		i, (cfi.cfiq->EraseRegionInfo[i] >> 8) & ~0xff, 
-		       		(cfi.cfiq->EraseRegionInfo[i] & 0xffff) + 1);
-#endif
-		}
-	}
-	else{
-		/* JEDEC flash */
-		if (cfi_jedec_setup(&cfi,index)<0){
-			printk(KERN_WARNING "cfi_jedec_setup failed\n");
-			return NULL;
-		}
+	cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
+	if (!cfi->cfiq) {
+		printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
+		return 0;
 	}
-
-	if (cfi.cfiq->NumEraseRegions == 0) {
-		printk(KERN_WARNING "Number of erase regions is zero\n");
-		kfree(cfi.cfiq);
-		return NULL;
+	
+	memset(cfi->cfiq,0,sizeof(struct cfi_ident));	
+	
+	cfi->cfi_mode = 1;
+	cfi->fast_prog=1;		/* CFI supports fast programming */
+	
+	/* Read the CFI info structure */
+	for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) {
+		((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor);
 	}
+	
+	/* Do any necessary byteswapping */
+	cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID);
+	
+	cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR);
+	cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID);
+	cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR);
+	cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc);
+	cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize);
 
 #ifdef DEBUG_CFI
 	/* Dump the information therein */
-	print_cfi_ident(cfi.cfiq);
+	print_cfi_ident(cfi->cfiq);
 #endif
 
-	cfi_send_cmd(0xFF, base, map, &cfi);
-
-	/* OK. We've worked out what it is and we're happy with it. Now see if there are others */
-
-	chip[0].start = 0;
-	chip[0].state = FL_READY;
-	chip[0].mutex = &chip[0]._spinlock;
-
-	cfi.chipshift = cfi.cfiq->DevSize;
-	cfi.numchips = 1;
-
-	if (!cfi.chipshift) {
-		printk(KERN_ERR"cfi.chipsize is zero. This is bad. cfi.cfiq->DevSize is %d\n", cfi.cfiq->DevSize);
-		kfree(cfi.cfiq);
-		return NULL;
-	}
-	switch (cfi.interleave) {
-	    case 2: cfi.chipshift += 1; break;
-	    case 4: cfi.chipshift += 2; break;
+	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
+		cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
+		
+#ifdef DEBUG_CFI		
+		printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
+		       i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, 
+		       (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
+#endif
 	}
+	/* Put it back into Read Mode */
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 
-	for (base = (1<<cfi.chipshift); base < map->size; base += (1<<cfi.chipshift))
-		cfi_probe_chip_1(map, base, &chip[0], &cfi);
-
-	retcfi = kmalloc(sizeof(struct cfi_private) + cfi.numchips * sizeof(struct flchip), GFP_KERNEL);
-
-	if (!retcfi) {
-		printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);
-		kfree(cfi.cfiq);
-		return NULL;
-	}
-	memcpy(retcfi, &cfi, sizeof(cfi));
-	memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);
-	for (i=0; i< retcfi->numchips; i++) {
-		init_waitqueue_head(&retcfi->chips[i].wq);
-		spin_lock_init(&retcfi->chips[i]._spinlock);
-		retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock;
-	}
-	return retcfi;
+	return 1;
 }
 
 #ifdef DEBUG_CFI
@@ -568,104 +293,40 @@
 }
 #endif /* DEBUG_CFI */
 
-typedef void cfi_cmdset_fn_t(struct map_info *, int, unsigned long);
-
-extern cfi_cmdset_fn_t cfi_cmdset_0001;
-extern cfi_cmdset_fn_t cfi_cmdset_0002;
-
-static void cfi_cmdset_unknown(struct map_info *map, int primary, unsigned long base)
-{
-	__u16 adr;
-	struct cfi_private *cfi = map->fldrv_priv;
-	__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
-#ifdef HAVE_INTER_MODULE
-	char probename[32];
-	cfi_cmdset_fn_t *probe_function;
-
-	sprintf(probename, "cfi_cmdset_%4.4X", type);
-		
-	probe_function = inter_module_get_request(probename, probename);
-
-	if (probe_function) {
-		(*probe_function)(map, primary, base);
-		return;
-	}	
-#endif
-	printk(KERN_NOTICE "Support for command set %04X not present\n", type);
-	/* This was a command set we don't know about. Print only the basic info */
-	adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
-	
-	if (!adr) {
-		printk(" No Extended Query Table\n");
-	}
-	else {
- 		int ofs_factor = cfi->interleave * cfi->device_type;
-
-		if (cfi_read_query(map,base + adr*ofs_factor) != (primary?'P':'A') ||
-		    cfi_read_query(map,base + (adr+1)*ofs_factor) != (primary?'R':'L') ||
-		    cfi_read_query(map,base + (adr+2)*ofs_factor) != (primary?'I':'T')) {
-			printk ("Invalid Extended Query Table at %4.4X: %2.2X %2.2X %2.2X\n",
-				adr,
-				cfi_read_query(map,base + adr*ofs_factor),
-				cfi_read_query(map,base + (adr+1)*ofs_factor),
-				cfi_read_query(map,base + (adr+2)*ofs_factor));
-		}
-		else {
-			printk(" Extended Query Table version %c.%c\n",
-			       cfi_read_query(map,base + (adr+3)*ofs_factor), 
-			       cfi_read_query(map,base + (adr+4)*ofs_factor));
-		}
-	}
-	cfi_send_cmd(0xff, base, map, cfi);
-}
+static struct chip_probe cfi_chip_probe = {
+	name: "CFI",
+	probe_chip: cfi_probe_chip
+};
 
-static void check_cmd_set(struct map_info *map, int primary, unsigned long base)
+struct mtd_info *cfi_probe(struct map_info *map)
 {
-	struct cfi_private *cfi = map->fldrv_priv;
-	__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
-	
-	if (type == P_ID_NONE || type == P_ID_RESERVED)
-		return;
-	/* Put it in query mode */
-	cfi_qry_mode(map,base,cfi);
-
-	switch(type){
-		/* Urgh. Ifdefs. The version with weak symbols was
-		 * _much_ nicer. Shame it didn't seem to work on
-		 * anything but x86, really.
-		 * But we can't rely in inter_module_get() because
-		 * that'd mean we depend on link order.
-		 */
-#ifdef CONFIG_MTD_CFI_INTELEXT
-	case 0x0001:
-	case 0x0003:
-		return cfi_cmdset_0001(map, primary, base);
-#endif
-#ifdef CONFIG_MTD_CFI_AMDSTD
-	case 0x0002:
-		return cfi_cmdset_0002(map, primary, base);
-#endif
-	}
-
-	return cfi_cmdset_unknown(map, primary, base);
+	/*
+	 * Just use the generic probe stuff to call our CFI-specific
+	 * chip_probe routine in all the possible permutations, etc.
+	 */
+	return mtd_do_chip_probe(map, &cfi_chip_probe);
 }
 
+static struct mtd_chip_driver cfi_chipdrv = {
+	probe: cfi_probe,
+	name: "cfi_probe",
+	module: THIS_MODULE
+};
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define cfi_probe_init init_module
-#define cfi_probe_exit cleanup_module
-#endif
-
-mod_init_t cfi_probe_init(void)
+int __init cfi_probe_init(void)
 {
 	register_mtd_chip_driver(&cfi_chipdrv);
 	return 0;
 }
 
-mod_exit_t cfi_probe_exit(void)
+static void __exit cfi_probe_exit(void)
 {
 	unregister_mtd_chip_driver(&cfi_chipdrv);
 }
 
 module_init(cfi_probe_init);
 module_exit(cfi_probe_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
+MODULE_DESCRIPTION("Probe code for CFI-compliant flash chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/chipreg.c linux/drivers/mtd/chips/chipreg.c
--- v2.4.10/linux/drivers/mtd/chips/chipreg.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/chipreg.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: chipreg.c,v 1.8 2001/06/09 19:58:19 dwmw2 Exp $
+ * $Id: chipreg.c,v 1.12 2001/10/02 15:29:53 dwmw2 Exp $
  *
  * Registration for chip drivers
  *
@@ -90,3 +90,7 @@
 EXPORT_SYMBOL(register_mtd_chip_driver);
 EXPORT_SYMBOL(unregister_mtd_chip_driver);
 EXPORT_SYMBOL(do_map_probe);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("Core routines for registering and invoking MTD chip drivers");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/gen_probe.c linux/drivers/mtd/chips/gen_probe.c
--- v2.4.10/linux/drivers/mtd/chips/gen_probe.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/gen_probe.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,299 @@
+/*
+ * Routines common to all CFI-type probes.
+ * (C) 2001, 2001 Red Hat, Inc.
+ * GPL'd
+ * $Id: gen_probe.c,v 1.5 2001/10/02 15:05:12 dwmw2 Exp $
+ */
+
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+#include <linux/mtd/gen_probe.h>
+
+static struct mtd_info *check_cmd_set(struct map_info *, int);
+static struct cfi_private *genprobe_ident_chips(struct map_info *map,
+						struct chip_probe *cp);
+static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
+			     struct cfi_private *cfi);
+
+struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
+{
+	struct mtd_info *mtd = NULL;
+	struct cfi_private *cfi;
+
+	/* First probe the map to see if we have CFI stuff there. */
+	cfi = genprobe_ident_chips(map, cp);
+	
+	if (!cfi)
+		return NULL;
+
+	map->fldrv_priv = cfi;
+	/* OK we liked it. Now find a driver for the command set it talks */
+
+	mtd = check_cmd_set(map, 1); /* First the primary cmdset */
+	if (!mtd)
+		mtd = check_cmd_set(map, 0); /* Then the secondary */
+	
+	if (mtd)
+		return mtd;
+
+	printk(KERN_WARNING"cfi_probe: No supported Vendor Command Set found\n");
+	
+	kfree(cfi->cfiq);
+	kfree(cfi);
+	map->fldrv_priv = NULL;
+	return NULL;
+}
+EXPORT_SYMBOL(mtd_do_chip_probe);
+
+
+struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
+{
+	unsigned long base=0;
+	struct cfi_private cfi;
+	struct cfi_private *retcfi;
+	struct flchip chip[MAX_CFI_CHIPS];
+	int i;
+
+	memset(&cfi, 0, sizeof(cfi));
+
+	/* Call the probetype-specific code with all permutations of 
+	   interleave and device type, etc. */
+	if (!genprobe_new_chip(map, cp, &cfi)) {
+		/* The probe didn't like it */
+		printk(KERN_WARNING "%s: Found no %s device at location zero\n",
+		       cp->name, map->name);
+		return NULL;
+	}		
+
+#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
+	 probe routines won't ever return a broken CFI structure anyway,
+	 because they make them up themselves.
+      */
+	if (cfi.cfiq->NumEraseRegions == 0) {
+		printk(KERN_WARNING "Number of erase regions is zero\n");
+		kfree(cfi.cfiq);
+		return NULL;
+	}
+#endif
+	chip[0].start = 0;
+	chip[0].state = FL_READY;
+	cfi.chipshift = cfi.cfiq->DevSize;
+
+	switch(cfi.interleave) {
+#ifdef CFIDEV_INTERLEAVE_1
+	case 1:
+		break;
+#endif
+#ifdef CFIDEV_INTERLEAVE_2
+	case 2:
+		cfi.chipshift++;
+		break;
+#endif
+#ifdef CFIDEV_INTERLEAVE_4
+	case 4:
+		cfi.chipshift+=2;
+		break;
+#endif
+	default:
+		BUG();
+	}
+		
+	cfi.numchips = 1;
+
+	/*
+	 * Now probe for other chips, checking sensibly for aliases while
+	 * we're at it. The new_chip probe above should have let the first
+	 * chip in read mode.
+	 */
+
+	for (base = (1<<cfi.chipshift); base + (1<<cfi.chipshift) <= map->size;
+	     base += (1<<cfi.chipshift))
+		cp->probe_chip(map, base, &chip[0], &cfi);
+
+	/*
+	 * Now allocate the space for the structures we need to return to 
+	 * our caller, and copy the appropriate data into them.
+	 */
+
+	retcfi = kmalloc(sizeof(struct cfi_private) + cfi.numchips * sizeof(struct flchip), GFP_KERNEL);
+
+	if (!retcfi) {
+		printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);
+		kfree(cfi.cfiq);
+		return NULL;
+	}
+
+	memcpy(retcfi, &cfi, sizeof(cfi));
+	memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);
+
+	/* Fix up the stuff that breaks when you move it */
+	for (i=0; i< retcfi->numchips; i++) {
+		init_waitqueue_head(&retcfi->chips[i].wq);
+		spin_lock_init(&retcfi->chips[i]._spinlock);
+		retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock;
+	}
+
+	return retcfi;
+}
+
+	
+static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
+			     struct cfi_private *cfi)
+{
+	switch (map->buswidth) {
+#ifdef CFIDEV_BUSWIDTH_1		
+	case CFIDEV_BUSWIDTH_1:
+		cfi->interleave = CFIDEV_INTERLEAVE_1;
+
+		cfi->device_type = CFI_DEVICETYPE_X8;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+		break;			
+#endif /* CFIDEV_BUSWITDH_1 */
+
+#ifdef CFIDEV_BUSWIDTH_2		
+	case CFIDEV_BUSWIDTH_2:
+#ifdef CFIDEV_INTERLEAVE_1
+		cfi->interleave = CFIDEV_INTERLEAVE_1;
+
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+#endif /* CFIDEV_INTERLEAVE_1 */
+#ifdef CFIDEV_INTERLEAVE_2
+		cfi->interleave = CFIDEV_INTERLEAVE_2;
+
+		cfi->device_type = CFI_DEVICETYPE_X8;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+#endif /* CFIDEV_INTERLEAVE_2 */
+		break;			
+#endif /* CFIDEV_BUSWIDTH_2 */
+
+#ifdef CFIDEV_BUSWIDTH_4
+	case CFIDEV_BUSWIDTH_4:
+#if defined(CFIDEV_INTERLEAVE_1) && defined(SOMEONE_ACTUALLY_MAKES_THESE)
+                cfi->interleave = CFIDEV_INTERLEAVE_1;
+
+                cfi->device_type = CFI_DEVICETYPE_X32;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+#endif /* CFIDEV_INTERLEAVE_1 */
+#ifdef CFIDEV_INTERLEAVE_2
+		cfi->interleave = CFIDEV_INTERLEAVE_2;
+
+#ifdef SOMEONE_ACTUALLY_MAKES_THESE
+		cfi->device_type = CFI_DEVICETYPE_X32;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+#endif
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+
+		cfi->device_type = CFI_DEVICETYPE_X8;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+#endif /* CFIDEV_INTERLEAVE_2 */
+#ifdef CFIDEV_INTERLEAVE_4
+		cfi->interleave = CFIDEV_INTERLEAVE_4;
+
+#ifdef SOMEONE_ACTUALLY_MAKES_THESE
+		cfi->device_type = CFI_DEVICETYPE_X32;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+#endif
+		cfi->device_type = CFI_DEVICETYPE_X16;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+
+		cfi->device_type = CFI_DEVICETYPE_X8;
+		if (cp->probe_chip(map, 0, NULL, cfi))
+			return 1;
+#endif /* CFIDEV_INTERLEAVE_4 */
+		break;
+#endif /* CFIDEV_BUSWIDTH_4 */
+
+	default:
+		printk(KERN_WARNING "genprobe_new_chip called with unsupported buswidth %d\n", map->buswidth);
+		return 0;
+	}
+	return 0;
+}
+
+
+typedef struct mtd_info *cfi_cmdset_fn_t(struct map_info *, int);
+
+extern cfi_cmdset_fn_t cfi_cmdset_0001;
+extern cfi_cmdset_fn_t cfi_cmdset_0002;
+
+static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, 
+						  int primary)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
+#if defined(CONFIG_MODULES) && defined(HAVE_INTER_MODULE)
+	char probename[32];
+	cfi_cmdset_fn_t *probe_function;
+
+	sprintf(probename, "cfi_cmdset_%4.4X", type);
+		
+	probe_function = inter_module_get_request(probename, probename);
+
+	if (probe_function) {
+		struct mtd_info *mtd;
+
+		mtd = (*probe_function)(map, primary);
+		/* If it was happy, it'll have increased its own use count */
+		inter_module_put(probename);
+		return mtd;
+	}
+#endif
+	printk(KERN_NOTICE "Support for command set %04X not present\n",
+	       type);
+
+	return NULL;
+}
+
+static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
+	
+	if (type == P_ID_NONE || type == P_ID_RESERVED)
+		return NULL;
+
+	switch(type){
+		/* Urgh. Ifdefs. The version with weak symbols was
+		 * _much_ nicer. Shame it didn't seem to work on
+		 * anything but x86, really.
+		 * But we can't rely in inter_module_get() because
+		 * that'd mean we depend on link order.
+		 */
+#ifdef CONFIG_MTD_CFI_INTELEXT
+	case 0x0001:
+	case 0x0003:
+		return cfi_cmdset_0001(map, primary);
+#endif
+#ifdef CONFIG_MTD_CFI_AMDSTD
+	case 0x0002:
+		return cfi_cmdset_0002(map, primary);
+#endif
+	}
+
+	return cfi_cmdset_unknown(map, primary);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("Helper routines for flash chip probe code");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/jedec.c linux/drivers/mtd/chips/jedec.c
--- v2.4.10/linux/drivers/mtd/chips/jedec.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/jedec.c	Thu Oct  4 15:14:59 2001
@@ -11,17 +11,17 @@
  * not going to guess how to send commands to them, plus I expect they will
  * all speak CFI..
  *
- * $Id: jedec.c,v 1.8 2001/06/09 23:56:57 dwmw2 Exp $
+ * $Id: jedec.c,v 1.11 2001/10/02 15:05:12 dwmw2 Exp $
  */
 
 #include <linux/mtd/jedec.h>
 
-struct mtd_info *jedec_probe(struct map_info *);
-int jedec_probe8(struct map_info *map,unsigned long base,
+static struct mtd_info *jedec_probe(struct map_info *);
+static int jedec_probe8(struct map_info *map,unsigned long base,
 		  struct jedec_private *priv);
-int jedec_probe16(struct map_info *map,unsigned long base,
+static int jedec_probe16(struct map_info *map,unsigned long base,
 		  struct jedec_private *priv);
-int jedec_probe32(struct map_info *map,unsigned long base,
+static int jedec_probe32(struct map_info *map,unsigned long base,
 		  struct jedec_private *priv);
 static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start,
 			    unsigned long len);
@@ -48,7 +48,7 @@
 static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 
 			     size_t *retlen, u_char *buf);
 
-struct mtd_info *jedec_probe(struct map_info *map);
+static struct mtd_info *jedec_probe(struct map_info *map);
 
 
 
@@ -59,23 +59,31 @@
 };
 
 /* Probe entry point */
-struct jedec_private priv;
-struct mtd_info __MTD;
-struct mtd_info *jedec_probe(struct map_info *map)
+
+static struct mtd_info *jedec_probe(struct map_info *map)
 {
-   struct mtd_info *MTD = &__MTD;
+   struct mtd_info *MTD;
+   struct jedec_private *priv;
    unsigned long Base;
    unsigned long SectorSize;
    unsigned count;
    unsigned I,Uniq;
    char Part[200];
    memset(&priv,0,sizeof(priv));
+
+   MTD = kmalloc(sizeof(struct mtd_info) + sizeof(struct jedec_private), GFP_KERNEL);
+   if (!MTD)
+	   return NULL;
+
+   memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
+   priv = (struct jedec_private *)&MTD[1];
    
    my_bank_size = map->size;
 
    if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
    {
       printk("mtd: Increase MAX_JEDEC_CHIPS, too many banks.\n");
+      kfree(MTD);
       return 0;
    }
    
@@ -86,33 +94,35 @@
 	 map->buswidth = 1;
       
       if (map->buswidth == 1){
-	 if (jedec_probe8(map,Base,&priv) == 0) {
+	 if (jedec_probe8(map,Base,priv) == 0) {
 		 printk("did recognize jedec chip\n");
+		 kfree(MTD);
 	         return 0;
 	 }
       }
       if (map->buswidth == 2)
-	 jedec_probe16(map,Base,&priv);
+	 jedec_probe16(map,Base,priv);
       if (map->buswidth == 4)
-	 jedec_probe32(map,Base,&priv);
+	 jedec_probe32(map,Base,priv);
    }
    
    // Get the biggest sector size
    SectorSize = 0;
-   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
    {
-	   //	   printk("priv.chips[%d].jedec is %x\n",I,priv.chips[I].jedec);
-	   //	   printk("priv.chips[%d].sectorsize is %lx\n",I,priv.chips[I].sectorsize);
-      if (priv.chips[I].sectorsize > SectorSize)
-	 SectorSize = priv.chips[I].sectorsize;
+	   //	   printk("priv->chips[%d].jedec is %x\n",I,priv->chips[I].jedec);
+	   //	   printk("priv->chips[%d].sectorsize is %lx\n",I,priv->chips[I].sectorsize);
+      if (priv->chips[I].sectorsize > SectorSize)
+	 SectorSize = priv->chips[I].sectorsize;
    }
    
    // Quickly ensure that the other sector sizes are factors of the largest
-   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
    {
-      if ((SectorSize/priv.chips[I].sectorsize)*priv.chips[I].sectorsize != SectorSize)
+      if ((SectorSize/priv->chips[I].sectorsize)*priv->chips[I].sectorsize != SectorSize)
       {
 	 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
+	 kfree(MTD);
 	 return 0;
       }      
    }
@@ -124,21 +134,22 @@
    Part[sizeof(Part)-11] = 0;
    strcat(Part," ");
    Uniq = 0;
-   for (I = 0; priv.chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
+   for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
    {
       const struct JEDECTable *JEDEC;
       
-      if (priv.chips[I+1].jedec == priv.chips[I].jedec)
+      if (priv->chips[I+1].jedec == priv->chips[I].jedec)
       {
 	 count++;
 	 continue;
       }
       
       // Locate the chip in the jedec table
-      JEDEC = jedec_idtoinf(priv.chips[I].jedec >> 8,priv.chips[I].jedec);
+      JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
       if (JEDEC == 0)
       {
 	 printk("mtd: Internal Error, JEDEC not set\n");
+	 kfree(MTD);
 	 return 0;
       }
       
@@ -159,37 +170,39 @@
       are empty banks. Note, the last bank does not count here, only the
       first banks are important. Holes on non-bank boundaries can not exist
       due to the way the detection algorithm works. */
-   if (priv.size < my_bank_size)
-      my_bank_size = priv.size;
-   priv.is_banked = 0;
-   //printk("priv.size is %x, my_bank_size is %x\n",priv.size,my_bank_size);
-   //printk("priv.bank_fill[0] is %x\n",priv.bank_fill[0]);
-   if (!priv.size) {
-	   printk("priv.size is zero\n");
+   if (priv->size < my_bank_size)
+      my_bank_size = priv->size;
+   priv->is_banked = 0;
+   //printk("priv->size is %x, my_bank_size is %x\n",priv->size,my_bank_size);
+   //printk("priv->bank_fill[0] is %x\n",priv->bank_fill[0]);
+   if (!priv->size) {
+	   printk("priv->size is zero\n");
+	   kfree(MTD);
 	   return 0;
    }
-   if (priv.size/my_bank_size) {
-	   if (priv.size/my_bank_size == 1) {
-		   priv.size = my_bank_size;
+   if (priv->size/my_bank_size) {
+	   if (priv->size/my_bank_size == 1) {
+		   priv->size = my_bank_size;
 	   }
 	   else {
-		   for (I = 0; I != priv.size/my_bank_size - 1; I++)
+		   for (I = 0; I != priv->size/my_bank_size - 1; I++)
 		   {
-		      if (priv.bank_fill[I] != my_bank_size)
-			 priv.is_banked = 1;
+		      if (priv->bank_fill[I] != my_bank_size)
+			 priv->is_banked = 1;
 		      
 		      /* This even could be eliminated, but new de-optimized read/write
 			 functions have to be written */
-		      printk("priv.bank_fill[%d] is %lx, priv.bank_fill[0] is %lx\n",I,priv.bank_fill[I],priv.bank_fill[0]);
-		      if (priv.bank_fill[I] != priv.bank_fill[0])
+		      printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
+		      if (priv->bank_fill[I] != priv->bank_fill[0])
 		      {
-			 printk("mtd: Failed. Cannot handle unsymetric banking\n");
+			 printk("mtd: Failed. Cannot handle unsymmetric banking\n");
+			 kfree(MTD);
 			 return 0;
 		      }      
 		   }
 	   }
    }
-   if (priv.is_banked == 1)
+   if (priv->is_banked == 1)
       strcat(Part,", banked");
 
    //   printk("Part: '%s'\n",Part);
@@ -202,18 +215,18 @@
    MTD->flags = MTD_CAP_NORFLASH;
    MTD->erasesize = SectorSize*(map->buswidth);
    //   printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize);
-   MTD->size = priv.size;
+   MTD->size = priv->size;
    //   printk("MTD->size is %x\n",(unsigned int)MTD->size);
    //MTD->module = THIS_MODULE; // ? Maybe this should be the low level module?
    MTD->erase = flash_erase;
-   if (priv.is_banked == 1)
+   if (priv->is_banked == 1)
       MTD->read = jedec_read_banked;
    else
       MTD->read = jedec_read;
    MTD->write = flash_write;
    MTD->sync = jedec_sync;
    MTD->priv = map;
-   map->fldrv_priv = &priv;
+   map->fldrv_priv = priv;
    map->fldrv = &jedec_chipdrv;
    MOD_INC_USE_COUNT;
    return MTD;
@@ -334,7 +347,7 @@
 }
 
 // Look for flash using an 8 bit bus interface
-int jedec_probe8(struct map_info *map,unsigned long base,
+static int jedec_probe8(struct map_info *map,unsigned long base,
 		  struct jedec_private *priv)
 { 
    #define flread(x) map->read8(map,base+x)
@@ -387,14 +400,14 @@
 }
 
 // Look for flash using a 16 bit bus interface (ie 2 8-bit chips)
-int jedec_probe16(struct map_info *map,unsigned long base,
+static int jedec_probe16(struct map_info *map,unsigned long base,
 		  struct jedec_private *priv)
 {
    return 0;
 }
 
 // Look for flash using a 32 bit bus interface (ie 4 8-bit chips)
-int jedec_probe32(struct map_info *map,unsigned long base,
+static int jedec_probe32(struct map_info *map,unsigned long base,
 		  struct jedec_private *priv)
 {
    #define flread(x) map->read32(map,base+((x)<<2))
@@ -859,11 +872,6 @@
 	 chip->length = (start + len - ByteStart + (1 << chip->addrshift)-1) >> chip->addrshift;
    }
 }
-									/*}}}*/
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define jedec_probe_init init_module
-#define jedec_probe_exit cleanup_module
-#endif
 
 int __init jedec_probe_init(void)
 {
@@ -878,3 +886,7 @@
 
 module_init(jedec_probe_init);
 module_exit(jedec_probe_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jason Gunthorpe <jgg@deltatee.com> et al.");
+MODULE_DESCRIPTION("Old MTD chip driver for JEDEC-compliant flash chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/jedec_probe.c linux/drivers/mtd/chips/jedec_probe.c
--- v2.4.10/linux/drivers/mtd/chips/jedec_probe.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/jedec_probe.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,441 @@
+/* 
+   Common Flash Interface probe code.
+   (C) 2000 Red Hat. GPL'd.
+   $Id: jedec_probe.c,v 1.3 2001/10/02 15:05:12 dwmw2 Exp $
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+#include <linux/mtd/gen_probe.h>
+
+
+/* Manufacturers */
+#define MANUFACTURER_AMD	0x0001
+#define MANUFACTURER_FUJITSU	0x0004
+#define MANUFACTURER_ATMEL	0x001f
+#define MANUFACTURER_ST		0x0020
+#define MANUFACTURER_SST	0x00BF
+#define MANUFACTURER_TOSHIBA	0x0098
+
+/* AMD */
+#define AM29F800BB	0x2258
+#define AM29F800BT	0x22D6
+#define AM29LV800BB	0x225B
+#define AM29LV800BT	0x22DA
+#define AM29LV160DT	0x22C4
+#define AM29LV160DB	0x2249
+
+/* Atmel */
+#define AT49BV16X4	0x00c0
+#define AT49BV16X4T	0x00c2
+
+/* Fujitsu */
+#define MBM29LV160TE	0x22C4
+#define MBM29LV160BE	0x2249
+
+/* ST - www.st.com */
+#define M29W800T	0x00D7
+#define M29W160DT	0x22C4
+#define M29W160DB	0x2249
+
+/* SST */
+#define SST39LF800	0x2781
+#define SST39LF160	0x2782
+
+/* Toshiba */
+#define TC58FVT160	0x00C2
+#define TC58FVB160	0x0043
+
+
+struct amd_flash_info {
+	const __u16 mfr_id;
+	const __u16 dev_id;
+	const char *name;
+	const int DevSize;
+	const int InterfaceDesc;
+	const int NumEraseRegions;
+	const ulong regions[4];
+};
+
+#define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
+
+#define SIZE_1MiB 20
+#define SIZE_2MiB 21
+#define SIZE_4MiB 22
+
+static const struct amd_flash_info jedec_table[] = {
+	{
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV160DT,
+		name: "AMD AM29LV160DT",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV160DB,
+		name: "AMD AM29LV160DB",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_TOSHIBA,
+		dev_id: TC58FVT160,
+		name: "Toshiba TC58FVT160",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_FUJITSU,
+		dev_id: MBM29LV160TE,
+		name: "Fujitsu MBM29LV160TE",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_TOSHIBA,
+		dev_id: TC58FVB160,
+		name: "Toshiba TC58FVB160",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_FUJITSU,
+		dev_id: MBM29LV160BE,
+		name: "Fujitsu MBM29LV160BE",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BB,
+		name: "AMD AM29LV800BB",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,15),
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29F800BB,
+		name: "AMD AM29F800BB",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,15),
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BT,
+		name: "AMD AM29LV800BT",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29F800BT,
+		name: "AMD AM29F800BT",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV800BB,
+		name: "AMD AM29LV800BB",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W800T,
+		name: "ST M29W800T",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,15),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W160DT,
+		name: "ST M29W160DT",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x10000,31),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x04000,1)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ST,
+		dev_id: M29W160DB,
+		name: "ST M29W160DB",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 4,
+		regions: {ERASEINFO(0x04000,1),
+			  ERASEINFO(0x02000,2),
+			  ERASEINFO(0x08000,1),
+			  ERASEINFO(0x10000,31)
+		}
+	}, {
+		mfr_id: MANUFACTURER_ATMEL,
+		dev_id: AT49BV16X4,
+		name: "Atmel AT49BV16X4",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 3,
+		regions: {ERASEINFO(0x02000,8),
+			  ERASEINFO(0x08000,2),
+			  ERASEINFO(0x10000,30)
+		}
+	}, {
+                mfr_id: MANUFACTURER_ATMEL,
+                dev_id: AT49BV16X4T,
+                name: "Atmel AT49BV16X4T",
+                DevSize: SIZE_2MiB,
+                NumEraseRegions: 3,
+                regions: {ERASEINFO(0x10000,30),
+                          ERASEINFO(0x08000,2),
+			  ERASEINFO(0x02000,8)
+                }
+	} 
+};
+
+
+static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
+
+static int jedec_probe_chip(struct map_info *map, __u32 base,
+			    struct flchip *chips, struct cfi_private *cfi);
+
+struct mtd_info *jedec_probe(struct map_info *map);
+#define jedec_read_mfr(map, base, osf) cfi_read(map, base)
+#define jedec_read_id(map, base, osf) cfi_read(map, (base)+(osf))
+
+static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
+{
+	int i,num_erase_regions;
+
+	printk("Found: %s\n",jedec_table[index].name);
+
+	num_erase_regions = jedec_table[index].NumEraseRegions;
+	
+	p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
+	if (!p_cfi->cfiq) {
+		//xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
+		return 0;
+	}
+
+	memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));	
+	
+	p_cfi->cfiq->P_ID = P_ID_AMD_STD;
+	p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
+	p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
+
+	for (i=0; i<num_erase_regions; i++){
+		p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
+	}	
+	return 1; 	/* ok */
+}
+
+static int jedec_probe_chip(struct map_info *map, __u32 base,
+			      struct flchip *chips, struct cfi_private *cfi)
+{
+	int i;
+	int osf = cfi->interleave * cfi->device_type;
+	int retried = 0;
+
+	if (!cfi->numchips) {
+		switch (cfi->device_type) {
+		case CFI_DEVICETYPE_X8:
+			cfi->addr_unlock1 = 0x555; 
+			cfi->addr_unlock2 = 0x2aa; 
+			break;
+		case CFI_DEVICETYPE_X16:
+			cfi->addr_unlock1 = 0xaaa;
+			if (map->buswidth == cfi->interleave) {
+				/* X16 chip(s) in X8 mode */
+				cfi->addr_unlock2 = 0x555;
+			} else {
+				cfi->addr_unlock2 = 0x554;
+			}
+			break;
+		case CFI_DEVICETYPE_X32:
+			cfi->addr_unlock1 = 0x1555; 
+			cfi->addr_unlock2 = 0xaaa; 
+			break;
+		default:
+			printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
+		return 0;
+		}
+	}
+
+ retry:
+	/* Reset */
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+
+	/* Autoselect Mode */
+	cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+
+	if (!cfi->numchips) {
+		/* This is the first time we're called. Set up the CFI 
+		   stuff accordingly and return */
+		
+		cfi->mfr = jedec_read_mfr(map, base, osf);
+		cfi->id = jedec_read_id(map, base, osf);
+		
+		for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
+			if (cfi->mfr == jedec_table[i].mfr_id &&
+			    cfi->id == jedec_table[i].dev_id)
+				return cfi_jedec_setup(cfi, i);
+		}
+		if (!retried++) {
+			/* Deal with whichever strange chips these were */
+			cfi->addr_unlock1 |= cfi->addr_unlock1 << 8;
+			cfi->addr_unlock2 |= cfi->addr_unlock2 << 8;
+			goto retry;
+		}
+		return 0;
+	}
+	
+	/* Check each previous chip to see if it's an alias */
+	for (i=0; i<cfi->numchips; i++) {
+		/* This chip should be in read mode if it's one
+		   we've already touched. */
+		if (jedec_read_mfr(map, base, osf) == cfi->mfr &&
+		    jedec_read_id(map, base, osf) == cfi->id) {
+			/* Eep. This chip also looks like it's in autoselect mode.
+			   Is it an alias for the new one? */
+			
+			cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
+			/* If the device IDs go away, it's an alias */
+			if (jedec_read_mfr(map, base, osf) != cfi->mfr ||
+			    jedec_read_id(map, base, osf) != cfi->id) {
+				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
+				       map->name, base, chips[i].start);
+				return 0;
+			}
+			
+			/* Yes, it's actually got the device IDs as data. Most
+			 * unfortunate. Stick the new chip in read mode
+			 * too and if it's the same, assume it's an alias. */
+			/* FIXME: Use other modes to do a proper check */
+			cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+			if (jedec_read_mfr(map, base, osf) == cfi->mfr &&
+			    jedec_read_id(map, base, osf) == cfi->id) {
+				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
+				       map->name, base, chips[i].start);
+				return 0;
+			}
+		}
+	}
+		
+	/* OK, if we got to here, then none of the previous chips appear to
+	   be aliases for the current one. */
+	if (cfi->numchips == MAX_CFI_CHIPS) {
+		printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
+		/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
+		return -1;
+	}
+	chips[cfi->numchips].start = base;
+	chips[cfi->numchips].state = FL_READY;
+	cfi->numchips++;
+		
+	/* Put it back into Read Mode */
+	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+
+	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
+	       map->name, cfi->interleave, cfi->device_type*8, base, 
+	       map->buswidth*8);
+	
+	return 1;
+}
+
+static struct chip_probe jedec_chip_probe = {
+	name: "JEDEC",
+	probe_chip: jedec_probe_chip
+};
+
+struct mtd_info *jedec_probe(struct map_info *map)
+{
+	/*
+	 * Just use the generic probe stuff to call our CFI-specific
+	 * chip_probe routine in all the possible permutations, etc.
+	 */
+	return mtd_do_chip_probe(map, &jedec_chip_probe);
+}
+
+static struct mtd_chip_driver jedec_chipdrv = {
+	probe: jedec_probe,
+	name: "jedec_probe",
+	module: THIS_MODULE
+};
+
+int __init jedec_probe_init(void)
+{
+	register_mtd_chip_driver(&jedec_chipdrv);
+	return 0;
+}
+
+static void __exit jedec_probe_exit(void)
+{
+	unregister_mtd_chip_driver(&jedec_chipdrv);
+}
+
+module_init(jedec_probe_init);
+module_exit(jedec_probe_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
+MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/map_absent.c linux/drivers/mtd/chips/map_absent.c
--- v2.4.10/linux/drivers/mtd/chips/map_absent.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/chips/map_absent.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,116 @@
+/*
+ * Common code to handle absent "placeholder" devices
+ * Copyright 2001 Resilience Corporation <ebrower@resilience.com>
+ * $Id: map_absent.c,v 1.2 2001/10/02 15:05:12 dwmw2 Exp $
+ *
+ * This map driver is used to allocate "placeholder" MTD
+ * devices on systems that have socketed/removable media. 
+ * Use of this driver as a fallback preserves the expected 
+ * registration of MTD device nodes regardless of probe outcome.
+ * A usage example is as follows:
+ *
+ *		my_dev[i] = do_map_probe("cfi", &my_map[i]);
+ *		if(NULL == my_dev[i]) {
+ *			my_dev[i] = do_map_probe("map_absent", &my_map[i]);
+ *		}
+ *
+ * Any device 'probed' with this driver will return -ENODEV
+ * upon open.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/map.h>
+
+
+static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int map_absent_erase (struct mtd_info *, struct erase_info *);
+static void map_absent_sync (struct mtd_info *);
+static struct mtd_info *map_absent_probe(struct map_info *map);
+static void map_absent_destroy (struct mtd_info *);
+
+
+static struct mtd_chip_driver map_absent_chipdrv = {
+	probe: 		map_absent_probe,
+	destroy:	map_absent_destroy,
+	name: 		"map_absent",
+	module: 	THIS_MODULE
+};
+
+static struct mtd_info *map_absent_probe(struct map_info *map)
+{
+	struct mtd_info *mtd;
+
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if (!mtd) {
+		return NULL;
+	}
+
+	memset(mtd, 0, sizeof(*mtd));
+
+	map->fldrv 	= &map_absent_chipdrv;
+	mtd->priv 	= map;
+	mtd->name 	= map->name;
+	mtd->type 	= MTD_ABSENT;
+	mtd->size 	= map->size;
+	mtd->erase 	= map_absent_erase;
+	mtd->read 	= map_absent_read;
+	mtd->write 	= map_absent_write;
+	mtd->sync 	= map_absent_sync;
+	mtd->flags 	= 0;
+	mtd->erasesize = PAGE_SIZE;
+
+	MOD_INC_USE_COUNT;
+	return mtd;
+}
+
+
+static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+	*retlen = 0;
+	return -ENODEV;
+}
+
+static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+	*retlen = 0;
+	return -ENODEV; 
+}
+
+static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	return -ENODEV;
+}
+
+static void map_absent_sync(struct mtd_info *mtd)
+{
+	/* nop */
+}
+
+static void map_absent_destroy(struct mtd_info *mtd)
+{
+	/* nop */
+}
+
+int __init map_absent_init(void)
+{
+	register_mtd_chip_driver(&map_absent_chipdrv);
+	return 0;
+}
+
+static void __exit map_absent_exit(void)
+{
+	unregister_mtd_chip_driver(&map_absent_chipdrv);
+}
+
+module_init(map_absent_init);
+module_exit(map_absent_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Resilience Corporation - Eric Brower <ebrower@resilience.com>");
+MODULE_DESCRIPTION("Placeholder MTD chip driver for 'absent' chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/map_ram.c linux/drivers/mtd/chips/map_ram.c
--- v2.4.10/linux/drivers/mtd/chips/map_ram.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/map_ram.c	Thu Oct  4 15:14:59 2001
@@ -1,7 +1,7 @@
 /*
  * Common code to handle map devices which are simple RAM
  * (C) 2000 Red Hat. GPL'd.
- * $Id: map_ram.c,v 1.11 2001/06/08 15:34:04 dwmw2 Exp $
+ * $Id: map_ram.c,v 1.14 2001/10/02 15:05:12 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -24,7 +24,7 @@
 
 static struct mtd_chip_driver mapram_chipdrv = {
 	probe: map_ram_probe,
-	name: "ram",
+	name: "map_ram",
 	module: THIS_MODULE
 };
 
@@ -63,14 +63,16 @@
 	mtd->priv = map;
 	mtd->name = map->name;
 	mtd->type = MTD_RAM;
-	mtd->erasesize = 0x10000;
 	mtd->size = map->size;
 	mtd->erase = mapram_erase;
 	mtd->read = mapram_read;
 	mtd->write = mapram_write;
 	mtd->sync = mapram_nop;
 	mtd->flags = MTD_CAP_RAM | MTD_VOLATILE;
+
 	mtd->erasesize = PAGE_SIZE;
+ 	while(mtd->size & (mtd->erasesize - 1))
+		mtd->erasesize >>= 1;
 
 	MOD_INC_USE_COUNT;
 	return mtd;
@@ -116,12 +118,7 @@
 	/* Nothing to see here */
 }
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define map_ram_init init_module
-#define map_ram_exit cleanup_module
-#endif
-
-static int __init map_ram_init(void)
+int __init map_ram_init(void)
 {
 	register_mtd_chip_driver(&mapram_chipdrv);
 	return 0;
@@ -134,3 +131,7 @@
 
 module_init(map_ram_init);
 module_exit(map_ram_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("MTD chip driver for RAM chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/map_rom.c linux/drivers/mtd/chips/map_rom.c
--- v2.4.10/linux/drivers/mtd/chips/map_rom.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/map_rom.c	Thu Oct  4 15:14:59 2001
@@ -1,9 +1,10 @@
 /*
  * Common code to handle map devices which are simple ROM
  * (C) 2000 Red Hat. GPL'd.
- * $Id: map_rom.c,v 1.14 2001/06/02 14:30:43 dwmw2 Exp $
+ * $Id: map_rom.c,v 1.17 2001/10/02 15:05:12 dwmw2 Exp $
  */
 
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -21,7 +22,7 @@
 
 static struct mtd_chip_driver maprom_chipdrv = {
 	probe: map_rom_probe,
-	name: "rom",
+	name: "map_rom",
 	module: THIS_MODULE
 };
 
@@ -45,6 +46,8 @@
 	mtd->sync = maprom_nop;
 	mtd->flags = MTD_CAP_ROM;
 	mtd->erasesize = 131072;
+ 	while(mtd->size & (mtd->erasesize - 1))
+		mtd->erasesize >>= 1;
 
 	MOD_INC_USE_COUNT;
 	return mtd;
@@ -71,21 +74,20 @@
 	return -EIO;
 }
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define map_rom_init init_module
-#define map_rom_exit cleanup_module
-#endif
-
-mod_init_t map_rom_init(void)
+int __init map_rom_init(void)
 {
 	register_mtd_chip_driver(&maprom_chipdrv);
 	return 0;
 }
 
-mod_exit_t map_rom_exit(void)
+static void __exit map_rom_exit(void)
 {
 	unregister_mtd_chip_driver(&maprom_chipdrv);
 }
 
 module_init(map_rom_init);
 module_exit(map_rom_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("MTD chip driver for ROM chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/chips/sharp.c linux/drivers/mtd/chips/sharp.c
--- v2.4.10/linux/drivers/mtd/chips/sharp.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/chips/sharp.c	Thu Oct  4 15:14:59 2001
@@ -4,7 +4,7 @@
  * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
  *           2000,2001 Lineo, Inc.
  *
- * $Id: sharp.c,v 1.4 2001/04/29 16:21:17 dwmw2 Exp $
+ * $Id: sharp.c,v 1.6 2001/10/02 15:05:12 dwmw2 Exp $
  *
  * Devices supported:
  *   LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/interrupt.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/cfi.h>
 #include <linux/delay.h>
@@ -569,11 +570,6 @@
 
 }
 
-#if LINUX_VERSION_CODE < 0x020212 && defined(MODULE)
-#define sharp_probe_init init_module
-#define sharp_probe_exit cleanup_module
-#endif
-
 int __init sharp_probe_init(void)
 {
 	printk("MTD Sharp chip driver <ds@lineo.com>\n");
@@ -591,3 +587,7 @@
 module_init(sharp_probe_init);
 module_exit(sharp_probe_exit);
 
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Schleef <ds@schleef.org>");
+MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/Config.in linux/drivers/mtd/devices/Config.in
--- v2.4.10/linux/drivers/mtd/devices/Config.in	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/Config.in	Thu Oct  4 15:13:18 2001
@@ -1,6 +1,6 @@
 # drivers/mtd/maps/Config.in
 
-# $Id: Config.in,v 1.2 2001/04/29 16:24:34 dwmw2 Exp $
+# $Id: Config.in,v 1.5 2001/09/23 15:33:10 dwmw2 Exp $
 
 mainmenu_option next_comment
 
@@ -11,6 +11,9 @@
    bool '    PMC551 Debugging' CONFIG_MTD_PMC551_DEBUG
 fi
 dep_tristate '  Uncached system RAM' CONFIG_MTD_SLRAM $CONFIG_MTD
+if [ "$CONFIG_SA1100_LART" = "y" ]; then
+  dep_tristate '  28F160xx flash driver for LART' CONFIG_MTD_LART $CONFIG_MTD
+fi
 dep_tristate '  Test driver using RAM' CONFIG_MTD_MTDRAM $CONFIG_MTD
 if [ "$CONFIG_MTD_MTDRAM" = "y" -o "$CONFIG_MTD_MTDRAM" = "m" ]; then
    int 'MTDRAM device size in KiB' CONFIG_MTDRAM_TOTAL_SIZE 4096
@@ -19,6 +22,7 @@
       hex 'SRAM Hexadecimal Absolute position or 0' CONFIG_MTDRAM_ABS_POS 0
    fi
 fi
+dep_tristate '  MTD emulation using block device' CONFIG_MTD_BLKMTD $CONFIG_MTD
 
 comment 'Disk-On-Chip Device Drivers'
    dep_tristate '  M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/Makefile linux/drivers/mtd/devices/Makefile
--- v2.4.10/linux/drivers/mtd/devices/Makefile	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/Makefile	Thu Oct  4 15:13:18 2001
@@ -1,7 +1,7 @@
 #
 # linux/drivers/devices/Makefile
 #
-# $Id: Makefile,v 1.2 2001/04/19 22:12:36 dwmw2 Exp $
+# $Id: Makefile,v 1.4 2001/06/26 21:10:05 spse Exp $
 
 O_TARGET	:= devlink.o
 
@@ -19,5 +19,7 @@
 obj-$(CONFIG_MTD_SLRAM)		+= slram.o
 obj-$(CONFIG_MTD_PMC551)	+= pmc551.o
 obj-$(CONFIG_MTD_MTDRAM)	+= mtdram.o
+obj-$(CONFIG_MTD_LART)		+= lart.o
+obj-$(CONFIG_MTD_BLKMTD)	+= blkmtd.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/blkmtd.c linux/drivers/mtd/devices/blkmtd.c
--- v2.4.10/linux/drivers/mtd/devices/blkmtd.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/blkmtd.c	Fri Oct  5 12:06:51 2001
@@ -0,0 +1,1043 @@
+/* 
+ * $Id: blkmtd.c,v 1.3 2001/10/02 15:33:20 dwmw2 Exp $
+ * blkmtd.c - use a block device as a fake MTD
+ *
+ * Author: Simon Evans <spse@secret.org.uk>
+ *
+ * Copyright (C) 2001 Simon Evans <spse@secret.org.uk>
+ * 
+ * Licence: GPL
+ *
+ * How it works:
+ *       The driver uses raw/io to read/write the device and the page
+ *       cache to cache access. Writes update the page cache with the
+ *       new data but make a copy of the new page(s) and then a kernel
+ *       thread writes pages out to the device in the background. This
+ *       ensures tht writes are order even if a page is updated twice.
+ *       Also, since pages in the page cache are never marked as dirty,
+ *       we dont have to worry about writepage() being called on some 
+ *       random page which may not be in the write order.
+ * 
+ *       Erases are handled like writes, so the callback is called after
+ *       the page cache has been updated. Sync()ing will wait until it is 
+ *       all done.
+ *
+ *       It can be loaded Read-Only to prevent erases and writes to the 
+ *       medium.
+ *
+ * Todo:
+ *       Make the write queue size dynamic so this it is not too big on
+ *       small memory systems and too small on large memory systems.
+ * 
+ *       Page cache usage may still be a bit wrong. Check we are doing
+ *       everything proberly.
+ * 
+ *       Somehow allow writes to dirty the page cache so we dont use too
+ *       much memory making copies of outgoing pages. Need to handle case
+ *       where page x is written to, then page y, then page x again before
+ *       any of them have been committed to disk.
+ * 
+ *       Reading should read multiple pages at once rather than using 
+ *       readpage() for each one. This is easy and will be fixed asap.
+ *
+ *       Dont run the write_thread if readonly. This is also easy and will
+ *       be fixed asap.
+ * 
+ *       Even though the multiple erase regions are used if the default erase
+ *       block size doesnt match the device properly, erases currently wont
+ *       work on the last page if it is not a full page.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/iobuf.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/mtd.h>
+
+/* Default erase size in K, always make it a multiple of PAGE_SIZE */
+#define CONFIG_MTD_BLKDEV_ERASESIZE 128
+#define VERSION "1.1"
+extern int *blk_size[];
+extern int *blksize_size[];
+
+/* Info for the block device */
+typedef struct mtd_raw_dev_data_s {
+  struct block_device *binding;
+  int sector_size, sector_bits, total_sectors;
+  size_t totalsize;
+  int readonly;
+  struct address_space as;
+  struct file *file;
+} mtd_raw_dev_data_t;
+
+/* Info for each queue item in the write queue */
+typedef struct mtdblkdev_write_queue_s {
+  mtd_raw_dev_data_t *rawdevice;
+  struct page **pages;
+  int pagenr;
+  int pagecnt;
+  int iserase;
+} mtdblkdev_write_queue_t;
+
+
+/* Static info about the MTD, used in cleanup_module */
+static struct mtd_info *mtd_info;
+
+/* Write queue fixed size */
+#define WRITE_QUEUE_SZ 512
+
+/* Storage for the write queue */
+static mtdblkdev_write_queue_t write_queue[WRITE_QUEUE_SZ];
+static int volatile write_queue_head;
+static int volatile write_queue_tail;
+static int volatile write_queue_cnt;
+static spinlock_t mbd_writeq_lock = SPIN_LOCK_UNLOCKED;
+
+/* Tell the write thread to finish */
+static volatile int write_task_finish = 0;
+
+/* ipc with the write thread */
+#if LINUX_VERSION_CODE > 0x020300
+static DECLARE_MUTEX_LOCKED(thread_sem);
+static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
+static DECLARE_WAIT_QUEUE_HEAD(mtbd_sync_wq);
+#else
+static struct semaphore thread_sem = MUTEX_LOCKED;
+DECLARE_WAIT_QUEUE_HEAD(thr_wq);
+DECLARE_WAIT_QUEUE_HEAD(mtbd_sync_wq);
+#endif
+
+
+
+/* Module parameters passed by insmod/modprobe */
+char *device;    /* the block device to use */
+int erasesz;     /* optional default erase size */
+int ro;          /* optional read only flag */
+int bs;          /* optionally force the block size (avoid using) */
+int count;       /* optionally force the block count (avoid using) */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
+MODULE_DESCRIPTION("Emulate an MTD using a block device");
+MODULE_PARM(device, "s");
+MODULE_PARM_DESC(device, "block device to use");
+MODULE_PARM(erasesz, "i");
+MODULE_PARM_DESC(erasesz, "optional erase size to use in KB. eg 4=4K.");
+MODULE_PARM(ro, "i");
+MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors");
+MODULE_PARM(bs, "i");
+MODULE_PARM_DESC(bs, "force the block size in bytes");
+MODULE_PARM(count, "i");
+MODULE_PARM_DESC(count, "force the block count");
+#endif
+
+
+
+/* Page cache stuff */
+
+/* writepage() - should never be called - catch it anyway */
+static int blkmtd_writepage(struct page *page)
+{
+  printk("blkmtd: writepage called!!!\n");
+  return -EIO;
+}
+
+
+/* readpage() - reads one page from the block device */                 
+static int blkmtd_readpage(struct file *file, struct page *page)
+{  
+  int err;
+  int sectornr, sectors, i;
+  struct kiobuf *iobuf;
+  mtd_raw_dev_data_t *rawdevice = (mtd_raw_dev_data_t *)file->private_data;
+  kdev_t dev;
+
+  if(!rawdevice) {
+    printk("blkmtd: readpage: PANIC file->private_data == NULL\n");
+    return -EIO;
+  }
+  dev = to_kdev_t(rawdevice->binding->bd_dev);
+
+  DEBUG(2, "blkmtd: readpage called, dev = `%s' page = %p index = %ld\n",
+	bdevname(dev), page, page->index);
+
+  if(Page_Uptodate(page)) {
+    DEBUG(1, "blkmtd: readpage page %ld is already upto date\n", page->index);
+    UnlockPage(page);
+    return 0;
+  }
+
+  ClearPageUptodate(page);
+  ClearPageError(page);
+
+  /* see if page is in the outgoing write queue */
+  spin_lock(&mbd_writeq_lock);
+  if(write_queue_cnt) {
+    int i = write_queue_tail;
+    while(i != write_queue_head) {
+      mtdblkdev_write_queue_t *item = &write_queue[i];
+      if(page->index >= item->pagenr && page->index < item->pagenr+item->pagecnt) {
+	/* yes it is */
+	int index = item->pagenr - page->index;
+	DEBUG(1, "blkmtd: readpage: found page %ld in outgoing write queue\n",
+	      page->index);
+	if(item->iserase) {
+	  memset(page_address(page), 0xff, PAGE_SIZE);
+	} else {
+	  memcpy(page_address(page), page_address(item->pages[index]), PAGE_SIZE);
+	}
+	SetPageUptodate(page);
+	flush_dcache_page(page);
+	UnlockPage(page);
+	spin_unlock(&mbd_writeq_lock);
+	return 0;
+      }
+      i++;
+      i %= WRITE_QUEUE_SZ;
+    }
+  }
+  spin_unlock(&mbd_writeq_lock);
+
+
+  DEBUG(3, "blkmtd: readpage: getting kiovec\n");
+  err = alloc_kiovec(1, &iobuf);
+  if (err) {
+    return err;
+  }
+  iobuf->offset = 0;
+  iobuf->nr_pages = 1;
+  iobuf->length = PAGE_SIZE;
+  iobuf->locked = 1;
+  iobuf->maplist[0] = page;
+  sectornr = page->index << (PAGE_SHIFT - rawdevice->sector_bits);
+  sectors = 1 << (PAGE_SHIFT - rawdevice->sector_bits);
+  DEBUG(3, "blkmtd: readpage: sectornr = %d sectors = %d\n", sectornr, sectors);
+  for(i = 0; i < sectors; i++) {
+    iobuf->blocks[i] = sectornr++;
+  }
+
+  DEBUG(3, "bklmtd: readpage: starting brw_kiovec\n");
+  err = brw_kiovec(READ, 1, &iobuf, dev, iobuf->blocks, rawdevice->sector_size);
+  DEBUG(3, "blkmtd: readpage: finished, err = %d\n", err);
+  iobuf->locked = 0;
+  free_kiovec(1, &iobuf);
+  if(err != PAGE_SIZE) {
+    printk("blkmtd: readpage: error reading page %ld\n", page->index);
+    memset(page_address(page), 0, PAGE_SIZE);
+    SetPageError(page);
+    err = -EIO;
+  } else {
+    DEBUG(3, "blkmtd: readpage: setting page upto date\n");
+    SetPageUptodate(page);
+    err = 0;
+  }
+  flush_dcache_page(page);
+  UnlockPage(page);
+  DEBUG(2, "blkmtd: readpage: finished, err = %d\n", err);
+  return 0;
+}
+
+                    
+static struct address_space_operations blkmtd_aops = {
+  writepage:     blkmtd_writepage,
+  readpage:      blkmtd_readpage,
+}; 
+
+
+/* This is the kernel thread that empties the write queue to disk */
+static int write_queue_task(void *data)
+{
+  int err;
+  struct task_struct *tsk = current;
+  struct kiobuf *iobuf;
+
+  DECLARE_WAITQUEUE(wait, tsk);
+  DEBUG(1, "blkmtd: writetask: starting (pid = %d)\n", tsk->pid);
+  daemonize();
+  strcpy(tsk->comm, "blkmtdd");
+  tsk->tty = NULL;
+  spin_lock_irq(&tsk->sigmask_lock);
+  sigfillset(&tsk->blocked);
+  recalc_sigpending(tsk);
+  spin_unlock_irq(&tsk->sigmask_lock);
+  exit_sighand(tsk);
+
+  if(alloc_kiovec(1, &iobuf))
+    return 0;
+  DEBUG(2, "blkmtd: writetask: entering main loop\n");
+  add_wait_queue(&thr_wq, &wait);
+
+  while(1) {
+    spin_lock(&mbd_writeq_lock);
+
+    if(!write_queue_cnt) {
+      /* If nothing in the queue, wake up anyone wanting to know when there
+	 is space in the queue then sleep for 2*HZ */
+      spin_unlock(&mbd_writeq_lock);
+      DEBUG(3, "blkmtd: writetask: queue empty\n");
+      if(waitqueue_active(&mtbd_sync_wq))
+	 wake_up(&mtbd_sync_wq);
+      interruptible_sleep_on_timeout(&thr_wq, 2*HZ);
+      DEBUG(3, "blkmtd: writetask: woken up\n");
+      if(write_task_finish)
+	break;
+    } else {
+      /* we have stuff to write */
+      mtdblkdev_write_queue_t *item = &write_queue[write_queue_tail];
+      struct page **pages = item->pages;
+      int pagecnt = item->pagecnt;
+      int pagenr = item->pagenr;
+      int i;
+      int max_sectors = KIO_MAX_SECTORS >> (item->rawdevice->sector_bits - 9);
+      kdev_t dev = to_kdev_t(item->rawdevice->binding->bd_dev);
+  
+
+      DEBUG(3, "blkmtd: writetask: got %d queue items\n", write_queue_cnt);
+      set_current_state(TASK_RUNNING);
+      spin_unlock(&mbd_writeq_lock);
+
+      DEBUG(2, "blkmtd: write_task: writing pagenr = %d pagecnt = %d", 
+	    item->pagenr, item->pagecnt);
+
+      iobuf->offset = 0;
+      iobuf->locked = 1;
+
+      /* Loop through all the pages to be written in the queue item, remembering
+	 we can only write KIO_MAX_SECTORS at a time */
+	 
+      while(pagecnt) {
+	int sectornr = pagenr << (PAGE_SHIFT - item->rawdevice->sector_bits);
+	int sectorcnt = pagecnt << (PAGE_SHIFT - item->rawdevice->sector_bits);
+	int cursectors = (sectorcnt < max_sectors) ? sectorcnt : max_sectors;
+	int cpagecnt = (cursectors << item->rawdevice->sector_bits) + PAGE_SIZE-1;
+	cpagecnt >>= PAGE_SHIFT;
+	
+	for(i = 0; i < cpagecnt; i++) 
+	    iobuf->maplist[i] = *(pages++);
+	
+	for(i = 0; i < cursectors; i++) {
+	  iobuf->blocks[i] = sectornr++;
+	}
+	
+	iobuf->nr_pages = cpagecnt;
+	iobuf->length = cursectors << item->rawdevice->sector_bits;
+	DEBUG(3, "blkmtd: write_task: about to kiovec\n");
+	err = brw_kiovec(WRITE, 1, &iobuf, dev, iobuf->blocks, item->rawdevice->sector_size);
+	DEBUG(3, "bklmtd: write_task: done, err = %d\n", err);
+	if(err != (cursectors << item->rawdevice->sector_bits)) {
+	  /* if an error occured - set this to exit the loop */
+	  pagecnt = 0;
+	} else {
+	  pagenr += cpagecnt;
+	  pagecnt -= cpagecnt;
+	}
+      }
+
+      /* free up the pages used in the write and list of pages used in the write
+	 queue item */
+      iobuf->locked = 0;
+      spin_lock(&mbd_writeq_lock);
+      write_queue_cnt--;
+      write_queue_tail++;
+      write_queue_tail %= WRITE_QUEUE_SZ;
+      for(i = 0 ; i < item->pagecnt; i++) {
+	UnlockPage(item->pages[i]);
+	__free_pages(item->pages[i], 0);
+      }
+      kfree(item->pages);
+      item->pages = NULL;
+      spin_unlock(&mbd_writeq_lock);
+      /* Tell others there is some space in the write queue */
+      if(waitqueue_active(&mtbd_sync_wq))
+	wake_up(&mtbd_sync_wq);
+    }
+  }
+  remove_wait_queue(&thr_wq, &wait);
+  DEBUG(1, "blkmtd: writetask: exiting\n");
+  free_kiovec(1, &iobuf);
+  /* Tell people we have exitd */
+  up(&thread_sem);
+  return 0;
+}
+
+
+/* Add a range of pages into the outgoing write queue, making copies of them */
+static int queue_page_write(mtd_raw_dev_data_t *rawdevice, struct page **pages,
+			    int pagenr, int pagecnt, int iserase)
+{
+  struct page *outpage;
+  struct page **new_pages;
+  mtdblkdev_write_queue_t *item;
+  int i;
+  DECLARE_WAITQUEUE(wait, current);
+  DEBUG(2, "mtdblkdev: queue_page_write: adding pagenr = %d pagecnt = %d\n", pagenr, pagecnt);
+
+  if(!pagecnt)
+    return 0;
+
+  if(pages == NULL)
+    return -EINVAL;
+
+  /* create a array for the list of pages */
+  new_pages = kmalloc(pagecnt * sizeof(struct page *), GFP_KERNEL);
+  if(new_pages == NULL)
+    return -ENOMEM;
+
+  /* make copies of the pages in the page cache */
+  for(i = 0; i < pagecnt; i++) {
+    outpage = alloc_pages(GFP_KERNEL, 0);
+    if(!outpage) {
+      while(i--) {
+	UnlockPage(new_pages[i]);
+	__free_pages(new_pages[i], 0);
+      }
+      kfree(new_pages);
+      return -ENOMEM;
+    }
+    lock_page(outpage);
+    memcpy(page_address(outpage), page_address(pages[i]), PAGE_SIZE);
+    new_pages[i] = outpage;
+  }
+
+  /* wait until there is some space in the write queue */
+ test_lock:
+  spin_lock(&mbd_writeq_lock);
+  if(write_queue_cnt == WRITE_QUEUE_SZ) {
+    spin_unlock(&mbd_writeq_lock);
+    DEBUG(3, "blkmtd: queue_page: Queue full\n");
+    current->state = TASK_UNINTERRUPTIBLE;
+    add_wait_queue(&mtbd_sync_wq, &wait);
+    wake_up_interruptible(&thr_wq);
+    schedule();
+    current->state = TASK_RUNNING;
+    remove_wait_queue(&mtbd_sync_wq, &wait);
+    DEBUG(3, "blkmtd: queue_page: Queue has %d items in it\n", write_queue_cnt);
+    goto test_lock;
+  }
+
+  DEBUG(3, "blkmtd: queue_write_page: qhead: %d qtail: %d qcnt: %d\n", 
+	write_queue_head, write_queue_tail, write_queue_cnt);
+
+  /* fix up the queue item */
+  item = &write_queue[write_queue_head];
+  item->pages = new_pages;
+  item->pagenr = pagenr;
+  item->pagecnt = pagecnt;
+  item->rawdevice = rawdevice;
+  item->iserase = iserase;
+
+  write_queue_head++;
+  write_queue_head %= WRITE_QUEUE_SZ;
+  write_queue_cnt++;
+  DEBUG(3, "blkmtd: queue_write_page: qhead: %d qtail: %d qcnt: %d\n", 
+	write_queue_head, write_queue_tail, write_queue_cnt);
+  spin_unlock(&mbd_writeq_lock);
+  DEBUG(2, "blkmtd: queue_page_write: finished\n");
+  return 0;
+}
+
+
+/* erase a specified part of the device */
+static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+  mtd_raw_dev_data_t *rawdevice = mtd->priv;
+  size_t from;
+  u_long len;
+  int err = 0;
+
+  /* check readonly */
+  if(rawdevice->readonly) {
+    printk("blkmtd: error: trying to erase readonly device %s\n", device);
+    instr->state = MTD_ERASE_FAILED;
+    goto erase_callback;
+  }
+
+  instr->state = MTD_ERASING;
+  from = instr->addr;
+  len = instr->len;
+
+  /* check page alignment of start and length */
+  DEBUG(2, "blkmtd: erase: dev = `%s' from = %d len = %ld\n",
+	bdevname(rawdevice->binding->bd_dev), from, len);
+  if(from % PAGE_SIZE) {
+    printk("blkmtd: erase: addr not page aligned (addr = %d)\n", from);
+    instr->state = MTD_ERASE_FAILED;
+    err = -EIO;
+  }
+
+  if(len % PAGE_SIZE) {
+    printk("blkmtd: erase: len not a whole number of pages (len = %ld)\n", len);
+    instr->state = MTD_ERASE_FAILED;
+    err = -EIO;
+  }
+  
+  if(instr->state != MTD_ERASE_FAILED) {
+    /* start the erase */
+    int pagenr, pagecnt;
+    struct page *page, **pages;
+    int i = 0;
+
+    pagenr = from >> PAGE_SHIFT;
+    pagecnt = len >> PAGE_SHIFT;
+    DEBUG(3, "blkmtd: erase: pagenr = %d pagecnt = %d\n", pagenr, pagecnt);
+    pages = kmalloc(pagecnt * sizeof(struct page *), GFP_KERNEL);
+    if(pages == NULL) {
+      err = -ENOMEM;
+      instr->state = MTD_ERASE_FAILED;
+      goto erase_out;
+    }
+
+    while(pagecnt) {
+      /* get the page via the page cache */
+      DEBUG(3, "blkmtd: erase: doing grap_cache_page() for page %d\n", pagenr);
+      page = grab_cache_page(&rawdevice->as, pagenr);
+      if(!page) {
+	DEBUG(3, "blkmtd: erase: grab_cache_page() failed for page %d\n", pagenr);
+	kfree(pages);
+	err = -EIO;
+	instr->state = MTD_ERASE_FAILED;
+	goto erase_out;
+      }
+      memset(page_address(page), 0xff, PAGE_SIZE);
+      pages[i] = page;
+      pagecnt--;
+      pagenr++;
+      i++;
+    }
+    DEBUG(3, "blkmtd: erase: queuing page write\n");
+    err = queue_page_write(rawdevice, pages, from >> PAGE_SHIFT, len >> PAGE_SHIFT, 1);
+    pagecnt = len >> PAGE_SHIFT;
+    if(!err) {
+      while(pagecnt--) {
+	SetPageUptodate(pages[pagecnt]);
+	UnlockPage(pages[pagecnt]);
+	page_cache_release(pages[pagecnt]);
+	flush_dcache_page(pages[pagecnt]);
+      }
+      kfree(pages);
+      instr->state = MTD_ERASE_DONE;
+    } else {
+      while(pagecnt--) {
+	SetPageError(pages[pagecnt]);
+	page_cache_release(pages[pagecnt]);
+      }
+      kfree(pages);
+      instr->state = MTD_ERASE_FAILED;
+    }
+  }
+ erase_out:
+  DEBUG(3, "blkmtd: erase: checking callback\n");
+ erase_callback:
+  if (instr->callback) {
+    (*(instr->callback))(instr);
+  }
+  DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err);
+  return err;
+}
+
+
+/* read a range of the data via the page cache */
+static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+	     size_t *retlen, u_char *buf)
+{
+  mtd_raw_dev_data_t *rawdevice = mtd->priv;
+  int err = 0;
+  int offset;
+  int pagenr, pages;
+
+  *retlen = 0;
+
+  DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %p\n",
+	bdevname(rawdevice->binding->bd_dev), (long int)from, len, buf);
+
+  pagenr = from >> PAGE_SHIFT;
+  offset = from - (pagenr << PAGE_SHIFT);
+  
+  pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT;
+  DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n", pagenr, offset, pages);
+
+  /* just loop through each page, getting it via readpage() - slow but easy */
+  while(pages) {
+    struct page *page;
+    int cpylen;
+    DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr);
+    page = read_cache_page(&rawdevice->as, pagenr, (filler_t *)blkmtd_readpage, rawdevice->file);
+    if(IS_ERR(page)) {
+      return PTR_ERR(page);
+    }
+    wait_on_page(page);
+    if(!Page_Uptodate(page)) {
+      /* error reading page */
+      printk("blkmtd: read: page not uptodate\n");
+      page_cache_release(page);
+      return -EIO;
+    }
+
+    cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE;
+    if(offset+cpylen > PAGE_SIZE)
+      cpylen = PAGE_SIZE-offset;
+    
+    memcpy(buf + *retlen, page_address(page) + offset, cpylen);
+    offset = 0;
+    len -= cpylen;
+    *retlen += cpylen;
+    pagenr++;
+    pages--;
+    page_cache_release(page);
+  }
+  
+  DEBUG(2, "blkmtd: end read: retlen = %d, err = %d\n", *retlen, err);
+  return err;
+}
+
+    
+/* write a range of the data via the page cache.
+ *
+ * Basic operation. break the write into three parts. 
+ *
+ * 1. From a page unaligned start up until the next page boundary
+ * 2. Page sized, page aligned blocks
+ * 3. From end of last aligned block to end of range
+ *
+ * 1,3 are read via the page cache and readpage() since these are partial
+ * pages, 2 we just grab pages from the page cache, not caring if they are
+ * already in memory or not since they will be completly overwritten.
+ *
+ */
+ 
+static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+	      size_t *retlen, const u_char *buf)
+{
+  mtd_raw_dev_data_t *rawdevice = mtd->priv;
+  int err = 0;
+  int offset;
+  int pagenr;
+  size_t len1 = 0, len2 = 0, len3 = 0;
+  struct page **pages;
+  int pagecnt = 0;
+
+  *retlen = 0;
+  DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %p\n",
+	bdevname(rawdevice->binding->bd_dev), (long int)to, len, buf);
+
+  /* handle readonly and out of range numbers */
+
+  if(rawdevice->readonly) {
+    printk("blkmtd: error: trying to write to a readonly device %s\n", device);
+    return -EROFS;
+  }
+
+  if(to >= rawdevice->totalsize) {
+    return -ENOSPC;
+  }
+
+  if(to + len > rawdevice->totalsize) {
+    len = (rawdevice->totalsize - to);
+  }
+
+
+  pagenr = to >> PAGE_SHIFT;
+  offset = to - (pagenr << PAGE_SHIFT);
+
+  /* see if we have to do a partial write at the start */
+  if(offset) {
+    if((offset + len) > PAGE_SIZE) {
+      len1 = PAGE_SIZE - offset;
+      len -= len1;
+    } else {
+      len1 = len;
+      len = 0;
+    }
+  }
+
+  /* calculate the length of the other two regions */
+  len3 = len & ~PAGE_MASK;
+  len -= len3;
+  len2 = len;
+
+
+  if(len1)
+    pagecnt++;
+  if(len2)
+    pagecnt += len2 >> PAGE_SHIFT;
+  if(len3)
+    pagecnt++;
+
+  DEBUG(3, "blkmtd: write: len1 = %d len2 = %d len3 = %d pagecnt = %d\n", len1, len2, len3, pagecnt);
+  
+  /* get space for list of pages */
+  pages = kmalloc(pagecnt * sizeof(struct page *), GFP_KERNEL);
+  if(pages == NULL) {
+    return -ENOMEM;
+  }
+  pagecnt = 0;
+
+  if(len1) {
+    /* do partial start region */
+    struct page *page;
+    
+    DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %d offset = %d\n", pagenr, len1, offset);
+    page = read_cache_page(&rawdevice->as, pagenr, (filler_t *)blkmtd_readpage, rawdevice->file);
+
+    if(IS_ERR(page)) {
+      kfree(pages);
+      return PTR_ERR(page);
+    }
+    memcpy(page_address(page)+offset, buf, len1);
+    pages[pagecnt++] = page;
+    buf += len1;
+    *retlen = len1;
+    err = 0;
+    pagenr++;
+  }
+
+  /* Now do the main loop to a page aligned, n page sized output */
+  if(len2) {
+    int pagesc = len2 >> PAGE_SHIFT;
+    DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n", pagenr, pagesc);
+    while(pagesc) {
+      struct page *page;
+
+      /* see if page is in the page cache */
+      DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr);
+      page = grab_cache_page(&rawdevice->as, pagenr);
+      DEBUG(3, "blkmtd: write: got page %d from page cache\n", pagenr);
+      if(!page) {
+	printk("blkmtd: write: cant grab cache page %d\n", pagenr);
+	err = -EIO;
+	goto write_err;
+      }
+      memcpy(page_address(page), buf, PAGE_SIZE);
+      pages[pagecnt++] = page;
+      UnlockPage(page);
+      pagenr++;
+      pagesc--;
+      buf += PAGE_SIZE;
+      *retlen += PAGE_SIZE;
+    }
+  }
+
+
+  if(len3) {
+    /* do the third region */
+    struct page *page;
+    DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %d\n", pagenr, len3);
+    page = read_cache_page(&rawdevice->as, pagenr, (filler_t *)blkmtd_readpage, rawdevice->file);
+    if(IS_ERR(page)) {
+      err = PTR_ERR(page);
+      goto write_err;
+    }
+    memcpy(page_address(page), buf, len3);
+    DEBUG(3, "blkmtd: write: writing out partial end\n");
+    pages[pagecnt++] = page;
+    *retlen += len3;
+    err = 0;
+  }
+  DEBUG(2, "blkmtd: write: end, retlen = %d, err = %d\n", *retlen, err);
+  /* submit it to the write task */
+  err = queue_page_write(rawdevice, pages, to >> PAGE_SHIFT, pagecnt, 0);
+  if(!err) {
+    while(pagecnt--) {
+      SetPageUptodate(pages[pagecnt]);
+      flush_dcache_page(pages[pagecnt]);
+      page_cache_release(pages[pagecnt]);
+    }
+    kfree(pages);
+    return 0;
+  }
+
+ write_err:
+  while(--pagecnt) {
+    SetPageError(pages[pagecnt]);
+    page_cache_release(pages[pagecnt]);
+  }
+  kfree(pages);
+  return err;
+}
+
+
+/* sync the device - wait until the write queue is empty */
+static void blkmtd_sync(struct mtd_info *mtd)
+{
+  DECLARE_WAITQUEUE(wait, current);
+  DEBUG(2, "blkmtd: sync: called\n");
+
+ stuff_inq:
+  spin_lock(&mbd_writeq_lock);
+  if(write_queue_cnt) {
+    spin_unlock(&mbd_writeq_lock);
+    current->state = TASK_UNINTERRUPTIBLE;
+    add_wait_queue(&mtbd_sync_wq, &wait);
+    DEBUG(3, "blkmtd: sync: waking up task\n");
+    wake_up_interruptible(&thr_wq);
+    schedule();
+    current->state = TASK_RUNNING;
+    remove_wait_queue(&mtbd_sync_wq, &wait);
+    DEBUG(3, "blkmtd: sync: waking up after write task\n");
+    goto stuff_inq;
+  }
+  spin_unlock(&mbd_writeq_lock);
+
+  DEBUG(2, "blkmtdL sync: finished\n");
+}
+
+/* Cleanup and exit - sync the device and kill of the kernel thread */
+static void __exit cleanup_blkmtd(void)
+{
+  if (mtd_info) {
+    mtd_raw_dev_data_t *rawdevice = mtd_info->priv;
+    // sync the device
+    if (rawdevice) {
+      blkmtd_sync(mtd_info);
+      write_task_finish = 1;
+      wake_up_interruptible(&thr_wq);
+      down(&thread_sem);
+      if(rawdevice->binding != NULL)
+	blkdev_put(rawdevice->binding, BDEV_RAW);
+      filp_close(rawdevice->file, NULL);
+      kfree(mtd_info->priv);
+    }
+    if(mtd_info->eraseregions)
+      kfree(mtd_info->eraseregions);
+    del_mtd_device(mtd_info);
+    kfree(mtd_info);
+    mtd_info = NULL;
+  }
+  printk("blkmtd: unloaded for %s\n", device);
+}
+
+extern struct module __this_module;
+
+/* for a given size and initial erase size, calculate the number and size of each
+   erase region */
+static int __init calc_erase_regions(struct mtd_erase_region_info *info, size_t erase_size, size_t total_size)
+{
+  int count = 0;
+  int offset = 0;
+  int regions = 0;
+
+   while(total_size) {
+     count = total_size / erase_size;
+     if(count) {
+       total_size = total_size % erase_size;
+       if(info) {
+	 info->offset = offset;
+	 info->erasesize = erase_size;
+	 info->numblocks = count;
+	 info++;
+       }
+       offset += (count * erase_size);
+       regions++;
+     }
+     while(erase_size > total_size)
+       erase_size >>= 1;
+   }
+   return regions;
+}
+
+
+/* Startup */
+static int __init init_blkmtd(void)
+{
+  struct file *file = NULL;
+  struct inode *inode;
+  mtd_raw_dev_data_t *rawdevice = NULL;
+  int maj, min;
+  int i, blocksize, blocksize_bits;
+  loff_t size = 0;
+  int readonly = 0;
+  int erase_size = CONFIG_MTD_BLKDEV_ERASESIZE;
+  kdev_t rdev;
+  int err;
+  int mode;
+  int totalsize = 0, total_sectors = 0;
+  int regions;
+
+  mtd_info = NULL;
+
+  // Check args
+  if(device == 0) {
+    printk("blkmtd: error, missing `device' name\n");
+    return 1;
+  }
+
+  if(ro)
+    readonly = 1;
+
+  if(erasesz)
+    erase_size = erasesz;
+
+  DEBUG(1, "blkmtd: got device = `%s' erase size = %dK readonly = %s\n", device, erase_size, readonly ? "yes" : "no");
+  // Get a handle on the device
+  mode = (readonly) ? O_RDONLY : O_RDWR;
+  file = filp_open(device, mode, 0);
+  if(IS_ERR(file)) {
+    DEBUG(2, "blkmtd: open_namei returned %ld\n", PTR_ERR(file));
+    return 1;
+  }
+  
+  /* determine is this is a block device and if so get its major and minor
+     numbers */
+  inode = file->f_dentry->d_inode;
+  if(!S_ISBLK(inode->i_mode)) {
+    printk("blkmtd: %s not a block device\n", device);
+    filp_close(file, NULL);
+    return 1;
+  }
+  rdev = inode->i_rdev;
+  //filp_close(file, NULL);
+  DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n",
+	 MAJOR(rdev), MINOR(rdev));
+  maj = MAJOR(rdev);
+  min = MINOR(rdev);
+
+  if(maj == MTD_BLOCK_MAJOR) {
+    printk("blkmtd: attempting to use an MTD device as a block device\n");
+    return 1;
+  }
+
+  DEBUG(1, "blkmtd: devname = %s\n", bdevname(rdev));
+  blocksize = BLOCK_SIZE;
+
+  if(bs) {
+    blocksize = bs;
+  } else {
+    if (blksize_size[maj] && blksize_size[maj][min]) {
+      DEBUG(2, "blkmtd: blksize_size = %d\n", blksize_size[maj][min]);
+      blocksize = blksize_size[maj][min];
+    }
+  }
+  i = blocksize;
+  blocksize_bits = 0;
+  while(i != 1) {
+    blocksize_bits++;
+    i >>= 1;
+  }
+
+  if(count) {
+    size = count;
+  } else {
+    if (blk_size[maj]) {
+      size = ((loff_t) blk_size[maj][min] << BLOCK_SIZE_BITS) >> blocksize_bits;
+    }
+  }
+  total_sectors = size;
+  size *= blocksize;
+  totalsize = size;
+  DEBUG(1, "blkmtd: size = %ld\n", (long int)size);
+
+  if(size == 0) {
+    printk("blkmtd: cant determine size\n");
+    return 1;
+  }
+  rawdevice = (mtd_raw_dev_data_t *)kmalloc(sizeof(mtd_raw_dev_data_t), GFP_KERNEL);
+  if(rawdevice == NULL) {
+    err = -ENOMEM;
+    goto init_err;
+  }
+  memset(rawdevice, 0, sizeof(mtd_raw_dev_data_t));
+  // get the block device
+  rawdevice->binding = bdget(kdev_t_to_nr(MKDEV(maj, min)));
+  err = blkdev_get(rawdevice->binding, mode, 0, BDEV_RAW);
+  if (err) {
+    goto init_err;
+  }
+  rawdevice->totalsize = totalsize;
+  rawdevice->total_sectors = total_sectors;
+  rawdevice->sector_size = blocksize;
+  rawdevice->sector_bits = blocksize_bits;
+  rawdevice->readonly = readonly;
+
+  DEBUG(2, "sector_size = %d, sector_bits = %d\n", rawdevice->sector_size, rawdevice->sector_bits);
+
+  mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+  if (mtd_info == NULL) {
+    err = -ENOMEM;
+    goto init_err;
+  }
+  memset(mtd_info, 0, sizeof(*mtd_info));
+
+  // Setup the MTD structure
+  mtd_info->name = "blkmtd block device";
+  if(readonly) {
+    mtd_info->type = MTD_ROM;
+    mtd_info->flags = MTD_CAP_ROM;
+    mtd_info->erasesize = erase_size << 10;
+  } else {
+    mtd_info->type = MTD_RAM;
+    mtd_info->flags = MTD_CAP_RAM;
+    mtd_info->erasesize = erase_size << 10;
+  }
+  mtd_info->size = size;
+  mtd_info->erase = blkmtd_erase;
+  mtd_info->read = blkmtd_read;
+  mtd_info->write = blkmtd_write;
+  mtd_info->sync = blkmtd_sync;
+  mtd_info->point = 0;
+  mtd_info->unpoint = 0;
+
+  mtd_info->priv = rawdevice;
+  regions = calc_erase_regions(NULL, erase_size << 10, size);
+  DEBUG(1, "blkmtd: init: found %d erase regions\n", regions);
+  mtd_info->eraseregions = kmalloc(regions * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
+  if(mtd_info->eraseregions == NULL) {
+  }
+  mtd_info->numeraseregions = regions;
+  calc_erase_regions(mtd_info->eraseregions, erase_size << 10, size);
+
+  /* setup the page cache info */
+  INIT_LIST_HEAD(&rawdevice->as.clean_pages);
+  INIT_LIST_HEAD(&rawdevice->as.dirty_pages);
+  INIT_LIST_HEAD(&rawdevice->as.locked_pages);
+  rawdevice->as.nrpages = 0;
+  rawdevice->as.a_ops = &blkmtd_aops;
+  rawdevice->as.host = inode;
+  rawdevice->as.i_mmap = NULL;
+  rawdevice->as.i_mmap_shared = NULL;
+  spin_lock_init(&rawdevice->as.i_shared_lock);
+  rawdevice->as.gfp_mask = GFP_KERNEL;
+  rawdevice->file = file;
+
+  file->private_data = rawdevice;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+   mtd_info->module = THIS_MODULE;			
+#endif
+   if (add_mtd_device(mtd_info)) {
+     err = -EIO;
+     goto init_err;
+   }
+   init_waitqueue_head(&thr_wq);
+   init_waitqueue_head(&mtbd_sync_wq);
+   DEBUG(3, "blkmtd: init: kernel task @ %p\n", write_queue_task);
+   DEBUG(2, "blkmtd: init: starting kernel task\n");
+   kernel_thread(write_queue_task, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+   DEBUG(2, "blkmtd: init: started\n");
+   printk("blkmtd loaded: version = %s using %s erase_size = %dK %s\n", VERSION, device, erase_size, (readonly) ? "(read-only)" : "");
+   return 0;
+
+ init_err:
+   if(!rawdevice) {
+     if(rawdevice->binding) 
+       blkdev_put(rawdevice->binding, BDEV_RAW);
+
+     kfree(rawdevice);
+     rawdevice = NULL;
+   }
+   if(mtd_info) {
+     if(mtd_info->eraseregions)
+       kfree(mtd_info->eraseregions);
+     kfree(mtd_info);
+     mtd_info = NULL;
+   }
+   return err;
+}
+
+module_init(init_blkmtd);
+module_exit(cleanup_blkmtd);
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/doc1000.c linux/drivers/mtd/devices/doc1000.c
--- v2.4.10/linux/drivers/mtd/devices/doc1000.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/doc1000.c	Thu Oct  4 15:14:59 2001
@@ -1,6 +1,6 @@
 /*======================================================================
 
-  $Id: doc1000.c,v 1.11 2000/11/24 13:43:16 dwmw2 Exp $
+  $Id: doc1000.c,v 1.15 2001/10/02 15:05:13 dwmw2 Exp $
 
 ======================================================================*/
 
@@ -286,9 +286,9 @@
 static inline int byte_write (volatile u_char *addr, u_char byte)
 {
 	register u_char status;
- 	register u_short i = 0;
-  	
- 	do {
+	register u_short i = 0;
+
+	do {
 		status = readb(addr);
 		if (status & CSR_WR_READY)
 		{
@@ -510,11 +510,6 @@
 
 }
 
-#if defined (MODULE) && LINUX_VERSION_CODE < 0x20211
-#define init_doc1000 init_module
-#define cleanup_doc1000 cleanup_module
-#endif
-
 int __init init_doc1000(void)
 {
 	struct mypriv *priv;
@@ -591,7 +586,10 @@
 	kfree(mymtd);
 }
 
-#if LINUX_VERSION_CODE >= 0x20211
 module_init(init_doc1000);
 module_exit(cleanup_doc1000);
-#endif
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("MTD driver for DiskOnChip 1000");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/doc2000.c linux/drivers/mtd/devices/doc2000.c
--- v2.4.10/linux/drivers/mtd/devices/doc2000.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/doc2000.c	Thu Oct  4 15:14:59 2001
@@ -4,7 +4,7 @@
  * (c) 1999 Machine Vision Holdings, Inc.
  * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
  *
- * $Id: doc2000.c,v 1.43 2001/06/02 14:30:43 dwmw2 Exp $
+ * $Id: doc2000.c,v 1.46 2001/10/02 15:05:13 dwmw2 Exp $
  */
 
 #include <linux/kernel.h>
@@ -61,6 +61,8 @@
 			size_t *retlen, u_char *buf);
 static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
 			 size_t *retlen, const u_char *buf);
+static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
+			 size_t *retlen, const u_char *buf);
 static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
 
 static struct mtd_info *doc2klist = NULL;
@@ -84,19 +86,26 @@
 static int _DoC_WaitReady(struct DiskOnChip *doc)
 {
 	unsigned long docptr = doc->virtadr;
-	unsigned short c = 0xffff;
+	unsigned long timeo = jiffies + (HZ * 10);
 
 	DEBUG(MTD_DEBUG_LEVEL3,
 	      "_DoC_WaitReady called for out-of-line wait\n");
 
 	/* Out-of-line routine to wait for chip response */
-	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
-		;
-
-	if (c == 0)
-		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+		if (time_after(jiffies, timeo)) {
+			DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+			return -EIO;
+		}
+		if (current->need_resched) {
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1);
+		}
+		else
+			udelay(1);
+	}
 
-	return (c == 0);
+	return 0;
 }
 
 static inline int DoC_WaitReady(struct DiskOnChip *doc)
@@ -220,7 +229,7 @@
 /* Read a buffer from DoC, taking care of Millennium odditys */
 static void DoC_ReadBuf(struct DiskOnChip *doc, u_char * buf, int len)
 {
-	int dummy;
+	volatile int dummy;
 	int modulus = 0xffff;
 	unsigned long docptr;
 	int i;
@@ -432,14 +441,14 @@
 
 	/* If there are none at all that we recognise, bail */
 	if (!this->numchips) {
-		printk("No flash chips recognised.\n");
+		printk(KERN_NOTICE "No flash chips recognised.\n");
 		return;
 	}
 
 	/* Allocate an array to hold the information for each chip */
 	this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
 	if (!this->chips) {
-		printk("No memory for allocating chip info structures\n");
+		printk(KERN_NOTICE "No memory for allocating chip info structures\n");
 		return;
 	}
 
@@ -566,6 +575,7 @@
 
 	this->curfloor = -1;
 	this->curchip = -1;
+	init_MUTEX(&this->lock);
 
 	/* Ident all the chips present. */
 	DoC_ScanChips(this);
@@ -606,6 +616,8 @@
 	if (from >= this->totlen)
 		return -EINVAL;
 
+	down(&this->lock);
+
 	/* Don't allow a single read to cross a 512-byte block boundary */
 	if (from + len > ((from | 0x1ff) + 1))
 		len = ((from | 0x1ff) + 1) - from;
@@ -686,7 +698,7 @@
 			int nb_errors;
 			/* There was an ECC error */
 #ifdef ECC_DEBUG
-			printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
+			printk(KERN_ERR "DiskOnChip ECC Error: Read at %lx\n", (long)from);
 #endif
 			/* Read the ECC syndrom through the DiskOnChip ECC logic.
 			   These syndrome will be all ZERO when there is no error */
@@ -697,7 +709,7 @@
                         nb_errors = doc_decode_ecc(buf, syndrome);
 
 #ifdef ECC_DEBUG
-			printk("Errors corrected: %x\n", nb_errors);
+			printk(KERN_ERR "Errors corrected: %x\n", nb_errors);
 #endif
                         if (nb_errors < 0) {
 				/* We return error, but have actually done the read. Not that
@@ -708,7 +720,7 @@
 		}
 
 #ifdef PSYCHO_DEBUG
-		printk("ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+		printk(KERN_DEBUG "ECC DATA at %lxB: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
 			     (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
 			     eccbuf[3], eccbuf[4], eccbuf[5]);
 #endif
@@ -724,6 +736,8 @@
 	    DoC_WaitReady(this);
 	}
 
+	up(&this->lock);
+
 	return ret;
 }
 
@@ -751,6 +765,8 @@
 	if (to >= this->totlen)
 		return -EINVAL;
 
+	down(&this->lock);
+
 	/* Don't allow a single write to cross a 512-byte block boundary */
 	if (to + len > ((to | 0x1ff) + 1))
 		len = ((to | 0x1ff) + 1) - to;
@@ -810,9 +826,10 @@
 		DoC_Delay(this, 2);
 
 		if (ReadDOC_(docptr, this->ioreg) & 1) {
-			printk("Error programming flash\n");
+			printk(KERN_ERR "Error programming flash\n");
 			/* Error in programming */
 			*retlen = 0;
+			up(&this->lock);
 			return -EIO;
 		}
 
@@ -862,9 +879,10 @@
 	DoC_Delay(this, 2);
 
 	if (ReadDOC_(docptr, this->ioreg) & 1) {
-		printk("Error programming flash\n");
+		printk(KERN_ERR "Error programming flash\n");
 		/* Error in programming */
 		*retlen = 0;
+		up(&this->lock);
 		return -EIO;
 	}
 
@@ -874,6 +892,7 @@
 	if (eccbuf) {
 		unsigned char x[8];
 		size_t dummy;
+		int ret;
 
 		/* Write the ECC data to flash */
 		for (di=0; di<6; di++)
@@ -882,9 +901,11 @@
 		x[6]=0x55;
 		x[7]=0x55;
 		
-		return doc_write_oob(mtd, to, 8, &dummy, x);
+		ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
+		up(&this->lock);
+		return ret;
 	}
-
+	up(&this->lock);
 	return 0;
 }
 
@@ -892,10 +913,12 @@
 			size_t * retlen, u_char * buf)
 {
 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	int len256 = 0;
+	int len256 = 0, ret;
 	unsigned long docptr;
 	struct Nand *mychip;
 
+	down(&this->lock);
+
 	docptr = this->virtadr;
 
 	mychip = &this->chips[ofs >> this->chipshift];
@@ -939,18 +962,22 @@
 	/* Reading the full OOB data drops us off of the end of the page,
          * causing the flash device to go into busy mode, so we need
          * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
-	return DoC_WaitReady(this);
+	
+	ret = DoC_WaitReady(this);
+
+	up(&this->lock);
+	return ret;
 
 }
 
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			 size_t * retlen, const u_char * buf)
+static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
+				size_t * retlen, const u_char * buf)
 {
 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
 	int len256 = 0;
 	unsigned long docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-	int dummy;
+	volatile int dummy;
 
 	//      printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
 	//   buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
@@ -1003,7 +1030,7 @@
 		DoC_Delay(this, 2);
 
 		if (ReadDOC_(docptr, this->ioreg) & 1) {
-			printk("Error programming oob data\n");
+			printk(KERN_ERR "Error programming oob data\n");
 			/* There was an error */
 			*retlen = 0;
 			return -EIO;
@@ -1022,7 +1049,7 @@
 	DoC_Delay(this, 2);
 
 	if (ReadDOC_(docptr, this->ioreg) & 1) {
-		printk("Error programming oob data\n");
+		printk(KERN_ERR "Error programming oob data\n");
 		/* There was an error */
 		*retlen = 0;
 		return -EIO;
@@ -1032,52 +1059,78 @@
 	return 0;
 
 }
+ 
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+ 			 size_t * retlen, const u_char * buf)
+{
+ 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+ 	int ret;
+
+ 	down(&this->lock);
+ 	ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf);
+
+ 	up(&this->lock);
+ 	return ret;
+}
 
-int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
+static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
 	__u32 ofs = instr->addr;
 	__u32 len = instr->len;
+	volatile int dummy;
 	unsigned long docptr;
 	struct Nand *mychip;
 
-	if (len != mtd->erasesize)
-		printk(KERN_WARNING "Erase not right size (%x != %x)n",
-		       len, mtd->erasesize);
-
-	docptr = this->virtadr;
+ 	down(&this->lock);
 
-	mychip = &this->chips[ofs >> this->chipshift];
-
-	if (this->curfloor != mychip->floor) {
-		DoC_SelectFloor(this, mychip->floor);
-		DoC_SelectChip(this, mychip->chip);
-	} else if (this->curchip != mychip->chip) {
-		DoC_SelectChip(this, mychip->chip);
+	if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) {
+		up(&this->lock);
+		return -EINVAL;
 	}
-	this->curfloor = mychip->floor;
-	this->curchip = mychip->chip;
 
-	instr->state = MTD_ERASE_PENDING;
+	instr->state = MTD_ERASING;
+		
+	docptr = this->virtadr;
 
-	DoC_Command(this, NAND_CMD_ERASE1, 0);
-	DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
-	DoC_Command(this, NAND_CMD_ERASE2, 0);
+	/* FIXME: Do this in the background. Use timers or schedule_task() */
+	while(len) {
+		mychip = &this->chips[ofs >> this->chipshift];
+
+		if (this->curfloor != mychip->floor) {
+			DoC_SelectFloor(this, mychip->floor);
+			DoC_SelectChip(this, mychip->chip);
+		} else if (this->curchip != mychip->chip) {
+			DoC_SelectChip(this, mychip->chip);
+		}
+		this->curfloor = mychip->floor;
+		this->curchip = mychip->chip;
 
-	instr->state = MTD_ERASING;
+		DoC_Command(this, NAND_CMD_ERASE1, 0);
+		DoC_Address(this, ADDR_PAGE, ofs, 0, 0);
+		DoC_Command(this, NAND_CMD_ERASE2, 0);
 
-	DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
+		DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
 
-	if (ReadDOC_(docptr, this->ioreg) & 1) {
-		printk("Error writing\n");
-		/* There was an error */
-		instr->state = MTD_ERASE_FAILED;
-	} else
-		instr->state = MTD_ERASE_DONE;
+		dummy = ReadDOC(docptr, CDSNSlowIO);
+		DoC_Delay(this, 2);
+		
+		if (ReadDOC_(docptr, this->ioreg) & 1) {
+			printk(KERN_ERR "Error erasing at 0x%x\n", ofs);
+			/* There was an error */
+			instr->state = MTD_ERASE_FAILED;
+			goto callback;
+		}
+		ofs += mtd->erasesize;
+		len -= mtd->erasesize;
+	}
+	instr->state = MTD_ERASE_DONE;
 
+ callback:
 	if (instr->callback)
 		instr->callback(instr);
 
+	up(&this->lock);
 	return 0;
 }
 
@@ -1088,11 +1141,6 @@
  *
  ****************************************************************************/
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define cleanup_doc2000 cleanup_module
-#define init_doc2000 init_module
-#endif
-
 int __init init_doc2000(void)
 {
        inter_module_register(im_name, THIS_MODULE, &DoC2k_init);
@@ -1119,3 +1167,8 @@
 
 module_exit(cleanup_doc2000);
 module_init(init_doc2000);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
+MODULE_DESCRIPTION("MTD driver for DiskOnChip 2000 and Millennium");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/doc2001.c linux/drivers/mtd/devices/doc2001.c
--- v2.4.10/linux/drivers/mtd/devices/doc2001.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/doc2001.c	Thu Oct  4 15:14:59 2001
@@ -4,7 +4,7 @@
  * (c) 1999 Machine Vision Holdings, Inc.
  * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
  *
- * $Id: doc2001.c,v 1.34 2001/06/02 14:30:43 dwmw2 Exp $
+ * $Id: doc2001.c,v 1.35 2001/10/02 15:05:13 dwmw2 Exp $
  */
 
 #include <linux/kernel.h>
@@ -848,11 +848,6 @@
  *
  ****************************************************************************/
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define cleanup_doc2001 cleanup_module
-#define init_doc2001 init_module
-#endif
-
 int __init init_doc2001(void)
 {
 	inter_module_register(im_name, THIS_MODULE, &DoCMil_init);
@@ -880,4 +875,6 @@
 module_exit(cleanup_doc2001);
 module_init(init_doc2001);
 
-
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
+MODULE_DESCRIPTION("Alternative driver for DiskOnChip Millennium");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/docecc.c linux/drivers/mtd/devices/docecc.c
--- v2.4.10/linux/drivers/mtd/devices/docecc.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/devices/docecc.c	Thu Oct  4 15:14:59 2001
@@ -7,7 +7,7 @@
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
  * Copyright (C) 2000 Netgem S.A.
  *
- * $Id: docecc.c,v 1.1 2000/11/03 12:43:43 dwmw2 Exp $
+ * $Id: docecc.c,v 1.4 2001/10/02 15:05:13 dwmw2 Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 
+#include <linux/mtd/compatmac.h> /* for min() in older kernels */
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/doc2000.h>
 
@@ -402,7 +403,7 @@
     den = 0;
     
     /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
-    for (i = min_t(int, deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
+    for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
       if(lambda[i+1] != A0)
 	den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
     }
@@ -518,3 +519,6 @@
     return nb_errors;
 }
 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Fabrice Bellard <fabrice.bellard@netgem.com>");
+MODULE_DESCRIPTION("ECC code for correcting errors detected by DiskOnChip 2000 and Millennium ECC hardware");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/docprobe.c linux/drivers/mtd/devices/docprobe.c
--- v2.4.10/linux/drivers/mtd/devices/docprobe.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/devices/docprobe.c	Thu Oct  4 15:14:59 2001
@@ -3,7 +3,7 @@
 /* Probe routines common to all DoC devices			*/
 /* (c) 1999 Machine Vision Holdings, Inc.			*/
 /* Author: David Woodhouse <dwmw2@infradead.org>		*/
-/* $Id: docprobe.c,v 1.27 2001/06/03 19:06:09 dwmw2 Exp $	*/
+/* $Id: docprobe.c,v 1.30 2001/10/02 15:05:13 dwmw2 Exp $	*/
 
 
 
@@ -176,6 +176,7 @@
 	return 0;
 }   
 
+static int docfound;
 
 static void __init DoC_Probe(unsigned long physadr)
 {
@@ -195,11 +196,11 @@
 		return;
 	
 	if ((ChipID = doccheck(docptr, physadr))) {
-		
+		docfound = 1;
 		mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
 
 		if (!mtd) {
-			printk("Cannot allocate memory for data structures. Dropping.\n");
+			printk(KERN_WARNING "Cannot allocate memory for data structures. Dropping.\n");
 			iounmap((void *)docptr);
 			return;
 		}
@@ -242,7 +243,7 @@
 			inter_module_put(im_funcname);
 			return;
 		}
-		printk("Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
+		printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
 	}
 	iounmap((void *)docptr);
 }
@@ -254,26 +255,22 @@
  *
  ****************************************************************************/
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_doc init_module
-#endif
-
 int __init init_doc(void)
 {
 	int i;
 	
-	printk(KERN_NOTICE "M-Systems DiskOnChip driver. (C) 1999 Machine Vision Holdings, Inc.\n");
-#ifdef PRERELEASE
-	printk(KERN_INFO "$Id: docprobe.c,v 1.27 2001/06/03 19:06:09 dwmw2 Exp $\n");
-#endif
 	if (doc_config_location) {
-		printk("Using configured probe address 0x%lx\n", doc_config_location);
+		printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
 		DoC_Probe(doc_config_location);
 	} else {
 		for (i=0; doc_locations[i]; i++) {
 			DoC_Probe(doc_locations[i]);
 		}
 	}
+	/* No banner message any more. Print a message if no DiskOnChip
+	   found, so the user knows we at least tried. */
+	if (!docfound)
+		printk(KERN_INFO "No recognised DiskOnChip devices found\n");
 	/* So it looks like we've been used and we get unloaded */
 	MOD_INC_USE_COUNT;
 	MOD_DEC_USE_COUNT;
@@ -282,4 +279,8 @@
 }
 
 module_init(init_doc);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("Probe code for DiskOnChip 2000 and Millennium devices");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/lart.c linux/drivers/mtd/devices/lart.c
--- v2.4.10/linux/drivers/mtd/devices/lart.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/devices/lart.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,716 @@
+
+/*
+ * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
+ *
+ * $Id: lart.c,v 1.2 2001/10/02 15:05:13 dwmw2 Exp $
+ *
+ * Author: Abraham vd Merwe <abraham@2d3d.co.za>
+ *
+ * Copyright (c) 2001, 2d3D, Inc.
+ *
+ * This code 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.
+ *
+ * References:
+ *
+ *    [1] 3 Volt Fast Boot Block Flash Memory" Intel Datasheet
+ *           - Order Number: 290644-005
+ *           - January 2000
+ *
+ *    [2] MTD internal API documentation
+ *           - http://www.linux-mtd.infradead.org/tech/
+ *
+ * Limitations:
+ *
+ *    Even though this driver is written for 3 Volt Fast Boot
+ *    Block Flash Memory, it is rather specific to LART. With
+ *    Minor modifications, notably the without data/address line
+ *    mangling and different bus settings, etc. it should be
+ *    trivial to adapt to other platforms.
+ *
+ *    If somebody would sponsor me a different board, I'll
+ *    adapt the driver (:
+ */
+
+/* debugging */
+//#define LART_DEBUG
+
+/* partition support */
+#define HAVE_PARTITIONS
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/mtd/mtd.h>
+#ifdef HAVE_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+
+#ifndef CONFIG_SA1100_LART
+#error This is for LART architecture only
+#endif
+
+static char module_name[] = "lart";
+
+/*
+ * These values is specific to 28Fxxxx3 flash memory.
+ * See section 2.3.1 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
+ */
+#define FLASH_BLOCKSIZE_PARAM		(4096 * BUSWIDTH)
+#define FLASH_NUMBLOCKS_16m_PARAM	8
+#define FLASH_NUMBLOCKS_8m_PARAM	8
+
+/*
+ * These values is specific to 28Fxxxx3 flash memory.
+ * See section 2.3.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
+ */
+#define FLASH_BLOCKSIZE_MAIN		(32768 * BUSWIDTH)
+#define FLASH_NUMBLOCKS_16m_MAIN	31
+#define FLASH_NUMBLOCKS_8m_MAIN		15
+
+/*
+ * These values are specific to LART
+ */
+
+/* general */
+#define BUSWIDTH			4				/* don't change this - a lot of the code _will_ break if you change this */
+#define FLASH_OFFSET		0xe8000000		/* see linux/arch/arm/mach-sa1100/lart.c */
+
+/* blob */
+#define NUM_BLOB_BLOCKS		FLASH_NUMBLOCKS_16m_PARAM
+#define BLOB_START			0x00000000
+#define BLOB_LEN			(NUM_BLOB_BLOCKS * FLASH_BLOCKSIZE_PARAM)
+
+/* kernel */
+#define NUM_KERNEL_BLOCKS	7
+#define KERNEL_START		(BLOB_START + BLOB_LEN)
+#define KERNEL_LEN			(NUM_KERNEL_BLOCKS * FLASH_BLOCKSIZE_MAIN)
+
+/* initial ramdisk */
+#define NUM_INITRD_BLOCKS	24
+#define INITRD_START		(KERNEL_START + KERNEL_LEN)
+#define INITRD_LEN			(NUM_INITRD_BLOCKS * FLASH_BLOCKSIZE_MAIN)
+
+/*
+ * See section 4.0 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
+ */
+#define READ_ARRAY			0x00FF00FF		/* Read Array/Reset */
+#define READ_ID_CODES		0x00900090		/* Read Identifier Codes */
+#define ERASE_SETUP			0x00200020		/* Block Erase */
+#define ERASE_CONFIRM		0x00D000D0		/* Block Erase and Program Resume */
+#define PGM_SETUP			0x00400040		/* Program */
+#define STATUS_READ			0x00700070		/* Read Status Register */
+#define STATUS_CLEAR		0x00500050		/* Clear Status Register */
+#define STATUS_BUSY			0x00800080		/* Write State Machine Status (WSMS) */
+#define STATUS_ERASE_ERR	0x00200020		/* Erase Status (ES) */
+#define STATUS_PGM_ERR		0x00100010		/* Program Status (PS) */
+
+/*
+ * See section 4.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
+ */
+#define FLASH_MANUFACTURER			0x00890089
+#define FLASH_DEVICE_8mbit_TOP		0x88f188f1
+#define FLASH_DEVICE_8mbit_BOTTOM	0x88f288f2
+#define FLASH_DEVICE_16mbit_TOP		0x88f388f3
+#define FLASH_DEVICE_16mbit_BOTTOM	0x88f488f4
+
+/***************************************************************************************************/
+
+/*
+ * The data line mapping on LART is as follows:
+ * 
+ *   	 U2  CPU |   U3  CPU
+ *   	 -------------------
+ *   	  0  20  |   0   12
+ *   	  1  22  |   1   14
+ *   	  2  19  |   2   11
+ *   	  3  17  |   3   9
+ *   	  4  24  |   4   0
+ *   	  5  26  |   5   2
+ *   	  6  31  |   6   7
+ *   	  7  29  |   7   5
+ *   	  8  21  |   8   13
+ *   	  9  23  |   9   15
+ *   	  10 18  |   10  10
+ *   	  11 16  |   11  8
+ *   	  12 25  |   12  1
+ *   	  13 27  |   13  3
+ *   	  14 30  |   14  6
+ *   	  15 28  |   15  4
+ */
+
+/* Mangle data (x) */
+#define DATA_TO_FLASH(x)				\
+	(									\
+		(((x) & 0x08009000) >> 11)	+	\
+		(((x) & 0x00002000) >> 10)	+	\
+		(((x) & 0x04004000) >> 8)	+	\
+		(((x) & 0x00000010) >> 4)	+	\
+		(((x) & 0x91000820) >> 3)	+	\
+		(((x) & 0x22080080) >> 2)	+	\
+		((x) & 0x40000400)			+	\
+		(((x) & 0x00040040) << 1)	+	\
+		(((x) & 0x00110000) << 4)	+	\
+		(((x) & 0x00220100) << 5)	+	\
+		(((x) & 0x00800208) << 6)	+	\
+		(((x) & 0x00400004) << 9)	+	\
+		(((x) & 0x00000001) << 12)	+	\
+		(((x) & 0x00000002) << 13)		\
+	)
+
+/* Unmangle data (x) */
+#define FLASH_TO_DATA(x)				\
+	(									\
+		(((x) & 0x00010012) << 11)	+	\
+		(((x) & 0x00000008) << 10)	+	\
+		(((x) & 0x00040040) << 8)	+	\
+		(((x) & 0x00000001) << 4)	+	\
+		(((x) & 0x12200104) << 3)	+	\
+		(((x) & 0x08820020) << 2)	+	\
+		((x) & 0x40000400)			+	\
+		(((x) & 0x00080080) >> 1)	+	\
+		(((x) & 0x01100000) >> 4)	+	\
+		(((x) & 0x04402000) >> 5)	+	\
+		(((x) & 0x20008200) >> 6)	+	\
+		(((x) & 0x80000800) >> 9)	+	\
+		(((x) & 0x00001000) >> 12)	+	\
+		(((x) & 0x00004000) >> 13)		\
+	)
+
+/* 
+ * The address line mapping on LART is as follows:
+ *
+ *   	 U3  CPU |   U2  CPU
+ *   	 -------------------
+ *   	  0  2   |   0   2
+ *   	  1  3   |   1   3
+ *   	  2  9   |   2   9
+ *   	  3  13  |   3   8
+ *   	  4  8   |   4   7
+ *   	  5  12  |   5   6
+ *   	  6  11  |   6   5
+ *   	  7  10  |   7   4
+ *   	  8  4   |   8   10
+ *   	  9  5   |   9   11
+ *   	 10  6   |   10  12
+ *   	 11  7   |   11  13
+ *
+ *   	 BOOT BLOCK BOUNDARY
+ *
+ *   	 12  15  |   12  15
+ *   	 13  14  |   13  14
+ *   	 14  16  |   14  16
+ * 
+ *   	 MAIN BLOCK BOUNDARY
+ *
+ *   	 15  17  |   15  18
+ *   	 16  18  |   16  17
+ *   	 17  20  |   17  20
+ *   	 18  19  |   18  19
+ *   	 19  21  |   19  21
+ *
+ * As we can see from above, the addresses aren't mangled across
+ * block boundaries, so we don't need to worry about address
+ * translations except for sending/reading commands during
+ * initialization
+ */
+
+/* Mangle address (x) on chip U2 */
+#define ADDR_TO_FLASH_U2(x)				\
+	(									\
+		(((x) & 0x00000f00) >> 4)	+	\
+		(((x) & 0x00042000) << 1)	+	\
+		(((x) & 0x0009c003) << 2)	+	\
+		(((x) & 0x00021080) << 3)	+	\
+		(((x) & 0x00000010) << 4)	+	\
+		(((x) & 0x00000040) << 5)	+	\
+		(((x) & 0x00000024) << 7)	+	\
+		(((x) & 0x00000008) << 10)		\
+	)
+
+/* Unmangle address (x) on chip U2 */
+#define FLASH_U2_TO_ADDR(x)				\
+	(									\
+		(((x) << 4) & 0x00000f00)	+	\
+		(((x) >> 1) & 0x00042000)	+	\
+		(((x) >> 2) & 0x0009c003)	+	\
+		(((x) >> 3) & 0x00021080)	+	\
+		(((x) >> 4) & 0x00000010)	+	\
+		(((x) >> 5) & 0x00000040)	+	\
+		(((x) >> 7) & 0x00000024)	+	\
+		(((x) >> 10) & 0x00000008)		\
+	)
+
+/* Mangle address (x) on chip U3 */
+#define ADDR_TO_FLASH_U3(x)				\
+	(									\
+		(((x) & 0x00000080) >> 3)	+	\
+		(((x) & 0x00000040) >> 1)	+	\
+		(((x) & 0x00052020) << 1)	+	\
+		(((x) & 0x00084f03) << 2)	+	\
+		(((x) & 0x00029010) << 3)	+	\
+		(((x) & 0x00000008) << 5)	+	\
+		(((x) & 0x00000004) << 7)		\
+	)
+
+/* Unmangle address (x) on chip U3 */
+#define FLASH_U3_TO_ADDR(x)				\
+	(									\
+		(((x) << 3) & 0x00000080)	+	\
+		(((x) << 1) & 0x00000040)	+	\
+		(((x) >> 1) & 0x00052020)	+	\
+		(((x) >> 2) & 0x00084f03)	+	\
+		(((x) >> 3) & 0x00029010)	+	\
+		(((x) >> 5) & 0x00000008)	+	\
+		(((x) >> 7) & 0x00000004)		\
+	)
+
+/***************************************************************************************************/
+
+static __u8 read8 (__u32 offset)
+{
+   volatile __u8 *data = (__u8 *) (FLASH_OFFSET + offset);
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.2x\n",__FUNCTION__,offset,*data);
+#endif
+   return (*data);
+}
+
+static __u32 read32 (__u32 offset)
+{
+   volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset);
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.8x\n",__FUNCTION__,offset,*data);
+#endif
+   return (*data);
+}
+
+static void write32 (__u32 x,__u32 offset)
+{
+   volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset);
+   *data = x;
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n",__FUNCTION__,offset,*data);
+#endif
+}
+
+/***************************************************************************************************/
+
+/*
+ * Probe for 16mbit flash memory on a LART board without doing
+ * too much damage. Since we need to write 1 dword to memory,
+ * we're f**cked if this happens to be DRAM since we can't
+ * restore the memory (otherwise we might exit Read Array mode).
+ *
+ * Returns 1 if we found 16mbit flash memory on LART, 0 otherwise.
+ */
+static int flash_probe (void)
+{
+   __u32 manufacturer,devtype;
+
+   /* setup "Read Identifier Codes" mode */
+   write32 (DATA_TO_FLASH (READ_ID_CODES),0x00000000);
+
+   /* probe U2. U2/U3 returns the same data since the first 3
+	* address lines is mangled in the same way */
+   manufacturer = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000000)));
+   devtype = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000001)));
+
+   /* put the flash back into command mode */
+   write32 (DATA_TO_FLASH (READ_ARRAY),0x00000000);
+
+   return (manufacturer == FLASH_MANUFACTURER && (devtype == FLASH_DEVICE_16mbit_TOP || FLASH_DEVICE_16mbit_BOTTOM));
+}
+
+/*
+ * Erase one block of flash memory at offset ``offset'' which is any
+ * address within the block which should be erased.
+ *
+ * Returns 1 if successful, 0 otherwise.
+ */
+static inline int erase_block (__u32 offset)
+{
+   __u32 status;
+
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(): 0x%.8x\n",__FUNCTION__,offset);
+#endif
+
+   /* erase and confirm */
+   write32 (DATA_TO_FLASH (ERASE_SETUP),offset);
+   write32 (DATA_TO_FLASH (ERASE_CONFIRM),offset);
+
+   /* wait for block erase to finish */
+   do
+	 {
+		write32 (DATA_TO_FLASH (STATUS_READ),offset);
+		status = FLASH_TO_DATA (read32 (offset));
+	 }
+   while ((~status & STATUS_BUSY) != 0);
+
+   /* put the flash back into command mode */
+   write32 (DATA_TO_FLASH (READ_ARRAY),offset);
+
+   /* was the erase successfull? */
+   if ((status & STATUS_ERASE_ERR))
+	 {
+		printk (KERN_WARNING "%s: erase error at address 0x%.8x.\n",module_name,offset);
+		return (0);
+	 }
+
+   return (1);
+}
+
+static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
+{
+   __u32 addr,len;
+   int i,first;
+
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len);
+#endif
+
+   /* sanity checks */
+   if (instr->addr + instr->len > mtd->size) return (-EINVAL);
+
+   /*
+	* check that both start and end of the requested erase are
+	* aligned with the erasesize at the appropriate addresses.
+	*
+	* skip all erase regions which are ended before the start of
+	* the requested erase. Actually, to save on the calculations,
+	* we skip to the first erase region which starts after the
+	* start of the requested erase, and then go back one.
+	*/
+   for (i = 0; i < mtd->numeraseregions && instr->addr >= mtd->eraseregions[i].offset; i++) ;
+   i--;
+
+   /*
+	* ok, now i is pointing at the erase region in which this
+	* erase request starts. Check the start of the requested
+	* erase range is aligned with the erase size which is in
+	* effect here.
+	*/
+   if (instr->addr & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL);
+
+   /* Remember the erase region we start on */
+   first = i;
+
+   /*
+	* next, check that the end of the requested erase is aligned
+	* with the erase region at that address.
+	*
+	* as before, drop back one to point at the region in which
+	* the address actually falls
+	*/
+   for (; i < mtd->numeraseregions && instr->addr + instr->len >= mtd->eraseregions[i].offset; i++) ;
+   i--;
+
+   /* is the end aligned on a block boundary? */
+   if ((instr->addr + instr->len) & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL);
+
+   addr = instr->addr;
+   len = instr->len;
+
+   i = first;
+
+   /* now erase those blocks */
+   while (len)
+	 {
+		if (!erase_block (addr))
+		  {
+			 instr->state = MTD_ERASE_FAILED;
+			 return (-EIO);
+		  }
+
+		addr += mtd->eraseregions[i].erasesize;
+		len -= mtd->eraseregions[i].erasesize;
+
+		if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++;
+	 }
+
+   instr->state = MTD_ERASE_DONE;
+   if (instr->callback) instr->callback (instr);
+
+   return (0);
+}
+
+static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retlen,u_char *buf)
+{
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,len);
+#endif
+
+   /* sanity checks */
+   if (!len) return (0);
+   if (from + len > mtd->size) return (-EINVAL);
+
+   /* we always read len bytes */
+   *retlen = len;
+
+   /* first, we read bytes until we reach a dword boundary */
+   if (from & (BUSWIDTH - 1))
+	 {
+		int gap = BUSWIDTH - (from & (BUSWIDTH - 1));
+
+		while (len && gap--) *buf++ = read8 (from++), len--;
+	 }
+
+   /* now we read dwords until we reach a non-dword boundary */
+   while (len >= BUSWIDTH)
+	 {
+		*((__u32 *) buf) = read32 (from);
+
+		buf += BUSWIDTH;
+		from += BUSWIDTH;
+		len -= BUSWIDTH;
+	 }
+
+   /* top up the last unaligned bytes */
+   if (len & (BUSWIDTH - 1))
+	 while (len--) *buf++ = read8 (from++);
+
+   return (0);
+}
+
+/*
+ * Write one dword ``x'' to flash memory at offset ``offset''. ``offset''
+ * must be 32 bits, i.e. it must be on a dword boundary.
+ *
+ * Returns 1 if successful, 0 otherwise.
+ */
+static inline int write_dword (__u32 offset,__u32 x)
+{
+   __u32 status;
+
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n",__FUNCTION__,offset,x);
+#endif
+
+   /* setup writing */
+   write32 (DATA_TO_FLASH (PGM_SETUP),offset);
+
+   /* write the data */
+   write32 (x,offset);
+
+   /* wait for the write to finish */
+   do
+	 {
+		write32 (DATA_TO_FLASH (STATUS_READ),offset);
+		status = FLASH_TO_DATA (read32 (offset));
+	 }
+   while ((~status & STATUS_BUSY) != 0);
+
+   /* put the flash back into command mode */
+   write32 (DATA_TO_FLASH (READ_ARRAY),offset);
+
+   /* was the write successfull? */
+   if ((status & STATUS_PGM_ERR) || read32 (offset) != x)
+	 {
+		printk (KERN_WARNING "%s: write error at address 0x%.8x.\n",module_name,offset);
+		return (0);
+	 }
+
+   return (1);
+}
+
+static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf)
+{
+   __u8 tmp[4];
+   int i,n;
+
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len);
+#endif
+
+   *retlen = 0;
+
+   /* sanity checks */
+   if (!len) return (0);
+   if (to + len > mtd->size) return (-EINVAL);
+
+   /* first, we write a 0xFF.... padded byte until we reach a dword boundary */
+   if (to & (BUSWIDTH - 1))
+	 {
+		__u32 aligned = to & ~(BUSWIDTH - 1);
+		int gap = to - aligned;
+
+		i = n = 0;
+
+		while (gap--) tmp[i++] = 0xFF;
+		while (len && i < BUSWIDTH) tmp[i++] = buf[n++], len--;
+		while (i < BUSWIDTH) tmp[i++] = 0xFF;
+
+		if (!write_dword (aligned,*((__u32 *) tmp))) return (-EIO);
+
+		to += n;
+		buf += n;
+		*retlen += n;
+	 }
+
+   /* now we write dwords until we reach a non-dword boundary */
+   while (len >= BUSWIDTH)
+	 {
+		if (!write_dword (to,*((__u32 *) buf))) return (-EIO);
+
+		to += BUSWIDTH;
+		buf += BUSWIDTH;
+		*retlen += BUSWIDTH;
+		len -= BUSWIDTH;
+	 }
+
+   /* top up the last unaligned bytes, padded with 0xFF.... */
+   if (len & (BUSWIDTH - 1))
+	 {
+		i = n = 0;
+
+		while (len--) tmp[i++] = buf[n++];
+		while (i < BUSWIDTH) tmp[i++] = 0xFF;
+
+		if (!write_dword (to,*((__u32 *) tmp))) return (-EIO);
+
+		*retlen += n;
+	 }
+
+   return (0);
+}
+
+/***************************************************************************************************/
+
+#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
+
+static struct mtd_info mtd;
+
+static struct mtd_erase_region_info erase_regions[] =
+{
+   /* parameter blocks */
+   {
+	     offset: 0x00000000,
+	  erasesize: FLASH_BLOCKSIZE_PARAM,
+	  numblocks: FLASH_NUMBLOCKS_16m_PARAM
+   },
+   /* main blocks */
+   {
+	     offset: FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM,
+	  erasesize: FLASH_BLOCKSIZE_MAIN,
+	  numblocks: FLASH_NUMBLOCKS_16m_MAIN
+   }
+};
+
+#ifdef HAVE_PARTITIONS
+static struct mtd_partition lart_partitions[] =
+{
+   /* blob */
+   {
+	       name: "blob",
+	     offset: BLOB_START,
+	       size: BLOB_LEN,
+	 mask_flags: 0
+   },
+   /* kernel */
+   {
+	       name: "kernel",
+	     offset: KERNEL_START,			/* MTDPART_OFS_APPEND */
+	       size: KERNEL_LEN,
+	 mask_flags: 0
+   },
+   /* initial ramdisk / file system */
+   {
+	       name: "file system",
+	     offset: INITRD_START,			/* MTDPART_OFS_APPEND */
+	       size: INITRD_LEN,			/* MTDPART_SIZ_FULL */
+	 mask_flags: 0
+   }
+};
+#endif
+
+int __init lart_flash_init (void)
+{
+   int result;
+   memset (&mtd,0,sizeof (mtd));
+   printk ("MTD driver for LART. Written by Abraham vd Merwe <abraham@2d3d.co.za>\n");
+   printk ("%s: Probing for 28F160x3 flash on LART...\n",module_name);
+   if (!flash_probe ())
+	 {
+		printk (KERN_WARNING "%s: Found no LART compatible flash device\n",module_name);
+		return (-ENXIO);
+	 }
+   printk ("%s: This looks like a LART board to me.\n",module_name);
+   mtd.name = module_name;
+   mtd.type = MTD_NORFLASH;
+   mtd.flags = MTD_CAP_NORFLASH;
+   mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN;
+   mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
+   mtd.numeraseregions = NB_OF (erase_regions);
+   mtd.eraseregions = erase_regions;
+   mtd.module = THIS_MODULE;
+   mtd.erase = flash_erase;
+   mtd.read = flash_read;
+   mtd.write = flash_write;
+
+#ifdef LART_DEBUG
+   printk (KERN_DEBUG
+		   "mtd.name = %s\n"
+		   "mtd.size = 0x%.8x (%uM)\n"
+		   "mtd.erasesize = 0x%.8x (%uK)\n"
+		   "mtd.numeraseregions = %d\n",
+		   mtd.name,
+		   mtd.size,mtd.size / (1024*1024),
+		   mtd.erasesize,mtd.erasesize / 1024,
+		   mtd.numeraseregions);
+
+   if (mtd.numeraseregions)
+	 for (result = 0; result < mtd.numeraseregions; result++)
+	   printk (KERN_DEBUG
+			   "\n\n"
+			   "mtd.eraseregions[%d].offset = 0x%.8x\n"
+			   "mtd.eraseregions[%d].erasesize = 0x%.8x (%uK)\n"
+			   "mtd.eraseregions[%d].numblocks = %d\n",
+			   result,mtd.eraseregions[result].offset,
+			   result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024,
+			   result,mtd.eraseregions[result].numblocks);
+
+#ifdef HAVE_PARTITIONS
+   printk ("\npartitions = %d\n",NB_OF (lart_partitions));
+
+   for (result = 0; result < NB_OF (lart_partitions); result++)
+	 printk (KERN_DEBUG
+			 "\n\n"
+			 "lart_partitions[%d].name = %s\n"
+			 "lart_partitions[%d].offset = 0x%.8x\n"
+			 "lart_partitions[%d].size = 0x%.8x (%uK)\n",
+			 result,lart_partitions[result].name,
+			 result,lart_partitions[result].offset,
+			 result,lart_partitions[result].size,lart_partitions[result].size / 1024);
+#endif
+#endif
+
+#ifndef HAVE_PARTITIONS
+   result = add_mtd_device (&mtd);
+#else
+   result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions));
+#endif
+
+   return (result);
+}
+
+void __exit lart_flash_exit (void)
+{
+#ifndef HAVE_PARTITIONS
+   del_mtd_device (&mtd);
+#else
+   del_mtd_partitions (&mtd);
+#endif
+}
+
+module_init (lart_flash_init);
+module_exit (lart_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Abraham vd Merwe <abraham@2d3d.co.za>");
+MODULE_DESCRIPTION("MTD driver for Intel 28F160F3 on LART board");
+
+
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/mtdram.c linux/drivers/mtd/devices/mtdram.c
--- v2.4.10/linux/drivers/mtd/devices/mtdram.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/mtdram.c	Thu Oct  4 15:14:59 2001
@@ -1,6 +1,6 @@
 /*
  * mtdram - a test mtd device
- * $Id: mtdram.c,v 1.24 2001/06/09 23:09:23 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.25 2001/10/02 15:05:13 dwmw2 Exp $
  * Author: Alexander Larsson <alex@cendio.se>
  *
  * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
@@ -104,13 +104,7 @@
   return 0;
 }
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_mtdram init_module
-#define cleanup_mtdram cleanup_module
-#endif
-
-//static void __exit cleanup_mtdram(void)
-mod_exit_t cleanup_mtdram(void)
+static void __exit cleanup_mtdram(void)
 {
   if (mtd_info) {
     del_mtd_device(mtd_info);
@@ -124,7 +118,7 @@
   }
 }
 
-mod_init_t init_mtdram(void)
+int __init init_mtdram(void)
 {
    // Allocate some memory
    mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
@@ -176,3 +170,8 @@
 
 module_init(init_mtdram);
 module_exit(cleanup_mtdram);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
+MODULE_DESCRIPTION("Simulated MTD driver for testing");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/pmc551.c linux/drivers/mtd/devices/pmc551.c
--- v2.4.10/linux/drivers/mtd/devices/pmc551.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/pmc551.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: pmc551.c,v 1.17 2001/05/22 13:56:46 dwmw2 Exp $
+ * $Id: pmc551.c,v 1.19 2001/10/02 15:05:13 dwmw2 Exp $
  *
  * PMC551 PCI Mezzanine Ram Device
  *
@@ -75,7 +75,11 @@
  *       waiting for it to set .. this does not safely handle busted
  *       devices that never reset the register correctly which will
  *       cause the system to hang w/ a reboot being the only chance at
- *       recover.
+ *       recover. [sort of fixed, could be better]
+ *       * Add I2C handling of the SROM so we can read the SROM's information
+ *       about the aperture size.  This should always accurately reflect the
+ *       onboard memory size.
+ *       * Comb the init routine.  It's still a bit cludgy on a few things.
  */
 
 #include <linux/config.h>
@@ -116,161 +120,168 @@
 
 static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr)
 {
-        struct mypriv *priv = mtd->priv;
-        u32 start_addr_highbits;
-        u32 end_addr_highbits;
-        u32 start_addr_lowbits;
-        u32 end_addr_lowbits;
+        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        u32 soff_hi, soff_lo; /* start address offset hi/lo */
+        u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
         unsigned long end;
+	u_char *ptr;
+	size_t retlen;
+
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len);
+#endif
 
-        end = instr->addr + instr->len;
+        end = instr->addr + instr->len - 1;
 
-        /* Is it too much memory?  The second check find if we wrap around
-           past the end of a u32. */
-        if ((end > mtd->size) || (end < instr->addr)) {
+        /* Is it past the end? */
+        if ( end > mtd->size ) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n", (long)end, (long)mtd->size);
+#endif
                 return -EINVAL;
         }
 
-        start_addr_highbits = instr->addr & PMC551_ADDR_HIGH_MASK;
-        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
-        start_addr_lowbits = instr->addr & PMC551_ADDR_LOW_MASK;
-        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
-
-        pci_write_config_dword ( priv->dev,
-                                 PMC551_PCI_MEM_MAP0,
-                                 (priv->mem_map0_base_val
-                                  | start_addr_highbits));
-        if (start_addr_highbits == end_addr_highbits) {
+        eoff_hi = end & ~(priv->asize - 1);
+        soff_hi = instr->addr & ~(priv->asize - 1);
+        eoff_lo = end & (priv->asize - 1);
+        soff_lo = instr->addr & (priv->asize - 1);
+
+	pmc551_point (mtd, instr->addr, instr->len, &retlen, &ptr);
+
+        if ( soff_hi == eoff_hi || mtd->size == priv->asize) {
                 /* The whole thing fits within one access, so just one shot
                    will do it. */
-                memset(priv->start + start_addr_lowbits,
-                       0xff,
-                       instr->len);
+                memset(ptr, 0xff, instr->len);
         } else {
                 /* We have to do multiple writes to get all the data
                    written. */
-                memset(priv->start + start_addr_lowbits,
-                       0xff,
-                       priv->aperture_size - start_addr_lowbits);
-                start_addr_highbits += priv->aperture_size;
-                while (start_addr_highbits != end_addr_highbits) {
-                        pci_write_config_dword ( priv->dev,
-                                                 PMC551_PCI_MEM_MAP0,
-                                                 (priv->mem_map0_base_val
-                                                  | start_addr_highbits));
-                        memset(priv->start,
-                               0xff,
-                               priv->aperture_size);
-                        start_addr_highbits += priv->aperture_size;
+                while (soff_hi != eoff_hi) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+			printk( KERN_DEBUG "pmc551_erase() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
+#endif
+                        memset(ptr, 0xff, priv->asize);
+                        if (soff_hi + priv->asize >= mtd->size) {
+                                goto out;
+                        }
+                        soff_hi += priv->asize;
+			pmc551_point (mtd,(priv->base_map0|soff_hi),
+				      priv->asize, &retlen, &ptr);
                 }
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-                memset(priv->start,
-                       0xff,
-                       end_addr_lowbits);
+                memset (ptr, 0xff, eoff_lo);
         }
 
+out:
 	instr->state = MTD_ERASE_DONE;
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_erase() done\n");
+#endif
 
         if (instr->callback) {
                 (*(instr->callback))(instr);
 	}
-
         return 0;
 }
 
 
+static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
+{
+        struct mypriv *priv = (struct mypriv *)mtd->priv;
+        u32 soff_hi;
+        u32 soff_lo;
+
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len);
+#endif
+
+	if (from + len > mtd->size) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+		printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n", (long)from+len, (long)mtd->size);
+#endif
+		return -EINVAL;
+	}
+
+        soff_hi = from & ~(priv->asize - 1);
+        soff_lo = from & (priv->asize - 1);
+
+	/* Cheap hack optimization */
+	if( priv->curr_map0 != from ) {
+        	pci_write_config_dword ( priv->dev, PMC551_PCI_MEM_MAP0,
+                                 	(priv->base_map0 | soff_hi) );
+		priv->curr_map0 = soff_hi;
+	}
+
+	*mtdbuf = priv->start + soff_lo;
+	*retlen = len;
+	return 0;
+}
+
+
 static void pmc551_unpoint (struct mtd_info *mtd, u_char *addr)
-{}
+{
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_unpoint()\n");
+#endif
+}
 
 
-static int pmc551_read (struct mtd_info *mtd,
-                        loff_t from,
-                        size_t len,
-                        size_t *retlen,
-                        u_char *buf)
+static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
         struct mypriv *priv = (struct mypriv *)mtd->priv;
-        u32 start_addr_highbits;
-        u32 end_addr_highbits;
-        u32 start_addr_lowbits;
-        u32 end_addr_lowbits;
+        u32 soff_hi, soff_lo; /* start address offset hi/lo */
+        u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
         unsigned long end;
+	u_char *ptr;
         u_char *copyto = buf;
 
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n", (long)from, (long)len, (long)priv->asize);
+#endif
+
+        end = from + len - 1;
 
         /* Is it past the end? */
-        if (from > mtd->size) {
+        if (end > mtd->size) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n", (long) end, (long)mtd->size);
+#endif
                 return -EINVAL;
         }
 
-        end = from + len;
-        start_addr_highbits = from & PMC551_ADDR_HIGH_MASK;
-        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
-        start_addr_lowbits = from & PMC551_ADDR_LOW_MASK;
-        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
-
-
-        /* Only rewrite the first value if it doesn't match our current
-           values.  Most operations are on the same page as the previous
-           value, so this is a pretty good optimization. */
-        if (priv->curr_mem_map0_val !=
-                        (priv->mem_map0_base_val | start_addr_highbits)) {
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-        }
+        soff_hi = from & ~(priv->asize - 1);
+        eoff_hi = end & ~(priv->asize - 1);
+        soff_lo = from & (priv->asize - 1);
+        eoff_lo = end & (priv->asize - 1);
+
+	pmc551_point (mtd, from, len, retlen, &ptr);
 
-        if (start_addr_highbits == end_addr_highbits) {
+        if (soff_hi == eoff_hi) {
                 /* The whole thing fits within one access, so just one shot
                    will do it. */
-                memcpy(copyto,
-                       priv->start + start_addr_lowbits,
-                       len);
+                memcpy(copyto, ptr, len);
                 copyto += len;
         } else {
                 /* We have to do multiple writes to get all the data
                    written. */
-                memcpy(copyto,
-                       priv->start + start_addr_lowbits,
-                       priv->aperture_size - start_addr_lowbits);
-                copyto += priv->aperture_size - start_addr_lowbits;
-                start_addr_highbits += priv->aperture_size;
-                while (start_addr_highbits != end_addr_highbits) {
-                        pci_write_config_dword ( priv->dev,
-                                                 PMC551_PCI_MEM_MAP0,
-                                                 (priv->mem_map0_base_val
-                                                  | start_addr_highbits));
-                        memcpy(copyto,
-                               priv->start,
-                               priv->aperture_size);
-                        copyto += priv->aperture_size;
-                        start_addr_highbits += priv->aperture_size;
-                        if (start_addr_highbits >= mtd->size) {
-                                /* Make sure we have the right value here. */
-                                priv->curr_mem_map0_val
-                                = (priv->mem_map0_base_val
-                                   | start_addr_highbits);
+                while (soff_hi != eoff_hi) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+			printk( KERN_DEBUG "pmc551_read() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
+#endif
+                        memcpy(copyto, ptr, priv->asize);
+                        copyto += priv->asize;
+                        if (soff_hi + priv->asize >= mtd->size) {
                                 goto out;
                         }
+                        soff_hi += priv->asize;
+			pmc551_point (mtd, soff_hi, priv->asize, retlen, &ptr);
                 }
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-                memcpy(copyto,
-                       priv->start,
-                       end_addr_lowbits);
-                copyto += end_addr_lowbits;
+                memcpy(copyto, ptr, eoff_lo);
+                copyto += eoff_lo;
         }
 
 out:
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_read() done\n");
+#endif
         *retlen = copyto - buf;
         return 0;
 }
@@ -278,83 +289,61 @@
 static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
         struct mypriv *priv = (struct mypriv *)mtd->priv;
-        u32 start_addr_highbits;
-        u32 end_addr_highbits;
-        u32 start_addr_lowbits;
-        u32 end_addr_lowbits;
+        u32 soff_hi, soff_lo; /* start address offset hi/lo */
+        u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
         unsigned long end;
+	u_char *ptr;
         const u_char *copyfrom = buf;
 
 
-        /* Is it past the end? */
-        if (to > mtd->size) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n", (long)to, (long)len, (long)priv->asize);
+#endif
+
+        end = to + len - 1;
+        /* Is it past the end?  or did the u32 wrap? */
+        if (end > mtd->size ) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, size: %ld, to: %ld)\n", (long) end, (long)mtd->size, (long)to);
+#endif
                 return -EINVAL;
         }
 
-        end = to + len;
-        start_addr_highbits = to & PMC551_ADDR_HIGH_MASK;
-        end_addr_highbits = end & PMC551_ADDR_HIGH_MASK;
-        start_addr_lowbits = to & PMC551_ADDR_LOW_MASK;
-        end_addr_lowbits = end & PMC551_ADDR_LOW_MASK;
-
-
-        /* Only rewrite the first value if it doesn't match our current
-           values.  Most operations are on the same page as the previous
-           value, so this is a pretty good optimization. */
-        if (priv->curr_mem_map0_val !=
-                        (priv->mem_map0_base_val | start_addr_highbits)) {
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-        }
+        soff_hi = to & ~(priv->asize - 1);
+        eoff_hi = end & ~(priv->asize - 1);
+        soff_lo = to & (priv->asize - 1);
+        eoff_lo = end & (priv->asize - 1);
 
-        if (start_addr_highbits == end_addr_highbits) {
+	pmc551_point (mtd, to, len, retlen, &ptr);
+
+        if (soff_hi == eoff_hi) {
                 /* The whole thing fits within one access, so just one shot
                    will do it. */
-                memcpy(priv->start + start_addr_lowbits,
-                       copyfrom,
-                       len);
+                memcpy(ptr, copyfrom, len);
                 copyfrom += len;
         } else {
                 /* We have to do multiple writes to get all the data
                    written. */
-                memcpy(priv->start + start_addr_lowbits,
-                       copyfrom,
-                       priv->aperture_size - start_addr_lowbits);
-                copyfrom += priv->aperture_size - start_addr_lowbits;
-                start_addr_highbits += priv->aperture_size;
-                while (start_addr_highbits != end_addr_highbits) {
-                        pci_write_config_dword ( priv->dev,
-                                                 PMC551_PCI_MEM_MAP0,
-                                                 (priv->mem_map0_base_val
-                                                  | start_addr_highbits));
-                        memcpy(priv->start,
-                               copyfrom,
-                               priv->aperture_size);
-                        copyfrom += priv->aperture_size;
-                        start_addr_highbits += priv->aperture_size;
-                        if (start_addr_highbits >= mtd->size) {
-                                /* Make sure we have the right value here. */
-                                priv->curr_mem_map0_val
-                                = (priv->mem_map0_base_val
-                                   | start_addr_highbits);
+                while (soff_hi != eoff_hi) {
+#ifdef CONFIG_MTD_PMC551_DEBUG
+			printk( KERN_DEBUG "pmc551_write() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
+#endif
+                	memcpy(ptr, copyfrom, priv->asize);
+                	copyfrom += priv->asize;
+                        if (soff_hi >= mtd->size) {
                                 goto out;
                         }
+                        soff_hi += priv->asize;
+			pmc551_point (mtd, soff_hi, priv->asize, retlen, &ptr);
                 }
-                priv->curr_mem_map0_val = (priv->mem_map0_base_val
-                                           | start_addr_highbits);
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-                memcpy(priv->start,
-                       copyfrom,
-                       end_addr_lowbits);
-                copyfrom += end_addr_lowbits;
+                memcpy(ptr, copyfrom, eoff_lo);
+                copyfrom += eoff_lo;
         }
 
 out:
+#ifdef CONFIG_MTD_PMC551_DEBUG
+	printk(KERN_DEBUG "pmc551_write() done\n");
+#endif
         *retlen = copyfrom - buf;
         return 0;
 }
@@ -437,8 +426,9 @@
 #ifndef CONFIG_MTD_PMC551_BUGFIX
 	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, ~0 );
 	pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &size );
+	size = (size&PCI_BASE_ADDRESS_MEM_MASK);
+	size &= ~(size-1);
 	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
-	size=~(size&PCI_BASE_ADDRESS_MEM_MASK)+1;
 #else
         /*
          * Get the size of the memory by reading all the DRAM size values
@@ -503,7 +493,6 @@
 	 * The loop is taken directly from Ramix's example code.  I assume that
 	 * this must be held high for some duration of time, but I can find no
 	 * documentation refrencing the reasons why.
-	 * 
          */
         for ( i = 1; i<=8 ; i++) {
                 pci_write_config_word (dev, PMC551_SDRAM_CMD, 0x0df);
@@ -558,8 +547,10 @@
 	 * it's possible that the reset of the V370PDC nuked the original
 	 * setup
          */
+	/*
         cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH;
 	pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
+	*/
 
         /*
          * Turn PCI memory and I/O bus access back on
@@ -571,7 +562,7 @@
          * Some screen fun
          */
         printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%lx\n",
-	       (size<1024)?size:(size<1048576)?size/1024:size/1024/1024,
+	       (size<1024)?size:(size<1048576)?size>>10:size>>20,
                (size<1024)?'B':(size<1048576)?'K':'M',
 	       size, ((dcmd&(0x1<<3)) == 0)?"non-":"",
                PCI_BASE_ADDRESS(dev)&PCI_BASE_ADDRESS_MEM_MASK );
@@ -644,19 +635,15 @@
  * Kernel version specific module stuffages
  */
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_pmc551 init_module
-#define cleanup_pmc551 cleanup_module
-#endif
 
-#if defined(MODULE)
+MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>");
 MODULE_DESCRIPTION(PMC551_VERSION);
 MODULE_PARM(msize, "i");
-MODULE_PARM_DESC(msize, "memory size, 6=32M, 7=64M, 8=128M, etc.. [32M-1024M]");
+MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]");
 MODULE_PARM(asize, "i");
-MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1M-1024M]");
-#endif
+MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
+
 /*
  * Stuff these outside the ifdef so as to not bust compiled in driver support
  */
@@ -679,19 +666,19 @@
         u32 length = 0;
 
 	if(msize) {
-		if (msize < 6 || msize > 11 ) {
-			printk(KERN_NOTICE "pmc551: Invalid memory size\n");
-			return -ENODEV;
+		msize = (1 << (ffs(msize) - 1))<<20;
+		if (msize > (1<<30)) {
+			printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n", msize);
+			return -EINVAL;
 		}
-		msize = (512*1024)<<msize;
 	}
 
 	if(asize) {
-		if (asize < 1 || asize > 11 ) {
-			printk(KERN_NOTICE "pmc551: Invalid aperture size\n");
-			return -ENODEV;
+		asize = (1 << (ffs(asize) - 1))<<20;
+		if (asize > (1<<30) ) {
+			printk(KERN_NOTICE "pmc551: Invalid aperture size [%d]\n", asize);
+			return -EINVAL;
 		}
-		asize = (512*1024)<<asize;
 	}
 
         printk(KERN_INFO PMC551_VERSION);
@@ -706,13 +693,14 @@
          */
         for( count = 0; count < MAX_MTD_DEVICES; count++ ) {
 
-                if ( (PCI_Device = pci_find_device( PCI_VENDOR_ID_V3_SEMI,
-                                                    PCI_DEVICE_ID_V3_SEMI_V370PDC, PCI_Device ) ) == NULL) {
+                if ((PCI_Device = pci_find_device(PCI_VENDOR_ID_V3_SEMI,
+                                                  PCI_DEVICE_ID_V3_SEMI_V370PDC,
+						  PCI_Device ) ) == NULL) {
                         break;
                 }
 
-                printk(KERN_NOTICE "pmc551: Found PCI V370PDC IRQ:%d\n",
-                       PCI_Device->irq);
+                printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%lX\n",
+				    PCI_BASE_ADDRESS(PCI_Device));
 
                 /*
                  * The PMC551 device acts VERY weird if you don't init it
@@ -726,9 +714,16 @@
                         printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n");
                         break;
                 }
+
+		/*
+		 * This is needed untill the driver is capable of reading the
+		 * onboard I2C SROM to discover the "real" memory size.
+		 */
 		if(msize) {
 			length = msize;
 			printk(KERN_NOTICE "pmc551: Using specified memory size 0x%x\n", length);
+		} else {
+			msize = length;
 		}
 
                 mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
@@ -747,71 +742,57 @@
                 }
                 memset(priv, 0, sizeof(*priv));
                 mtd->priv = priv;
-
                 priv->dev = PCI_Device;
-		if(asize) {
-			if(asize > length) {
-				asize=length;
-				printk(KERN_NOTICE "pmc551: reducing aperture size to fit memory [0x%x]\n",asize);
-			} else {
-				printk(KERN_NOTICE "pmc551: Using specified aperture size 0x%x\n", asize);
-			}
-			priv->aperture_size = asize;
+
+		if(asize > length) {
+			printk(KERN_NOTICE "pmc551: reducing aperture size to fit %dM\n",length>>20);
+			priv->asize = asize = length;
+		} else if (asize == 0 || asize == length) {
+			printk(KERN_NOTICE "pmc551: Using existing aperture size %dM\n", length>>20);
+			priv->asize = asize = length;
 		} else {
-                	priv->aperture_size = length;
+			printk(KERN_NOTICE "pmc551: Using specified aperture size %dM\n", asize>>20);
+			priv->asize = asize;
 		}
                 priv->start = ioremap((PCI_BASE_ADDRESS(PCI_Device)
                                        & PCI_BASE_ADDRESS_MEM_MASK),
-                                      priv->aperture_size);
+                                      priv->asize);
 		
 		if (!priv->start) {
+			printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
                         kfree(mtd->priv);
                         kfree(mtd);
 			break;
 		}
-		/*
-		 * Due to the dynamic nature of the code, we need to figure
-		 * this out in order to stuff the register to set the proper
-		 * aperture size.  If you know of an easier way to do this then
-		 * PLEASE help yourself.
-		 *
-		 * Not with bloody floating point, you don't. Consider yourself
-		 * duly LARTed. dwmw2.
-		 */
-		{
-			u32 size;
-			u16 bits;
-			size = priv->aperture_size>>20;
-			for(bits=0;!(size&0x01)&&size>0;bits++,size=size>>1);
-			//size=((u32)((log10(priv->aperture_size)/.30103)-19)<<4);
-                	priv->mem_map0_base_val = (PMC551_PCI_MEM_MAP_REG_EN
-						| PMC551_PCI_MEM_MAP_ENABLE
-						| size);
+
 #ifdef CONFIG_MTD_PMC551_DEBUG
-			printk(KERN_NOTICE "pmc551: aperture set to %d[%d]\n", 
-					size, size>>4);
+		printk( KERN_DEBUG "pmc551: setting aperture to %d\n",
+			ffs(priv->asize>>20)-1);
 #endif
-		}
-                priv->curr_mem_map0_val = priv->mem_map0_base_val;
 
-                pci_write_config_dword ( priv->dev,
-                                         PMC551_PCI_MEM_MAP0,
-                                         priv->curr_mem_map0_val);
-
-                mtd->size 		= length;
-                mtd->flags 		= (MTD_CLEAR_BITS
-                                | MTD_SET_BITS
-                                | MTD_WRITEB_WRITEABLE
-                                | MTD_VOLATILE);
-                mtd->erase 		= pmc551_erase;
-                mtd->point 		= NULL;
-                mtd->unpoint 		= pmc551_unpoint;
-                mtd->read 		= pmc551_read;
-                mtd->write 		= pmc551_write;
-                mtd->module 		= THIS_MODULE;
-                mtd->type 		= MTD_RAM;
-                mtd->name 		= "PMC551 RAM board";
-                mtd->erasesize 		= 0x10000;
+                priv->base_map0 = ( PMC551_PCI_MEM_MAP_REG_EN
+				  | PMC551_PCI_MEM_MAP_ENABLE
+				  | (ffs(priv->asize>>20)-1)<<4 );
+                priv->curr_map0 = priv->base_map0;
+                pci_write_config_dword ( priv->dev, PMC551_PCI_MEM_MAP0,
+                                         priv->curr_map0 );
+
+#ifdef CONFIG_MTD_PMC551_DEBUG
+		printk( KERN_DEBUG "pmc551: aperture set to %d\n", 
+			(priv->base_map0 & 0xF0)>>4 );
+#endif
+
+                mtd->size 	= msize;
+                mtd->flags 	= MTD_CAP_RAM;
+                mtd->erase 	= pmc551_erase;
+                mtd->read 	= pmc551_read;
+                mtd->write 	= pmc551_write;
+                mtd->point 	= pmc551_point;
+                mtd->unpoint 	= pmc551_unpoint;
+                mtd->module 	= THIS_MODULE;
+                mtd->type 	= MTD_RAM;
+                mtd->name 	= "PMC551 RAM board";
+                mtd->erasesize 	= 0x10000;
 
                 if (add_mtd_device(mtd)) {
                         printk(KERN_NOTICE "pmc551: Failed to register new device\n");
@@ -822,12 +803,12 @@
                 }
                 printk(KERN_NOTICE "Registered pmc551 memory device.\n");
                 printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n",
-                       priv->aperture_size/1024/1024,
+                       priv->asize>>20,
                        priv->start,
-                       priv->start + priv->aperture_size);
+                       priv->start + priv->asize);
                 printk(KERN_NOTICE "Total memory is %d%c\n",
 	       		(length<1024)?length:
-				(length<1048576)?length/1024:length/1024/1024,
+				(length<1048576)?length>>10:length>>20,
                		(length<1024)?'B':(length<1048576)?'K':'M');
 		priv->nextpmc551 = pmc551list;
 		pmc551list = mtd;
@@ -835,7 +816,7 @@
         }
 
         if( !pmc551list ) {
-                printk(KERN_NOTICE "pmc551: not detected,\n");
+                printk(KERN_NOTICE "pmc551: not detected\n");
                 return -ENODEV;
         } else {
 		printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found);
@@ -856,12 +837,15 @@
 		priv = (struct mypriv *)mtd->priv;
 		pmc551list = priv->nextpmc551;
 		
-		if(priv->start)
-			iounmap(priv->start);
+		if(priv->start) {
+			printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n",
+				priv->asize>>20, priv->start);
+			iounmap (priv->start);
+		}
 		
 		kfree (mtd->priv);
-		del_mtd_device(mtd);
-		kfree(mtd);
+		del_mtd_device (mtd);
+		kfree (mtd);
 		found++;
 	}
 
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/devices/slram.c linux/drivers/mtd/devices/slram.c
--- v2.4.10/linux/drivers/mtd/devices/slram.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/devices/slram.c	Thu Oct  4 15:14:59 2001
@@ -1,6 +1,6 @@
 /*======================================================================
 
-  $Id: slram.c,v 1.19 2001/06/02 20:33:20 dwmw2 Exp $
+  $Id: slram.c,v 1.25 2001/10/02 15:05:13 dwmw2 Exp $
 
 ======================================================================*/
 
@@ -46,15 +46,8 @@
 static char *map;
 #endif
 
-#ifdef MODULE
-#if LINUX_VERSION_CODE < 0x20212
-#define init_slram init_module
-#define cleanup_slram cleanup_module
-#endif
-
 MODULE_PARM(map, "3-" __MODULE_STRING(SLRAM_MAX_DEVICES_PARAMS) "s");
 MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\"");
-#endif
 
 static slram_mtd_list_t *slram_mtdlist = NULL;
 
@@ -129,7 +122,7 @@
 
 /*====================================================================*/
 
-int register_device(char *name, long start, long length)
+int register_device(char *name, unsigned long start, unsigned long length)
 {
 	slram_mtd_list_t **curmtd;
 
@@ -139,7 +132,7 @@
 	}
 
 	*curmtd = kmalloc(sizeof(slram_mtd_list_t), GFP_KERNEL);
-	if (!curmtd) {
+	if (!(*curmtd)) {
 		E("slram: Cannot allocate new MTD device.\n");
 		return(-ENOMEM);
 	}
@@ -193,8 +186,8 @@
 		kfree((*curmtd)->mtdinfo);
 		return(-EAGAIN);
 	}
-	T("slram: Registered device %s from %dKiB to %dKiB\n", name,
-			(int)(start / 1024), (int)((start + length) / 1024));
+	T("slram: Registered device %s from %luKiB to %luKiB\n", name,
+			(start / 1024), ((start + length) / 1024));
 	T("slram: Mapped from 0x%p to 0x%p\n",
 			((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
 			((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
@@ -216,7 +209,7 @@
 	}
 }
 
-int handle_unit(long value, char *unit)
+unsigned long handle_unit(unsigned long value, char *unit)
 {
 	if ((*unit == 'M') || (*unit == 'm')) {
 		return(value * 1024 * 1024);
@@ -229,8 +222,8 @@
 int parse_cmdline(char *devname, char *szstart, char *szlength)
 {
 	char *buffer;
-	long devstart;
-	long devlength;
+	unsigned long devstart;
+	unsigned long devlength;
 	
 	if ((!devname) || (!szstart) || (!szlength)) {
 		unregister_devices();
@@ -247,7 +240,7 @@
 		devlength = simple_strtoul(szlength + 1, &buffer, 0);
 		devlength = handle_unit(devlength, buffer);
 	}
-	T("slram: devname=%s, devstart=%li, devlength=%li\n",
+	T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
 			devname, devstart, devlength);
 	if ((devstart < 0) || (devlength < 0)) {
 		E("slram: Illegal start / length parameter.\n");
@@ -339,3 +332,7 @@
 
 module_init(init_slram);
 module_exit(cleanup_slram);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jochen Schaeuble <psionic@psionic.de>");
+MODULE_DESCRIPTION("MTD driver for uncached system RAM");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- v2.4.10/linux/drivers/mtd/ftl.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/ftl.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.35 2001/06/09 00:40:17 dwmw2 Exp $
+ * $Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -258,7 +258,7 @@
     max_offset = (0x100000<part->mtd->size)?0x100000:part->mtd->size;
     /* Search first megabyte for a valid FTL header */
     for (offset = 0;
-	 offset < max_offset;
+	 (offset + sizeof(header)) < max_offset;
 	 offset += part->mtd->erasesize ? : 0x2000) {
 
 	ret = part->mtd->read(part->mtd, offset, sizeof(header), &ret, 
@@ -1400,18 +1400,13 @@
 		}
 }
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_ftl init_module
-#define cleanup_ftl cleanup_module
-#endif
-
-mod_init_t init_ftl(void)
+int init_ftl(void)
 {
     int i;
 
     memset(myparts, 0, sizeof(myparts));
     
-    DEBUG(0, "$Id: ftl.c,v 1.35 2001/06/09 00:40:17 dwmw2 Exp $\n");
+    DEBUG(0, "$Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $\n");
     
     if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
 	printk(KERN_NOTICE "ftl_cs: unable to grab major "
@@ -1435,7 +1430,7 @@
     return 0;
 }
 
-mod_exit_t cleanup_ftl(void)
+static void __exit cleanup_ftl(void)
 {
     unregister_mtd_user(&ftl_notifier);
 
@@ -1448,3 +1443,8 @@
 
 module_init(init_ftl);
 module_exit(cleanup_ftl);
+
+
+MODULE_LICENSE("Dual MPL/GPL");
+MODULE_AUTHOR("David Hinds <dhinds@sonic.net>");
+MODULE_DESCRIPTION("Support code for Flash Translation Layer, used on PCMCIA devices and M-Systems DiskOnChip 1000");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/Config.in linux/drivers/mtd/maps/Config.in
--- v2.4.10/linux/drivers/mtd/maps/Config.in	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/maps/Config.in	Thu Oct  4 15:13:18 2001
@@ -1,6 +1,6 @@
 # drivers/mtd/maps/Config.in
 
-# $Id: Config.in,v 1.9.2.1 2001/06/09 19:43:49 dwmw2 Exp $
+# $Id: Config.in,v 1.16 2001/09/19 18:28:37 dwmw2 Exp $
 
 mainmenu_option next_comment
 
@@ -14,36 +14,49 @@
 fi
 
 if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
-   dep_tristate '  Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_SPARC64
+   dep_tristate '  Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_MTD_CFI
 fi
-if [ "$CONFIG_ARM" = "y" ]; then
-   dep_tristate '  CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
-fi
-dep_tristate '  CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
-dep_tristate '  CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI 
-if [ "$CONFIG_X86" = "y"  ]; then
+
+if [ "$CONFIG_X86" = "y" ]; then
+   dep_tristate '  CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
    dep_tristate '  CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI
    dep_tristate '  CFI Flash device mapped on AMD NetSc520'  CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
+   dep_tristate '  CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
+   dep_tristate '  CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
+   dep_tristate '  JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
+   dep_tristate '  JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
+   dep_tristate '  JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
+   dep_tristate '  BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_I386 $CONFIG_MTD_JEDEC
 fi
-dep_tristate '  CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
-dep_tristate '  CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
+
+if [ "$CONFIG_PPC" = "y" ]; then
+   dep_tristate '  CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI $CONFIG_TQM8xxL $CONFIG_PPC
+   dep_tristate '  CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI $CONFIG_PPC
+   dep_tristate '  CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI_INTELSTD $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI_AMDSTD
+   dep_tristate '  CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI
+fi
+
+if [ "$CONFIG_MIPS" = "y" ]; then
+   dep_tristate '  Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS 
+   if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
+      hex '    Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
+      hex '    Physical length of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_LEN 0x4000000
+      int '    Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2
+   fi
+   dep_tristate '  Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT
+fi
+
+if [ "$CONFIG_SH" = "y" ]; then
+   dep_tristate '  CFI Flash device mapped on Hitachi SolutionEngine' CONFIG_MTD_SOLUTIONENGINE $CONFIG_MTD_CFI $CONFIG_SH $CONFIG_MTD_REDBOOT_PARTS
+fi
+
 if [ "$CONFIG_ARM" = "y" ]; then
-dep_tristate '  CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
-   dep_bool '    Support for RedBoot partition tables on SA11x0' CONFIG_MTD_SA1100_REDBOOT_PARTITIONS $CONFIG_MTD_SA1100 $CONFIG_MTD_REDBOOT_PARTS
-   dep_bool '    Support for Compaq bootldr partition tables on SA11x0' CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS $CONFIG_MTD_SA1100 $CONFIG_MTD_BOOTLDR_PARTS
+   dep_tristate '  CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
+   dep_tristate '  CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI
+   dep_tristate '  Cirrus CDB89712 evaluation board mappings' CONFIG_MTD_CDB89712 $CONFIG_MTD_CFI $CONFIG_ARCH_CDB89712
+   dep_tristate '  CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
    dep_tristate '  CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_PARTITIONS
-   dep_tristate '  CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_XSCALE_IQ80310
+   dep_tristate '  CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_ARCH_IQ80310
 fi
-dep_tristate '  CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI_INTELSTD $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI_AMDSTD
-dep_tristate '  Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS 
-if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
-   hex '    Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
-   hex '    Physical length of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_LEN 0x4000000
-   int '    Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2
-fi
-dep_tristate '  CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI
-dep_tristate '  JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
-dep_tristate '  JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
-dep_tristate '  JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
-dep_tristate '  Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT
+
 endmenu
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/Makefile linux/drivers/mtd/maps/Makefile
--- v2.4.10/linux/drivers/mtd/maps/Makefile	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/Makefile	Thu Oct  4 15:13:18 2001
@@ -1,22 +1,25 @@
 #
 # linux/drivers/maps/Makefile
 #
-# $Id: Makefile,v 1.9.2.1 2001/06/09 19:43:49 dwmw2 Exp $
+# $Id: Makefile,v 1.13 2001/08/16 15:16:58 rmk Exp $
 
 O_TARGET	:= mapslink.o
 
 # Chip mappings
-
+obj-$(CONFIG_MTD_CDB89712)      += cdb89712.o
+obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
 obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_flagadm.o
 obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o
 obj-$(CONFIG_MTD_DC21285)       += dc21285.o
 obj-$(CONFIG_MTD_ELAN_104NC)    += elan-104nc.o
 obj-$(CONFIG_MTD_IQ80310)	+= iq80310.o
+obj-$(CONFIG_MTD_L440GX)	+= l440gx.o
 obj-$(CONFIG_MTD_NORA)		+= nora.o
 obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
 obj-$(CONFIG_MTD_PHYSMAP)	+= physmap.o 
 obj-$(CONFIG_MTD_PNC2000)	+= pnc2000.o
 obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o
+obj-$(CONFIG_MTD_TQM8XXL)	+= tqm8xxl.o
 obj-$(CONFIG_MTD_SA1100)        += sa1100-flash.o
 obj-$(CONFIG_MTD_SBC_GXX)	+= sbc_gxx.o
 obj-$(CONFIG_MTD_SC520CDP)	+= sc520cdp.o
@@ -25,5 +28,6 @@
 obj-$(CONFIG_MTD_VMAX)		+= vmax301.o
 obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.o
 obj-$(CONFIG_MTD_OCELOT)	+= ocelot.o
+obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/cdb89712.c linux/drivers/mtd/maps/cdb89712.c
--- v2.4.10/linux/drivers/mtd/maps/cdb89712.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/cdb89712.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,333 @@
+/*
+ * Flash on Cirrus CDB89712
+ *
+ * $Id: cdb89712.c,v 1.3 2001/10/02 15:14:43 rmk Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+
+__u8 cdb89712_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 cdb89712_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 cdb89712_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void cdb89712_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cdb89712_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cdb89712_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void cdb89712_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	// printk ("cdb89712_copy_from: 0x%x@0x%x -> 0x%x\n", len, from, to);
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void cdb89712_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	while(len) {
+		__raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
+		from++;
+		to++;
+		len--;
+	}
+}
+
+
+static struct mtd_info *flash_mtd;
+
+struct map_info cdb89712_flash_map = {
+	name: "flash",
+	size: FLASH_SIZE,
+	buswidth: FLASH_WIDTH,
+	read8: cdb89712_read8,
+	read16: cdb89712_read16,
+	read32: cdb89712_read32,
+	copy_from: cdb89712_copy_from,
+	write8: cdb89712_write8,
+	write16: cdb89712_write16,
+	write32: cdb89712_write32,
+	copy_to: cdb89712_copy_to
+};
+
+struct resource cdb89712_flash_resource = {
+	name:   "Flash",
+	start:  FLASH_START,
+	end:    FLASH_START + FLASH_SIZE - 1,
+	flags:  IORESOURCE_IO | IORESOURCE_BUSY,
+};
+
+static int __init init_cdb89712_flash (void)
+{
+	int err;
+	
+	if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
+		printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
+		err = -EBUSY;
+		goto out;
+	}
+	
+	cdb89712_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
+	if (!cdb89712_flash_map.map_priv_1) {
+		printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
+		err = -EIO;
+		goto out_resource;
+	}
+
+	flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map);
+	if (!flash_mtd) {
+		flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map);
+		if (flash_mtd)
+			flash_mtd->erasesize = 0x10000;
+	}
+	if (!flash_mtd) {
+		printk("FLASH probe failed\n");
+		err = -ENXIO;
+		goto out_ioremap;
+	}
+
+	flash_mtd->module = THIS_MODULE;
+	
+	if (add_mtd_device(flash_mtd)) {
+		printk("FLASH device addition failed\n");
+		err = -ENOMEM;
+		goto out_probe;
+	}
+		
+	return 0;
+
+out_probe:
+	map_destroy(flash_mtd);
+	flash_mtd = 0;
+out_ioremap:
+	iounmap((void *)cdb89712_flash_map.map_priv_1);
+out_resource:
+	release_resource (&cdb89712_flash_resource);
+out:
+	return err;
+}
+
+
+
+
+
+static struct mtd_info *sram_mtd;
+
+struct map_info cdb89712_sram_map = {
+	name: "SRAM",
+	size: SRAM_SIZE,
+	buswidth: SRAM_WIDTH,
+	read8: cdb89712_read8,
+	read16: cdb89712_read16,
+	read32: cdb89712_read32,
+	copy_from: cdb89712_copy_from,
+	write8: cdb89712_write8,
+	write16: cdb89712_write16,
+	write32: cdb89712_write32,
+	copy_to: cdb89712_copy_to
+};
+
+struct resource cdb89712_sram_resource = {
+	name:   "SRAM",
+	start:  SRAM_START,
+	end:    SRAM_START + SRAM_SIZE - 1,
+	flags:  IORESOURCE_IO | IORESOURCE_BUSY,
+};
+
+static int __init init_cdb89712_sram (void)
+{
+	int err;
+	
+	if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
+		printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
+		err = -EBUSY;
+		goto out;
+	}
+	
+	cdb89712_sram_map.map_priv_1 = (unsigned long)ioremap(SRAM_START, SRAM_SIZE);
+	if (!cdb89712_sram_map.map_priv_1) {
+		printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
+		err = -EIO;
+		goto out_resource;
+	}
+
+	sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map);
+	if (!sram_mtd) {
+		printk("SRAM probe failed\n");
+		err = -ENXIO;
+		goto out_ioremap;
+	}
+
+	sram_mtd->module = THIS_MODULE;
+	sram_mtd->erasesize = 16;
+	
+	if (add_mtd_device(sram_mtd)) {
+		printk("SRAM device addition failed\n");
+		err = -ENOMEM;
+		goto out_probe;
+	}
+		
+	return 0;
+
+out_probe:
+	map_destroy(sram_mtd);
+	sram_mtd = 0;
+out_ioremap:
+	iounmap((void *)cdb89712_sram_map.map_priv_1);
+out_resource:
+	release_resource (&cdb89712_sram_resource);
+out:
+	return err;
+}
+
+
+
+
+
+
+
+static struct mtd_info *bootrom_mtd;
+
+struct map_info cdb89712_bootrom_map = {
+	name: "BootROM",
+	size: BOOTROM_SIZE,
+	buswidth: BOOTROM_WIDTH,
+	read8: cdb89712_read8,
+	read16: cdb89712_read16,
+	read32: cdb89712_read32,
+	copy_from: cdb89712_copy_from,
+};
+
+struct resource cdb89712_bootrom_resource = {
+	name:   "BootROM",
+	start:  BOOTROM_START,
+	end:    BOOTROM_START + BOOTROM_SIZE - 1,
+	flags:  IORESOURCE_IO | IORESOURCE_BUSY,
+};
+
+static int __init init_cdb89712_bootrom (void)
+{
+	int err;
+	
+	if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
+		printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
+		err = -EBUSY;
+		goto out;
+	}
+	
+	cdb89712_bootrom_map.map_priv_1 = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE);
+	if (!cdb89712_bootrom_map.map_priv_1) {
+		printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
+		err = -EIO;
+		goto out_resource;
+	}
+
+	bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map);
+	if (!bootrom_mtd) {
+		printk("BootROM probe failed\n");
+		err = -ENXIO;
+		goto out_ioremap;
+	}
+
+	bootrom_mtd->module = THIS_MODULE;
+	bootrom_mtd->erasesize = 0x10000;
+	
+	if (add_mtd_device(bootrom_mtd)) {
+		printk("BootROM device addition failed\n");
+		err = -ENOMEM;
+		goto out_probe;
+	}
+		
+	return 0;
+
+out_probe:
+	map_destroy(bootrom_mtd);
+	bootrom_mtd = 0;
+out_ioremap:
+	iounmap((void *)cdb89712_bootrom_map.map_priv_1);
+out_resource:
+	release_resource (&cdb89712_bootrom_resource);
+out:
+	return err;
+}
+
+
+
+
+
+static int __init init_cdb89712_maps(void)
+{
+
+       	printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n  Flash 0x%x at 0x%x\n  SRAM 0x%x at 0x%x\n  BootROM 0x%x at 0x%x\n", 
+	       FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
+
+	init_cdb89712_flash();
+	init_cdb89712_sram();
+	init_cdb89712_bootrom();
+	
+	return 0;
+}
+	
+
+static void __exit cleanup_cdb89712_maps(void)
+{
+	if (sram_mtd) {
+		del_mtd_device(sram_mtd);
+		map_destroy(sram_mtd);
+		iounmap((void *)cdb89712_sram_map.map_priv_1);
+		release_resource (&cdb89712_sram_resource);
+	}
+	
+	if (flash_mtd) {
+		del_mtd_device(flash_mtd);
+		map_destroy(flash_mtd);
+		iounmap((void *)cdb89712_flash_map.map_priv_1);
+		release_resource (&cdb89712_flash_resource);
+	}
+
+	if (bootrom_mtd) {
+		del_mtd_device(bootrom_mtd);
+		map_destroy(bootrom_mtd);
+		iounmap((void *)cdb89712_bootrom_map.map_priv_1);
+		release_resource (&cdb89712_bootrom_resource);
+	}
+}
+
+module_init(init_cdb89712_maps);
+module_exit(cleanup_cdb89712_maps);
+
+MODULE_AUTHOR("Ray L");
+MODULE_DESCRIPTION("ARM CDB89712 map driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/cfi_flagadm.c linux/drivers/mtd/maps/cfi_flagadm.c
--- v2.4.10/linux/drivers/mtd/maps/cfi_flagadm.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/cfi_flagadm.c	Thu Oct  4 15:14:59 2001
@@ -1,7 +1,7 @@
 /*
  *  Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
  *
- *  $Id: cfi_flagadm.c,v 1.5 2001/05/29 15:47:49 kd Exp $
+ *  $Id: cfi_flagadm.c,v 1.7 2001/10/02 15:05:13 dwmw2 Exp $
  *  
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
@@ -137,11 +137,6 @@
 
 #define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition))
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_flagadm init_module
-#define cleanup_flagadm cleanup_module
-#endif
-
 static struct mtd_info *mymtd;
 
 int __init init_flagadm(void)
@@ -156,7 +151,7 @@
 		printk("Failed to ioremap\n");
 		return -EIO;
 	}
-	mymtd = do_map_probe("cfi", &flagadm_map);
+	mymtd = do_map_probe("cfi_probe", &flagadm_map);
 	if (mymtd) {
 		mymtd->module = THIS_MODULE;
 		add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT);
@@ -182,3 +177,8 @@
 
 module_init(init_flagadm);
 module_exit(cleanup_flagadm);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
+MODULE_DESCRIPTION("MTD map driver for Flaga digital module");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/cstm_mips_ixx.c linux/drivers/mtd/maps/cstm_mips_ixx.c
--- v2.4.10/linux/drivers/mtd/maps/cstm_mips_ixx.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/cstm_mips_ixx.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: cstm_mips_ixx.c,v 1.3 2001/06/02 14:52:23 dwmw2 Exp $
+ * $Id: cstm_mips_ixx.c,v 1.5 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
  * Config with both CFI and JEDEC device support.
@@ -207,11 +207,6 @@
 
 struct map_info cstm_mips_ixx_map[PHYSMAP_NUMBER];
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_cstm_mips_ixx init_module
-#define cleanup_cstm_mips_ixx cleanup_module
-#endif
-
 int __init init_cstm_mips_ixx(void)
 {
 	int i;
@@ -241,7 +236,7 @@
 	for (i=0;i<PHYSMAP_NUMBER;i++) {
                 parts = &cstm_mips_ixx_partitions[i][0];
 		jedec = 0;
-		mymtd = (struct mtd_info *)do_map_probe("cfi", &cstm_mips_ixx_map[i]);
+		mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &cstm_mips_ixx_map[i]);
 		//printk(KERN_NOTICE "phymap %d cfi_probe: mymtd is %x\n",i,(unsigned int)mymtd);
 		if (!mymtd) {
 			jedec = 1;
@@ -312,3 +307,8 @@
 
 module_init(init_cstm_mips_ixx);
 module_exit(cleanup_cstm_mips_ixx);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
+MODULE_DESCRIPTION("MTD map driver for ITE 8172G and Globespan IVR boards");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/dbox2-flash.c linux/drivers/mtd/maps/dbox2-flash.c
--- v2.4.10/linux/drivers/mtd/maps/dbox2-flash.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/dbox2-flash.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: dbox2-flash.c,v 1.2 2001/04/26 15:42:43 dwmw2 Exp $
+ * $Id: dbox2-flash.c,v 1.4 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * Nokia / Sagem D-Box 2 flash driver
  */
@@ -97,12 +97,7 @@
 	copy_to: dbox2_flash_copy_to
 };
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_dbox2_flash init_module
-#define cleanup_dbox2_flash cleanup_module
-#endif
-
-mod_init_t init_dbox2_flash(void)
+int __init init_dbox2_flash(void)
 {
        	printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR);
 	dbox2_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
@@ -113,12 +108,12 @@
 	}
 
 	// Probe for dual Intel 28F320 or dual AMD
-	mymtd = do_map_probe("cfi", &dbox2_flash_map);
+	mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
 	if (!mymtd) {
 	    // Probe for single Intel 28F640
 	    dbox2_flash_map.buswidth = 2;
 	
-	    mymtd = do_map_probe("cfi", &dbox2_flash_map);
+	    mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
 	}
 	    
 	if (mymtd) {
@@ -134,7 +129,7 @@
 	return -ENXIO;
 }
 
-mod_exit_t cleanup_dbox2_flash(void)
+static void __exit cleanup_dbox2_flash(void)
 {
 	if (mymtd) {
 		del_mtd_partitions(mymtd);
@@ -149,3 +144,7 @@
 module_init(init_dbox2_flash);
 module_exit(cleanup_dbox2_flash);
 
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
+MODULE_DESCRIPTION("MTD map driver for Nokia/Sagem D-Box 2 board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/dc21285.c linux/drivers/mtd/maps/dc21285.c
--- v2.4.10/linux/drivers/mtd/maps/dc21285.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/dc21285.c	Thu Oct  4 15:14:59 2001
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  * 
- * $Id: dc21285.c,v 1.4 2001/04/26 15:40:23 dwmw2 Exp $
+ * $Id: dc21285.c,v 1.6 2001/10/02 15:05:14 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -137,7 +137,7 @@
 		return -EIO;
 	}
 
-	mymtd = do_map_probe("cfi", &dc21285_map);
+	mymtd = do_map_probe("cfi_probe", &dc21285_map);
 	if (mymtd) {
 		int nrparts;
 
@@ -191,3 +191,8 @@
 
 module_init(init_dc21285);
 module_exit(cleanup_dc21285);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_DESCRIPTION("MTD map driver for DC21285 boards");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/elan-104nc.c linux/drivers/mtd/maps/elan-104nc.c
--- v2.4.10/linux/drivers/mtd/maps/elan-104nc.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/elan-104nc.c	Thu Oct  4 15:14:59 2001
@@ -16,7 +16,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
-   $Id: elan-104nc.c,v 1.10 2001/06/02 14:30:44 dwmw2 Exp $
+   $Id: elan-104nc.c,v 1.12 2001/10/02 15:05:14 dwmw2 Exp $
 
 The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
 mode.  This drivers uses the CFI probe and Intel Extended Command Set drivers.
@@ -213,12 +213,7 @@
 /* MTD device for all of the flash. */
 static struct mtd_info *all_mtd;
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_elan_104nc init_module
-#define cleanup_elan_104nc cleanup_module
-#endif
-
-mod_exit_t cleanup_elan_104nc(void)
+static void __exit cleanup_elan_104nc(void)
 {
 	if( all_mtd ) {
 		del_mtd_partitions( all_mtd );
@@ -229,7 +224,7 @@
 	release_region(PAGE_IO,PAGE_IO_SIZE);
 }
 
-mod_init_t init_elan_104nc(void)
+int __init init_elan_104nc(void)
 {
 	/* Urg! We use I/O port 0x22 without request_region()ing it */
 	/*
@@ -259,7 +254,7 @@
 	elan_104nc_setup();
 
 	/* Probe for chip. */
-	all_mtd = do_map_probe("cfi",  &elan_104nc_map );
+	all_mtd = do_map_probe("cfi_probe",  &elan_104nc_map );
 	if( !all_mtd ) {
 		cleanup_elan_104nc();
 		return -ENXIO;
@@ -275,3 +270,8 @@
 
 module_init(init_elan_104nc);
 module_exit(cleanup_elan_104nc);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arcom Control Systems Ltd.");
+MODULE_DESCRIPTION("MTD map driver for Arcom Control Systems ELAN-104NC");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/integrator-flash.c linux/drivers/mtd/maps/integrator-flash.c
--- v2.4.10/linux/drivers/mtd/maps/integrator-flash.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/integrator-flash.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,303 @@
+/*======================================================================
+
+    drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning
+  
+    Copyright (C) 2000 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
+  
+   This is access code for flashes using ARM's flash partitioning 
+   standards.
+
+   $Id: integrator-flash.c,v 1.6 2001/10/02 16:00:01 dwmw2 Exp $
+
+======================================================================*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+extern int parse_afs_partitions(struct mtd_info *, struct mtd_partition **);
+
+// board specific stuff - sorry, it should be in arch/arm/mach-*.
+#ifdef CONFIG_ARCH_INTEGRATOR
+
+#define FLASH_BASE	INTEGRATOR_FLASH_BASE
+#define FLASH_SIZE	INTEGRATOR_FLASH_SIZE
+
+#define FLASH_PART_SIZE 0x400000
+
+#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
+#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+#define EBI_CSR1	(IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET)
+#define EBI_LOCK	(IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET)
+
+/*
+ * Initialise the flash access systems:
+ *  - Disable VPP
+ *  - Assert WP
+ *  - Set write enable bit in EBI reg
+ */
+static void armflash_flash_init(void)
+{
+	unsigned int tmp;
+
+	__raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+
+	tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
+	__raw_writel(tmp, EBI_CSR1);
+
+	if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
+		__raw_writel(0xa05f, EBI_LOCK);
+		__raw_writel(tmp, EBI_CSR1);
+		__raw_writel(0, EBI_LOCK);
+	}
+}
+
+/*
+ * Shutdown the flash access systems:
+ *  - Disable VPP
+ *  - Assert WP
+ *  - Clear write enable bit in EBI reg
+ */
+static void armflash_flash_exit(void)
+{
+	unsigned int tmp;
+
+	__raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+
+	/*
+	 * Clear the write enable bit in system controller EBI register.
+	 */
+	tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
+	__raw_writel(tmp, EBI_CSR1);
+
+	if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
+		__raw_writel(0xa05f, EBI_LOCK);
+		__raw_writel(tmp, EBI_CSR1);
+		__raw_writel(0, EBI_LOCK);
+	}
+}
+
+static void armflash_flash_wp(int on)
+{
+	unsigned int reg;
+
+	if (on)
+		reg = SC_CTRLC;
+	else
+		reg = SC_CTRLS;
+
+	__raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg);
+}
+
+static void armflash_set_vpp(struct map_info *map, int on)
+{
+	unsigned int reg;
+
+	if (on)
+		reg = SC_CTRLS;
+	else
+		reg = SC_CTRLC;
+
+	__raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
+}
+#endif
+
+#ifdef CONFIG_ARCH_P720T
+
+#define FLASH_BASE		(0x04000000)
+#define FLASH_SIZE		(64*1024*1024)
+
+#define FLASH_PART_SIZE 	(4*1024*1024)
+#define FLASH_BLOCK_SIZE	(128*1024)
+
+static void armflash_flash_init(void)
+{
+}
+
+static void armflash_flash_exit(void)
+{
+}
+
+static void armflash_flash_wp(int on)
+{
+}
+
+static void armflash_set_vpp(struct map_info *map, int on)
+{
+}
+#endif
+
+static __u8 armflash_read8(struct map_info *map, unsigned long ofs)
+{
+	return readb(ofs + map->map_priv_2);
+}
+
+static __u16 armflash_read16(struct map_info *map, unsigned long ofs)
+{
+	return readw(ofs + map->map_priv_2);
+}
+
+static __u32 armflash_read32(struct map_info *map, unsigned long ofs)
+{
+	return readl(ofs + map->map_priv_2);
+}
+
+static void armflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *) (from + map->map_priv_2), len);
+}
+
+static void armflash_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	writeb(d, adr + map->map_priv_2);
+}
+
+static void armflash_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	writew(d, adr + map->map_priv_2);
+}
+
+static void armflash_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	writel(d, adr + map->map_priv_2);
+}
+
+static void armflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy((void *) (to + map->map_priv_2), from, len);
+}
+
+static struct map_info armflash_map =
+{
+	name:		"AFS",
+	read8:		armflash_read8,
+	read16:		armflash_read16,
+	read32:		armflash_read32,
+	copy_from:	armflash_copy_from,
+	write8:		armflash_write8,
+	write16:	armflash_write16,
+	write32:	armflash_write32,
+	copy_to:	armflash_copy_to,
+	set_vpp:	armflash_set_vpp,
+};
+
+static struct mtd_info *mtd;
+
+static int __init armflash_cfi_init(void *base, u_int size)
+{
+	struct mtd_partition *parts;
+	int ret;
+
+	armflash_flash_init();
+	armflash_flash_wp(1);
+
+	/*
+	 * look for CFI based flash parts fitted to this board
+	 */
+	armflash_map.size       = size;
+	armflash_map.buswidth   = 4;
+	armflash_map.map_priv_2 = (unsigned long) base;
+
+	/*
+	 * Also, the CFI layer automatically works out what size
+	 * of chips we have, and does the necessary identification
+	 * for us automatically.
+	 */
+	mtd = do_map_probe("cfi_probe", &armflash_map);
+	if (!mtd)
+		return -ENXIO;
+
+	mtd->module = THIS_MODULE;
+
+	ret = parse_afs_partitions(mtd, &parts);
+	if (ret > 0) {
+		ret = add_mtd_partitions(mtd, parts, ret);
+		/* we don't need the partition info any longer */
+		kfree(parts);
+		if (ret)
+			printk(KERN_ERR "mtd partition registration "
+				"failed: %d\n", ret);
+	}
+
+	/*
+	 * If we got an error, free all resources.
+	 */
+	if (ret < 0) {
+		del_mtd_partitions(mtd);
+		map_destroy(mtd);
+	}
+
+	return ret;
+}
+
+static void armflash_cfi_exit(void)
+{
+	if (mtd) {
+		del_mtd_partitions(mtd);
+		map_destroy(mtd);
+	}
+}
+
+static int __init armflash_init(void)
+{
+	int err = -EBUSY;
+	void *base;
+
+	if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL)
+		goto out;
+
+	base = ioremap(FLASH_BASE, FLASH_SIZE);
+	err = -ENOMEM;
+	if (base == NULL)
+		goto release;
+
+	err = armflash_cfi_init(base, FLASH_SIZE);
+	if (err) {
+		iounmap(base);
+release:
+		release_mem_region(FLASH_BASE, FLASH_SIZE);
+	}
+out:
+	return err;
+}
+
+static void __exit armflash_exit(void)
+{
+	armflash_cfi_exit();
+	iounmap((void *)armflash_map.map_priv_2);
+	release_mem_region(FLASH_BASE, FLASH_SIZE);
+	armflash_flash_exit();
+}
+
+module_init(armflash_init);
+module_exit(armflash_exit);
+
+MODULE_AUTHOR("ARM Ltd");
+MODULE_DESCRIPTION("ARM Integrator CFI map driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/iq80310.c linux/drivers/mtd/maps/iq80310.c
--- v2.4.10/linux/drivers/mtd/maps/iq80310.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/iq80310.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: iq80310.c,v 1.3 2001/04/26 15:40:23 dwmw2 Exp $
+ * $Id: iq80310.c,v 1.8 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * Mapping for the Intel XScale IQ80310 evaluation board
  *
@@ -80,40 +80,75 @@
 	copy_to:	iq80310_copy_to
 };
 
-static struct mtd_partition iq80310_partitions[3] = {
+static struct mtd_partition iq80310_partitions[4] = {
 	{
-		name:		"firmware",
+		name:		"Firmware",
 		size:		0x00080000,
 		offset:		0,
 		mask_flags:	MTD_WRITEABLE  /* force read-only */
 	},{
-		name:		"kernel",
-		size:		0x00080000,
+		name:		"Kernel",
+		size:		0x000a0000,
 		offset:		0x00080000,
 	},{
-		name:		"filesystem",
-		size:		0x00700000,
-		offset:		0x00100000
+		name:		"Filesystem",
+		size:		0x00600000,
+		offset:		0x00120000
+	},{
+		name:		"RedBoot",
+		size:		0x000e0000,
+		offset:		0x00720000,
+		mask_flags:	MTD_WRITEABLE
 	}
 };
 
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_info *mymtd;
+static struct mtd_partition *parsed_parts;
+
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+
 static int __init init_iq80310(void)
 {
-	iq80310_map.map_priv_1 = (unsigned long)__ioremap(WINDOW_ADDR, WINDOW_SIZE, 0);
+	struct mtd_partition *parts;
+	int nb_parts = 0;
+	int parsed_nr_parts = 0;
+	char *part_type = "static";
 
+	iq80310_map.map_priv_1 = (unsigned long)__ioremap(WINDOW_ADDR, WINDOW_SIZE, 0);
 	if (!iq80310_map.map_priv_1) {
 		printk("Failed to ioremap\n");
 		return -EIO;
 	}
-	mymtd = do_map_probe("cfi", &iq80310_map);
-	if (mymtd) {
-		mymtd->module = THIS_MODULE;
-		add_mtd_partitions(mymtd, iq80310_partitions, 3);
-		return 0;
+	mymtd = do_map_probe("cfi_probe", &iq80310_map);
+	if (!mymtd) {
+		iounmap((void *)iq80310_map.map_priv_1);
+		return -ENXIO;
+	}
+	mymtd->module = THIS_MODULE;
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+	if (parsed_nr_parts == 0) {
+		int ret = parse_redboot_partitions(mymtd, &parsed_parts);
+
+		if (ret > 0) {
+			part_type = "RedBoot";
+			parsed_nr_parts = ret;
+		}
 	}
+#endif
 
-	iounmap((void *)iq80310_map.map_priv_1);
-	return -ENXIO;
+	if (parsed_nr_parts > 0) {
+		parts = parsed_parts;
+		nb_parts = parsed_nr_parts;
+	} else {
+		parts = iq80310_partitions;
+		nb_parts = NB_OF(iq80310_partitions);
+	}
+	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+	add_mtd_partitions(mymtd, parts, nb_parts);
+	return 0;
 }
 
 static void __exit cleanup_iq80310(void)
@@ -121,13 +156,18 @@
 	if (mymtd) {
 		del_mtd_partitions(mymtd);
 		map_destroy(mymtd);
+		if (parsed_parts)
+			kfree(parsed_parts);
 	}
-	if (iq80310_map.map_priv_1) {
+	if (iq80310_map.map_priv_1)
 		iounmap((void *)iq80310_map.map_priv_1);
-		iq80310_map.map_priv_1 = 0;
-	}
+	return 0;
 }
 
 module_init(init_iq80310);
 module_exit(cleanup_iq80310);
 
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_DESCRIPTION("MTD map driver for Intel XScale IQ80310 evaluation board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/l440gx.c linux/drivers/mtd/maps/l440gx.c
--- v2.4.10/linux/drivers/mtd/maps/l440gx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/l440gx.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,156 @@
+/*
+ * $Id: l440gx.c,v 1.7 2001/10/02 15:05:14 dwmw2 Exp $
+ *
+ * BIOS Flash chip on Intel 440GX board.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/config.h>
+
+
+#define WINDOW_ADDR 0xfff00000
+#define WINDOW_SIZE 0x00100000
+#define BUSWIDTH 1
+
+#define IOBASE 0xc00
+#define TRIBUF_PORT (IOBASE+0x37)
+#define VPP_PORT (IOBASE+0x28)
+
+static struct mtd_info *mymtd;
+
+__u8 l440gx_read8(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readb(map->map_priv_1 + ofs);
+}
+
+__u16 l440gx_read16(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 l440gx_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void l440gx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+void l440gx_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void l440gx_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void l440gx_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void l440gx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+void l440gx_set_vpp(struct map_info *map, int vpp)
+{
+	unsigned long l;
+
+	l = inl(VPP_PORT);
+	l = vpp?(l | 1):(l & ~1);
+	outl(l, VPP_PORT);
+}
+
+struct map_info l440gx_map = {
+	name: "L440GX BIOS",
+	size: WINDOW_SIZE,
+	buswidth: BUSWIDTH,
+	read8: l440gx_read8,
+	read16: l440gx_read16,
+	read32: l440gx_read32,
+	copy_from: l440gx_copy_from,
+	write8: l440gx_write8,
+	write16: l440gx_write16,
+	write32: l440gx_write32,
+	copy_to: l440gx_copy_to,
+	set_vpp: l440gx_set_vpp
+};
+
+static int __init init_l440gx(void)
+{
+	struct pci_dev *dev;
+	unsigned char b;
+	__u16 w;
+
+	dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
+			      NULL);
+
+	if (!dev) {
+		printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n");
+		return -ENODEV;
+	}
+
+
+	l440gx_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+	if (!l440gx_map.map_priv_1) {
+		printk("Failed to ioremap L440GX flash region\n");
+		return -ENOMEM;
+	}
+
+	/* Set XBCS# */
+	pci_read_config_word(dev, 0x4e, &w);
+	w |= 0x4;
+        pci_write_config_word(dev, 0x4e, w);
+
+	/* Enable the gate on the WE line */
+	b = inb(TRIBUF_PORT);
+	b |= 1;
+	outb(b, TRIBUF_PORT);
+	
+       	printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");
+
+	mymtd = do_map_probe("jedec", &l440gx_map);
+	if (!mymtd) {
+		printk(KERN_NOTICE "JEDEC probe on BIOS chip failed. Using ROM\n");
+		mymtd = do_map_probe("map_rom", &l440gx_map);
+	}
+	if (mymtd) {
+		mymtd->module = THIS_MODULE;
+
+		add_mtd_device(mymtd);
+		return 0;
+	}
+
+	iounmap((void *)l440gx_map.map_priv_1);
+	return -ENXIO;
+}
+
+static void __exit cleanup_l440gx(void)
+{
+	del_mtd_device(mymtd);
+	map_destroy(mymtd);
+	
+	iounmap((void *)l440gx_map.map_priv_1);
+}
+
+module_init(init_l440gx);
+module_exit(cleanup_l440gx);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("MTD map driver for BIOS chips on Intel L440GX motherboards");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/netsc520.c linux/drivers/mtd/maps/netsc520.c
--- v2.4.10/linux/drivers/mtd/maps/netsc520.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/netsc520.c	Thu Oct  4 15:14:59 2001
@@ -3,7 +3,7 @@
  * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
  *	based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
  *
- * $Id: netsc520.c,v 1.3 2001/06/02 14:52:23 dwmw2 Exp $
+ * $Id: netsc520.c,v 1.5 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -145,12 +145,6 @@
 
 static struct mtd_info *mymtd;
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_netsc520 init_module
-#define cleanup_netsc520 cleanup_module
-#endif
-
-
 static int __init init_netsc520(void)
 {
 	printk(KERN_NOTICE "NetSc520 flash device: %lx at %lx\n", netsc520_map.size, netsc520_map.map_priv_2);
@@ -160,11 +154,11 @@
 		printk("Failed to ioremap_nocache\n");
 		return -EIO;
 	}
-	mymtd = do_map_probe("cfi", &netsc520_map);
+	mymtd = do_map_probe("cfi_probe", &netsc520_map);
 	if(!mymtd)
-		mymtd = do_map_probe("ram", &netsc520_map);
+		mymtd = do_map_probe("map_ram", &netsc520_map);
 	if(!mymtd)
-		mymtd = do_map_probe("rom", &netsc520_map);
+		mymtd = do_map_probe("map_rom", &netsc520_map);
 
 	if (!mymtd) {
 		iounmap((void *)netsc520_map.map_priv_1);
@@ -190,3 +184,7 @@
 
 module_init(init_netsc520);
 module_exit(cleanup_netsc520);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@amd.com>");
+MODULE_DESCRIPTION("MTD map driver for AMD NetSc520 Demonstration Board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/nora.c linux/drivers/mtd/maps/nora.c
--- v2.4.10/linux/drivers/mtd/maps/nora.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/nora.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: nora.c,v 1.19 2001/04/26 15:40:23 dwmw2 Exp $
+ * $Id: nora.c,v 1.21 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * This is so simple I love it.
  */
@@ -167,17 +167,11 @@
 	}
 };
 
-
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_nora init_module
-#define cleanup_nora cleanup_module
-#endif
-
 int __init init_nora(void)
 {
        	printk(KERN_NOTICE "nora flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
 
-	mymtd = do_map_probe("cfi", &nora_map);
+	mymtd = do_map_probe("cfi_probe", &nora_map);
 	if (mymtd) {
 		mymtd->module = THIS_MODULE;
 		
@@ -204,3 +198,7 @@
 
 module_init(init_nora);
 module_exit(cleanup_nora);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>");
+MODULE_DESCRIPTION("MTD map driver for Nora board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/ocelot.c linux/drivers/mtd/maps/ocelot.c
--- v2.4.10/linux/drivers/mtd/maps/ocelot.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/ocelot.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: ocelot.c,v 1.4 2001/06/08 15:36:27 dwmw2 Exp $
+ * $Id: ocelot.c,v 1.6 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * Flash on Momenco Ocelot
  */
@@ -115,7 +115,7 @@
 	//	ocelot_nvram_map.map_priv_2 = ocelot_nvram_map.map_priv_1;
 
 	/* And do the RAM probe on it to get an MTD device */
-	nvram_mtd = do_map_probe("ram", &ocelot_nvram_map);
+	nvram_mtd = do_map_probe("map_ram", &ocelot_nvram_map);
 	if (!nvram_mtd) {
 		printk("NVRAM probe failed\n");
 		goto fail_1;
@@ -145,7 +145,7 @@
 	}
 	/* If that failed or the jumper's absent, pretend it's ROM */
 	if (!flash_mtd) {
-		flash_mtd = do_map_probe("rom", &ocelot_flash_map);
+		flash_mtd = do_map_probe("map_rom", &ocelot_flash_map);
 		/* If we're treating it as ROM, set the erase size */
 		if (flash_mtd)
 			flash_mtd->erasesize = 0x10000;
@@ -197,3 +197,6 @@
 module_init(init_ocelot_maps);
 module_exit(cleanup_ocelot_maps);
 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>");
+MODULE_DESCRIPTION("MTD map driver for Momenco Ocelot board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/octagon-5066.c linux/drivers/mtd/maps/octagon-5066.c
--- v2.4.10/linux/drivers/mtd/maps/octagon-5066.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/octagon-5066.c	Thu Oct  4 15:14:59 2001
@@ -1,4 +1,4 @@
-// $Id: octagon-5066.c,v 1.17 2001/06/02 14:30:44 dwmw2 Exp $
+// $Id: octagon-5066.c,v 1.19 2001/10/02 15:05:14 dwmw2 Exp $
 /* ######################################################################
 
    Octagon 5066 MTD Driver. 
@@ -213,11 +213,6 @@
    return 0;
 }
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_oct5066 init_module
-#define cleanup_oct5066 cleanup_module
-#endif
-
 void cleanup_oct5066(void)
 {
 	int i;
@@ -260,13 +255,13 @@
 	       WINDOW_START+WINDOW_LENGTH);
 	
 	for (i=0; i<2; i++) {
-		oct5066_mtd[i] = do_map_probe("cfi", &oct5066_map[i]);
+		oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]);
 		if (!oct5066_mtd[i])
 			oct5066_mtd[i] = do_map_probe("jedec", &oct5066_map[i]);
 		if (!oct5066_mtd[i])
-			oct5066_mtd[i] = do_map_probe("ram", &oct5066_map[i]);
+			oct5066_mtd[i] = do_map_probe("map_ram", &oct5066_map[i]);
 		if (!oct5066_mtd[i])
-			oct5066_mtd[i] = do_map_probe("rom", &oct5066_map[i]);
+			oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]);
 		if (oct5066_mtd[i]) {
 			oct5066_mtd[i]->module = THIS_MODULE;
 			add_mtd_device(oct5066_mtd[i]);
@@ -283,3 +278,7 @@
 
 module_init(init_oct5066);
 module_exit(cleanup_oct5066);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jason Gunthorpe <jgg@deltatee.com>, David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("MTD map driver for Octagon 5066 Single Board Computer");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/physmap.c linux/drivers/mtd/maps/physmap.c
--- v2.4.10/linux/drivers/mtd/maps/physmap.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/physmap.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: physmap.c,v 1.13 2001/06/10 00:14:55 dwmw2 Exp $
+ * $Id: physmap.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * Normal mappings of chips in physical memory
  */
@@ -76,11 +76,6 @@
 	copy_to: physmap_copy_to
 };
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_physmap init_module
-#define cleanup_physmap cleanup_module
-#endif
-
 int __init init_physmap(void)
 {
        	printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
@@ -90,7 +85,7 @@
 		printk("Failed to ioremap\n");
 		return -EIO;
 	}
-	mymtd = do_map_probe("cfi", &physmap_map);
+	mymtd = do_map_probe("cfi_probe", &physmap_map);
 	if (mymtd) {
 		mymtd->module = THIS_MODULE;
 
@@ -117,3 +112,7 @@
 module_init(init_physmap);
 module_exit(cleanup_physmap);
 
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("Generic configurable MTD map driver");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/pnc2000.c linux/drivers/mtd/maps/pnc2000.c
--- v2.4.10/linux/drivers/mtd/maps/pnc2000.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/pnc2000.c	Thu Oct  4 15:14:59 2001
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  *
- * $Id: pnc2000.c,v 1.8 2001/06/10 00:09:45 dwmw2 Exp $
+ * $Id: pnc2000.c,v 1.10 2001/10/02 15:05:14 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -106,16 +106,11 @@
  */
 static struct mtd_info *mymtd;
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_pnc2000 init_module
-#define cleanup_pnc2000 cleanup_module
-#endif
-
 int __init init_pnc2000(void)
 {
 	printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
 
-	mymtd = do_map_probe("cfi", &pnc_map);
+	mymtd = do_map_probe("cfi_probe", &pnc_map);
 	if (mymtd) {
 		mymtd->module = THIS_MODULE;
 		return add_mtd_partitions(mymtd, pnc_partitions, 3);
@@ -134,3 +129,7 @@
 
 module_init(init_pnc2000);
 module_exit(cleanup_pnc2000);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp>");
+MODULE_DESCRIPTION("MTD map driver for Photron PNC-2000 board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/rpxlite.c linux/drivers/mtd/maps/rpxlite.c
--- v2.4.10/linux/drivers/mtd/maps/rpxlite.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/rpxlite.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: rpxlite.c,v 1.12 2001/04/26 15:40:23 dwmw2 Exp $
+ * $Id: rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * Handle mapping of the flash on the RPX Lite and CLLF boards
  */
@@ -19,17 +19,17 @@
 
 __u8 rpxlite_read8(struct map_info *map, unsigned long ofs)
 {
-	return readb(map->map_priv_1 + ofs);
+	return __raw_readb(map->map_priv_1 + ofs);
 }
 
 __u16 rpxlite_read16(struct map_info *map, unsigned long ofs)
 {
-	return readw(map->map_priv_1 + ofs);
+	return __raw_readw(map->map_priv_1 + ofs);
 }
 
 __u32 rpxlite_read32(struct map_info *map, unsigned long ofs)
 {
-	return readl(map->map_priv_1 + ofs);
+	return __raw_readl(map->map_priv_1 + ofs);
 }
 
 void rpxlite_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
@@ -39,17 +39,20 @@
 
 void rpxlite_write8(struct map_info *map, __u8 d, unsigned long adr)
 {
-	writeb(d, map->map_priv_1 + adr);
+	__raw_writeb(d, map->map_priv_1 + adr);
+	mb();
 }
 
 void rpxlite_write16(struct map_info *map, __u16 d, unsigned long adr)
 {
-	writew(d, map->map_priv_1 + adr);
+	__raw_writew(d, map->map_priv_1 + adr);
+	mb();
 }
 
 void rpxlite_write32(struct map_info *map, __u32 d, unsigned long adr)
 {
-	writel(d, map->map_priv_1 + adr);
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
 }
 
 void rpxlite_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
@@ -71,11 +74,6 @@
 	copy_to: rpxlite_copy_to
 };
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_rpxlite init_module
-#define cleanup_rpxlite cleanup_module
-#endif
-
 int __init init_rpxlite(void)
 {
 	printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
@@ -85,7 +83,7 @@
 		printk("Failed to ioremap\n");
 		return -EIO;
 	}
-	mymtd = do_map_probe("cfi", &rpxlite_map);
+	mymtd = do_map_probe("cfi_probe", &rpxlite_map);
 	if (mymtd) {
 		mymtd->module = THIS_MODULE;
 		add_mtd_device(mymtd);
@@ -110,3 +108,7 @@
 
 module_init(init_rpxlite);
 module_exit(cleanup_rpxlite);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arnold Christensen <AKC@pel.dk>");
+MODULE_DESCRIPTION("MTD map driver for RPX Lite and CLLF boards");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/sa1100-flash.c linux/drivers/mtd/maps/sa1100-flash.c
--- v2.4.10/linux/drivers/mtd/maps/sa1100-flash.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/sa1100-flash.c	Thu Oct  4 15:14:59 2001
@@ -3,7 +3,7 @@
  * 
  * (C) 2000 Nicolas Pitre <nico@cam.org>
  * 
- * $Id: sa1100-flash.c,v 1.15 2001/06/02 18:29:22 nico Exp $
+ * $Id: sa1100-flash.c,v 1.22 2001/10/02 10:04:52 rmk Exp $
  */
 
 #include <linux/config.h>
@@ -16,6 +16,7 @@
 #include <linux/mtd/partitions.h>
 
 #include <asm/hardware.h>
+#include <asm/io.h>
 
 
 #ifndef CONFIG_ARCH_SA1100
@@ -27,53 +28,53 @@
 
 static __u8 sa1100_read8(struct map_info *map, unsigned long ofs)
 {
-	return *(__u8 *)(WINDOW_ADDR + ofs);
+	return readb(map->map_priv_1 + ofs);
 }
 
 static __u16 sa1100_read16(struct map_info *map, unsigned long ofs)
 {
-	return *(__u16 *)(WINDOW_ADDR + ofs);
+	return readw(map->map_priv_1 + ofs);
 }
 
 static __u32 sa1100_read32(struct map_info *map, unsigned long ofs)
 {
-	return *(__u32 *)(WINDOW_ADDR + ofs);
+	return readl(map->map_priv_1 + ofs);
 }
 
 static void sa1100_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
 {
-	memcpy(to, (void *)(WINDOW_ADDR + from), len);
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
 }
 
 static void sa1100_write8(struct map_info *map, __u8 d, unsigned long adr)
 {
-	*(__u8 *)(WINDOW_ADDR + adr) = d;
+	writeb(d, map->map_priv_1 + adr);
 }
 
 static void sa1100_write16(struct map_info *map, __u16 d, unsigned long adr)
 {
-	*(__u16 *)(WINDOW_ADDR + adr) = d;
+	writew(d, map->map_priv_1 + adr);
 }
 
 static void sa1100_write32(struct map_info *map, __u32 d, unsigned long adr)
 {
-	*(__u32 *)(WINDOW_ADDR + adr) = d;
+	writel(d, map->map_priv_1 + adr);
 }
 
 static void sa1100_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
 {
-	memcpy((void *)(WINDOW_ADDR + to), from, len);
+	memcpy((void *)(map->map_priv_1 + to), from, len);
 }
 
 
-#ifdef CONFIG_SA1100_BITSY
+#ifdef CONFIG_SA1100_H3600
 
-static void bitsy_set_vpp(struct map_info *map, int vpp)
+static void h3600_set_vpp(struct map_info *map, int vpp)
 {
 	if (vpp)
-		set_bitsy_egpio(EGPIO_BITSY_VPP_ON);
+		set_h3600_egpio(EGPIO_H3600_VPP_ON);
 	else
-		clr_bitsy_egpio(EGPIO_BITSY_VPP_ON);
+		clr_h3600_egpio(EGPIO_H3600_VPP_ON);
 }
 
 #endif
@@ -100,7 +101,9 @@
 	write8:		sa1100_write8,
 	write16:	sa1100_write16,
 	write32:	sa1100_write32,
-	copy_to:	sa1100_copy_to
+	copy_to:	sa1100_copy_to,
+
+	map_priv_1:	WINDOW_ADDR,
 };
 
 
@@ -231,42 +234,42 @@
 #endif /* CONFIG_SA1100_HUW_WEBPANEL */
 
 
-#ifdef CONFIG_SA1100_BITSY
+#ifdef CONFIG_SA1100_H3600
 
-static unsigned long bitsy_max_flash_size = 0x02000000;
-static struct mtd_partition bitsy_partitions[] = {
+static unsigned long h3600_max_flash_size = 0x02000000;
+static struct mtd_partition h3600_partitions[] = {
 	{
-		name: "BITSY boot firmware",
+		name: "H3600 boot firmware",
 		size: 0x00040000,
 		offset: 0,
 		mask_flags: MTD_WRITEABLE  /* force read-only */
 	},{
-		name: "BITSY kernel",
+		name: "H3600 kernel",
 		size: 0x00080000,
 		offset: 0x40000
 	},{
-		name: "BITSY params",
+		name: "H3600 params",
 		size: 0x00040000,
 		offset: 0xC0000
 	},{
 #ifdef CONFIG_JFFS2_FS
-		name: "BITSY root jffs2",
+		name: "H3600 root jffs2",
 		offset: 0x00100000,
 		size: MTDPART_SIZ_FULL
 #else
-		name: "BITSY initrd",
+		name: "H3600 initrd",
 		size: 0x00100000,
 		offset: 0x00100000
 	},{
-		name: "BITSY root cramfs",
+		name: "H3600 root cramfs",
 		size: 0x00300000,
 		offset: 0x00200000
 	},{
-		name: "BITSY usr cramfs",
+		name: "H3600 usr cramfs",
 		size: 0x00800000,
 		offset: 0x00500000
 	},{
-		name: "BITSY usr local",
+		name: "H3600 usr local",
 		offset: 0x00d00000,
 		size: MTDPART_SIZ_FULL
 #endif
@@ -333,7 +336,7 @@
 static unsigned long graphicsclient_max_flash_size = 0x01000000;
 static struct mtd_partition graphicsclient_partitions[] = {
 	{ 
-	 name: "Bootloader + zImage",
+	 name: "zImage",
 	 offset: 0,
 	 size: 0x100000
 	},
@@ -351,13 +354,25 @@
 
 #endif
 
-#ifdef CONFIG_SA1100_LART
+#ifdef CONFIG_SA1100_GRAPHICSMASTER
 
-static unsigned long lart_max_flash_size = 0x00400000;
-static struct mtd_partition lart_partitions[] = {
-	{ offset: 0,			size: 0x020000 		},
-	{ offset: MTDPART_OFS_APPEND,	size: 0x0e0000 		},
-	{ offset: MTDPART_OFS_APPEND,	size: MTDPART_SIZ_FULL 	}
+static unsigned long graphicsmaster_max_flash_size = 0x01000000;
+static struct mtd_partition graphicsmaster_partitions[] = {
+	{ 
+	 name: "zImage",
+	 offset: 0,
+	 size: 0x100000
+	},
+	{ 
+         name: "ramdisk.gz",
+         offset: MTDPART_OFS_APPEND,
+         size: 0x300000 		
+	},
+	{ 
+	  name: "User FS",
+          offset: MTDPART_OFS_APPEND,	
+          size: MTDPART_SIZ_FULL
+	}
 };
 
 #endif
@@ -380,7 +395,7 @@
 	{
 	  name: "initrd",
 	  offset: 0x00180000,
-	  size: 0x00200000,
+	  size: 0x00280000,
 	},
 	{
 	  name: "initrd-test",
@@ -469,6 +484,50 @@
 
 #endif
 
+#ifdef CONFIG_SA1100_STORK
+
+static unsigned long stork_max_flash_size = 0x02000000;
+static struct mtd_partition stork_partitions[] = {
+	{
+		name: "STORK boot firmware",
+		size: 0x00040000,
+		offset: 0,
+		mask_flags: MTD_WRITEABLE  /* force read-only */
+	},{
+		name: "STORK params",
+		size: 0x00040000,
+		offset: 0x40000
+	},{
+		name: "STORK kernel",
+		size: 0x00100000,
+		offset: 0x80000
+	},{
+#ifdef CONFIG_JFFS2_FS
+		name: "STORK root jffs2",
+		offset: 0x00180000,
+		size: MTDPART_SIZ_FULL
+#else
+		name: "STORK initrd",
+		size: 0x00100000,
+		offset: 0x00180000
+	},{
+		name: "STORK root cramfs",
+		size: 0x00300000,
+		offset: 0x00280000
+	},{
+		name: "STORK usr cramfs",
+		size: 0x00800000,
+		offset: 0x00580000
+	},{
+		name: "STORK usr local",
+		offset: 0x00d80000,
+		size: MTDPART_SIZ_FULL
+#endif
+	}
+};
+
+#endif
+
 #define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
 
 
@@ -485,12 +544,8 @@
 	int parsed_nr_parts = 0;
 	char *part_type;
 	
+	/* Default flash buswidth */
 	sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4;
-	printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
-	mymtd = do_map_probe("cfi", &sa1100_map);
-	if (!mymtd)
-		return -ENXIO;
-	mymtd->module = THIS_MODULE;
 
 	/*
 	 * Static partition definition selection
@@ -512,12 +567,12 @@
 	}
 #endif
 
-#ifdef CONFIG_SA1100_BITSY
-	if (machine_is_bitsy()) {
-		parts = bitsy_partitions;
-		nb_parts = NB_OF(bitsy_partitions);
-		sa1100_map.size = bitsy_max_flash_size;
-		sa1100_map.set_vpp = bitsy_set_vpp;
+#ifdef CONFIG_SA1100_H3600
+	if (machine_is_h3600()) {
+		parts = h3600_partitions;
+		nb_parts = NB_OF(h3600_partitions);
+		sa1100_map.size = h3600_max_flash_size;
+		sa1100_map.set_vpp = h3600_set_vpp;
 	}
 #endif
 #ifdef CONFIG_SA1100_FREEBIRD
@@ -539,13 +594,15 @@
 		parts = graphicsclient_partitions;
 		nb_parts = NB_OF(graphicsclient_partitions);
 		sa1100_map.size = graphicsclient_max_flash_size;
+		sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
 	}
 #endif
-#ifdef CONFIG_SA1100_LART
-	if (machine_is_lart()) {
-		parts = lart_partitions;
-		nb_parts = NB_OF(lart_partitions);
-		sa1100_map.size = lart_max_flash_size;
+#ifdef CONFIG_SA1100_GRAPHICSMASTER
+	if (machine_is_graphicsmaster()) {
+		parts = graphicsmaster_partitions;
+		nb_parts = NB_OF(graphicsmaster_partitions);
+		sa1100_map.size = graphicsmaster_max_flash_size;
+		sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
 	}
 #endif
 #ifdef CONFIG_SA1100_PANGOLIN
@@ -584,18 +641,28 @@
 		sa1100_map.size = flexanet_max_flash_size;
 	}
 #endif
-
-
-	if (!nb_parts) {
-		printk(KERN_WARNING "MTD: no known flash definition for this SA1100 machine\n");
-		return -ENXIO;
+#ifdef CONFIG_SA1100_STORK
+	if (machine_is_stork()) {
+		parts = stork_partitions;
+		nb_parts = NB_OF(stork_partitions);
+		sa1100_map.size = stork_max_flash_size;
 	}
+#endif
 
+	/*
+	 * Now let's probe for the actual flash.  Do it here since
+	 * specific machine settings might have been set above.
+	 */
+	printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
+	mymtd = do_map_probe("cfi_probe", &sa1100_map);
+	if (!mymtd)
+		return -ENXIO;
+	mymtd->module = THIS_MODULE;
 
 	/*
 	 * Dynamic partition selection stuff (might override the static ones)
 	 */
-#ifdef CONFIG_MTD_SA1100_REDBOOT_PARTITIONS
+#ifdef CONFIG_MTD_REDBOOT_PARTS
 	if (parsed_nr_parts == 0) {
 		int ret = parse_redboot_partitions(mymtd, &parsed_parts);
 		
@@ -605,7 +672,7 @@
 		}
 	}
 #endif
-#ifdef CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS
+#ifdef CONFIG_MTD_BOOTLDR_PARTS
 	if (parsed_nr_parts == 0) {
 		int ret = parse_bootldr_partitions(mymtd, &parsed_parts);
 		if (ret > 0) {
@@ -642,3 +709,7 @@
 
 module_init(sa1100_mtd_init);
 module_exit(sa1100_mtd_cleanup);
+
+MODULE_AUTHOR("Nicolas Pitre");
+MODULE_DESCRIPTION("SA1100 CFI map driver");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/sbc_gxx.c linux/drivers/mtd/maps/sbc_gxx.c
--- v2.4.10/linux/drivers/mtd/maps/sbc_gxx.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/sbc_gxx.c	Thu Oct  4 15:14:59 2001
@@ -17,7 +17,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
-   $Id: sbc_gxx.c,v 1.17 2001/06/02 14:52:23 dwmw2 Exp $
+   $Id: sbc_gxx.c,v 1.19 2001/10/02 15:05:14 dwmw2 Exp $
 
 The SBC-MediaGX / SBC-GXx has up to 16 MiB of 
 Intel StrataFlash (28F320/28F640) in x8 mode.  
@@ -221,12 +221,7 @@
 /* MTD device for all of the flash. */
 static struct mtd_info *all_mtd;
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_sbc_gxx init_module
-#define cleanup_sbc_gxx cleanup_module
-#endif
-
-mod_exit_t cleanup_sbc_gxx(void)
+static void __exit cleanup_sbc_gxx(void)
 {
 	if( all_mtd ) {
 		del_mtd_partitions( all_mtd );
@@ -237,7 +232,7 @@
 	release_region(PAGE_IO,PAGE_IO_SIZE);
 }
 
-mod_init_t init_sbc_gxx(void)
+int __init init_sbc_gxx(void)
 {
 	if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
 		printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
@@ -260,7 +255,7 @@
 		WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
 
 	/* Probe for chip. */
-	all_mtd = do_map_probe( "cfi", &sbc_gxx_map );
+	all_mtd = do_map_probe( "cfi_probe", &sbc_gxx_map );
 	if( !all_mtd ) {
 		cleanup_sbc_gxx();
 		return -ENXIO;
@@ -276,3 +271,7 @@
 
 module_init(init_sbc_gxx);
 module_exit(cleanup_sbc_gxx);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arcom Control Systems Ltd.");
+MODULE_DESCRIPTION("MTD map driver for SBC-GXm and SBC-GX1 series boards");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/sc520cdp.c linux/drivers/mtd/maps/sc520cdp.c
--- v2.4.10/linux/drivers/mtd/maps/sc520cdp.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/sc520cdp.c	Thu Oct  4 15:14:59 2001
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  *
- * $Id: sc520cdp.c,v 1.7 2001/06/02 14:52:23 dwmw2 Exp $
+ * $Id: sc520cdp.c,v 1.9 2001/10/02 15:05:14 dwmw2 Exp $
  *
  *
  * The SC520CDP is an evaluation board for the Elan SC520 processor available
@@ -172,11 +172,6 @@
 
 static struct mtd_info *mymtd[NUM_FLASH_BANKS];
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_sc520cdp init_module
-#define cleanup_sc520cdp cleanup_module
-#endif
-
 #ifdef REPROGRAM_PAR
 
 /*
@@ -310,11 +305,11 @@
 			printk("Failed to ioremap_nocache\n");
 			return -EIO;
 		}
-		mymtd[i] = do_map_probe("cfi", &sc520cdp_map[i]);
+		mymtd[i] = do_map_probe("cfi_probe", &sc520cdp_map[i]);
 		if(!mymtd[i])
 			mymtd[i] = do_map_probe("jedec", &sc520cdp_map[i]);
 		if(!mymtd[i])
-			mymtd[i] = do_map_probe("rom", &sc520cdp_map[i]);
+			mymtd[i] = do_map_probe("map_rom", &sc520cdp_map[i]);
 
 		if (mymtd[i]) {
 			mymtd[i]->module = THIS_MODULE;
@@ -346,3 +341,7 @@
 
 module_init(init_sc520cdp);
 module_exit(cleanup_sc520cdp);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sysgo Real-Time Solutions GmbH");
+MODULE_DESCRIPTION("MTD map driver for AMD SC520 Customer Development Platform");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/solutionengine.c linux/drivers/mtd/maps/solutionengine.c
--- v2.4.10/linux/drivers/mtd/maps/solutionengine.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/solutionengine.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,123 @@
+/*
+ * $Id: solutionengine.c,v 1.3 2001/10/02 15:05:14 dwmw2 Exp $
+ *
+ * Flash and EPROM on Hitachi Solution Engine and similar boards.
+ *
+ * (C) 2001 Red Hat, Inc.
+ *
+ * GPL'd
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
+
+__u32 soleng_read32(struct map_info *map, unsigned long ofs)
+{
+	return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void soleng_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	__raw_writel(d, map->map_priv_1 + adr);
+	mb();
+}
+
+void soleng_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, map->map_priv_1 + from, len);
+}
+
+
+static struct mtd_info *flash_mtd;
+static struct mtd_info *eprom_mtd;
+
+static struct mtd_partition *parsed_parts;
+
+struct map_info soleng_eprom_map = {
+	name: "Solution Engine EPROM",
+	size: 0x400000,
+	buswidth: 4,
+	copy_from: soleng_copy_from,
+};
+
+struct map_info soleng_flash_map = {
+	name: "Solution Engine FLASH",
+	size: 0x400000,
+	buswidth: 4,
+	read32: soleng_read32,
+	copy_from: soleng_copy_from,
+	write32: soleng_write32,
+};
+
+static int __init init_soleng_maps(void)
+{
+	int nr_parts;
+
+	/* First probe at offset 0 */
+	soleng_flash_map.map_priv_1 = P2SEGADDR(0);
+	soleng_eprom_map.map_priv_1 = P1SEGADDR(0x400000);
+
+	printk(KERN_NOTICE "Probing for flash chips at 0x000000:\n");
+	flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
+	if (!flash_mtd) {
+		/* Not there. Try swapping */
+		printk(KERN_NOTICE "Probing for flash chips at 0x400000:\n");
+		soleng_flash_map.map_priv_1 = P2SEGADDR(0x400000);
+		soleng_eprom_map.map_priv_1 = P1SEGADDR(0);
+		flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
+		if (!flash_mtd) {
+			/* Eep. */
+			printk(KERN_NOTICE "Flash chips not detected at either possible location.\n");
+			return -ENXIO;
+		}
+	}
+	printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n",
+	       soleng_flash_map.map_priv_1 & 0x1fffffff,
+	       soleng_eprom_map.map_priv_1 & 0x1fffffff);
+	flash_mtd->module = THIS_MODULE;
+
+	eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map);
+	if (eprom_mtd) {
+		eprom_mtd->module = THIS_MODULE;
+		add_mtd_device(eprom_mtd);
+	}
+
+	nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
+
+	if (nr_parts)
+		add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
+	else
+		add_mtd_device(flash_mtd);
+
+	return 0;
+}
+
+static void __exit cleanup_soleng_maps(void)
+{
+	if (eprom_mtd) {
+		del_mtd_device(eprom_mtd);
+		map_destroy(eprom_mtd);
+	}
+
+	if (parsed_parts)
+		del_mtd_partitions(flash_mtd);
+	else
+		del_mtd_device(flash_mtd);
+	map_destroy(flash_mtd);
+}
+
+module_init(init_soleng_maps);
+module_exit(cleanup_soleng_maps);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("MTD map driver for Hitachi SolutionEngine (and similar) boards");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/sun_uflash.c linux/drivers/mtd/maps/sun_uflash.c
--- v2.4.10/linux/drivers/mtd/maps/sun_uflash.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/sun_uflash.c	Thu Oct  4 15:14:59 2001
@@ -1,4 +1,4 @@
-/* $Id: sun_uflash.c,v 1.2 2001/04/26 15:40:23 dwmw2 Exp $
+/* $Id: sun_uflash.c,v 1.4 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * sun_uflash - Driver implementation for user-programmable flash
  * present on many Sun Microsystems SME boardsets.
@@ -37,6 +37,8 @@
 	("User-programmable flash device on Sun Microsystems boardsets");
 MODULE_SUPPORTED_DEVICE
 	("userflash");
+MODULE_LICENSE
+	("GPL");
 
 static LIST_HEAD(device_list);
 struct uflash_dev {
@@ -154,7 +156,7 @@
 	}
 
 	/* MTD registration */
-	pdev->mtd = do_map_probe("cfi", &pdev->map);
+	pdev->mtd = do_map_probe("cfi_probe", &pdev->map);
 	if(0 == pdev->mtd) {
 		iounmap((void *)pdev->map.map_priv_1);
 		kfree(pdev->name);
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/tqm8xxl.c linux/drivers/mtd/maps/tqm8xxl.c
--- v2.4.10/linux/drivers/mtd/maps/tqm8xxl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/mtd/maps/tqm8xxl.c	Thu Oct  4 15:14:59 2001
@@ -0,0 +1,315 @@
+/*
+ * Handle mapping of the flash memory access routines 
+ * on TQM8xxL based devices.
+ *
+ * $Id: tqm8xxl.c,v 1.3 2001/10/02 15:05:14 dwmw2 Exp $
+ *
+ * based on rpxlite.c
+ *
+ * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
+ *
+ * This code is GPLed
+ * 
+ */
+
+/*
+ * According to TQM8xxL hardware manual, TQM8xxL series have
+ * following flash memory organisations:
+ *	| capacity |	| chip type |	| bank0 |	| bank1 |
+ *	    2MiB	   512Kx16	  2MiB		   0
+ *	    4MiB	   1Mx16	  4MiB		   0
+ *	    8MiB	   1Mx16	  4MiB		   4MiB
+ * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at 
+ * kernel configuration.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#define FLASH_ADDR 0x40000000
+#define FLASH_SIZE 0x00800000
+#define FLASH_BANK_MAX 4
+
+// trivial struct to describe partition information
+struct mtd_part_def
+{
+	int nums;
+	unsigned char *type;
+	struct mtd_partition* mtd_part;
+};
+
+//static struct mtd_info *mymtd;
+static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
+static struct map_info* map_banks[FLASH_BANK_MAX];
+static struct mtd_part_def part_banks[FLASH_BANK_MAX];
+static unsigned long num_banks;
+static unsigned long start_scan_addr;
+
+__u8 tqm8xxl_read8(struct map_info *map, unsigned long ofs)
+{
+	return *((__u8 *)(map->map_priv_1 + ofs));
+}
+
+__u16 tqm8xxl_read16(struct map_info *map, unsigned long ofs)
+{
+	return *((__u16 *)(map->map_priv_1 + ofs));
+}
+
+__u32 tqm8xxl_read32(struct map_info *map, unsigned long ofs)
+{
+	return *((__u32 *)(map->map_priv_1 + ofs));
+}
+
+void tqm8xxl_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+	memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+void tqm8xxl_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+	*((__u8 *)(map->map_priv_1 + adr)) = d;
+}
+
+void tqm8xxl_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+	*((__u16 *)( map->map_priv_1 + adr)) = d;
+}
+
+void tqm8xxl_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+	*((__u32 *)(map->map_priv_1 + adr)) = d;
+}
+
+void tqm8xxl_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+	memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+struct map_info tqm8xxl_map = {
+	name: "TQM8xxL",
+	//size: WINDOW_SIZE,
+	buswidth: 4,
+	read8: tqm8xxl_read8,
+	read16: tqm8xxl_read16,
+	read32: tqm8xxl_read32,
+	copy_from: tqm8xxl_copy_from,
+	write8: tqm8xxl_write8,
+	write16: tqm8xxl_write16,
+	write32: tqm8xxl_write32,
+	copy_to: tqm8xxl_copy_to
+};
+
+/*
+ * Here are partition information for all known TQM8xxL series devices.
+ * See include/linux/mtd/partitions.h for definition of the mtd_partition
+ * structure.
+ * 
+ * The *_max_flash_size is the maximum possible mapped flash size which
+ * is not necessarily the actual flash size.  It must correspond to the 
+ * value specified in the mapping definition defined by the
+ * "struct map_desc *_io_desc" for the corresponding machine.
+ */
+
+#ifdef CONFIG_MTD_PARTITIONS
+/* Currently, TQM8xxL has upto 8MiB flash */
+static unsigned long tqm8xxl_max_flash_size = 0x00800000;
+
+/* partition definition for first flash bank
+ * also ref. to "drivers\char\flash_config.c" 
+ */
+static struct mtd_partition tqm8xxl_partitions[] = {
+	{
+	  name: "ppcboot",
+	  offset: 0x00000000,
+	  size: 0x00020000,           /* 128KB           */
+	  mask_flags: MTD_WRITEABLE,  /* force read-only */
+	},
+	{
+	  name: "kernel",             /* default kernel image */
+	  offset: 0x00020000,
+	  size: 0x000e0000,
+	  mask_flags: MTD_WRITEABLE,  /* force read-only */
+	},
+	{
+	  name: "user",
+	  offset: 0x00100000,
+	  size: 0x00100000,
+	},
+	{
+	  name: "initrd",
+	  offset: 0x00200000,
+	  size: 0x00200000,
+	}
+};
+/* partition definition for second flahs bank */
+static struct mtd_partition tqm8xxl_fs_partitions[] = {
+	{
+	  name: "cramfs",
+	  offset: 0x00000000,
+	  size: 0x00200000,
+	},
+	{
+	  name: "jffs",
+	  offset: 0x00200000,
+	  size: 0x00200000,
+	  //size: MTDPART_SIZ_FULL,
+	}
+};
+#endif
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+int __init init_tqm_mtd(void)
+{
+	int idx = 0, ret = 0;
+	unsigned long flash_addr, flash_size, mtd_size = 0;
+	/* pointer to TQM8xxL board info data */
+	bd_t *bd = (bd_t *)__res;
+
+	flash_addr = bd->bi_flashstart;
+	flash_size = bd->bi_flashsize;
+	//request maximum flash size address spzce
+	start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
+	if (!start_scan_addr) {
+		//printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, FLASH_ADDR);
+		printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr);
+		return -EIO;
+	}
+	for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
+	{
+		if(mtd_size >= flash_size)
+			break;
+		
+		printk("%s: chip probing count %d\n", __FUNCTION__, idx);
+		
+		map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
+		if(map_banks[idx] == NULL)
+		{
+			//return -ENOMEM;
+			ret = -ENOMEM;
+			goto error_mem;
+		}
+		memset((void *)map_banks[idx], 0, sizeof(struct map_info));
+		map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
+		if(map_banks[idx]->name == NULL)
+		{
+			//return -ENOMEM;
+			ret = -ENOMEM;
+			goto error_mem;
+		}
+		memset((void *)map_banks[idx]->name, 0, 16);
+		
+		sprintf(map_banks[idx]->name, "TQM8xxL%d", idx);
+		map_banks[idx]->buswidth = 4;
+		map_banks[idx]->read8 = tqm8xxl_read8;
+		map_banks[idx]->read16 = tqm8xxl_read16;
+		map_banks[idx]->read32 = tqm8xxl_read32;
+		map_banks[idx]->copy_from = tqm8xxl_copy_from;
+		map_banks[idx]->write8 = tqm8xxl_write8;
+		map_banks[idx]->write16 = tqm8xxl_write16;
+		map_banks[idx]->write32 = tqm8xxl_write32;
+		map_banks[idx]->copy_to = tqm8xxl_copy_to;
+		map_banks[idx]->map_priv_1 = 
+		start_scan_addr + ((idx > 0) ? 
+		(mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
+		//start to probe flash chips
+		mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
+		if(mtd_banks[idx])
+		{
+			mtd_banks[idx]->module = THIS_MODULE;
+			mtd_size += mtd_banks[idx]->size;
+			num_banks++;
+			printk("%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, 
+			mtd_banks[idx]->name, mtd_banks[idx]->size);
+		}
+	}
+
+	/* no supported flash chips found */
+	if(!num_banks)
+	{
+		printk("TQM8xxL: No support flash chips found!\n");
+		ret = -ENXIO;
+		goto error_mem;
+	}
+
+#ifdef CONFIG_MTD_PARTITIONS
+	/*
+	 * Select Static partition definitions
+	 */
+	part_banks[0].mtd_part = tqm8xxl_partitions;
+	part_banks[0].type = "Static image";
+	part_banks[0].nums = NB_OF(tqm8xxl_partitions);
+	part_banks[1].mtd_part = tqm8xxl_fs_partitions;
+	part_banks[1].type = "Static file system";
+	part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions);
+	for(idx = 0; idx < num_banks ; idx++)
+	{
+		if (part_banks[idx].nums == 0) {
+			printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx);
+			add_mtd_device(mtd_banks[idx]);
+		} else {
+			printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
+					idx, part_banks[idx].type);
+			add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part, 
+								part_banks[idx].nums);
+		}
+	}
+#else
+	printk(KERN_NOTICE "TQM flash: registering %d whole flash banks at once\n", num_banks);
+	for(idx = 0 ; idx < num_banks ; idx++)
+		add_mtd_device(mtd_banks[idx]);
+#endif
+	return 0;
+error_mem:
+	for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
+	{
+		if(map_banks[idx] != NULL)
+		{
+			if(map_banks[idx]->name != NULL)
+			{
+				kfree(map_banks[idx]->name);
+				map_banks[idx]->name = NULL;
+			}
+			kfree(map_banks[idx]);
+			map_banks[idx] = NULL;
+		}
+	}
+	//return -ENOMEM;
+error:
+	iounmap((void *)start_scan_addr);
+	//return -ENXIO;
+	return ret;
+}
+
+static void __exit cleanup_tqm_mtd(void)
+{
+	unsigned int idx = 0;
+	for(idx = 0 ; idx < num_banks ; idx++)
+	{
+		/* destroy mtd_info previously allocated */
+		if (mtd_banks[idx]) {
+			del_mtd_partitions(mtd_banks[idx]);
+			map_destroy(mtd_banks[idx]);
+		}
+		/* release map_info not used anymore */
+		kfree(map_banks[idx]->name);
+		kfree(map_banks[idx]);
+	}
+	if (start_scan_addr) {
+		iounmap((void *)start_scan_addr);
+		start_scan_addr = 0;
+	}
+}
+
+module_init(init_tqm_mtd);
+module_exit(cleanup_tqm_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kirk Lee <kirk@hpc.ee.ntu.edu.tw>");
+MODULE_DESCRIPTION("MTD map driver for TQM8xxL boards");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/maps/vmax301.c linux/drivers/mtd/maps/vmax301.c
--- v2.4.10/linux/drivers/mtd/maps/vmax301.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/maps/vmax301.c	Thu Oct  4 15:14:59 2001
@@ -1,4 +1,4 @@
-// $Id: vmax301.c,v 1.22 2001/06/02 14:30:44 dwmw2 Exp $
+// $Id: vmax301.c,v 1.24 2001/10/02 15:05:14 dwmw2 Exp $
 /* ######################################################################
 
    Tempustech VMAX SBC301 MTD Driver.
@@ -175,11 +175,6 @@
 
 static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_vmax301 init_module
-#define cleanup_vmax301 cleanup_module
-#endif
-
 static void __exit cleanup_vmax301(void)
 {
 	int i;
@@ -215,13 +210,13 @@
 	vmax_map[1].map_priv_1 = iomapadr + (3*WINDOW_START);
 	
 	for (i=0; i<2; i++) {
-		vmax_mtd[i] = do_map_probe("cfi", &vmax_map[i]);
+		vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
 		if (!vmax_mtd[i])
 			vmax_mtd[i] = do_map_probe("jedec", &vmax_map[i]);
 		if (!vmax_mtd[i])
-			vmax_mtd[i] = do_map_probe("ram", &vmax_map[i]);
+			vmax_mtd[i] = do_map_probe("map_ram", &vmax_map[i]);
 		if (!vmax_mtd[i])
-			vmax_mtd[i] = do_map_probe("rom", &vmax_map[i]);
+			vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]);
 		if (vmax_mtd[i]) {
 			vmax_mtd[i]->module = THIS_MODULE;
 			add_mtd_device(vmax_mtd[i]);
@@ -238,3 +233,7 @@
 
 module_init(init_vmax301);
 module_exit(cleanup_vmax301);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("MTD map driver for Tempustech VMAX SBC301 board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
--- v2.4.10/linux/drivers/mtd/mtdblock.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/mtdblock.c	Thu Oct  4 15:14:59 2001
@@ -1,7 +1,7 @@
 /* 
  * Direct MTD block device access
  *
- * $Id: mtdblock.c,v 1.38 2000/11/27 08:50:22 dwmw2 Exp $
+ * $Id: mtdblock.c,v 1.47 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * 02-nov-2000	Nicolas Pitre		Added read-modify-write with cache
  */
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/compatmac.h>
 
 #define MAJOR_NR MTD_BLOCK_MAJOR
 #define DEVICE_NAME "mtdblock"
@@ -158,13 +159,16 @@
 			    int len, const char *buf)
 {
 	struct mtd_info *mtd = mtdblk->mtd;
-	unsigned int sect_size = mtd->erasesize;
+	unsigned int sect_size = mtdblk->cache_size;
 	size_t retlen;
 	int ret;
 
 	DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
 		mtd->name, pos, len);
 	
+	if (!sect_size)
+		return MTD_WRITE (mtd, pos, len, &retlen, buf);
+
 	while (len > 0) {
 		unsigned long sect_start = (pos/sect_size)*sect_size;
 		unsigned int offset = pos - sect_start;
@@ -224,13 +228,16 @@
 			   int len, char *buf)
 {
 	struct mtd_info *mtd = mtdblk->mtd;
-	unsigned int sect_size = mtd->erasesize;
+	unsigned int sect_size = mtdblk->cache_size;
 	size_t retlen;
 	int ret;
 
 	DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", 
 			mtd->name, pos, len);
 	
+	if (!sect_size)
+		return MTD_READ (mtd, pos, len, &retlen, buf);
+
 	while (len > 0) {
 		unsigned long sect_start = (pos/sect_size)*sect_size;
 		unsigned int offset = pos - sect_start;
@@ -268,6 +275,7 @@
 static int mtdblock_open(struct inode *inode, struct file *file)
 {
 	struct mtdblk_dev *mtdblk;
+	struct mtd_info *mtd;
 	int dev;
 
 	DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
@@ -278,6 +286,14 @@
 	dev = MINOR(inode->i_rdev);
 	if (dev >= MAX_MTD_DEVICES)
 		return -EINVAL;
+
+	mtd = get_mtd_device(NULL, dev);
+	if (!mtd)
+		return -ENODEV;
+	if (MTD_ABSENT == mtd->type) {
+		put_mtd_device(mtd);
+		return -ENODEV;
+	}
 	
 	MOD_INC_USE_COUNT;
 
@@ -299,28 +315,26 @@
 
 	mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
 	if (!mtdblk) {
+		put_mtd_device(mtd);
 		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
 	memset(mtdblk, 0, sizeof(*mtdblk));
 	mtdblk->count = 1;
-	mtdblk->mtd = get_mtd_device(NULL, dev);
-
-	if (!mtdblk->mtd) {
-		kfree(mtdblk);
-		MOD_DEC_USE_COUNT;
-		return -ENODEV;
-	}
+	mtdblk->mtd = mtd;
 
 	init_MUTEX (&mtdblk->cache_sem);
 	mtdblk->cache_state = STATE_EMPTY;
-	mtdblk->cache_size = mtdblk->mtd->erasesize;
-	mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
-	if (!mtdblk->cache_data) {
-		put_mtd_device(mtdblk->mtd);
-		kfree(mtdblk);
-		MOD_DEC_USE_COUNT;
-		return -ENOMEM;
+	if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
+	    mtdblk->mtd->erasesize) {
+		mtdblk->cache_size = mtdblk->mtd->erasesize;
+		mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
+		if (!mtdblk->cache_data) {
+			put_mtd_device(mtdblk->mtd);
+			kfree(mtdblk);
+			MOD_DEC_USE_COUNT;
+			return -ENOMEM;
+		}
 	}
 
 	/* OK, we've created a new one. Add it to the list. */
@@ -339,7 +353,8 @@
 
 	mtdblks[dev] = mtdblk;
 	mtd_sizes[dev] = mtdblk->mtd->size/1024;
-	mtd_blksizes[dev] = mtdblk->mtd->erasesize;
+	if (mtdblk->mtd->erasesize)
+		mtd_blksizes[dev] = mtdblk->mtd->erasesize;
 	if (mtd_blksizes[dev] > PAGE_SIZE)
 		mtd_blksizes[dev] = PAGE_SIZE;
 	set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
@@ -359,7 +374,7 @@
 
 	if (inode == NULL)
 		release_return(-ENODEV);
-   
+
 	invalidate_device(inode->i_rdev, 1);
 
 	dev = MINOR(inode->i_rdev);
@@ -454,13 +469,8 @@
 }
 
 static volatile int leaving = 0;
-#if LINUX_VERSION_CODE > 0x020300
 static DECLARE_MUTEX_LOCKED(thread_sem);
 static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
-#else
-static struct semaphore thread_sem = MUTEX_LOCKED;
-DECLARE_WAIT_QUEUE_HEAD(thr_wq);
-#endif
 
 int mtdblock_thread(void *dummy)
 {
@@ -578,7 +588,7 @@
 {
         char name[8];
 
-        if (!mtd)
+        if (!mtd || mtd->type == MTD_ABSENT)
                 return;
 
         sprintf(name, "%d", mtd->index);
@@ -590,18 +600,13 @@
 
 static void mtd_notify_remove(struct mtd_info* mtd)
 {
-        if (!mtd)
+        if (!mtd || mtd->type == MTD_ABSENT)
                 return;
 
         devfs_unregister(devfs_rw_handle[mtd->index]);
 }
 #endif
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_mtdblock init_module
-#define cleanup_mtdblock cleanup_module
-#endif
-
 int __init init_mtdblock(void)
 {
 	int i;
@@ -635,11 +640,7 @@
 	blksize_size[MAJOR_NR] = mtd_blksizes;
 	blk_size[MAJOR_NR] = mtd_sizes;
 	
-#if LINUX_VERSION_CODE < 0x20320
-	blk_dev[MAJOR_NR].request_fn = mtdblock_request;
-#else
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
-#endif
 	kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
 	return 0;
 }
@@ -656,14 +657,15 @@
 #else
 	unregister_blkdev(MAJOR_NR,DEVICE_NAME);
 #endif
-#if LINUX_VERSION_CODE < 0x20320
-	blk_dev[MAJOR_NR].request_fn = NULL;
-#else
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-#endif
 	blksize_size[MAJOR_NR] = NULL;
 	blk_size[MAJOR_NR] = NULL;
 }
 
 module_init(init_mtdblock);
 module_exit(cleanup_mtdblock);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org> et al.");
+MODULE_DESCRIPTION("Caching read/erase/writeback block device emulation access to MTD devices");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c
--- v2.4.10/linux/drivers/mtd/mtdblock_ro.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/mtdblock_ro.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdblock_ro.c,v 1.5 2001/06/10 01:41:53 dwmw2 Exp $
+ * $Id: mtdblock_ro.c,v 1.9 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * Read-only version of the mtdblock device, without the 
  * read/erase/modify/writeback stuff
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/compatmac.h>
 
 #define MAJOR_NR MTD_BLOCK_MAJOR
 #define DEVICE_NAME "mtdblock"
@@ -53,15 +54,16 @@
 	
 	dev = MINOR(inode->i_rdev);
 	
-	MOD_INC_USE_COUNT;
-
 	mtd = get_mtd_device(NULL, dev);
-
-	if (!mtd) {
-		MOD_DEC_USE_COUNT;
-		return -ENODEV;
+	if (!mtd)
+		return -EINVAL;
+	if (MTD_ABSENT == mtd->type) {
+		put_mtd_device(mtd);
+		return -EINVAL;
 	}
 
+	MOD_INC_USE_COUNT;
+
 	mtd_sizes[dev] = mtd->size>>9;
 
 	DEBUG(1, "ok\n");
@@ -248,11 +250,6 @@
 };
 #endif
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_mtdblock init_module
-#define cleanup_mtdblock cleanup_module
-#endif
-
 int __init init_mtdblock(void)
 {
 	int i;
@@ -272,18 +269,21 @@
 	blksize_size[MAJOR_NR] = NULL;
 	blk_size[MAJOR_NR] = mtd_sizes;
 	
-#if LINUX_VERSION_CODE < 0x20320
-	blk_dev[MAJOR_NR].request_fn = mtdblock_request;
-#else
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
-#endif
 	return 0;
 }
 
 static void __exit cleanup_mtdblock(void)
 {
 	unregister_blkdev(MAJOR_NR,DEVICE_NAME);
+	blksize_size[MAJOR_NR] = NULL;
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 }
 
 module_init(init_mtdblock);
 module_exit(cleanup_mtdblock);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
+MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
--- v2.4.10/linux/drivers/mtd/mtdchar.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/mtdchar.c	Thu Oct  4 15:14:59 2001
@@ -1,12 +1,11 @@
 /*
- * $Id: mtdchar.c,v 1.38.2.1 2001/06/09 17:31:16 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.44 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * Character-device access to raw MTD devices.
+ * Pure 2.4 version - compatibility cruft removed to mtdchar-compat.c
  *
  */
 
-
-#include <linux/mtd/compatmac.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -75,10 +74,15 @@
 		return -EACCES;
 
 	mtd = get_mtd_device(NULL, devnum);
-		
+	
 	if (!mtd)
 		return -ENODEV;
 	
+	if (MTD_ABSENT == mtd->type) {
+		put_mtd_device(mtd);
+		return -ENODEV;
+	}
+
 	file->private_data = mtd;
 		
 	/* You can't open it RW if it's not a writeable device */
@@ -92,8 +96,7 @@
 
 /*====================================================================*/
 
-static release_t mtd_close(struct inode *inode,
-				 struct file *file)
+static int mtd_close(struct inode *inode, struct file *file)
 {
 	struct mtd_info *mtd;
 
@@ -106,15 +109,9 @@
 	
 	put_mtd_device(mtd);
 
-	release_return(0);
+	return 0;
 } /* mtd_close */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-#define FILE_POS *ppos
-#else
-#define FILE_POS file->f_pos
-#endif
-
 /* FIXME: This _really_ needs to die. In 2.5, we should lock the
    userspace buffer down and use it directly with readv/writev.
 */
@@ -131,8 +128,8 @@
 	
 	DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
 
-	if (FILE_POS + count > mtd->size)
-		count = mtd->size - FILE_POS;
+	if (*ppos + count > mtd->size)
+		count = mtd->size - *ppos;
 
 	if (!count)
 		return 0;
@@ -149,9 +146,9 @@
 		if (!kbuf)
 			return -ENOMEM;
 		
-		ret = MTD_READ(mtd, FILE_POS, len, &retlen, kbuf);
+		ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
 		if (!ret) {
-			FILE_POS += retlen;
+			*ppos += retlen;
 			if (copy_to_user(buf, kbuf, retlen)) {
 			        kfree(kbuf);
 				return -EFAULT;
@@ -184,11 +181,11 @@
 
 	DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
 	
-	if (FILE_POS == mtd->size)
+	if (*ppos == mtd->size)
 		return -ENOSPC;
 	
-	if (FILE_POS + count > mtd->size)
-		count = mtd->size - FILE_POS;
+	if (*ppos + count > mtd->size)
+		count = mtd->size - *ppos;
 
 	if (!count)
 		return 0;
@@ -210,9 +207,9 @@
 			return -EFAULT;
 		}
 		
-	        ret = (*(mtd->write))(mtd, FILE_POS, len, &retlen, kbuf);
+	        ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
 		if (!ret) {
-			FILE_POS += retlen;
+			*ppos += retlen;
 			total_retlen += retlen;
 			count -= retlen;
 			buf += retlen;
@@ -318,15 +315,18 @@
 			  wq_head is no longer there when the
 			  callback routine tries to wake us up.
 			*/
-			current->state = TASK_UNINTERRUPTIBLE;
-			add_wait_queue(&waitq, &wait);
 			ret = mtd->erase(mtd, erase);
-			if (!ret)
-				schedule();
-			remove_wait_queue(&waitq, &wait);
-			current->state = TASK_RUNNING;
-			if (!ret)
-				ret = (erase->state == MTD_ERASE_FAILED);
+			if (!ret) {
+				set_current_state(TASK_UNINTERRUPTIBLE);
+				add_wait_queue(&waitq, &wait);
+				if (erase->state != MTD_ERASE_DONE &&
+				    erase->state != MTD_ERASE_FAILED)
+					schedule();
+				remove_wait_queue(&waitq, &wait);
+				set_current_state(TASK_RUNNING);
+
+				ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0;
+			}
 			kfree(erase);
 		}
 		break;
@@ -488,12 +488,7 @@
 }
 #endif
 
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_mtdchar init_module
-#define cleanup_mtdchar cleanup_module
-#endif
-
-mod_init_t init_mtdchar(void)
+static int __init init_mtdchar(void)
 {
 #ifdef CONFIG_DEVFS_FS
 	if (devfs_register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
@@ -518,7 +513,7 @@
 	return 0;
 }
 
-mod_exit_t cleanup_mtdchar(void)
+static void __exit cleanup_mtdchar(void)
 {
 #ifdef CONFIG_DEVFS_FS
 	unregister_mtd_user(&notifier);
@@ -531,3 +526,8 @@
 
 module_init(init_mtdchar);
 module_exit(cleanup_mtdchar);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("Direct character-device access to MTD devices");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/mtdcore.c linux/drivers/mtd/mtdcore.c
--- v2.4.10/linux/drivers/mtd/mtdcore.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/mtdcore.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdcore.c,v 1.30 2001/06/02 14:30:42 dwmw2 Exp $
+ * $Id: mtdcore.c,v 1.31 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * Core registration and callback routines for MTD
  * drivers and users.
@@ -317,12 +317,7 @@
 /*====================================================================*/
 /* Init code */
 
-#if  LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define init_mtd init_module
-#define cleanup_mtd cleanup_module
-#endif
-
-mod_init_t init_mtd(void)
+int __init init_mtd(void)
 {
 #ifdef CONFIG_PROC_FS
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
@@ -343,7 +338,7 @@
 	return 0;
 }
 
-mod_exit_t cleanup_mtd(void)
+static void __exit cleanup_mtd(void)
 {
 #ifdef CONFIG_PM
 	if (mtd_pm_dev) {
@@ -366,3 +361,6 @@
 module_exit(cleanup_mtd);
 
 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("Core MTD registration and access routines");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/mtdpart.c linux/drivers/mtd/mtdpart.c
--- v2.4.10/linux/drivers/mtd/mtdpart.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/mtdpart.c	Thu Oct  4 15:14:59 2001
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  *
- * $Id: mtdpart.c,v 1.21 2001/06/09 16:33:32 dwmw2 Exp $
+ * $Id: mtdpart.c,v 1.23 2001/10/02 15:05:11 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -203,7 +203,8 @@
 
 		slave->mtd.read = part_read;
 		slave->mtd.write = part_write;
-		slave->mtd.sync = part_sync;
+		if (master->sync)
+			slave->mtd.sync = part_sync;
 		if (!i && master->suspend && master->resume) {
 				slave->mtd.suspend = part_suspend;
 				slave->mtd.resume = part_resume;
@@ -287,3 +288,9 @@
 
 EXPORT_SYMBOL(add_mtd_partitions);
 EXPORT_SYMBOL(del_mtd_partitions);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_DESCRIPTION("Generic support for partitioning of MTD devices");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/nand/Config.in linux/drivers/mtd/nand/Config.in
--- v2.4.10/linux/drivers/mtd/nand/Config.in	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/nand/Config.in	Thu Oct  4 15:13:18 2001
@@ -1,6 +1,6 @@
 # drivers/mtd/nand/Config.in
 
-# $Id: Config.in,v 1.3 2001/07/03 17:50:56 sjhill Exp $
+# $Id: Config.in,v 1.4 2001/09/19 09:35:23 dwmw2 Exp $
 
 mainmenu_option next_comment
 
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/nand/Makefile linux/drivers/mtd/nand/Makefile
--- v2.4.10/linux/drivers/mtd/nand/Makefile	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/nand/Makefile	Thu Oct  4 15:13:18 2001
@@ -1,14 +1,16 @@
 #
 # linux/drivers/nand/Makefile
 #
-# $Id: Makefile,v 1.4 2001/06/28 10:49:45 dwmw2 Exp $
+# $Id: Makefile,v 1.5 2001/09/19 22:39:59 dwmw2 Exp $
 
 O_TARGET	:= nandlink.o
 
 export-objs	:= nand.o nand_ecc.o
 
-obj-$(CONFIG_MTD_NAND)		+= nand.o
-obj-$(CONFIG_MTD_NAND_ECC)	+= nand_ecc.o
+nandobjs-y			:= nand.o
+nandobjs-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o
+
+obj-$(CONFIG_MTD_NAND)		+= $(nandobjs-y)
 obj-$(CONFIG_MTD_NAND_SPIA)	+= spia.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/nand/nand.c linux/drivers/mtd/nand/nand.c
--- v2.4.10/linux/drivers/mtd/nand/nand.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/nand/nand.c	Thu Oct  4 15:14:59 2001
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
  *
- * $Id: nand.c,v 1.10 2001/03/20 07:26:01 dwmw2 Exp $
+ * $Id: nand.c,v 1.12 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -21,6 +21,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ids.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 
 #ifdef CONFIG_MTD_NAND_ECC
@@ -1367,3 +1368,7 @@
 }
 
 EXPORT_SYMBOL(nand_scan);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com");
+MODULE_DESCRIPTION("Generic NAND flash driver code");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/nand/spia.c linux/drivers/mtd/nand/spia.c
--- v2.4.10/linux/drivers/mtd/nand/spia.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/nand/spia.c	Thu Oct  4 15:14:59 2001
@@ -1,9 +1,9 @@
 /*
- *  drivers/mtd/spia.c
+ *  drivers/mtd/nand/spia.c
  *
  *  Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
  *
- * $Id: spia.c,v 1.11 2001/07/03 17:50:56 sjhill Exp $
+ * $Id: spia.c,v 1.12 2001/10/02 15:05:14 dwmw2 Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -46,10 +46,6 @@
 /*
  * Module stuff
  */
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-  #define spia_init init_module
-  #define spia_cleanup cleanup_module
-#endif
 
 static int spia_io_base = SPIA_IO_BASE;
 static int spia_fio_base = SPIA_FIO_BASE;
@@ -158,3 +154,7 @@
 }
 module_exit(spia_cleanup);
 #endif
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com");
+MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on SPIA board");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
--- v2.4.10/linux/drivers/mtd/nftlcore.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/mtd/nftlcore.c	Thu Oct  4 15:14:59 2001
@@ -1,7 +1,7 @@
 /* Linux driver for NAND Flash Translation Layer      */
 /* (c) 1999 Machine Vision Holdings, Inc.             */
 /* Author: David Woodhouse <dwmw2@infradead.org>      */
-/* $Id: nftlcore.c,v 1.73 2001/06/09 01:09:43 dwmw2 Exp $ */
+/* $Id: nftlcore.c,v 1.82 2001/10/02 15:05:11 dwmw2 Exp $ */
 
 /*
   The contents of this file are distributed under the GNU General
@@ -229,7 +229,7 @@
 	/* We're passed the number of the last EUN in the chain, to save us from
 	   having to look it up again */
 	u16 pot = nftl->LastFreeEUN;
-	int silly = -1;
+	int silly = nftl->nb_blocks;
 
 	/* Normally, we force a fold to happen before we run out of free blocks completely */
 	if (!desperate && nftl->numfreeEUNs < 2) {
@@ -330,8 +330,17 @@
 					       "in Virtual Unit Chain %d for block %d\n",
 					       thisVUC, block);
 				break;
-			case SECTOR_IGNORE:
 			case SECTOR_DELETED:
+				if (!BlockFreeFound[block])
+					BlockMap[block] = BLOCK_NIL;
+				else
+					printk(KERN_WARNING 
+					       "SECTOR_DELETED found after SECTOR_FREE "
+					       "in Virtual Unit Chain %d for block %d\n",
+					       thisVUC, block);
+				break;
+
+			case SECTOR_IGNORE:
 				break;
 			default:
 				printk("Unknown status for block %d in EUN %d: %x\n",
@@ -350,12 +359,15 @@
 
 	if (inplace) {
 		/* We're being asked to be a fold-in-place. Check
-		   that all blocks are either present or SECTOR_FREE
-		   in the target block. If not, we're going to have
-		   to fold out-of-place anyway.
+		   that all blocks which actually have data associated
+		   with them (i.e. BlockMap[block] != BLOCK_NIL) are 
+		   either already present or SECTOR_FREE in the target
+		   block. If not, we're going to have to fold out-of-place
+		   anyway.
 		*/
 		for (block = 0; block < nftl->EraseSize / 512 ; block++) {
 			if (BlockLastState[block] != SECTOR_FREE &&
+			    BlockMap[block] != BLOCK_NIL &&
 			    BlockMap[block] != targetEUN) {
 				DEBUG(MTD_DEBUG_LEVEL1, "Setting inplace to 0. VUC %d, "
 				      "block %d was %x lastEUN, "
@@ -497,7 +509,7 @@
 	u16 ChainLength = 0, thislen;
 	u16 chain, EUN;
 
-	for (chain = 0; chain < nftl->MediaHdr.FormattedSize / nftl->EraseSize; chain++) {
+	for (chain = 0; chain < le32_to_cpu(nftl->MediaHdr.FormattedSize) / nftl->EraseSize; chain++) {
 		EUN = nftl->EUNtable[chain];
 		thislen = 0;
 
@@ -796,7 +808,7 @@
 	case BLKGETSIZE64:
 		return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
                                 (u64 *)arg);
-		
+
 	case BLKFLSBUF:
 		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 		fsync_dev(inode->i_rdev);
@@ -1031,19 +1043,18 @@
 	remove:	NFTL_notify_remove
 };
 
-static int __init init_nftl(void)
+extern char nftlmountrev[];
+
+int __init init_nftl(void)
 {
 	int i;
 
-	printk(KERN_NOTICE
-	       "M-Systems NAND Flash Translation Layer driver. (C) 1999 MVHI\n");
 #ifdef PRERELEASE 
-	printk(KERN_INFO"$Id: nftlcore.c,v 1.73 2001/06/09 01:09:43 dwmw2 Exp $\n");
+	printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.82 $, nftlmount.c %s\n", nftlmountrev);
 #endif
 
 	if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
-		printk("unable to register NFTL block device on major %d\n",
-		       MAJOR_NR);
+		printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
 		return -EBUSY;
 	} else {
 		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
@@ -1074,3 +1085,7 @@
 
 module_init(init_nftl);
 module_exit(cleanup_nftl);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
+MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium");
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/nftlmount.c linux/drivers/mtd/nftlmount.c
--- v2.4.10/linux/drivers/mtd/nftlmount.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/nftlmount.c	Thu Oct  4 15:13:18 2001
@@ -4,7 +4,7 @@
  * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 
  * Copyright (C) 2000 Netgem S.A.
  *
- * $Id: nftlmount.c,v 1.17 2001/06/02 20:33:20 dwmw2 Exp $
+ * $Id: nftlmount.c,v 1.23 2001/09/19 21:42:32 dwmw2 Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,6 +39,8 @@
 
 #define SECTORSIZE 512
 
+char nftlmountrev[]="$Revision: 1.23 $";
+
 /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
  *	various device information of the NFTL partition and Bad Unit Table. Update
  *	the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
@@ -48,94 +50,152 @@
 {
 	struct nftl_uci1 h1;
 	struct nftl_oob oob;
-	unsigned int block, boot_record_count;
+	unsigned int block, boot_record_count = 0;
 	int retlen;
 	u8 buf[SECTORSIZE];
 	struct NFTLMediaHeader *mh = &nftl->MediaHdr;
+	unsigned int i;
 
 	nftl->MediaUnit = BLOCK_NIL;
 	nftl->SpareMediaUnit = BLOCK_NIL;
-	boot_record_count = 0;
 
 	/* search for a valid boot record */
 	for (block = 0; block < nftl->nb_blocks; block++) {
-		unsigned int erase_mark;
+		int ret;
+
+		/* Check for ANAND header first. Then can whinge if it's found but later
+		   checks fail */
+		if ((ret = MTD_READ(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) {
+			static int warncount = 5;
+
+			if (warncount) {
+				printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n",
+				       block * nftl->EraseSize, nftl->mtd->index, ret);
+				if (!--warncount)
+					printk(KERN_WARNING "Further failures for this block will not be printed\n");
+			}
+			continue;
+		}
 
-		/* read ANAND header. To be safer with BIOS, also use erase mark as discriminant */
-		if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-				8, &retlen, (char *)&h1) < 0)
+		if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
+			/* ANAND\0 not found. Continue */
+#if 0
+			printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", 
+			       block * nftl->EraseSize, nftl->mtd->index);
+#endif			
 			continue;
+		}
 
-		erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
-		if (erase_mark != ERASE_MARK) 
+		/* To be safer with BIOS, also use erase mark as discriminant */
+		if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
+				8, &retlen, (char *)&h1) < 0)) {
+			printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
+			       block * nftl->EraseSize, nftl->mtd->index, ret);
 			continue;
+		}
 
-		if (MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
-				&retlen, buf, (char *)&oob) < 0)
+#if 1 /* Some people seem to have devices without ECC or erase marks
+	 on the Media Header blocks. There are enough other sanity
+	 checks in here that we can probably do without it.
+      */
+		if (le16_to_cpu ((h1.EraseMark | h1.EraseMark1) != ERASE_MARK)) {
+			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
+			       block * nftl->EraseSize, nftl->mtd->index, 
+			       le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
 			continue;
+		}
 
+		/* Finally reread to check ECC */
+		if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
+				&retlen, buf, (char *)&oob) < 0)) {
+			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
+			       block * nftl->EraseSize, nftl->mtd->index, ret);
+			continue;
+		}
+
+		/* Paranoia. Check the ANAND header is still there after the ECC read */
+		if (memcmp(buf, "ANAND", 6)) {
+			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n",
+			       block * nftl->EraseSize, nftl->mtd->index);
+			printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n",
+			       buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+			continue;
+		}
+#endif
+			       
+		/* OK, we like it. */
+
+		if (boot_record_count) {
+			/* We've already processed one. So we just check if
+			   this one is the same as the first one we found */
+			if (memcmp(mh, buf, sizeof(struct NFTLMediaHeader))) {
+				printk(KERN_NOTICE "NFTL Media Headers at 0x%x and 0x%x disagree.\n",
+				       nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
+				/* if (debug) Print both side by side */
+				return -1;
+			}
+			if (boot_record_count == 1)
+				nftl->SpareMediaUnit = block;
+
+			boot_record_count++;
+			continue;
+		}
+
+		/* This is the first we've seen. Copy the media header structure into place */
 		memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
-		if (memcmp(mh->DataOrgID, "ANAND", 6) == 0) {
-			/* first boot record */
-			if (boot_record_count == 0) {
-				unsigned int i;
-				/* header found : read the bad block table data */
-				if (mh->UnitSizeFactor != 0xff) {
-					printk("Sorry, we don't support UnitSizeFactor "
-					       "of != 1 yet\n");
-					goto ReplUnitTable;
-				}
 
-				nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
-				if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
-					printk(KERN_NOTICE "Potential NFTL Media Header found, but sanity check failed:\n");
-					printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", 
-					       nftl->nb_boot_blocks, nftl->nb_blocks);
-					goto ReplUnitTable; /* small consistency check */
-				}
+		/* Do some sanity checks on it */
+		if (mh->UnitSizeFactor != 0xff) {
+			printk(KERN_NOTICE "Sorry, we don't support UnitSizeFactor "
+			       "of != 1 yet.\n");
+			return -1;
+		}
 
-				nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
-				if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
-					printk(KERN_NOTICE "Potential NFTL Media Header found, but sanity check failed:\n");
-					printk(KERN_NOTICE "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
-					       nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
-					goto ReplUnitTable; /* small consistency check */
-				}
-				/* FixMe: with bad blocks, the total size available is not FormattedSize any
-				   more !!! */
-				nftl->nr_sects  = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
-				nftl->MediaUnit = block;
-
-				/* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
-				for (i = 0; i < nftl->nb_blocks; i++) {
-					if ((i & (SECTORSIZE - 1)) == 0) {
-						/* read one sector for every SECTORSIZE of blocks */
-						if (MTD_READECC(nftl->mtd, block * nftl->EraseSize +
-								i + SECTORSIZE, SECTORSIZE,
-								&retlen, buf, (char *)&oob) < 0)
-							goto ReplUnitTable;
-					}
-					/* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
-					if (buf[i & (SECTORSIZE - 1)] != 0xff)
-						nftl->ReplUnitTable[i] = BLOCK_RESERVED;
-				}
+		nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
+		if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
+			printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
+			printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", 
+			       nftl->nb_boot_blocks, nftl->nb_blocks);
+			return -1;
+		}
 
-				boot_record_count++;
-			} else if (boot_record_count == 1) {
-				nftl->SpareMediaUnit = block;
-				boot_record_count++;
-				break;
+		nftl->numvunits = le32_to_cpu(mh->FormattedSize) / nftl->EraseSize;
+		if (nftl->numvunits > (nftl->nb_blocks - nftl->nb_boot_blocks - 2)) {
+			printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
+			printk(KERN_NOTICE "numvunits (%d) > nb_blocks (%d) - nb_boot_blocks(%d) - 2\n",
+			       nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
+			return -1;
+		}
+		
+		nftl->nr_sects  = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
+		
+		/* If we're not using the last sectors in the device for some reason,
+		   reduce nb_blocks accordingly so we forget they're there */
+		nftl->nb_blocks = le16_to_cpu(mh->NumEraseUnits) + le16_to_cpu(mh->FirstPhysicalEUN);
+
+		/* read the Bad Erase Unit Table and modify ReplUnitTable[] accordingly */
+		for (i = 0; i < nftl->nb_blocks; i++) {
+			if ((i & (SECTORSIZE - 1)) == 0) {
+				/* read one sector for every SECTORSIZE of blocks */
+				if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize +
+						       i + SECTORSIZE, SECTORSIZE,
+						       &retlen, buf, (char *)&oob)) < 0) {
+					printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
+					       ret);
+					return -1;
+				}
 			}
+			/* mark the Bad Erase Unit as RESERVED in ReplUnitTable */
+			if (buf[i & (SECTORSIZE - 1)] != 0xff)
+				nftl->ReplUnitTable[i] = BLOCK_RESERVED;
 		}
-	ReplUnitTable:;
-	}
-
-	if (boot_record_count == 0) {
-		/* no boot record found */
-		return -1;
-	} else {
-		return 0;
-	}
+		
+		nftl->MediaUnit = block;
+		boot_record_count++;
+		
+	} /* foreach (block) */
+		
+	return boot_record_count?0:-1;
 }
 
 static int memcmpb(void *a, int c, int n)
diff -u --recursive --new-file v2.4.10/linux/drivers/mtd/redboot.c linux/drivers/mtd/redboot.c
--- v2.4.10/linux/drivers/mtd/redboot.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/mtd/redboot.c	Thu Oct  4 15:14:59 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: redboot.c,v 1.4 2001/05/31 20:43:18 dwmw2 Exp $
+ * $Id: redboot.c,v 1.5 2001/10/02 15:05:11 dwmw2 Exp $
  *
  * Parse RedBoot-style Flash Image System (FIS) tables and
  * produce a Linux partition array to match.
@@ -148,3 +148,7 @@
 }
 
 EXPORT_SYMBOL(parse_redboot_partitions);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>");
+MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c501.c linux/drivers/net/3c501.c
--- v2.4.10/linux/drivers/net/3c501.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/3c501.c	Sun Sep 30 12:26:06 2001
@@ -980,6 +980,8 @@
 }
 
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c503.c linux/drivers/net/3c503.c
--- v2.4.10/linux/drivers/net/3c503.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/3c503.c	Sun Sep 30 12:26:06 2001
@@ -667,6 +667,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v2.4.10/linux/drivers/net/3c505.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/3c505.c	Sun Sep 30 12:26:06 2001
@@ -1673,3 +1673,4 @@
 }
 
 #endif				/* MODULE */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v2.4.10/linux/drivers/net/3c507.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/3c507.c	Sun Sep 30 12:26:08 2001
@@ -126,6 +126,7 @@
 	ushort tx_head;
 	ushort tx_cmd_link;
 	ushort tx_reap;
+	ushort tx_pkts_in_ring;
 	spinlock_t lock;
 };
 
@@ -194,7 +195,7 @@
 #define DUMP_DATA	0x56	/* A 170 byte buffer for dump and Set-MC into. */
 
 #define TX_BUF_START	0x0100
-#define NUM_TX_BUFS 	4
+#define NUM_TX_BUFS 	5
 #define TX_BUF_SIZE 	(1518+14+20+16) /* packet+header+TBD */
 
 #define RX_BUF_START	0x2000
@@ -463,6 +464,7 @@
 			printk ("Resetting board.\n");
 		/* Completely reset the adaptor. */
 		init_82586_mem (dev);
+		lp->tx_pkts_in_ring = 0;
 	} else {
 		/* Issue the channel attention signal and hope it "gets better". */
 		if (net_debug > 1)
@@ -538,30 +540,34 @@
 	outb(0x80, ioaddr + MISC_CTRL);
 
 	/* Reap the Tx packet buffers. */
-	while (lp->tx_reap != lp->tx_head) {
+	while (lp->tx_pkts_in_ring) {
 	  unsigned short tx_status = isa_readw(shmem+lp->tx_reap);
-
-	  if (tx_status == 0) {
-		if (net_debug > 5)  printk("Couldn't reap %#x.\n", lp->tx_reap);
+	  if (!(tx_status & 0x8000)) {
+		if (net_debug > 5) 
+			printk("Tx command incomplete (%#x).\n", lp->tx_reap);
 		break;
 	  }
-	  if (tx_status & 0x2000) {
-		lp->stats.tx_packets++;
-		lp->stats.collisions += tx_status & 0xf;
-		netif_wake_queue(dev);
-	  } else {
+	  /* Tx unsuccessful or some interesting status bit set. */
+	  if (!(tx_status & 0x2000) || (tx_status & 0x0f3f)) {
 		lp->stats.tx_errors++;
 		if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
 		if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
 		if (!(tx_status & 0x0040))  lp->stats.tx_heartbeat_errors++;
 		if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
+		lp->stats.collisions += tx_status & 0xf;
 	  }
+	  lp->stats.tx_packets++;
 	  if (net_debug > 5)
 		  printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
 	  lp->tx_reap += TX_BUF_SIZE;
 	  if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
 		lp->tx_reap = TX_BUF_START;
-	  if (++boguscount > 4)
+
+	  lp->tx_pkts_in_ring--;
+	  /* There is always more space in the Tx ring buffer now. */
+	  netif_wake_queue(dev);
+
+	  if (++boguscount > 10)
 		break;
 	}
 
@@ -782,7 +788,8 @@
 			   dev->name, ioaddr, length, tx_block, lp->tx_head);
 	}
 
-	if (lp->tx_head != lp->tx_reap)
+	/* Grimly block further packets if there has been insufficient reaping. */
+	if (++lp->tx_pkts_in_ring < NUM_TX_BUFS) 
 		netif_wake_queue(dev);
 }
 
@@ -892,6 +899,8 @@
 	release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v2.4.10/linux/drivers/net/3c509.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/3c509.c	Sun Sep 30 12:26:06 2001
@@ -202,6 +202,8 @@
 };
 
 MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters);
+MODULE_LICENSE("GPL");
+
 
 static u16 el3_isapnp_phys_addr[8][3];
 #endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c515.c linux/drivers/net/3c515.c
--- v2.4.10/linux/drivers/net/3c515.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/3c515.c	Sun Sep 30 12:26:06 2001
@@ -82,14 +82,14 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
 MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
-MODULE_PARM_DESC(full_duplex, "(ignored)");
 MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.4.10/linux/drivers/net/3c59x.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/3c59x.c	Sun Sep 30 12:26:06 2001
@@ -267,6 +267,8 @@
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver "
 					DRV_VERSION " " DRV_RELDATE);
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.4.10/linux/drivers/net/8139too.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/8139too.c	Tue Oct  9 15:13:02 2001
@@ -78,6 +78,8 @@
 		Andrew Morton - Clear blocked signals, avoid
 		buffer overrun setting current->comm.
 
+		Kalle Olavi Niemitalo - Wake-on-LAN ioctls
+
 	Submitting bug reports:
 
 		"rtl8139-diag -mmmaaavvveefN" output
@@ -137,7 +139,7 @@
 */
 
 #define DRV_NAME	"8139too"
-#define DRV_VERSION	"0.9.18a"
+#define DRV_VERSION	"0.9.19"
 
 
 #include <linux/config.h>
@@ -429,11 +431,34 @@
 	PWRDN = (1 << 0),	/* only on 8139, 8139A */
 };
 
+/* Bits in Config3 */
+enum Config3Bits {
+	Cfg3_FBtBEn    = (1 << 0), /* 1 = Fast Back to Back */
+	Cfg3_FuncRegEn = (1 << 1), /* 1 = enable CardBus Function registers */
+	Cfg3_CLKRUN_En = (1 << 2), /* 1 = enable CLKRUN */
+	Cfg3_CardB_En  = (1 << 3), /* 1 = enable CardBus registers */
+	Cfg3_LinkUp    = (1 << 4), /* 1 = wake up on link up */
+	Cfg3_Magic     = (1 << 5), /* 1 = wake up on Magic Packet (tm) */
+	Cfg3_PARM_En   = (1 << 6), /* 0 = software can set twister parameters */
+	Cfg3_GNTSel    = (1 << 7), /* 1 = delay 1 clock from PCI GNT signal */
+};
+
 /* Bits in Config4 */
 enum Config4Bits {
 	LWPTN = (1 << 2),	/* not on 8139, 8139A */
 };
 
+/* Bits in Config5 */
+enum Config5Bits {
+	Cfg5_PME_STS     = (1 << 0), /* 1 = PCI reset resets PME_Status */
+	Cfg5_LANWake     = (1 << 1), /* 1 = enable LANWake signal */
+	Cfg5_LDPS        = (1 << 2), /* 0 = save power when link is down */
+	Cfg5_FIFOAddrPtr = (1 << 3), /* Realtek internal SRAM testing */
+	Cfg5_UWF         = (1 << 4), /* 1 = accept unicast wakeup frame */
+	Cfg5_MWF         = (1 << 5), /* 1 = accept multicast wakeup frame */
+	Cfg5_BWF         = (1 << 6), /* 1 = accept broadcast wakeup frame */
+};
+
 enum RxConfigBits {
 	/* Early Rx threshold, none or X/16 */
 	RxCfgEarlyRxNone = 0,
@@ -592,6 +617,8 @@
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
 MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM (multicast_filter_limit, "i");
 MODULE_PARM (max_interrupt_work, "i");
 MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i");
@@ -618,6 +645,7 @@
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
 static inline u32 ether_crc (int length, unsigned char *data);
 static void rtl8139_set_rx_mode (struct net_device *dev);
+static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
 
 #ifdef USE_IO_OPS
@@ -825,6 +853,7 @@
 #ifdef USE_IO_OPS
 	ioaddr = (void *) pio_start;
 	dev->base_addr = pio_start;
+	tp->mmio_addr = ioaddr;
 #else
 	/* ioremap MMIO region */
 	ioaddr = ioremap (mmio_start, mmio_len);
@@ -959,6 +988,7 @@
 	dev->do_ioctl = netdev_ioctl;
 	dev->tx_timeout = rtl8139_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
 
 	dev->irq = pdev->irq;
 
@@ -1036,11 +1066,11 @@
 		tp->duplex_lock = 1;
 	}
 	if (tp->default_port) {
-		printk(KERN_INFO "  Forcing %dMbs %s-duplex operation.\n",
+		printk(KERN_INFO "  Forcing %dMbps %s-duplex operation.\n",
 			   (option & 0x20 ? 100 : 10),
 			   (option & 0x10 ? "full" : "half"));
 		mdio_write(dev, tp->phys[0], 0,
-				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100mbps? */
+				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100Mbps? */
 				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
 	}
 
@@ -1395,9 +1425,10 @@
 	rtl_check_media (dev);
 
 	if (tp->chipset >= CH_8139B) {
-		/* disable magic packet scanning, which is enabled
-		 * when PM is enabled in Config1 */
-		RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
+		/* Disable magic packet scanning, which is enabled
+		 * when PM is enabled in Config1.  It can be reenabled
+		 * via ETHTOOL_SWOL if desired.  */
+		RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
 	}
 
 	DPRINTK("init buffer addresses\n");
@@ -1722,18 +1753,21 @@
 	assert (tp->tx_info[entry].mapping == 0);
 
 	tp->tx_info[entry].skb = skb;
-	if ((long) skb->data & 3) {	/* Must use alignment buffer. */
-		/* tp->tx_info[entry].mapping = 0; */
-		memcpy (tp->tx_buf[entry], skb->data, skb->len);
-		dma_addr = tp->tx_bufs_dma + (tp->tx_buf[entry] - tp->tx_bufs);
-	} else {
+	if ( !((unsigned long)skb->data & 3) && skb_shinfo(skb)->nr_frags == 0 &&
+			skb->ip_summed != CHECKSUM_HW) {
 		tp->xstats.tx_buf_mapped++;
 		tp->tx_info[entry].mapping =
 		    pci_map_single (tp->pci_dev, skb->data, skb->len,
 				    PCI_DMA_TODEVICE);
 		dma_addr = tp->tx_info[entry].mapping;
-	}
-
+	} else if (skb->len < TX_BUF_SIZE) {
+		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
+		dma_addr = tp->tx_bufs_dma + (tp->tx_buf[entry] - tp->tx_bufs);
+	} else {
+		dev_kfree_skb(skb);
+		tp->tx_info[entry].skb = NULL;
+		return 0;
+  	}
 	/* Note: the chip doesn't have auto-pad! */
 	spin_lock_irq(&tp->lock);
 	RTL_W32_F (TxAddr0 + (entry * 4), dma_addr);
@@ -1844,8 +1878,8 @@
 			    struct rtl8139_private *tp, void *ioaddr)
 {
 	u8 tmp8;
-	int tmp_work = 1000;
-
+	int tmp_work;
+    
 	DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
 	         dev->name, rx_status);
 	if (rx_status & RxTooLong) {
@@ -1860,33 +1894,52 @@
 		tp->stats.rx_length_errors++;
 	if (rx_status & RxCRCErr)
 		tp->stats.rx_crc_errors++;
+
 	/* Reset the receiver, based on RealTek recommendation. (Bug?) */
-	tp->cur_rx = 0;
 
 	/* disable receive */
-	RTL_W8 (ChipCmd, CmdTxEnb);
-
-	/* A.C.: Reset the multicast list. */
-	rtl8139_set_rx_mode (dev);
-
-	/* XXX potentially temporary hack to
-	 * restart hung receiver */
+	RTL_W8_F (ChipCmd, CmdTxEnb);
+	tmp_work = 200;
 	while (--tmp_work > 0) {
-		barrier();
+		udelay(1);
+		tmp8 = RTL_R8 (ChipCmd);
+		if (!(tmp8 & CmdRxEnb))
+			break;
+	}
+	if (tmp_work <= 0)
+		printk (KERN_WARNING PFX "rx stop wait too long\n");
+	/* restart receive */
+	tmp_work = 200;
+	while (--tmp_work > 0) {
+		RTL_W8_F (ChipCmd, CmdRxEnb | CmdTxEnb);
+		udelay(1);
 		tmp8 = RTL_R8 (ChipCmd);
 		if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
 			break;
-		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 	}
-
-	/* G.S.: Re-enable receiver */
-	/* XXX temporary hack to work around receiver hang */
-	rtl8139_set_rx_mode (dev);
-
 	if (tmp_work <= 0)
 		printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
-}
 
+	/* and reinitialize all rx related registers */
+	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
+	/* Must enable Tx/Rx before setting transfer thresholds! */
+	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
+
+	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
+	RTL_W32 (RxConfig, tp->rx_config);
+	tp->cur_rx = 0;
+
+	DPRINTK("init buffer addresses\n");
+
+	/* Lock Config[01234] and BMCR register writes */
+	RTL_W8 (Cfg9346, Cfg9346_Lock);
+
+	/* init Rx ring buffer DMA address */
+	RTL_W32_F (RxBuf, tp->rx_ring_dma);
+
+	/* A.C.: Reset the multicast list. */
+	__set_rx_mode (dev);
+}
 
 static void rtl8139_rx_interrupt (struct net_device *dev,
 				  struct rtl8139_private *tp, void *ioaddr)
@@ -2182,15 +2235,148 @@
 }
 
 
+/* Get the ethtool settings.  Assumes that eset points to kernel
+   memory, *eset has been initialized as {ETHTOOL_GSET}, and other
+   threads or interrupts aren't messing with the 8139.  */
+static void netdev_get_eset (struct net_device *dev, struct ethtool_cmd *eset)
+{
+	struct rtl8139_private *np = dev->priv;
+	void *ioaddr = np->mmio_addr;
+	u16 advert;
+
+	eset->supported = SUPPORTED_10baseT_Half
+		      	| SUPPORTED_10baseT_Full
+		      	| SUPPORTED_100baseT_Half
+		      	| SUPPORTED_100baseT_Full
+		      	| SUPPORTED_Autoneg
+		      	| SUPPORTED_TP;
+
+	eset->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
+	advert = mdio_read (dev, np->phys[0], 4);
+	if (advert & 0x0020)
+		eset->advertising |= ADVERTISED_10baseT_Half;
+	if (advert & 0x0040)
+		eset->advertising |= ADVERTISED_10baseT_Full;
+	if (advert & 0x0080)
+		eset->advertising |= ADVERTISED_100baseT_Half;
+	if (advert & 0x0100)
+		eset->advertising |= ADVERTISED_100baseT_Full;
+
+	eset->speed = (RTL_R8 (MediaStatus) & 0x08) ? 10 : 100;
+	/* (KON)FIXME: np->full_duplex is set or reset by the thread,
+	   which means this always shows half duplex if the interface
+	   isn't up yet, even if it has already autonegotiated.  */
+	eset->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+	eset->port = PORT_TP;
+	/* (KON)FIXME: Is np->phys[0] correct?  starfire.c uses that.  */
+	eset->phy_address = np->phys[0];
+	eset->transceiver = XCVR_INTERNAL;
+	eset->autoneg = (mdio_read (dev, np->phys[0], 0) & 0x1000) != 0;
+	eset->maxtxpkt = 1;
+	eset->maxrxpkt = 1;
+}
+
+
+/* Get the ethtool Wake-on-LAN settings.  Assumes that wol points to
+   kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and
+   other threads or interrupts aren't messing with the 8139.  */
+static void netdev_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct rtl8139_private *np = dev->priv;
+	void *ioaddr = np->mmio_addr;
+
+	if (rtl_chip_info[np->chipset].flags & HasLWake) {
+		u8 cfg3 = RTL_R8 (Config3);
+		u8 cfg5 = RTL_R8 (Config5);
+
+		wol->supported = WAKE_PHY | WAKE_MAGIC
+			| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST;
+
+		wol->wolopts = 0;
+		if (cfg3 & Cfg3_LinkUp)
+			wol->wolopts |= WAKE_PHY;
+		if (cfg3 & Cfg3_Magic)
+			wol->wolopts |= WAKE_MAGIC;
+		/* (KON)FIXME: See how netdev_set_wol() handles the
+		   following constants.  */
+		if (cfg5 & Cfg5_UWF)
+			wol->wolopts |= WAKE_UCAST;
+		if (cfg5 & Cfg5_MWF)
+			wol->wolopts |= WAKE_MCAST;
+		if (cfg5 & Cfg5_BWF)
+			wol->wolopts |= WAKE_BCAST;
+	}
+}
+
+
+/* Set the ethtool Wake-on-LAN settings.  Return 0 or -errno.  Assumes
+   that wol points to kernel memory and other threads or interrupts
+   aren't messing with the 8139.  */
+static int netdev_set_wol (struct net_device *dev,
+			   const struct ethtool_wolinfo *wol)
+{
+	struct rtl8139_private *np = dev->priv;
+	void *ioaddr = np->mmio_addr;
+	u32 support;
+	u8 cfg3, cfg5;
+
+	support = ((rtl_chip_info[np->chipset].flags & HasLWake)
+		   ? (WAKE_PHY | WAKE_MAGIC
+		      | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
+		   : 0);
+	if (wol->wolopts & ~support)
+		return -EINVAL;
+
+	cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
+	if (wol->wolopts & WAKE_PHY)
+		cfg3 |= Cfg3_LinkUp;
+	if (wol->wolopts & WAKE_MAGIC)
+		cfg3 |= Cfg3_Magic;
+	RTL_W8 (Cfg9346, Cfg9346_Unlock);
+	RTL_W8 (Config3, cfg3);
+	RTL_W8 (Cfg9346, Cfg9346_Lock);
+
+	cfg5 = RTL_R8 (Config5) & ~(Cfg5_UWF | Cfg5_MWF | Cfg5_BWF);
+	/* (KON)FIXME: These are untested.  We may have to set the
+	   CRC0, Wakeup0 and LSBCRC0 registers too, but I have no
+	   documentation.  */
+	if (wol->wolopts & WAKE_UCAST)
+		cfg5 |= Cfg5_UWF;
+	if (wol->wolopts & WAKE_MCAST)
+		cfg5 |= Cfg5_MWF;
+	if (wol->wolopts & WAKE_BCAST)
+		cfg5 |= Cfg5_BWF;
+	RTL_W8 (Config5, cfg5);	/* need not unlock via Cfg9346 */
+
+	return 0;
+}
+
+
 static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
 {
 	struct rtl8139_private *np = dev->priv;
 	u32 ethcmd;
 
+	/* dev_ioctl() in ../../net/core/dev.c has already checked
+	   capable(CAP_NET_ADMIN), so don't bother with that here.  */
+
 	if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
 		return -EFAULT;
 
 	switch (ethcmd) {
+	case ETHTOOL_GSET:
+		{
+			struct ethtool_cmd eset = { ETHTOOL_GSET };
+			spin_lock_irq (&np->lock);
+			netdev_get_eset (dev, &eset);
+			spin_unlock_irq (&np->lock);
+			if (copy_to_user (useraddr, &eset, sizeof (eset)))
+				return -EFAULT;
+			return 0;
+		}
+
+	/* TODO: ETHTOOL_SSET */
+		
 	case ETHTOOL_GDRVINFO:
 		{
 			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
@@ -2202,6 +2388,29 @@
 			return 0;
 		}
 
+	case ETHTOOL_GWOL:
+		{
+			struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
+			spin_lock_irq (&np->lock);
+			netdev_get_wol (dev, &wol);
+			spin_unlock_irq (&np->lock);
+			if (copy_to_user (useraddr, &wol, sizeof (wol)))
+				return -EFAULT;
+			return 0;
+		}
+
+	case ETHTOOL_SWOL:
+		{
+			struct ethtool_wolinfo wol;
+			int rc;
+			if (copy_from_user (&wol, useraddr, sizeof (wol)))
+				return -EFAULT;
+			spin_lock_irq (&np->lock);
+			rc = netdev_set_wol (dev, &wol);
+			spin_unlock_irq (&np->lock);
+			return rc;
+		}
+
 	default:
 		break;
 	}
@@ -2209,6 +2418,7 @@
 	return -EOPNOTSUPP;
 }
 
+
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct rtl8139_private *tp = dev->priv;
@@ -2218,8 +2428,11 @@
 
 	DPRINTK ("ENTER\n");
 
-	data->phy_id &= 0x1f;
-	data->reg_num &= 0x1f;
+	if (cmd != SIOCETHTOOL) {
+		/* With SIOCETHTOOL, this would corrupt the pointer.  */
+		data->phy_id &= 0x1f;
+		data->reg_num &= 0x1f;
+	}
 
 	switch (cmd) {
 	case SIOCETHTOOL:
@@ -2309,11 +2522,10 @@
 }
 
 
-static void rtl8139_set_rx_mode (struct net_device *dev)
+static void __set_rx_mode (struct net_device *dev)
 {
 	struct rtl8139_private *tp = dev->priv;
 	void *ioaddr = tp->mmio_addr;
-	unsigned long flags;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	int i, rx_mode;
 	u32 tmp;
@@ -2350,22 +2562,28 @@
 		}
 	}
 
-	spin_lock_irqsave (&tp->lock, flags);
-
 	/* We can safely update without stopping the chip. */
 	tmp = rtl8139_rx_config | rx_mode;
 	if (tp->rx_config != tmp) {
-		RTL_W32 (RxConfig, tmp);
+		RTL_W32_F (RxConfig, tmp);
 		tp->rx_config = tmp;
 	}
 	RTL_W32_F (MAR0 + 0, mc_filter[0]);
 	RTL_W32_F (MAR0 + 4, mc_filter[1]);
 
-	spin_unlock_irqrestore (&tp->lock, flags);
 
 	DPRINTK ("EXIT\n");
 }
 
+static void rtl8139_set_rx_mode (struct net_device *dev)
+{
+	unsigned long flags;
+	struct rtl8139_private *tp = dev->priv;
+
+	spin_lock_irqsave (&tp->lock, flags);
+	__set_rx_mode(dev);
+	spin_unlock_irqrestore (&tp->lock, flags);
+}
 
 #ifdef CONFIG_PM
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/82596.c linux/drivers/net/82596.c
--- v2.4.10/linux/drivers/net/82596.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/82596.c	Sun Sep 30 12:26:06 2001
@@ -150,6 +150,8 @@
 
 MODULE_AUTHOR("Richard Hirst");
 MODULE_DESCRIPTION("i82596 driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(i596_debug, "i");
 MODULE_PARM_DESC(i596_debug, "i82596 debug mask");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/8390.c linux/drivers/net/8390.c
--- v2.4.10/linux/drivers/net/8390.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/8390.c	Sun Sep 30 12:26:06 2001
@@ -1156,6 +1156,8 @@
 }
 
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- v2.4.10/linux/drivers/net/ac3200.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/ac3200.c	Sun Sep 30 12:26:06 2001
@@ -395,6 +395,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/acenic.c linux/drivers/net/acenic.c
--- v2.4.10/linux/drivers/net/acenic.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/acenic.c	Sun Sep 30 12:26:06 2001
@@ -747,6 +747,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
 MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/aironet4500_card.c linux/drivers/net/aironet4500_card.c
--- v2.4.10/linux/drivers/net/aironet4500_card.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/aironet4500_card.c	Sun Sep 30 12:26:08 2001
@@ -38,6 +38,7 @@
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include "aironet4500.h"
 
@@ -66,6 +67,8 @@
 	{ }			/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, aironet4500_card_pci_tbl);
+MODULE_LICENSE("GPL");
+
 
 static int reverse_probe;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/aironet4500_core.c linux/drivers/net/aironet4500_core.c
--- v2.4.10/linux/drivers/net/aironet4500_core.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/aironet4500_core.c	Sun Sep 30 12:26:06 2001
@@ -2582,6 +2582,8 @@
 MODULE_PARM_DESC(slave,"Aironet is Adhoc slave (0-1)");
 MODULE_PARM_DESC(max_mtu,"Aironet MTU limit (256-2312)");
 #endif
+MODULE_LICENSE("GPL");
+
 
 /*EXPORT_SYMBOL(tx_queue_len);
 EXPORT_SYMBOL(awc_debug);
diff -u --recursive --new-file v2.4.10/linux/drivers/net/aironet4500_proc.c linux/drivers/net/aironet4500_proc.c
--- v2.4.10/linux/drivers/net/aironet4500_proc.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/aironet4500_proc.c	Sun Sep 30 12:26:06 2001
@@ -604,3 +604,4 @@
 module_exit(aironet_proc_exit);
 
 #endif // whole proc system styff
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/arlan-proc.c linux/drivers/net/arlan-proc.c
--- v2.4.10/linux/drivers/net/arlan-proc.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/arlan-proc.c	Sun Sep 30 12:26:06 2001
@@ -1068,3 +1068,4 @@
 };
 
 #endif				// MODULE
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/arlan.c linux/drivers/net/arlan.c
--- v2.4.10/linux/drivers/net/arlan.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/arlan.c	Sun Sep 30 12:26:06 2001
@@ -2079,3 +2079,4 @@
 
 
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v2.4.10/linux/drivers/net/at1700.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/at1700.c	Tue Oct  9 15:13:02 2001
@@ -471,12 +471,12 @@
 #define EE_READ_CMD		(6 << 6)
 #define EE_ERASE_CMD	(7 << 6)
 
-static int __init read_eeprom(int ioaddr, int location)
+static int __init read_eeprom(long ioaddr, int location)
 {
 	int i;
 	unsigned short retval = 0;
-	int ee_addr = ioaddr + EEPROM_Ctrl;
-	int ee_daddr = ioaddr + EEPROM_Data;
+	long ee_addr = ioaddr + EEPROM_Ctrl;
+	long ee_daddr = ioaddr + EEPROM_Data;
 	int read_cmd = location | EE_READ_CMD;
 
 	/* Shift the read command bits out. */
@@ -918,6 +918,8 @@
 	release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v2.4.10/linux/drivers/net/atp.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/atp.c	Sun Sep 30 12:26:06 2001
@@ -151,6 +151,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("RealTek RTL8002/8012 parallel port Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(io, "1-" __MODULE_STRING(NUM_UNITS) "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/bonding.c linux/drivers/net/bonding.c
--- v2.4.10/linux/drivers/net/bonding.c	Tue Mar  6 22:44:15 2001
+++ linux/drivers/net/bonding.c	Sun Sep 30 12:26:06 2001
@@ -299,6 +299,7 @@
 
 module_init(bonding_init);
 module_exit(bonding_exit);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/bsd_comp.c linux/drivers/net/bsd_comp.c
--- v2.4.10/linux/drivers/net/bsd_comp.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/bsd_comp.c	Sun Sep 30 12:26:06 2001
@@ -1173,3 +1173,4 @@
 
 module_init(bsdcomp_init);
 module_exit(bsdcomp_cleanup);
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- v2.4.10/linux/drivers/net/cs89x0.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/cs89x0.c	Sun Sep 30 12:26:06 2001
@@ -1628,6 +1628,8 @@
 #endif
 
 MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>");
+MODULE_LICENSE("GPL");
+
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.4.10/linux/drivers/net/de4x5.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/de4x5.c	Sun Sep 30 12:26:06 2001
@@ -1047,6 +1047,8 @@
 MODULE_PARM_DESC(de4x5_debug, "de4x5 debug mask");
 MODULE_PARM_DESC(dec_only, "de4x5 probe only for Digital boards (0-1)");
 MODULE_PARM_DESC(args, "de4x5 full duplex and media type settings; see de4x5.c for details");
+MODULE_LICENSE("GPL");
+
 # else
 static int loading_module;
 #endif /* MODULE */
diff -u --recursive --new-file v2.4.10/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v2.4.10/linux/drivers/net/de600.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/de600.c	Sun Sep 30 12:26:06 2001
@@ -841,6 +841,9 @@
 	release_region(DE600_IO, 3);
 }
 #endif /* MODULE */
+
+MODULE_LICENSE("GPL");
+
 /*
  * Local variables:
  *  kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v2.4.10/linux/drivers/net/de620.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/de620.c	Sun Sep 30 12:26:06 2001
@@ -1008,6 +1008,8 @@
 	release_region(de620_dev.base_addr, 3);
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * (add '-DMODULE' when compiling as loadable module)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/defxx.c linux/drivers/net/defxx.c
--- v2.4.10/linux/drivers/net/defxx.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/defxx.c	Sun Sep 30 12:26:06 2001
@@ -3413,6 +3413,7 @@
 
 module_init(dfx_init);
 module_exit(dfx_cleanup);
+MODULE_LICENSE("GPL");
 
 
 /*
diff -u --recursive --new-file v2.4.10/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v2.4.10/linux/drivers/net/depca.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/depca.c	Sun Sep 30 12:26:06 2001
@@ -2076,6 +2076,7 @@
   release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE);
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
 
 
 /*
diff -u --recursive --new-file v2.4.10/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- v2.4.10/linux/drivers/net/dgrs.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/dgrs.c	Sun Sep 30 12:26:06 2001
@@ -126,6 +126,8 @@
 	{ }			/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, dgrs_pci_tbl);
+MODULE_LICENSE("GPL");
+
 
 /*
  *	Firmware.  Compiled separately for local compilation,
diff -u --recursive --new-file v2.4.10/linux/drivers/net/dl2k.c linux/drivers/net/dl2k.c
--- v2.4.10/linux/drivers/net/dl2k.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/dl2k.c	Sun Sep 30 12:26:06 2001
@@ -34,6 +34,8 @@
 
 MODULE_AUTHOR ("Edward Peng");
 MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM (mtu, "1-" __MODULE_STRING (MAX_UNITS) "i");
 MODULE_PARM (media, "1-" __MODULE_STRING (MAX_UNITS) "s");
 MODULE_PARM (vlan, "1-" __MODULE_STRING (MAX_UNITS) "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/dmfe.c linux/drivers/net/dmfe.c
--- v2.4.10/linux/drivers/net/dmfe.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/dmfe.c	Sun Sep 30 12:26:06 2001
@@ -2000,6 +2000,7 @@
 };
 MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl);
 
+
 static struct pci_driver dmfe_driver = {
 	name:		"dmfe",
 	id_table:	dmfe_pci_tbl,
@@ -2009,6 +2010,8 @@
 
 MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
 MODULE_DESCRIPTION("Davicom DM910X fast ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug, "i");
 MODULE_PARM(mode, "i");
 MODULE_PARM(cr6set, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/dummy.c linux/drivers/net/dummy.c
--- v2.4.10/linux/drivers/net/dummy.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/dummy.c	Sun Sep 30 12:26:06 2001
@@ -122,3 +122,4 @@
 
 module_init(dummy_init_module);
 module_exit(dummy_cleanup_module);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v2.4.10/linux/drivers/net/e2100.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/e2100.c	Sun Sep 30 12:26:06 2001
@@ -440,6 +440,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/eepro.c linux/drivers/net/eepro.c
--- v2.4.10/linux/drivers/net/eepro.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/eepro.c	Sun Sep 30 12:26:06 2001
@@ -1767,6 +1767,8 @@
 
 MODULE_AUTHOR("Pascal Dupuis <dupuis@lei.ucl.ac.be> for the 2.1 stuff (locking,...)");
 MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.4.10/linux/drivers/net/eepro100.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/eepro100.c	Sun Sep 30 12:26:08 2001
@@ -43,7 +43,8 @@
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
    Lower values use more memory, but are faster. */
-#if defined(__alpha__) || defined(__sparc__) || defined(__arm__)
+#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
+    defined(__arm__)
 static int rx_copybreak = 1518;
 #else
 static int rx_copybreak = 200;
@@ -103,6 +104,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/mii.h>
+#include <linux/delay.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -114,6 +116,7 @@
 
 MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
 MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(debug, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
@@ -165,7 +168,7 @@
 #endif
 
 
-int speedo_debug = 1;
+static int speedo_debug = 1;
 
 /*
 				Theory of Operation
@@ -319,7 +322,7 @@
 static inline void wait_for_cmd_done(long cmd_ioaddr)
 {
 	int wait = 1000;
-	do   ;
+	do  udelay(1) ;
 	while(inb(cmd_ioaddr) && --wait >= 0);
 #ifndef final_version
 	if (wait < 0)
@@ -1332,57 +1335,64 @@
 	long ioaddr = dev->base_addr;
 	int entry;
 
-	{	/* Prevent interrupts from changing the Tx ring from underneath us. */
-		unsigned long flags;
+	/* Prevent interrupts from changing the Tx ring from underneath us. */
+	unsigned long flags;
 
-		spin_lock_irqsave(&sp->lock, flags);
+	spin_lock_irqsave(&sp->lock, flags);
 
-		/* Check if there are enough space. */
-		if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
-			printk(KERN_ERR "%s: incorrect tbusy state, fixed.\n", dev->name);
-			netif_stop_queue(dev);
-			sp->tx_full = 1;
-			spin_unlock_irqrestore(&sp->lock, flags);
-			return 1;
-		}
+	/* Check if there are enough space. */
+	if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
+		printk(KERN_ERR "%s: incorrect tbusy state, fixed.\n", dev->name);
+		netif_stop_queue(dev);
+		sp->tx_full = 1;
+		spin_unlock_irqrestore(&sp->lock, flags);
+		return 1;
+	}
 
-		/* Calculate the Tx descriptor entry. */
-		entry = sp->cur_tx++ % TX_RING_SIZE;
+	/* Calculate the Tx descriptor entry. */
+	entry = sp->cur_tx++ % TX_RING_SIZE;
 
-		sp->tx_skbuff[entry] = skb;
-		sp->tx_ring[entry].status =
-			cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex);
-		if (!(entry & ((TX_RING_SIZE>>2)-1)))
-			sp->tx_ring[entry].status |= cpu_to_le32(CmdIntr);
-		sp->tx_ring[entry].link =
-			cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));
-		sp->tx_ring[entry].tx_desc_addr =
-			cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET);
-		/* The data region is always in one buffer descriptor. */
-		sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold);
-		sp->tx_ring[entry].tx_buf_addr0 =
-			cpu_to_le32(pci_map_single(sp->pdev, skb->data,
-						   skb->len, PCI_DMA_TODEVICE));
-		sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len);
-		/* Trigger the command unit resume. */
-		wait_for_cmd_done(ioaddr + SCBCmd);
-		clear_suspend(sp->last_cmd);
-		/* We want the time window between clearing suspend flag on the previous
-		   command and resuming CU to be as small as possible.
-		   Interrupts in between are very undesired.  --SAW */
-		outb(CUResume, ioaddr + SCBCmd);
-		sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+	sp->tx_skbuff[entry] = skb;
+	sp->tx_ring[entry].status =
+		cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex);
+	if (!(entry & ((TX_RING_SIZE>>2)-1)))
+		sp->tx_ring[entry].status |= cpu_to_le32(CmdIntr);
+	sp->tx_ring[entry].link =
+		cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));
+	sp->tx_ring[entry].tx_desc_addr =
+		cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET);
+	/* The data region is always in one buffer descriptor. */
+	sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold);
+	sp->tx_ring[entry].tx_buf_addr0 =
+		cpu_to_le32(pci_map_single(sp->pdev, skb->data,
+					   skb->len, PCI_DMA_TODEVICE));
+	sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len);
 
-		/* Leave room for set_rx_mode(). If there is no more space than reserved
-		   for multicast filter mark the ring as full. */
-		if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
-			netif_stop_queue(dev);
-			sp->tx_full = 1;
-		}
+	/* workaround for hardware bug on 10 mbit half duplex */
 
-		spin_unlock_irqrestore(&sp->lock, flags);
+	if ((sp->partner==0) && (sp->chip_id==1)) {
+		wait_for_cmd_done(ioaddr + SCBCmd);
+		outb(0 , ioaddr + SCBCmd);
+	}
+
+	/* Trigger the command unit resume. */
+	wait_for_cmd_done(ioaddr + SCBCmd);
+	clear_suspend(sp->last_cmd);
+	/* We want the time window between clearing suspend flag on the previous
+	   command and resuming CU to be as small as possible.
+	   Interrupts in between are very undesired.  --SAW */
+	outb(CUResume, ioaddr + SCBCmd);
+	sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+
+	/* Leave room for set_rx_mode(). If there is no more space than reserved
+	   for multicast filter mark the ring as full. */
+	if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
+		netif_stop_queue(dev);
+		sp->tx_full = 1;
 	}
 
+	spin_unlock_irqrestore(&sp->lock, flags);
+
 	dev->trans_start = jiffies;
 
 	return 0;
@@ -2205,11 +2215,14 @@
 	pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD)
 								+ sizeof(struct speedo_stats),
 						sp->tx_ring, sp->tx_ring_dma);
+	pci_disable_device(pdev);
 	kfree(dev);
 }
 
 static struct pci_device_id eepro100_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562ET,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER,
 		PCI_ANY_ID, PCI_ANY_ID, },
diff -u --recursive --new-file v2.4.10/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.4.10/linux/drivers/net/eexpress.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/eexpress.c	Sun Sep 30 12:26:06 2001
@@ -1634,6 +1634,8 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
 MODULE_PARM_DESC(io, "EtherExpress 16 I/O base address(es)");
 MODULE_PARM_DESC(irq, "EtherExpress 16 IRQ number(s)");
+MODULE_LICENSE("GPL");
+
 
 /* Ideally the user would give us io=, irq= for every card.  If any parameters
  * are specified, we verify and then use them.  If no parameters are given, we
diff -u --recursive --new-file v2.4.10/linux/drivers/net/epic100.c linux/drivers/net/epic100.c
--- v2.4.10/linux/drivers/net/epic100.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/epic100.c	Sun Sep 30 12:26:06 2001
@@ -138,6 +138,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("SMC 83c170 EPIC series Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(rx_copybreak, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/eql.c linux/drivers/net/eql.c
--- v2.4.10/linux/drivers/net/eql.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/eql.c	Sun Sep 30 12:26:06 2001
@@ -1016,6 +1016,7 @@
 
 module_init(eql_init_module);
 module_exit(eql_cleanup_module);
+MODULE_LICENSE("GPL");
 
 /*
  * Local Variables: 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/es3210.c linux/drivers/net/es3210.c
--- v2.4.10/linux/drivers/net/es3210.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/es3210.c	Sun Sep 30 12:26:06 2001
@@ -429,3 +429,5 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- v2.4.10/linux/drivers/net/eth16i.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/eth16i.c	Sun Sep 30 12:26:06 2001
@@ -1405,6 +1405,8 @@
 #if (LINUX_VERSION_CODE >= 0x20115) 
 MODULE_AUTHOR("Mika Kuoppala <miku@iki.fi>");
 MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
 MODULE_PARM_DESC(io, "eth16i I/O base address(es)");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ethertap.c linux/drivers/net/ethertap.c
--- v2.4.10/linux/drivers/net/ethertap.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/ethertap.c	Sun Sep 30 12:26:06 2001
@@ -374,3 +374,5 @@
 }
 
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v2.4.10/linux/drivers/net/ewrk3.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/ewrk3.c	Sun Sep 30 12:26:06 2001
@@ -1876,6 +1876,8 @@
 	release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE);
 }
 #endif				/* MODULE */
+MODULE_LICENSE("GPL");
+
 
 
 /*
diff -u --recursive --new-file v2.4.10/linux/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c
--- v2.4.10/linux/drivers/net/fc/iph5526.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/fc/iph5526.c	Sun Sep 30 12:26:08 2001
@@ -1932,7 +1932,7 @@
 		fi->g.name_server = FALSE;
 		fi->g.alpa_list_index = 0;
 		fi->g.ox_id = NOT_SCSI_XID;
-		fi->g.my_mtu = FRAME_SIZE;
+		fi->g.my_mtu = TACH_FRAME_SIZE;
 		
 		/* Implicitly LOGO with all logged-in nodes. 
 		 */
@@ -2811,7 +2811,7 @@
 	else
 	if (logi == ELS_FLOGI)
 		fi->g.login.common_features = htons(FLOGI_C_F);
-	fi->g.login.recv_data_field_size = htons(FRAME_SIZE);
+	fi->g.login.recv_data_field_size = htons(TACH_FRAME_SIZE);
 	fi->g.login.n_port_total_conc_seq = htons(CONCURRENT_SEQUENCES);
 	fi->g.login.rel_off_by_info_cat = htons(RO_INFO_CATEGORY);
 	fi->g.login.ED_TOV = htonl(E_D_TOV);
@@ -2847,7 +2847,7 @@
 		fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID);
 	fi->g.login.c_of_s[2].initiator_ctl = htons(0);
 	fi->g.login.c_of_s[2].recipient_ctl = htons(0);
-	fi->g.login.c_of_s[2].recv_data_field_size = htons(FRAME_SIZE);
+	fi->g.login.c_of_s[2].recv_data_field_size = htons(TACH_FRAME_SIZE);
 	fi->g.login.c_of_s[2].concurrent_sequences = htons(CLASS3_CONCURRENT_SEQUENCE);
 	fi->g.login.c_of_s[2].n_port_end_to_end_credit = htons(0);
 	fi->g.login.c_of_s[2].open_seq_per_exchange = htons(CLASS3_OPEN_SEQUENCE);
diff -u --recursive --new-file v2.4.10/linux/drivers/net/fc/tach.h linux/drivers/net/fc/tach.h
--- v2.4.10/linux/drivers/net/fc/tach.h	Mon Aug 23 10:12:38 1999
+++ linux/drivers/net/fc/tach.h	Sun Sep 30 12:26:08 2001
@@ -94,9 +94,9 @@
 
 /* Size of the various buffers.
  */
-#define FRAME_SIZE              2048
-#define MFS_BUFFER_SIZE         FRAME_SIZE
-#define SFS_BUFFER_SIZE         (FRAME_SIZE + TACHYON_HEADER_LEN)
+#define TACH_FRAME_SIZE         2048
+#define MFS_BUFFER_SIZE         TACH_FRAME_SIZE
+#define SFS_BUFFER_SIZE         (TACH_FRAME_SIZE + TACHYON_HEADER_LEN)
 #define SEST_BUFFER_SIZE        512
 #define TACH_HEADER_SIZE        64
 #define NO_OF_TACH_HEADERS      ((MY_PAGE_SIZE)/TACH_HEADER_SIZE)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/hamachi.c linux/drivers/net/hamachi.c
--- v2.4.10/linux/drivers/net/hamachi.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/hamachi.c	Tue Oct  9 15:13:03 2001
@@ -514,13 +514,15 @@
 	int mii_cnt;								/* MII device addresses. */
 	u16 advertising;							/* NWay media advertisement */
 	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
-	u_int32_t rx_int_var, tx_int_var;	/* interrupt control variables */
-	u_int32_t option;							/* Hold on to a copy of the options */
+	u32 rx_int_var, tx_int_var;	/* interrupt control variables */
+	u32 option;							/* Hold on to a copy of the options */
 	struct pci_dev *pci_dev;
 };
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>");
 MODULE_DESCRIPTION("Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
@@ -844,8 +846,8 @@
 	struct hamachi_private *hmp = dev->priv;
 	long ioaddr = dev->base_addr;
 	int i;
-	u_int32_t rx_int_var, tx_int_var;
-	u_int16_t fifo_info;
+	u32 rx_int_var, tx_int_var;
+	u16 fifo_info;
 
 	i = request_irq(dev->irq, &hamachi_interrupt, SA_SHIRQ, dev->name, dev);
 	if (i)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/hamradio/yam.c linux/drivers/net/hamradio/yam.c
--- v2.4.10/linux/drivers/net/hamradio/yam.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/hamradio/yam.c	Sun Sep 30 12:26:08 2001
@@ -35,6 +35,9 @@
  *   0.6 F6FBB 25.08.98  Added 1200Bds format
  *   0.7 F6FBB 12.09.98  Added to the kernel configuration
  *   0.8 F6FBB 14.10.98  Fixed slottime/persistance timing bug
+ *       OK1ZIA 2.09.01  Fixed "kfree_skb on hard IRQ" 
+ *                       using dev_kfree_skb_any(). (important in 2.4 kernel)
+ *   
  */
 
 /*****************************************************************************/
@@ -649,16 +652,16 @@
 			yp->tx_state = TX_DATA;
 			if (skb->data[0] != 0) {
 /*                              do_kiss_params(s, skb->data, skb->len); */
-				dev_kfree_skb(skb);
+				dev_kfree_skb_any(skb);
 				break;
 			}
 			yp->tx_len = skb->len - 1;	/* strip KISS byte */
 			if (yp->tx_len >= YAM_MAX_FRAME || yp->tx_len < 2) {
-				dev_kfree_skb(skb);
+        			dev_kfree_skb_any(skb);
 				break;
 			}
 			memcpy(yp->tx_buf, skb->data + 1, yp->tx_len);
-			dev_kfree_skb(skb);
+			dev_kfree_skb_any(skb);
 			yp->tx_count = 0;
 			yp->tx_crcl = 0x21;
 			yp->tx_crch = 0xf3;
@@ -858,7 +861,7 @@
 		return -EIO;
 	}
 	outb(0, IER(dev->base_addr));
-	if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, NULL)) {
+	if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, dev)) {
 		printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq);
 		return -EBUSY;
 	}
@@ -896,7 +899,7 @@
 	outb(0, IER(dev->base_addr));
 	outb(1, MCR(dev->base_addr));
 	/* Remove IRQ handler if last */
-	free_irq(dev->irq, NULL);
+	free_irq(dev->irq,dev);
 	release_region(dev->base_addr, YAM_EXTENT);
 	netif_stop_queue(dev);
 	while ((skb = skb_dequeue(&yp->send_queue)))
diff -u --recursive --new-file v2.4.10/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- v2.4.10/linux/drivers/net/hp-plus.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/hp-plus.c	Sun Sep 30 12:26:06 2001
@@ -457,6 +457,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/hp.c linux/drivers/net/hp.c
--- v2.4.10/linux/drivers/net/hp.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/hp.c	Sun Sep 30 12:26:06 2001
@@ -429,6 +429,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v2.4.10/linux/drivers/net/hp100.c	Sat Mar  3 10:55:47 2001
+++ linux/drivers/net/hp100.c	Sun Sep 30 12:26:08 2001
@@ -2,7 +2,7 @@
 ** hp100.c 
 ** HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters
 **
-** $Id: hp100.c,v 1.57 1998/04/10 16:27:23 perex Exp perex $
+** $Id: hp100.c,v 1.58 2001/09/24 18:03:01 perex Exp perex $
 **
 ** Based on the HP100 driver written by Jaroslav Kysela <perex@jcu.cz>
 ** Extended for new busmaster capable chipsets by 
@@ -45,6 +45,11 @@
 **   along with this program; if not, write to the Free Software
 **   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
+** 1.57c -> 1.58
+**   - used indent to change coding-style
+**   - added KTI DP-200 EISA ID
+**   - ioremap is also used for low (<1MB) memory (multi-architecture support)
+**
 ** 1.57b -> 1.57c - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 **   - release resources on failure in init_module
 **
@@ -78,18 +83,18 @@
 **
 */
 
-#define HP100_DEFAULT_PRIORITY_TX 0 
+#define HP100_DEFAULT_PRIORITY_TX 0
 
 #undef HP100_DEBUG
-#undef HP100_DEBUG_B           /* Trace  */
-#undef HP100_DEBUG_BM          /* Debug busmaster code (PDL stuff) */
+#undef HP100_DEBUG_B		/* Trace  */
+#undef HP100_DEBUG_BM		/* Debug busmaster code (PDL stuff) */
 
-#undef HP100_DEBUG_TRAINING    /* Debug login-to-hub procedure */
-#undef HP100_DEBUG_TX   
-#undef HP100_DEBUG_IRQ 
-#undef HP100_DEBUG_RX 
+#undef HP100_DEBUG_TRAINING	/* Debug login-to-hub procedure */
+#undef HP100_DEBUG_TX
+#undef HP100_DEBUG_IRQ
+#undef HP100_DEBUG_RX
 
-#undef HP100_MULTICAST_FILTER  /* Need to be debugged... */
+#undef HP100_MULTICAST_FILTER	/* Need to be debugged... */
 
 #include <linux/version.h>
 #include <linux/module.h>
@@ -110,7 +115,7 @@
 #include <linux/skbuff.h>
 
 #include <linux/types.h>
-#include <linux/config.h>  /* for CONFIG_PCI */
+#include <linux/config.h>	/* for CONFIG_PCI */
 #include <linux/delay.h>
 #include <linux/init.h>
 
@@ -144,7 +149,7 @@
 #define PCI_DEVICE_ID_COMPEX2_100VG 0x0005
 #endif
 
-#define HP100_REGION_SIZE	0x20 /* for ioports */
+#define HP100_REGION_SIZE	0x20	/* for ioports */
 
 #define HP100_MAX_PACKET_SIZE	(1536+4)
 #define HP100_MIN_PACKET_SIZE	60
@@ -164,51 +169,51 @@
  */
 
 struct hp100_eisa_id {
-  u_int id;
-  const char *name;
-  u_char bus;
+	u_int id;
+	const char *name;
+	u_char bus;
 };
 
 struct hp100_pci_id {
-  u_short vendor;
-  u_short device;
+	u_short vendor;
+	u_short device;
 };
 
 struct hp100_private {
-  struct hp100_eisa_id *id;
-  spinlock_t lock;
-  u_short chip;
-  u_short soft_model;
-  u_int memory_size; 
-  u_int virt_memory_size;
-  u_short rx_ratio;       /* 1 - 99 */
-  u_short priority_tx;    /* != 0 - priority tx */
-  u_short mode;           /* PIO, Shared Mem or Busmaster */
-  u_char bus;
-  struct pci_dev *pci_dev;
-  short mem_mapped;	  /* memory mapped access */
-  void *mem_ptr_virt;    /* virtual memory mapped area, maybe NULL */
-  unsigned long mem_ptr_phys;	  /* physical memory mapped area */
-  short lan_type;	  /* 10Mb/s, 100Mb/s or -1 (error) */
-  int hub_status;	  /* was login to hub successful? */
-  u_char mac1_mode;
-  u_char mac2_mode;
-  u_char hash_bytes[ 8 ];
-  hp100_stats_t stats;
-
-  /* Rings for busmaster mode: */
-  hp100_ring_t *rxrhead;  /* Head (oldest) index into rxring */
-  hp100_ring_t *rxrtail;  /* Tail (newest) index into rxring */
-  hp100_ring_t *txrhead;  /* Head (oldest) index into txring */
-  hp100_ring_t *txrtail;  /* Tail (newest) index into txring */
-
-  hp100_ring_t rxring[ MAX_RX_PDL ];
-  hp100_ring_t txring[ MAX_TX_PDL ];
-
-  u_int *page_vaddr;      /* Virtual address of allocated page */
-  u_int *page_vaddr_algn; /* Aligned virtual address of allocated page */
-  int rxrcommit;          /* # Rx PDLs commited to adapter */
-  int txrcommit;          /* # Tx PDLs commited to adapter */
+	struct hp100_eisa_id *id;
+	spinlock_t lock;
+	u_short chip;
+	u_short soft_model;
+	u_int memory_size;
+	u_int virt_memory_size;
+	u_short rx_ratio;	/* 1 - 99 */
+	u_short priority_tx;	/* != 0 - priority tx */
+	u_short mode;		/* PIO, Shared Mem or Busmaster */
+	u_char bus;
+	struct pci_dev *pci_dev;
+	short mem_mapped;	/* memory mapped access */
+	void *mem_ptr_virt;	/* virtual memory mapped area, maybe NULL */
+	unsigned long mem_ptr_phys;	/* physical memory mapped area */
+	short lan_type;		/* 10Mb/s, 100Mb/s or -1 (error) */
+	int hub_status;		/* was login to hub successful? */
+	u_char mac1_mode;
+	u_char mac2_mode;
+	u_char hash_bytes[8];
+	hp100_stats_t stats;
+
+	/* Rings for busmaster mode: */
+	hp100_ring_t *rxrhead;	/* Head (oldest) index into rxring */
+	hp100_ring_t *rxrtail;	/* Tail (newest) index into rxring */
+	hp100_ring_t *txrhead;	/* Head (oldest) index into txring */
+	hp100_ring_t *txrtail;	/* Tail (newest) index into txring */
+
+	hp100_ring_t rxring[MAX_RX_PDL];
+	hp100_ring_t txring[MAX_TX_PDL];
+
+	u_int *page_vaddr;	/* Virtual address of allocated page */
+	u_int *page_vaddr_algn;	/* Aligned virtual address of allocated page */
+	int rxrcommit;		/* # Rx PDLs commited to adapter */
+	int txrcommit;		/* # Tx PDLs commited to adapter */
 };
 
 /*
@@ -217,62 +222,64 @@
 
 static struct hp100_eisa_id hp100_eisa_ids[] = {
 
-  /* 10/100 EISA card with revision A Cascade chip */
-  { 0x80F1F022, "HP J2577 rev A", HP100_BUS_EISA },
+	/* 10/100 EISA card with revision A Cascade chip */
+	{0x80F1F022, "HP J2577 rev A", HP100_BUS_EISA},
+
+	/* 10/100 ISA card with revision A Cascade chip */
+	{0x50F1F022, "HP J2573 rev A", HP100_BUS_ISA},
+
+	/* 10 only EISA card with Cascade chip */
+	{0x2019F022, "HP 27248B", HP100_BUS_EISA},
+
+	/* 10/100 EISA card with Cascade chip */
+	{0x4019F022, "HP J2577", HP100_BUS_EISA},
+
+	/* 10/100 ISA card with Cascade chip */
+	{0x5019F022, "HP J2573", HP100_BUS_ISA},
 
-  /* 10/100 ISA card with revision A Cascade chip */
-  { 0x50F1F022, "HP J2573 rev A", HP100_BUS_ISA },
+	/* 10/100 PCI card - old J2585A */
+	{0x1030103c, "HP J2585A", HP100_BUS_PCI},
 
-  /* 10 only EISA card with Cascade chip */
-  { 0x2019F022, "HP 27248B",      HP100_BUS_EISA },
+	/* 10/100 PCI card - new J2585B - master capable */
+	{0x1041103c, "HP J2585B", HP100_BUS_PCI},
 
-  /* 10/100 EISA card with Cascade chip */
-  { 0x4019F022, "HP J2577",       HP100_BUS_EISA },
-
-  /* 10/100 ISA card with Cascade chip */
-  { 0x5019F022, "HP J2573",       HP100_BUS_ISA },
-
-  /* 10/100 PCI card - old J2585A */
-  { 0x1030103c, "HP J2585A", 	    HP100_BUS_PCI },
-
-  /* 10/100 PCI card - new J2585B - master capable */
-  { 0x1041103c, "HP J2585B",      HP100_BUS_PCI },
-
-  /* 10 Mbit Combo Adapter */
-  { 0x1042103c, "HP J2970",       HP100_BUS_PCI },
-
-  /* 10 Mbit 10baseT Adapter */
-  { 0x1040103c, "HP J2973",       HP100_BUS_PCI },
-
-  /* 10/100 EISA card from Compex */
-  { 0x0103180e, "ReadyLink ENET100-VG4", HP100_BUS_EISA },
-
-  /* 10/100 EISA card from Compex - FreedomLine (sq5bpf) */
-  /* Note: plhbrod@mbox.vol.cz reported that same ID have ISA */
-  /*       version of adapter, too... */
-  { 0x0104180e, "FreedomLine 100/VG", HP100_BUS_EISA },
-
-  /* 10/100 PCI card from Compex - FreedomLine
-   *
-   * I think this card doesn't like aic7178 scsi controller, but
-   * I haven't tested this much. It works fine on diskless machines.
-   *                            Jacek Lipkowski <sq5bpf@acid.ch.pw.edu.pl>
-   */
-  { 0x021211f6, "FreedomLine 100/VG", HP100_BUS_PCI },
-  
-  /* 10/100 PCI card from Compex (J2585A compatible) */
-  { 0x011211f6, "ReadyLink ENET100-VG4", HP100_BUS_PCI }
+	/* 10 Mbit Combo Adapter */
+	{0x1042103c, "HP J2970", HP100_BUS_PCI},
 
+	/* 10 Mbit 10baseT Adapter */
+	{0x1040103c, "HP J2973", HP100_BUS_PCI},
+
+	/* 10/100 EISA card from Compex */
+	{0x0103180e, "ReadyLink ENET100-VG4", HP100_BUS_EISA},
+
+	/* 10/100 EISA card from Compex - FreedomLine (sq5bpf) */
+	/* Note: plhbrod@mbox.vol.cz reported that same ID have ISA */
+	/*       version of adapter, too... */
+	{0x0104180e, "FreedomLine 100/VG", HP100_BUS_EISA},
+
+	/* 10/100 PCI card from Compex - FreedomLine
+	 *
+	 * I think this card doesn't like aic7178 scsi controller, but
+	 * I haven't tested this much. It works fine on diskless machines.
+	 *                            Jacek Lipkowski <sq5bpf@acid.ch.pw.edu.pl>
+	 */
+	{0x021211f6, "FreedomLine 100/VG", HP100_BUS_PCI},
+
+	/* 10/100 PCI card from Compex (J2585A compatible) */
+	{0x011211f6, "ReadyLink ENET100-VG4", HP100_BUS_PCI},
+	
+	/* 10/100 PCI card from KTI */
+	{0x40008e2e, "KTI DP-200", HP100_BUS_PCI }
 };
 
 #define HP100_EISA_IDS_SIZE	(sizeof(hp100_eisa_ids)/sizeof(struct hp100_eisa_id))
 
 #ifdef CONFIG_PCI
 static struct hp100_pci_id hp100_pci_ids[] = {
-  { PCI_VENDOR_ID_HP, 		PCI_DEVICE_ID_HP_J2585A },
-  { PCI_VENDOR_ID_HP,		PCI_DEVICE_ID_HP_J2585B },
-  { PCI_VENDOR_ID_COMPEX,	PCI_DEVICE_ID_COMPEX_ENET100VG4 },
-  { PCI_VENDOR_ID_COMPEX2,	PCI_DEVICE_ID_COMPEX2_100VG }
+	{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A},
+	{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B},
+	{PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4},
+	{PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG}
 };
 #endif
 
@@ -280,62 +287,71 @@
 
 #if LINUX_VERSION_CODE >= 0x20400
 static struct pci_device_id hp100_pci_tbl[] __initdata = {
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG, PCI_ANY_ID, PCI_ANY_ID, },
-	{ }			/* Terminating entry */
+	{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
+	{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
+	{PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID,},
+	{PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG, PCI_ANY_ID, PCI_ANY_ID,},
+	{}			/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, hp100_pci_tbl);
-#endif /* LINUX_VERSION_CODE >= 0x20400 */
+#endif				/* LINUX_VERSION_CODE >= 0x20400 */
 
 static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
 static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
 static int hp100_mode = 1;
 
-MODULE_PARM( hp100_rx_ratio, "1i" );
-MODULE_PARM( hp100_priority_tx, "1i" );
-MODULE_PARM( hp100_mode, "1i" );
+MODULE_PARM(hp100_rx_ratio, "1i");
+MODULE_PARM(hp100_priority_tx, "1i");
+MODULE_PARM(hp100_mode, "1i");
 
 /*
  *  prototypes
  */
 
-static int  hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev );
-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 void hp100_rx( struct net_device *dev );
-static hp100_stats_t *hp100_get_stats( struct net_device *dev );
-static void hp100_misc_interrupt( struct net_device *dev );
-static void hp100_update_stats( struct net_device *dev );
-static void hp100_clear_stats( struct hp100_private *lp, int ioaddr );
-static void hp100_set_multicast_list( struct net_device *dev);
-static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs );
-static void hp100_start_interface( struct net_device *dev );
-static void hp100_stop_interface( struct net_device *dev );
-static void hp100_load_eeprom( struct net_device *dev, u_short ioaddr );
-static int  hp100_sense_lan( struct net_device *dev );
-static int  hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin );
-static int  hp100_down_vg_link( struct net_device *dev );
-static void hp100_cascade_reset( struct net_device *dev, u_short enable );
-static void hp100_BM_shutdown( struct net_device *dev );
-static void hp100_mmuinit( struct net_device *dev );
-static void hp100_init_pdls( struct net_device *dev );
-static int  hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr);
-static int  hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u_int *pdlptr);
-static void hp100_rxfill( struct net_device *dev );
-static void hp100_hwinit( struct net_device *dev );
-static void hp100_clean_txring( struct net_device *dev );
+static int hp100_probe1(struct net_device *dev, int ioaddr, u_char bus,
+			struct pci_dev *pci_dev);
+
+
+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 void hp100_rx(struct net_device *dev);
+static hp100_stats_t *hp100_get_stats(struct net_device *dev);
+static void hp100_misc_interrupt(struct net_device *dev);
+static void hp100_update_stats(struct net_device *dev);
+static void hp100_clear_stats(struct hp100_private *lp, int ioaddr);
+static void hp100_set_multicast_list(struct net_device *dev);
+static void hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void hp100_start_interface(struct net_device *dev);
+static void hp100_stop_interface(struct net_device *dev);
+static void hp100_load_eeprom(struct net_device *dev, u_short ioaddr);
+static int hp100_sense_lan(struct net_device *dev);
+static int hp100_login_to_vg_hub(struct net_device *dev,
+				 u_short force_relogin);
+static int hp100_down_vg_link(struct net_device *dev);
+static void hp100_cascade_reset(struct net_device *dev, u_short enable);
+static void hp100_BM_shutdown(struct net_device *dev);
+static void hp100_mmuinit(struct net_device *dev);
+static void hp100_init_pdls(struct net_device *dev);
+static int hp100_init_rxpdl(struct net_device *dev,
+			    register hp100_ring_t * ringptr,
+			    register u_int * pdlptr);
+static int hp100_init_txpdl(struct net_device *dev,
+			    register hp100_ring_t * ringptr,
+			    register u_int * pdlptr);
+static void hp100_rxfill(struct net_device *dev);
+static void hp100_hwinit(struct net_device *dev);
+static void hp100_clean_txring(struct net_device *dev);
 #ifdef HP100_DEBUG
-static void hp100_RegisterDump( struct net_device *dev );
+static void hp100_RegisterDump(struct net_device *dev);
 #endif
 
 /* TODO: This function should not really be needed in a good design... */
-static void wait( void )
+static void wait(void)
 {
-  mdelay(1);
+	mdelay(1);
 }
 
 /*
@@ -343,977 +359,923 @@
  *  These functions should - if possible - avoid doing write operations
  *  since this could cause problems when the card is not installed.
  */
- 
-int __init hp100_probe( struct net_device *dev )
+
+int __init hp100_probe(struct net_device *dev)
 {
-  int base_addr = dev ? dev -> base_addr : 0;
-  int ioaddr = 0;
+	int base_addr = dev ? dev->base_addr : 0;
+	int ioaddr = 0;
 #ifdef CONFIG_PCI
-  int pci_start_index = 0;
+	int pci_start_index = 0;
 #endif
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4200, TRACE );
-  printk( "hp100: %s: probe\n", dev->name );
+	hp100_outw(0x4200, TRACE);
+	printk("hp100: %s: probe\n", dev->name);
 #endif
 
-  if ( base_addr > 0xff )	/* Check a single specified location. */
-    {
-      if ( check_region( base_addr, HP100_REGION_SIZE ) ) return -EINVAL;
-      if ( base_addr < 0x400 )
-        return hp100_probe1( dev, base_addr, HP100_BUS_ISA, NULL );
-      if ( EISA_bus && base_addr >= 0x1c38 && ( (base_addr - 0x1c38) & 0x3ff ) == 0 )
-        return hp100_probe1( dev, base_addr, HP100_BUS_EISA, NULL );
+	if (base_addr > 0xff) {	/* Check a single specified location. */
+		if (check_region(base_addr, HP100_REGION_SIZE))
+			return -EINVAL;
+		if (base_addr < 0x400)
+			return hp100_probe1(dev, base_addr, HP100_BUS_ISA,
+					    NULL);
+		if (EISA_bus && base_addr >= 0x1c38 && ((base_addr - 0x1c38) & 0x3ff) == 0)
+			return hp100_probe1(dev, base_addr, HP100_BUS_EISA, NULL);
 #ifdef CONFIG_PCI
-      printk( "hp100: %s: You must specify card # in i/o address parameter for PCI bus...", dev->name );
+		printk("hp100: %s: You must specify card # in i/o address parameter for PCI bus...", dev->name);
 #else
-      return -ENODEV;
+		return -ENODEV;
 #endif
-    }
-  else
+	} else
 #ifdef CONFIG_PCI
-    if ( base_addr > 0 && base_addr < 8 + 1 )
-      pci_start_index = 0x100 | ( base_addr - 1 );
-    else
+		if (base_addr > 0 && base_addr < 8 + 1)
+			pci_start_index = 0x100 | (base_addr - 1);
+	  else
 #endif
-      if ( base_addr != 0 ) return -ENXIO;
+		if (base_addr != 0)
+			return -ENXIO;
 
-  /* at first - scan PCI bus(es) */
+	/* First: scan PCI bus(es) */
 
 #ifdef CONFIG_PCI
-  if ( pcibios_present() )
-    {
-      int pci_index;
-      struct pci_dev *pci_dev = NULL;
-      int pci_id_index;
-      u_short pci_command;
+	if (pcibios_present()) {
+		int pci_index;
+		struct pci_dev *pci_dev = NULL;
+		int pci_id_index;
+		u_short pci_command;
 
 #ifdef HP100_DEBUG_PCI
-      printk( "hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name );
+		printk("hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name);
 #endif
-      pci_index = 0;
-      for ( pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE; pci_id_index++ ) {
-        while ( (pci_dev = pci_find_device( hp100_pci_ids[ pci_id_index ].vendor,
-            			            hp100_pci_ids[ pci_id_index ].device,
-            			            pci_dev )) != NULL ) {
-          if ( pci_index < (pci_start_index & 7) ) {
-            pci_index++;
-            continue;
-          }
-	  if (pci_enable_device(pci_dev))
-	  	continue;
-          /* found... */
-          ioaddr = pci_resource_start (pci_dev, 0);
-          if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
-          pci_read_config_word( pci_dev, PCI_COMMAND, &pci_command );
-          if ( !( pci_command & PCI_COMMAND_IO ) ) {
-#ifdef HP100_DEBUG
-            printk( "hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name );
-#endif
-            pci_command |= PCI_COMMAND_IO;
-            pci_write_config_word( pci_dev, PCI_COMMAND, pci_command );
-          }
-          if ( !( pci_command & PCI_COMMAND_MASTER ) ) {
-#ifdef HP100_DEBUG
-            printk( "hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name );
-#endif
-            pci_command |= PCI_COMMAND_MASTER;
-            pci_write_config_word( pci_dev, PCI_COMMAND, pci_command );
-          }
-#ifdef HP100_DEBUG
-          printk( "hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr );
-#endif
-	  if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI, pci_dev ) == 0 )
-	    return 0;
-        }
-      }      
-    }
-  if ( pci_start_index > 0 ) return -ENODEV;
+		pci_index = 0;
+		for (pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE;
+		     pci_id_index++) {
+			while ((pci_dev = pci_find_device(hp100_pci_ids[pci_id_index].vendor,
+							  hp100_pci_ids[pci_id_index].device,
+							  pci_dev)) != NULL) {
+				if (pci_index < (pci_start_index & 7)) {
+					pci_index++;
+					continue;
+				}
+				if (pci_enable_device(pci_dev))
+					continue;
+				/* found... */
+				ioaddr = pci_resource_start(pci_dev, 0);
+				if (check_region(ioaddr, HP100_REGION_SIZE))
+					continue;
+				pci_read_config_word(pci_dev, PCI_COMMAND, &pci_command);
+				if (!(pci_command & PCI_COMMAND_IO)) {
+#ifdef HP100_DEBUG
+					printk("hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name);
+#endif
+					pci_command |= PCI_COMMAND_IO;
+					pci_write_config_word(pci_dev, PCI_COMMAND, pci_command);
+				}
+				if (!(pci_command & PCI_COMMAND_MASTER)) {
+#ifdef HP100_DEBUG
+					printk("hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name);
+#endif
+					pci_command |= PCI_COMMAND_MASTER;
+					pci_write_config_word(pci_dev, PCI_COMMAND, pci_command);
+				}
+#ifdef HP100_DEBUG
+				printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr);
+#endif
+				if (hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pci_dev) == 0)
+					return 0;
+			}
+		}
+	}
+	if (pci_start_index > 0)
+		return -ENODEV;
 #endif /* CONFIG_PCI */
 
-  /* Second: Probe all EISA possible port regions (if EISA bus present) */
-  for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 )
-    {
-      if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
-      if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA, NULL ) == 0 ) return 0;
-    }
-
-  /* Third Probe all ISA possible port regions */
-  for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 )
-    {
-      if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
-      if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA, NULL ) == 0 ) return 0;
-    }
+	/* Second: Probe all EISA possible port regions (if EISA bus present) */
+	for (ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400) {
+		if (check_region(ioaddr, HP100_REGION_SIZE))
+			continue;
+		if (hp100_probe1(dev, ioaddr, HP100_BUS_EISA, NULL) == 0)
+			return 0;
+	}
+
+	/* Third: Probe all ISA possible port regions */
+	for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
+		if (check_region(ioaddr, HP100_REGION_SIZE))
+			continue;
+		if (hp100_probe1(dev, ioaddr, HP100_BUS_ISA, NULL) == 0)
+			return 0;
+	}
 
-  return -ENODEV;
+	return -ENODEV;
 }
 
-
-static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev )
+static int __init hp100_probe1(struct net_device *dev, int ioaddr,
+			       u_char bus, struct pci_dev *pci_dev)
 {
-  int i;
+	int i;
+
+	u_char uc, uc_1;
+	u_int eisa_id;
+	u_int chip;
+	u_int memory_size = 0, virt_memory_size = 0;
+	u_short local_mode, lsw;
+	short mem_mapped;
+	unsigned long mem_ptr_phys;
+	void **mem_ptr_virt;
+	struct hp100_private *lp;
+	struct hp100_eisa_id *eid;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4201, TRACE);
+	printk("hp100: %s: probe1\n", dev->name);
+#endif
+
+	if (dev == NULL) {
+#ifdef HP100_DEBUG
+		printk("hp100_probe1: %s: dev == NULL ?\n", dev->name);
+#endif
+		return -EIO;
+	}
+
+	if (hp100_inw(HW_ID) != HP100_HW_ID_CASCADE) {
+		return -ENODEV;
+	} else {
+		chip = hp100_inw(PAGING) & HP100_CHIPID_MASK;
+#ifdef HP100_DEBUG
+		if (chip == HP100_CHIPID_SHASTA)
+			printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name);
+		else if (chip == HP100_CHIPID_RAINIER)
+			printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name);
+		else if (chip == HP100_CHIPID_LASSEN)
+			printk("hp100: %s: Lassen Chip detected.\n", dev->name);
+		else
+			printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n", dev->name, chip);
+#endif
+	}
+
+	dev->base_addr = ioaddr;
+
+	hp100_page(ID_MAC_ADDR);
+	for (i = uc = eisa_id = 0; i < 4; i++) {
+		eisa_id >>= 8;
+		uc_1 = hp100_inb(BOARD_ID + i);
+		eisa_id |= uc_1 << 24;
+		uc += uc_1;
+	}
+	uc += hp100_inb(BOARD_ID + 4);
 
-  u_char uc, uc_1;
-  u_int eisa_id;
-  u_int chip;
-  u_int memory_size = 0, virt_memory_size = 0;
-  u_short local_mode, lsw;
-  short mem_mapped;
-  unsigned long mem_ptr_phys;
-  void **mem_ptr_virt;
-  struct hp100_private *lp;
-  struct hp100_eisa_id *eid;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4201, TRACE );
-  printk("hp100: %s: probe1\n",dev->name);
-#endif
-
-  if ( dev == NULL )
-    {
-#ifdef HP100_DEBUG
-      printk( "hp100_probe1: %s: dev == NULL ?\n", dev->name );
-#endif
-      return -EIO;
-    }
-  
-  if ( hp100_inw( HW_ID ) != HP100_HW_ID_CASCADE ) 
-    {
-      return -ENODEV;
-    }
-  else
-    {
-      chip = hp100_inw( PAGING ) & HP100_CHIPID_MASK;
-#ifdef HP100_DEBUG
-      if ( chip == HP100_CHIPID_SHASTA )
-        printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name);
-      else if ( chip == HP100_CHIPID_RAINIER )
-        printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name);
-      else if ( chip == HP100_CHIPID_LASSEN )
-        printk("hp100: %s: Lassen Chip detected.\n", dev->name);
-      else
-        printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n",dev->name,chip);
-#endif 
-    }
-
-  dev->base_addr = ioaddr;
-
-  hp100_page( ID_MAC_ADDR );
-  for ( i = uc = eisa_id = 0; i < 4; i++ )
-    {
-      eisa_id >>= 8;
-      uc_1 = hp100_inb( BOARD_ID + i );
-      eisa_id |= uc_1 << 24;
-      uc += uc_1;
-    }
-  uc += hp100_inb( BOARD_ID + 4 );
-
-  if ( uc != 0xff )    /* bad checksum? */
-    {
-      printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr );
-      return -ENODEV;
-    }
-
-  for ( i=0; i < HP100_EISA_IDS_SIZE; i++)
-    if ( hp100_eisa_ids[ i ].id == eisa_id )
-      break;
-  if ( i >= HP100_EISA_IDS_SIZE ) {
-    for ( i = 0; i < HP100_EISA_IDS_SIZE; i++)
-      if ( ( hp100_eisa_ids[ i ].id & 0xf0ffffff ) == ( eisa_id & 0xf0ffffff ) )
-        break;
-    if ( i >= HP100_EISA_IDS_SIZE ) {
-      printk( "hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev -> name, ioaddr, eisa_id );
-        return -ENODEV;
-    }
-  }
-  eid = &hp100_eisa_ids[ i ];
-  if ( ( eid->id & 0x0f000000 ) < ( eisa_id & 0x0f000000 ) )
-    {
-      printk( "hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n",
-	      dev->name, eid->name, ioaddr );
-      return -ENODEV;
-    }
-
-  for ( i = uc = 0; i < 7; i++ )
-    uc += hp100_inb( LAN_ADDR + i );
-  if ( uc != 0xff )
-    {
-      printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n",
-	     dev->name, eid->name, ioaddr );
-      return -EIO;
-    }
-
-  /* Make sure, that all registers are correctly updated... */
-
-  hp100_load_eeprom( dev, ioaddr );
-  wait();
-
-  /*
-   * Determine driver operation mode
-   *
-   * Use the variable "hp100_mode" upon insmod or as kernel parameter to
-   * force driver modes:
-   * hp100_mode=1 -> default, use busmaster mode if configured.
-   * hp100_mode=2 -> enable shared memory mode 
-   * hp100_mode=3 -> force use of i/o mapped mode.
-   * hp100_mode=4 -> same as 1, but re-set the enable bit on the card.
-   */
-
-  /*
-   * LSW values:
-   *   0x2278 -> J2585B, PnP shared memory mode
-   *   0x2270 -> J2585B, shared memory mode, 0xdc000
-   *   0xa23c -> J2585B, I/O mapped mode
-   *   0x2240 -> EISA COMPEX, BusMaster (Shasta Chip)
-   *   0x2220 -> EISA HP, I/O (Shasta Chip)
-   *   0x2260 -> EISA HP, BusMaster (Shasta Chip)
-   */
+	if (uc != 0xff) {	/* bad checksum? */
+		printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < HP100_EISA_IDS_SIZE; i++)
+		if (hp100_eisa_ids[i].id == eisa_id)
+			break;
+	if (i >= HP100_EISA_IDS_SIZE) {
+		for (i = 0; i < HP100_EISA_IDS_SIZE; i++)
+			if ((hp100_eisa_ids[i].id & 0xf0ffffff) == (eisa_id & 0xf0ffffff))
+				break;
+		if (i >= HP100_EISA_IDS_SIZE) {
+			printk ("hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev->name, ioaddr, eisa_id);
+			return -ENODEV;
+		}
+	}
+	eid = &hp100_eisa_ids[i];
+	if ((eid->id & 0x0f000000) < (eisa_id & 0x0f000000)) {
+		printk("hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n", dev->name, eid->name, ioaddr);
+		return -ENODEV;
+	}
+
+	for (i = uc = 0; i < 7; i++)
+		uc += hp100_inb(LAN_ADDR + i);
+	if (uc != 0xff) {
+		printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n", dev->name, eid->name, ioaddr);
+		return -EIO;
+	}
+
+	/* Make sure, that all registers are correctly updated... */
+
+	hp100_load_eeprom(dev, ioaddr);
+	wait();
+
+	/*
+	 * Determine driver operation mode
+	 *
+	 * Use the variable "hp100_mode" upon insmod or as kernel parameter to
+	 * force driver modes:
+	 * hp100_mode=1 -> default, use busmaster mode if configured.
+	 * hp100_mode=2 -> enable shared memory mode 
+	 * hp100_mode=3 -> force use of i/o mapped mode.
+	 * hp100_mode=4 -> same as 1, but re-set the enable bit on the card.
+	 */
+
+	/*
+	 * LSW values:
+	 *   0x2278 -> J2585B, PnP shared memory mode
+	 *   0x2270 -> J2585B, shared memory mode, 0xdc000
+	 *   0xa23c -> J2585B, I/O mapped mode
+	 *   0x2240 -> EISA COMPEX, BusMaster (Shasta Chip)
+	 *   0x2220 -> EISA HP, I/O (Shasta Chip)
+	 *   0x2260 -> EISA HP, BusMaster (Shasta Chip)
+	 */
 
 #if 0
-  local_mode = 0x2270;
-  hp100_outw(0xfefe,OPTION_LSW);
-  hp100_outw(local_mode|HP100_SET_LB|HP100_SET_HB,OPTION_LSW);
-#endif
-
-  /* hp100_mode value maybe used in future by another card */
-  local_mode=hp100_mode;
-  if ( local_mode < 1 || local_mode > 4 )
-    local_mode = 1;		/* default */
-#ifdef HP100_DEBUG
-  printk( "hp100: %s: original LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) );
-#endif
-
-  if(local_mode==3)
-    {
-      hp100_outw(HP100_MEM_EN|HP100_RESET_LB, OPTION_LSW);
-      hp100_outw(HP100_IO_EN|HP100_SET_LB, OPTION_LSW);
-      hp100_outw(HP100_BM_WRITE|HP100_BM_READ|HP100_RESET_HB, OPTION_LSW);
-      printk("hp100: %s: IO mapped mode forced.\n", dev->name);
-    }
-  else if(local_mode==2)
-    {
-      hp100_outw(HP100_MEM_EN|HP100_SET_LB, OPTION_LSW);
-      hp100_outw(HP100_IO_EN |HP100_SET_LB, OPTION_LSW);
-      hp100_outw(HP100_BM_WRITE|HP100_BM_READ|HP100_RESET_HB, OPTION_LSW);
-      printk("hp100: %s: Shared memory mode requested.\n", dev->name);
-    } 
-  else if(local_mode==4)
-    {
-      if(chip==HP100_CHIPID_LASSEN)
-	{
-	  hp100_outw(HP100_BM_WRITE|
-		     HP100_BM_READ | HP100_SET_HB, OPTION_LSW);
-	  hp100_outw(HP100_IO_EN   | 
-		     HP100_MEM_EN  | HP100_RESET_LB, OPTION_LSW);
-	  printk("hp100: %s: Busmaster mode requested.\n",dev->name);
-	}
-      local_mode=1;
-    }
-		
-  if(local_mode==1) /* default behaviour */
-    {
-      lsw = hp100_inw(OPTION_LSW);
-    
-      if ( (lsw & HP100_IO_EN) &&
-	   (~lsw & HP100_MEM_EN) &&
-	   (~lsw & (HP100_BM_WRITE|HP100_BM_READ)) )
-	{
-#ifdef HP100_DEBUG
-	  printk("hp100: %s: IO_EN bit is set on card.\n",dev->name);
-#endif
-	  local_mode=3;
-	}
-      else if ( chip == HP100_CHIPID_LASSEN &&
-	        ( lsw & (HP100_BM_WRITE|HP100_BM_READ) ) ==
-	                (HP100_BM_WRITE|HP100_BM_READ) )
-	{
-	  printk("hp100: %s: Busmaster mode enabled.\n",dev->name);
-	  hp100_outw(HP100_MEM_EN|HP100_IO_EN|HP100_RESET_LB, OPTION_LSW);
-	}
-      else
-	{
-#ifdef HP100_DEBUG
-	  printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name );
-	  printk("hp100: %s: Trying shared memory mode.\n", dev->name);
-#endif
-	  /* In this case, try shared memory mode */
-	  local_mode=2;
-	  hp100_outw(HP100_MEM_EN|HP100_SET_LB, OPTION_LSW);
-	  /* hp100_outw(HP100_IO_EN|HP100_RESET_LB, OPTION_LSW); */
-	}
-    }
-
-#ifdef HP100_DEBUG
-  printk( "hp100: %s: new LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) );
-#endif
-
-  /* Check for shared memory on the card, eventually remap it */
-  hp100_page( HW_MAP );
-  mem_mapped = (( hp100_inw( OPTION_LSW ) & ( HP100_MEM_EN ) ) != 0);
-  mem_ptr_phys = 0UL;
-  mem_ptr_virt = NULL;
-  memory_size = (8192<<( (hp100_inb(SRAM)>>5)&0x07));
-  virt_memory_size = 0;
-
-  /* For memory mapped or busmaster mode, we want the memory address */
-  if ( mem_mapped || (local_mode==1))
-    {
-      mem_ptr_phys = ( hp100_inw( MEM_MAP_LSW ) | 
-				( hp100_inw( MEM_MAP_MSW ) << 16 ) );
-      mem_ptr_phys &= ~0x1fff;  /* 8k alignment */
-
-      if ( bus == HP100_BUS_ISA && (mem_ptr_phys & ~0xfffff ) != 0 )
-        {
-	  printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name);
-          mem_ptr_phys = 0;
-          mem_mapped = 0;
-	  local_mode=3; /* Use programmed i/o */
-        }
-						
-      /* We do not need access to shared memory in busmaster mode */
-      /* However in slave mode we need to remap high (>1GB) card memory  */
-      if(local_mode!=1) /* = not busmaster */
-	{
-	  if ( bus == HP100_BUS_PCI && mem_ptr_phys >= 0x100000 )
-	    {
-	      /* We try with smaller memory sizes, if ioremap fails */
-	      for(virt_memory_size = memory_size; virt_memory_size>16383; virt_memory_size>>=1)
-		{
-		  if((mem_ptr_virt=ioremap((u_long)mem_ptr_phys,virt_memory_size))==NULL)
-		    {
-#ifdef HP100_DEBUG
-		      printk( "hp100: %s: ioremap for 0x%x bytes high PCI memory at 0x%lx failed\n", dev->name, virt_memory_size, mem_ptr_phys );
-#endif
-		    }	
-		  else
-		    {
-#ifdef HP100_DEBUG
-		      printk( "hp100: %s: remapped 0x%x bytes high PCI memory at 0x%lx to %p.\n", dev->name, virt_memory_size, mem_ptr_phys, mem_ptr_virt);
-#endif
-		      break;
-		    }
-		}
-														
-	      if(mem_ptr_virt==NULL) /* all ioremap tries failed */
-		{
-		  printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name);
-		  local_mode=3;
-		  virt_memory_size = 0;
-		}
-	    }
-	}
-						
-    }
-
-  if(local_mode==3) /* io mapped forced */
-    {
-      mem_mapped = 0;
-      mem_ptr_phys = 0;
-      mem_ptr_virt = NULL;
-      printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name);
-    }
-
-  /* Initialise the "private" data structure for this card. */
-  if ( (dev->priv=kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL)
-    return -ENOMEM;
-
-  lp = (struct hp100_private *)dev->priv;
-  memset( lp, 0, sizeof( struct hp100_private ) );
-  spin_lock_init(&lp->lock);
-  lp->id = eid;
-  lp->chip = chip;
-  lp->mode = local_mode;
-  lp->bus = bus;
-  lp->pci_dev = pci_dev;
-  lp->priority_tx = hp100_priority_tx;
-  lp->rx_ratio = hp100_rx_ratio;
-  lp->mem_ptr_phys = mem_ptr_phys;
-  lp->mem_ptr_virt = mem_ptr_virt;
-  hp100_page( ID_MAC_ADDR );
-  lp->soft_model = hp100_inb( SOFT_MODEL );
-  lp->mac1_mode = HP100_MAC1MODE3;
-  lp->mac2_mode = HP100_MAC2MODE3;
-  memset( &lp->hash_bytes, 0x00, 8 );
-
-  dev->base_addr = ioaddr;
-
-  lp->memory_size = memory_size;
-  lp->virt_memory_size = virt_memory_size;
-  lp->rx_ratio = hp100_rx_ratio; /* can be conf'd with insmod */
-
-  /* memory region for programmed i/o */
-  request_region( dev->base_addr, HP100_REGION_SIZE, eid->name );
-
-  dev->open = hp100_open;
-  dev->stop = hp100_close;
-
-  if (lp->mode==1) /* busmaster */
-    dev->hard_start_xmit = hp100_start_xmit_bm;
-  else
-    dev->hard_start_xmit = hp100_start_xmit;
-
-  dev->get_stats = hp100_get_stats;
-  dev->set_multicast_list = &hp100_set_multicast_list;
-
-  /* Ask the card for which IRQ line it is configured */
-  if ( bus == HP100_BUS_PCI ) {
-    dev->irq = pci_dev->irq;
-  } else {
-    hp100_page( HW_MAP );
-    dev->irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQMASK;
-    if ( dev->irq == 2 )
-      dev->irq = 9;
-  }
-
-  if(lp->mode==1) /* busmaster */
-    dev->dma=4; 
-
-  /* Ask the card for its MAC address and store it for later use. */
-  hp100_page( ID_MAC_ADDR );
-  for ( i = uc = 0; i < 6; i++ )
-    dev->dev_addr[ i ] = hp100_inb( LAN_ADDR + i );
-
-  /* Reset statistics (counters) */
-  hp100_clear_stats( lp, ioaddr );
-
-  SET_MODULE_OWNER(dev);
-  ether_setup( dev );
-
-  /* If busmaster mode is wanted, a dma-capable memory area is needed for
-   * the rx and tx PDLs 
-   * PCI cards can access the whole PC memory. Therefore GFP_DMA is not
-   * needed for the allocation of the memory area. 
-   */
-
-  /* TODO: We do not need this with old cards, where PDLs are stored
-   * in the cards shared memory area. But currently, busmaster has been
-   * implemented/tested only with the lassen chip anyway... */
-  if(lp->mode==1) /* busmaster */
-    {
-      /* Get physically continous memory for TX & RX PDLs    */
-      if ( (lp->page_vaddr=kmalloc(MAX_RINGSIZE+0x0f,GFP_KERNEL) ) == NULL)
-        return -ENOMEM;
-      lp->page_vaddr_algn=((u_int *) ( ((u_int)(lp->page_vaddr)+0x0f) &~0x0f));
-      memset(lp->page_vaddr, 0, MAX_RINGSIZE+0x0f);
+	local_mode = 0x2270;
+	hp100_outw(0xfefe, OPTION_LSW);
+	hp100_outw(local_mode | HP100_SET_LB | HP100_SET_HB, OPTION_LSW);
+#endif
+
+	/* hp100_mode value maybe used in future by another card */
+	local_mode = hp100_mode;
+	if (local_mode < 1 || local_mode > 4)
+		local_mode = 1;	/* default */
+#ifdef HP100_DEBUG
+	printk("hp100: %s: original LSW = 0x%x\n", dev->name,
+	       hp100_inw(OPTION_LSW));
+#endif
+
+	if (local_mode == 3) {
+		hp100_outw(HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW);
+		hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
+		hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW);
+		printk("hp100: %s: IO mapped mode forced.\n", dev->name);
+	} else if (local_mode == 2) {
+		hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW);
+		hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
+		hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW);
+		printk("hp100: %s: Shared memory mode requested.\n", dev->name);
+	} else if (local_mode == 4) {
+		if (chip == HP100_CHIPID_LASSEN) {
+			hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_SET_HB, OPTION_LSW);
+			hp100_outw(HP100_IO_EN | HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW);
+			printk("hp100: %s: Busmaster mode requested.\n", dev->name);
+		}
+		local_mode = 1;
+	}
+
+	if (local_mode == 1) {	/* default behaviour */
+		lsw = hp100_inw(OPTION_LSW);
+
+		if ((lsw & HP100_IO_EN) && (~lsw & HP100_MEM_EN) &&
+		    (~lsw & (HP100_BM_WRITE | HP100_BM_READ))) {
+#ifdef HP100_DEBUG
+			printk("hp100: %s: IO_EN bit is set on card.\n", dev->name);
+#endif
+			local_mode = 3;
+		} else if (chip == HP100_CHIPID_LASSEN &&
+			   (lsw & (HP100_BM_WRITE | HP100_BM_READ)) == (HP100_BM_WRITE | HP100_BM_READ)) {
+			printk("hp100: %s: Busmaster mode enabled.\n", dev->name);
+			hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW);
+		} else {
+#ifdef HP100_DEBUG
+			printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name);
+			printk("hp100: %s: Trying shared memory mode.\n", dev->name);
+#endif
+			/* In this case, try shared memory mode */
+			local_mode = 2;
+			hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW);
+			/* hp100_outw(HP100_IO_EN|HP100_RESET_LB, OPTION_LSW); */
+		}
+	}
+#ifdef HP100_DEBUG
+	printk("hp100: %s: new LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW));
+#endif
+
+	/* Check for shared memory on the card, eventually remap it */
+	hp100_page(HW_MAP);
+	mem_mapped = ((hp100_inw(OPTION_LSW) & (HP100_MEM_EN)) != 0);
+	mem_ptr_phys = 0UL;
+	mem_ptr_virt = NULL;
+	memory_size = (8192 << ((hp100_inb(SRAM) >> 5) & 0x07));
+	virt_memory_size = 0;
+
+	/* For memory mapped or busmaster mode, we want the memory address */
+	if (mem_mapped || (local_mode == 1)) {
+		mem_ptr_phys = (hp100_inw(MEM_MAP_LSW) | (hp100_inw(MEM_MAP_MSW) << 16));
+		mem_ptr_phys &= ~0x1fff;	/* 8k alignment */
+
+		if (bus == HP100_BUS_ISA && (mem_ptr_phys & ~0xfffff) != 0) {
+			printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name);
+			mem_ptr_phys = 0;
+			mem_mapped = 0;
+			local_mode = 3;	/* Use programmed i/o */
+		}
+
+		/* We do not need access to shared memory in busmaster mode */
+		/* However in slave mode we need to remap high (>1GB) card memory  */
+		if (local_mode != 1) {	/* = not busmaster */
+			/* We try with smaller memory sizes, if ioremap fails */
+			for (virt_memory_size = memory_size; virt_memory_size > 16383; virt_memory_size >>= 1) {
+				if ((mem_ptr_virt = ioremap((u_long) mem_ptr_phys, virt_memory_size)) == NULL) {
+#ifdef HP100_DEBUG
+					printk("hp100: %s: ioremap for 0x%x bytes high PCI memory at 0x%lx failed\n", dev->name, virt_memory_size, mem_ptr_phys);
+#endif
+				} else {
+#ifdef HP100_DEBUG
+					printk("hp100: %s: remapped 0x%x bytes high PCI memory at 0x%lx to %p.\n", dev->name, virt_memory_size, mem_ptr_phys, mem_ptr_virt);
+#endif
+					break;
+				}
+			}
+
+			if (mem_ptr_virt == NULL) {	/* all ioremap tries failed */
+				printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name);
+				local_mode = 3;
+				virt_memory_size = 0;
+			}
+		}
+	}
+
+	if (local_mode == 3) {	/* io mapped forced */
+		mem_mapped = 0;
+		mem_ptr_phys = 0;
+		mem_ptr_virt = NULL;
+		printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name);
+	}
+
+	/* Initialise the "private" data structure for this card. */
+	if ((dev->priv = kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+
+	lp = (struct hp100_private *) dev->priv;
+	memset(lp, 0, sizeof(struct hp100_private));
+	spin_lock_init(&lp->lock);
+	lp->id = eid;
+	lp->chip = chip;
+	lp->mode = local_mode;
+	lp->bus = bus;
+	lp->pci_dev = pci_dev;
+	lp->priority_tx = hp100_priority_tx;
+	lp->rx_ratio = hp100_rx_ratio;
+	lp->mem_ptr_phys = mem_ptr_phys;
+	lp->mem_ptr_virt = mem_ptr_virt;
+	hp100_page(ID_MAC_ADDR);
+	lp->soft_model = hp100_inb(SOFT_MODEL);
+	lp->mac1_mode = HP100_MAC1MODE3;
+	lp->mac2_mode = HP100_MAC2MODE3;
+	memset(&lp->hash_bytes, 0x00, 8);
+
+	dev->base_addr = ioaddr;
+
+	lp->memory_size = memory_size;
+	lp->virt_memory_size = virt_memory_size;
+	lp->rx_ratio = hp100_rx_ratio;	/* can be conf'd with insmod */
+
+	/* memory region for programmed i/o */
+	request_region(dev->base_addr, HP100_REGION_SIZE, eid->name);
+
+	dev->open = hp100_open;
+	dev->stop = hp100_close;
+
+	if (lp->mode == 1)	/* busmaster */
+		dev->hard_start_xmit = hp100_start_xmit_bm;
+	else
+		dev->hard_start_xmit = hp100_start_xmit;
+
+	dev->get_stats = hp100_get_stats;
+	dev->set_multicast_list = &hp100_set_multicast_list;
+
+	/* Ask the card for which IRQ line it is configured */
+	if (bus == HP100_BUS_PCI) {
+		dev->irq = pci_dev->irq;
+	} else {
+		hp100_page(HW_MAP);
+		dev->irq = hp100_inb(IRQ_CHANNEL) & HP100_IRQMASK;
+		if (dev->irq == 2)
+			dev->irq = 9;
+	}
+
+	if (lp->mode == 1)	/* busmaster */
+		dev->dma = 4;
+
+	/* Ask the card for its MAC address and store it for later use. */
+	hp100_page(ID_MAC_ADDR);
+	for (i = uc = 0; i < 6; i++)
+		dev->dev_addr[i] = hp100_inb(LAN_ADDR + i);
+
+	/* Reset statistics (counters) */
+	hp100_clear_stats(lp, ioaddr);
+
+	SET_MODULE_OWNER(dev);
+	ether_setup(dev);
+
+	/* If busmaster mode is wanted, a dma-capable memory area is needed for
+	 * the rx and tx PDLs 
+	 * PCI cards can access the whole PC memory. Therefore GFP_DMA is not
+	 * needed for the allocation of the memory area. 
+	 */
+
+	/* TODO: We do not need this with old cards, where PDLs are stored
+	 * in the cards shared memory area. But currently, busmaster has been
+	 * implemented/tested only with the lassen chip anyway... */
+	if (lp->mode == 1) {	/* busmaster */
+		/* Get physically continous memory for TX & RX PDLs    */
+		if ((lp->page_vaddr = kmalloc(MAX_RINGSIZE + 0x0f, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		lp->page_vaddr_algn = ((u_int *) (((u_int) (lp->page_vaddr) + 0x0f) & ~0x0f));
+		memset(lp->page_vaddr, 0, MAX_RINGSIZE + 0x0f);
 
 #ifdef HP100_DEBUG_BM
-      printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n",
-      	     dev->name,
-             (u_int)lp->page_vaddr_algn,
-             (u_int)lp->page_vaddr_algn+MAX_RINGSIZE);
-#endif
-      lp->rxrcommit  = lp->txrcommit = 0;
-      lp->rxrhead    = lp->rxrtail   = &(lp->rxring[0]);
-      lp->txrhead    = lp->txrtail   = &(lp->txring[0]); 
-    }
-
-  /* Initialise the card. */
-  /* (I'm not really sure if it's a good idea to do this during probing, but 
-   * like this it's assured that the lan connection type can be sensed
-   * correctly)
-   */
-  hp100_hwinit( dev );
-
-  /* Try to find out which kind of LAN the card is connected to. */
-  lp->lan_type = hp100_sense_lan( dev );
-     
-  /* Print out a message what about what we think we have probed. */
-  printk( "hp100: %s: %s at 0x%x, IRQ %d, ",
-          dev->name, lp->id->name, ioaddr, dev->irq );
-  switch ( bus ) {
-  case HP100_BUS_EISA: printk( "EISA" ); break;
-  case HP100_BUS_PCI:  printk( "PCI" );  break;
-  default:     printk( "ISA" );  break;
-  }
-  printk( " bus, %dk SRAM (rx/tx %d%%).\n",
-          lp->memory_size >> 10, lp->rx_ratio );
-
-  if ( lp->mode==2 ) /* memory mapped */ 
-    {
-      printk( "hp100: %s: Memory area at 0x%lx-0x%lx",
-              dev->name,mem_ptr_phys,
-              (mem_ptr_phys+(mem_ptr_phys>0x100000?(u_long)lp->memory_size:16*1024))-1 );
-      if ( mem_ptr_virt )
-	printk( " (virtual base %p)", mem_ptr_virt );
-      printk( ".\n" );
-
-      /* Set for info when doing ifconfig */
-      dev->mem_start = mem_ptr_phys;
-      dev->mem_end = mem_ptr_phys+lp->memory_size;
-    }
-  printk( "hp100: %s: ", dev->name );
-  if ( lp->lan_type != HP100_LAN_ERR )
-    printk( "Adapter is attached to " );
-  switch ( lp->lan_type ) {
-  case HP100_LAN_100:
-    printk( "100Mb/s Voice Grade AnyLAN network.\n" );
-    break;
-  case HP100_LAN_10:
-    printk( "10Mb/s network.\n" );
-    break;
-  default:
-    printk( "Warning! Link down.\n" );
-  }
+		printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n", dev->name, (u_int) lp->page_vaddr_algn, (u_int) lp->page_vaddr_algn + MAX_RINGSIZE);
+#endif
+		lp->rxrcommit = lp->txrcommit = 0;
+		lp->rxrhead = lp->rxrtail = &(lp->rxring[0]);
+		lp->txrhead = lp->txrtail = &(lp->txring[0]);
+	}
+
+	/* Initialise the card. */
+	/* (I'm not really sure if it's a good idea to do this during probing, but 
+	 * like this it's assured that the lan connection type can be sensed
+	 * correctly)
+	 */
+	hp100_hwinit(dev);
+
+	/* Try to find out which kind of LAN the card is connected to. */
+	lp->lan_type = hp100_sense_lan(dev);
+
+	/* Print out a message what about what we think we have probed. */
+	printk("hp100: %s: %s at 0x%x, IRQ %d, ", dev->name, lp->id->name, ioaddr, dev->irq);
+	switch (bus) {
+	case HP100_BUS_EISA:
+		printk("EISA");
+		break;
+	case HP100_BUS_PCI:
+		printk("PCI");
+		break;
+	default:
+		printk("ISA");
+		break;
+	}
+	printk(" bus, %dk SRAM (rx/tx %d%%).\n", lp->memory_size >> 10, lp->rx_ratio);
+
+	if (lp->mode == 2) {	/* memory mapped */
+		printk("hp100: %s: Memory area at 0x%lx-0x%lx", dev->name, mem_ptr_phys,
+				(mem_ptr_phys + (mem_ptr_phys > 0x100000 ? (u_long) lp->memory_size : 16 * 1024)) - 1);
+		if (mem_ptr_virt)
+			printk(" (virtual base %p)", mem_ptr_virt);
+		printk(".\n");
+
+		/* Set for info when doing ifconfig */
+		dev->mem_start = mem_ptr_phys;
+		dev->mem_end = mem_ptr_phys + lp->memory_size;
+	}
+	printk("hp100: %s: ", dev->name);
+	if (lp->lan_type != HP100_LAN_ERR)
+		printk("Adapter is attached to ");
+	switch (lp->lan_type) {
+	case HP100_LAN_100:
+		printk("100Mb/s Voice Grade AnyLAN network.\n");
+		break;
+	case HP100_LAN_10:
+		printk("10Mb/s network.\n");
+		break;
+	default:
+		printk("Warning! Link down.\n");
+	}
 
-  return 0;
+	return 0;
 }
 
-
 /* This procedure puts the card into a stable init state */
-static void hp100_hwinit( struct net_device *dev )
+static void hp100_hwinit(struct net_device *dev)
 {
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4202, TRACE );
-  printk("hp100: %s: hwinit\n", dev->name);
+	hp100_outw(0x4202, TRACE);
+	printk("hp100: %s: hwinit\n", dev->name);
 #endif
 
-  /* Initialise the card. -------------------------------------------- */
-
-  /* Clear all pending Ints and disable Ints */
-  hp100_page( PERFORMANCE );
-  hp100_outw( 0xfefe, IRQ_MASK );    /* mask off all ints */
-  hp100_outw( 0xffff, IRQ_STATUS );  /* clear all pending ints */
-
-  hp100_outw( HP100_INT_EN | HP100_RESET_LB, OPTION_LSW );
-  hp100_outw( HP100_TRI_INT | HP100_SET_HB, OPTION_LSW );
-
-  if(lp->mode==1)
-    { 
-      hp100_BM_shutdown( dev ); /* disables BM, puts cascade in reset */
-      wait();
-    }
-  else
-    {
-      hp100_outw( HP100_INT_EN | HP100_RESET_LB, OPTION_LSW );
-      hp100_cascade_reset( dev, TRUE );
-      hp100_page( MAC_CTRL );
-      hp100_andb( ~(HP100_RX_EN|HP100_TX_EN), MAC_CFG_1); 
-    }
-		
-  /* Initiate EEPROM reload */
-  hp100_load_eeprom( dev, 0 );
-		
-  wait();
-		
-  /* Go into reset again. */
-  hp100_cascade_reset( dev, TRUE );
-		
-  /* Set Option Registers to a safe state  */
-  hp100_outw( HP100_DEBUG_EN |
-              HP100_RX_HDR   |
-              HP100_EE_EN    |
-              HP100_BM_WRITE |
-              HP100_BM_READ  | HP100_RESET_HB |
-              HP100_FAKE_INT |
-              HP100_INT_EN   |
-	      HP100_MEM_EN   |
-              HP100_IO_EN    | HP100_RESET_LB, OPTION_LSW);
-		
-  hp100_outw( HP100_TRI_INT  |
-              HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
-
-  hp100_outb( HP100_PRIORITY_TX |
-              HP100_ADV_NXT_PKT |
-              HP100_TX_CMD      | HP100_RESET_LB, OPTION_MSW );
-
-  /* TODO: Configure MMU for Ram Test. */
-  /* TODO: Ram Test. */
-
-  /* Re-check if adapter is still at same i/o location      */
-  /* (If the base i/o in eeprom has been changed but the    */
-  /* registers had not been changed, a reload of the eeprom */
-  /* would move the adapter to the address stored in eeprom */
-  
-  /* TODO: Code to implement. */
-		
-  /* Until here it was code from HWdiscover procedure. */
-  /* Next comes code from mmuinit procedure of SCO BM driver which is
-   * called from HWconfigure in the SCO driver.  */
-
-  /* Initialise MMU, eventually switch on Busmaster Mode, initialise 
-   * multicast filter...
-   */
-  hp100_mmuinit( dev );
-
-  /* We don't turn the interrupts on here - this is done by start_interface. */
-  wait(); /* TODO: Do we really need this? */
-
-  /* Enable Hardware (e.g. unreset) */
-  hp100_cascade_reset( dev, FALSE );
-
-  /* ------- initialisation complete ----------- */
-
-  /* Finally try to log in the Hub if there may be a VG connection. */
-  if( lp->lan_type != HP100_LAN_10 )
-    hp100_login_to_vg_hub( dev, FALSE ); /* relogin */
-}
+	/* Initialise the card. -------------------------------------------- */
+
+	/* Clear all pending Ints and disable Ints */
+	hp100_page(PERFORMANCE);
+	hp100_outw(0xfefe, IRQ_MASK);	/* mask off all ints */
+	hp100_outw(0xffff, IRQ_STATUS);	/* clear all pending ints */
+
+	hp100_outw(HP100_INT_EN | HP100_RESET_LB, OPTION_LSW);
+	hp100_outw(HP100_TRI_INT | HP100_SET_HB, OPTION_LSW);
+
+	if (lp->mode == 1) {
+		hp100_BM_shutdown(dev);	/* disables BM, puts cascade in reset */
+		wait();
+	} else {
+		hp100_outw(HP100_INT_EN | HP100_RESET_LB, OPTION_LSW);
+		hp100_cascade_reset(dev, TRUE);
+		hp100_page(MAC_CTRL);
+		hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1);
+	}
+
+	/* Initiate EEPROM reload */
+	hp100_load_eeprom(dev, 0);
+
+	wait();
+
+	/* Go into reset again. */
+	hp100_cascade_reset(dev, TRUE);
+
+	/* Set Option Registers to a safe state  */
+	hp100_outw(HP100_DEBUG_EN |
+		   HP100_RX_HDR |
+		   HP100_EE_EN |
+		   HP100_BM_WRITE |
+		   HP100_BM_READ | HP100_RESET_HB |
+		   HP100_FAKE_INT |
+		   HP100_INT_EN |
+		   HP100_MEM_EN |
+		   HP100_IO_EN | HP100_RESET_LB, OPTION_LSW);
+
+	hp100_outw(HP100_TRI_INT |
+		   HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW);
+
+	hp100_outb(HP100_PRIORITY_TX |
+		   HP100_ADV_NXT_PKT |
+		   HP100_TX_CMD | HP100_RESET_LB, OPTION_MSW);
+
+	/* TODO: Configure MMU for Ram Test. */
+	/* TODO: Ram Test. */
+
+	/* Re-check if adapter is still at same i/o location      */
+	/* (If the base i/o in eeprom has been changed but the    */
+	/* registers had not been changed, a reload of the eeprom */
+	/* would move the adapter to the address stored in eeprom */
+
+	/* TODO: Code to implement. */
+
+	/* Until here it was code from HWdiscover procedure. */
+	/* Next comes code from mmuinit procedure of SCO BM driver which is
+	 * called from HWconfigure in the SCO driver.  */
+
+	/* Initialise MMU, eventually switch on Busmaster Mode, initialise 
+	 * multicast filter...
+	 */
+	hp100_mmuinit(dev);
 
+	/* We don't turn the interrupts on here - this is done by start_interface. */
+	wait();			/* TODO: Do we really need this? */
+
+	/* Enable Hardware (e.g. unreset) */
+	hp100_cascade_reset(dev, FALSE);
+
+	/* ------- initialisation complete ----------- */
+
+	/* Finally try to log in the Hub if there may be a VG connection. */
+	if (lp->lan_type != HP100_LAN_10)
+		hp100_login_to_vg_hub(dev, FALSE);	/* relogin */
+}
 
+
 /* 
  * mmuinit - Reinitialise Cascade MMU and MAC settings.
  * Note: Must already be in reset and leaves card in reset. 
  */
-static void hp100_mmuinit( struct net_device *dev )
+static void hp100_mmuinit(struct net_device *dev)
 {
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  int i;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4203, TRACE );
-  printk("hp100: %s: mmuinit\n",dev->name);
-#endif
-
-#ifdef HP100_DEBUG
-  if( 0!=(hp100_inw(OPTION_LSW)&HP100_HW_RST) )
-    {
-      printk("hp100: %s: Not in reset when entering mmuinit. Fix me.\n",dev->name);
-      return;
-    }
-#endif
-
-  /* Make sure IRQs are masked off and ack'ed. */
-  hp100_page( PERFORMANCE );
-  hp100_outw( 0xfefe, IRQ_MASK );  /* mask off all ints */
-  hp100_outw( 0xffff, IRQ_STATUS );  /* ack IRQ */
-
-  /*
-   * Enable Hardware 
-   * - Clear Debug En, Rx Hdr Pipe, EE En, I/O En, Fake Int and Intr En
-   * - Set Tri-State Int, Bus Master Rd/Wr, and Mem Map Disable
-   * - Clear Priority, Advance Pkt and Xmit Cmd
-   */
-
-  hp100_outw( HP100_DEBUG_EN |
-              HP100_RX_HDR   |
-              HP100_EE_EN    | HP100_RESET_HB |
-              HP100_IO_EN    |
-              HP100_FAKE_INT |
-              HP100_INT_EN   | HP100_RESET_LB, OPTION_LSW );
-  	
-  hp100_outw( HP100_TRI_INT | HP100_SET_HB, OPTION_LSW);
-		
-  if(lp->mode==1) /* busmaster */
-    {
-      hp100_outw( HP100_BM_WRITE | 
-		  HP100_BM_READ  |
-		  HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
-    }
-  else if(lp->mode==2) /* memory mapped */
-    {
-      hp100_outw( HP100_BM_WRITE |
-		  HP100_BM_READ  | HP100_RESET_HB, OPTION_LSW );
-      hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );
-      hp100_outw( HP100_MEM_EN | HP100_SET_LB, OPTION_LSW );
-      hp100_outw( HP100_IO_EN | HP100_SET_LB, OPTION_LSW );
-    }
-  else if( lp->mode==3 ) /* i/o mapped mode */
-    {
-      hp100_outw( HP100_MMAP_DIS | HP100_SET_HB | 
-                  HP100_IO_EN    | HP100_SET_LB, OPTION_LSW );
-    }
-
-  hp100_page( HW_MAP );
-  hp100_outb( 0, EARLYRXCFG );
-  hp100_outw( 0, EARLYTXCFG );
-  
-  /*
-   * Enable Bus Master mode
-   */
-  if(lp->mode==1) /* busmaster */
-    {
-      /* Experimental: Set some PCI configuration bits */
-      hp100_page( HW_MAP );
-      hp100_andb( ~HP100_PDL_USE3, MODECTRL1 ); /* BM engine read maximum */
-      hp100_andb( ~HP100_TX_DUALQ, MODECTRL1 ); /* No Queue for Priority TX */
-
-      /* PCI Bus failures should result in a Misc. Interrupt */
-      hp100_orb( HP100_EN_BUS_FAIL, MODECTRL2);
-					
-      hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_SET_HB, OPTION_LSW );
-      hp100_page( HW_MAP );					
-      /* Use Burst Mode and switch on PAGE_CK */
-      hp100_orb( HP100_BM_BURST_RD |
-                 HP100_BM_BURST_WR, BM);
-      if((lp->chip==HP100_CHIPID_RAINIER)||(lp->chip==HP100_CHIPID_SHASTA))
-	hp100_orb( HP100_BM_PAGE_CK, BM );
-      hp100_orb( HP100_BM_MASTER, BM );		
-    }
-  else /* not busmaster */
-    {
-      hp100_page(HW_MAP);
-      hp100_andb(~HP100_BM_MASTER, BM );
-    }
-
-  /*
-   * Divide card memory into regions for Rx, Tx and, if non-ETR chip, PDLs
-   */  
-  hp100_page( MMU_CFG );
-  if(lp->mode==1) /* only needed for Busmaster */
-    {
-      int xmit_stop, recv_stop;
-
-      if((lp->chip==HP100_CHIPID_RAINIER)||(lp->chip==HP100_CHIPID_SHASTA))
-        {
-          int pdl_stop;
-          
-          /*
-           * Each pdl is 508 bytes long. (63 frags * 4 bytes for address and
-           * 4 bytes for header). We will leave NUM_RXPDLS * 508 (rounded
-           * to the next higher 1k boundary) bytes for the rx-pdl's
-	   * Note: For non-etr chips the transmit stop register must be
-	   * programmed on a 1k boundary, i.e. bits 9:0 must be zero. 
-	   */
-          pdl_stop  = lp->memory_size;
-          xmit_stop = ( pdl_stop-508*(MAX_RX_PDL)-16 )& ~(0x03ff);
-          recv_stop = ( xmit_stop * (lp->rx_ratio)/100 ) &~(0x03ff);
-          hp100_outw( (pdl_stop>>4)-1, PDL_MEM_STOP );
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	int i;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4203, TRACE);
+	printk("hp100: %s: mmuinit\n", dev->name);
+#endif
+
+#ifdef HP100_DEBUG
+	if (0 != (hp100_inw(OPTION_LSW) & HP100_HW_RST)) {
+		printk("hp100: %s: Not in reset when entering mmuinit. Fix me.\n", dev->name);
+		return;
+	}
+#endif
+
+	/* Make sure IRQs are masked off and ack'ed. */
+	hp100_page(PERFORMANCE);
+	hp100_outw(0xfefe, IRQ_MASK);	/* mask off all ints */
+	hp100_outw(0xffff, IRQ_STATUS);	/* ack IRQ */
+
+	/*
+	 * Enable Hardware 
+	 * - Clear Debug En, Rx Hdr Pipe, EE En, I/O En, Fake Int and Intr En
+	 * - Set Tri-State Int, Bus Master Rd/Wr, and Mem Map Disable
+	 * - Clear Priority, Advance Pkt and Xmit Cmd
+	 */
+
+	hp100_outw(HP100_DEBUG_EN |
+		   HP100_RX_HDR |
+		   HP100_EE_EN | HP100_RESET_HB |
+		   HP100_IO_EN |
+		   HP100_FAKE_INT |
+		   HP100_INT_EN | HP100_RESET_LB, OPTION_LSW);
+
+	hp100_outw(HP100_TRI_INT | HP100_SET_HB, OPTION_LSW);
+
+	if (lp->mode == 1) {	/* busmaster */
+		hp100_outw(HP100_BM_WRITE |
+			   HP100_BM_READ |
+			   HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW);
+	} else if (lp->mode == 2) {	/* memory mapped */
+		hp100_outw(HP100_BM_WRITE |
+			   HP100_BM_READ | HP100_RESET_HB, OPTION_LSW);
+		hp100_outw(HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW);
+		hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW);
+		hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
+	} else if (lp->mode == 3) {	/* i/o mapped mode */
+		hp100_outw(HP100_MMAP_DIS | HP100_SET_HB |
+			   HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
+	}
+
+	hp100_page(HW_MAP);
+	hp100_outb(0, EARLYRXCFG);
+	hp100_outw(0, EARLYTXCFG);
+
+	/*
+	 * Enable Bus Master mode
+	 */
+	if (lp->mode == 1) {	/* busmaster */
+		/* Experimental: Set some PCI configuration bits */
+		hp100_page(HW_MAP);
+		hp100_andb(~HP100_PDL_USE3, MODECTRL1);	/* BM engine read maximum */
+		hp100_andb(~HP100_TX_DUALQ, MODECTRL1);	/* No Queue for Priority TX */
+
+		/* PCI Bus failures should result in a Misc. Interrupt */
+		hp100_orb(HP100_EN_BUS_FAIL, MODECTRL2);
+
+		hp100_outw(HP100_BM_READ | HP100_BM_WRITE | HP100_SET_HB, OPTION_LSW);
+		hp100_page(HW_MAP);
+		/* Use Burst Mode and switch on PAGE_CK */
+		hp100_orb(HP100_BM_BURST_RD | HP100_BM_BURST_WR, BM);
+		if ((lp->chip == HP100_CHIPID_RAINIER) || (lp->chip == HP100_CHIPID_SHASTA))
+			hp100_orb(HP100_BM_PAGE_CK, BM);
+		hp100_orb(HP100_BM_MASTER, BM);
+	} else {		/* not busmaster */
+
+		hp100_page(HW_MAP);
+		hp100_andb(~HP100_BM_MASTER, BM);
+	}
+
+	/*
+	 * Divide card memory into regions for Rx, Tx and, if non-ETR chip, PDLs
+	 */
+	hp100_page(MMU_CFG);
+	if (lp->mode == 1) {	/* only needed for Busmaster */
+		int xmit_stop, recv_stop;
+
+		if ((lp->chip == HP100_CHIPID_RAINIER)
+		    || (lp->chip == HP100_CHIPID_SHASTA)) {
+			int pdl_stop;
+
+			/*
+			 * Each pdl is 508 bytes long. (63 frags * 4 bytes for address and
+			 * 4 bytes for header). We will leave NUM_RXPDLS * 508 (rounded
+			 * to the next higher 1k boundary) bytes for the rx-pdl's
+			 * Note: For non-etr chips the transmit stop register must be
+			 * programmed on a 1k boundary, i.e. bits 9:0 must be zero. 
+			 */
+			pdl_stop = lp->memory_size;
+			xmit_stop = (pdl_stop - 508 * (MAX_RX_PDL) - 16) & ~(0x03ff);
+			recv_stop = (xmit_stop * (lp->rx_ratio) / 100) & ~(0x03ff);
+			hp100_outw((pdl_stop >> 4) - 1, PDL_MEM_STOP);
 #ifdef HP100_DEBUG_BM
-          printk("hp100: %s: PDL_STOP = 0x%x\n", dev->name, pdl_stop);
+			printk("hp100: %s: PDL_STOP = 0x%x\n", dev->name, pdl_stop);
 #endif
-        }
-      else /* ETR chip (Lassen) in busmaster mode */
-        {
-          xmit_stop = ( lp->memory_size ) - 1;
-          recv_stop = ( ( lp->memory_size * lp->rx_ratio ) / 100 ) & ~(0x03ff);
-        }
+		} else {
+			/* ETR chip (Lassen) in busmaster mode */
+			xmit_stop = (lp->memory_size) - 1;
+			recv_stop = ((lp->memory_size * lp->rx_ratio) / 100) & ~(0x03ff);
+		}
 
-      hp100_outw( xmit_stop>>4 , TX_MEM_STOP );
-      hp100_outw( recv_stop>>4 , RX_MEM_STOP );
+		hp100_outw(xmit_stop >> 4, TX_MEM_STOP);
+		hp100_outw(recv_stop >> 4, RX_MEM_STOP);
 #ifdef HP100_DEBUG_BM
-      printk("hp100: %s: TX_STOP  = 0x%x\n",dev->name,xmit_stop>>4);
-      printk("hp100: %s: RX_STOP  = 0x%x\n",dev->name,recv_stop>>4);
+		printk("hp100: %s: TX_STOP  = 0x%x\n", dev->name, xmit_stop >> 4);
+		printk("hp100: %s: RX_STOP  = 0x%x\n", dev->name, recv_stop >> 4);
 #endif
-    }  
-  else /* Slave modes (memory mapped and programmed io)  */
-    {
-      hp100_outw( (((lp->memory_size*lp->rx_ratio)/100)>>4), RX_MEM_STOP );
-      hp100_outw( ((lp->memory_size - 1 )>>4), TX_MEM_STOP );  
-#ifdef HP100_DEBUG
-      printk("hp100: %s: TX_MEM_STOP: 0x%x\n", dev->name,hp100_inw(TX_MEM_STOP));
-      printk("hp100: %s: RX_MEM_STOP: 0x%x\n", dev->name,hp100_inw(RX_MEM_STOP));
-#endif
-    }
-
-  /* Write MAC address into page 1 */
-  hp100_page( MAC_ADDRESS );
-  for ( i = 0; i < 6; i++ )
-    hp100_outb( dev->dev_addr[ i ], MAC_ADDR + i );
-  
-  /* Zero the multicast hash registers */
-  for ( i = 0; i < 8; i++ )
-    hp100_outb( 0x0, HASH_BYTE0 + i );  
-  
-  /* Set up MAC defaults */
-  hp100_page( MAC_CTRL );
- 
-  /* Go to LAN Page and zero all filter bits */
-  /* Zero accept error, accept multicast, accept broadcast and accept */
-  /* all directed packet bits */
-  hp100_andb( ~(HP100_RX_EN|
-		HP100_TX_EN|
-		HP100_ACC_ERRORED|
-		HP100_ACC_MC|
-		HP100_ACC_BC|
-		HP100_ACC_PHY),   MAC_CFG_1 );
-
-  hp100_outb( 0x00, MAC_CFG_2 );
-
-  /* Zero the frame format bit. This works around a training bug in the */
-  /* new hubs. */
-  hp100_outb( 0x00, VG_LAN_CFG_2); /* (use 802.3) */	
-
-  if(lp->priority_tx)
-    hp100_outb( HP100_PRIORITY_TX | HP100_SET_LB, OPTION_MSW );
-  else
-    hp100_outb( HP100_PRIORITY_TX | HP100_RESET_LB, OPTION_MSW );
-	
-  hp100_outb( HP100_ADV_NXT_PKT |
-	      HP100_TX_CMD      | HP100_RESET_LB, OPTION_MSW );
-	
-  /* If busmaster, initialize the PDLs */
-  if(lp->mode==1)
-    hp100_init_pdls( dev );
-
-  /* Go to performance page and initalize isr and imr registers */
-  hp100_page( PERFORMANCE );
-  hp100_outw( 0xfefe, IRQ_MASK );  /* mask off all ints */
-  hp100_outw( 0xffff, IRQ_STATUS );  /* ack IRQ */
+	} else {
+		/* Slave modes (memory mapped and programmed io)  */
+		hp100_outw((((lp->memory_size * lp->rx_ratio) / 100) >> 4), RX_MEM_STOP);
+		hp100_outw(((lp->memory_size - 1) >> 4), TX_MEM_STOP);
+#ifdef HP100_DEBUG
+		printk("hp100: %s: TX_MEM_STOP: 0x%x\n", dev->name, hp100_inw(TX_MEM_STOP));
+		printk("hp100: %s: RX_MEM_STOP: 0x%x\n", dev->name, hp100_inw(RX_MEM_STOP));
+#endif
+	}
+
+	/* Write MAC address into page 1 */
+	hp100_page(MAC_ADDRESS);
+	for (i = 0; i < 6; i++)
+		hp100_outb(dev->dev_addr[i], MAC_ADDR + i);
+
+	/* Zero the multicast hash registers */
+	for (i = 0; i < 8; i++)
+		hp100_outb(0x0, HASH_BYTE0 + i);
+
+	/* Set up MAC defaults */
+	hp100_page(MAC_CTRL);
+
+	/* Go to LAN Page and zero all filter bits */
+	/* Zero accept error, accept multicast, accept broadcast and accept */
+	/* all directed packet bits */
+	hp100_andb(~(HP100_RX_EN |
+		     HP100_TX_EN |
+		     HP100_ACC_ERRORED |
+		     HP100_ACC_MC |
+		     HP100_ACC_BC | HP100_ACC_PHY), MAC_CFG_1);
+
+	hp100_outb(0x00, MAC_CFG_2);
+
+	/* Zero the frame format bit. This works around a training bug in the */
+	/* new hubs. */
+	hp100_outb(0x00, VG_LAN_CFG_2);	/* (use 802.3) */
+
+	if (lp->priority_tx)
+		hp100_outb(HP100_PRIORITY_TX | HP100_SET_LB, OPTION_MSW);
+	else
+		hp100_outb(HP100_PRIORITY_TX | HP100_RESET_LB, OPTION_MSW);
+
+	hp100_outb(HP100_ADV_NXT_PKT |
+		   HP100_TX_CMD | HP100_RESET_LB, OPTION_MSW);
+
+	/* If busmaster, initialize the PDLs */
+	if (lp->mode == 1)
+		hp100_init_pdls(dev);
+
+	/* Go to performance page and initalize isr and imr registers */
+	hp100_page(PERFORMANCE);
+	hp100_outw(0xfefe, IRQ_MASK);	/* mask off all ints */
+	hp100_outw(0xffff, IRQ_STATUS);	/* ack IRQ */
 }
 
-
 /*
  *  open/close functions
  */
 
-static int hp100_open( struct net_device *dev )
+static int hp100_open(struct net_device *dev)
 {
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 #ifdef HP100_DEBUG_B
-  int ioaddr=dev->base_addr;
+	int ioaddr = dev->base_addr;
 #endif
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4204, TRACE );
-  printk("hp100: %s: open\n",dev->name);
+	hp100_outw(0x4204, TRACE);
+	printk("hp100: %s: open\n", dev->name);
 #endif
-		
-  /* New: if bus is PCI or EISA, interrupts might be shared interrupts */
-  if ( request_irq(dev->irq, hp100_interrupt,
-  		   lp->bus==HP100_BUS_PCI||lp->bus==HP100_BUS_EISA?SA_SHIRQ:SA_INTERRUPT,
-  		   lp->id->name, dev))
-    {
-      printk( "hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq );
-      return -EAGAIN;
-    }
 
-  dev->trans_start = jiffies;
-  netif_start_queue(dev);
+	/* New: if bus is PCI or EISA, interrupts might be shared interrupts */
+	if (request_irq(dev->irq, hp100_interrupt,
+			lp->bus == HP100_BUS_PCI || lp->bus ==
+			HP100_BUS_EISA ? SA_SHIRQ : SA_INTERRUPT,
+			lp->id->name, dev)) {
+		printk("hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq);
+		return -EAGAIN;
+	}
+
+	dev->trans_start = jiffies;
+	netif_start_queue(dev);
+
+	lp->lan_type = hp100_sense_lan(dev);
+	lp->mac1_mode = HP100_MAC1MODE3;
+	lp->mac2_mode = HP100_MAC2MODE3;
+	memset(&lp->hash_bytes, 0x00, 8);
 
-  lp->lan_type = hp100_sense_lan( dev );
-  lp->mac1_mode = HP100_MAC1MODE3;
-  lp->mac2_mode = HP100_MAC2MODE3;
-  memset( &lp->hash_bytes, 0x00, 8 );
+	hp100_stop_interface(dev);
 
-  hp100_stop_interface( dev );
- 
-  hp100_hwinit( dev );
+	hp100_hwinit(dev);
 
-  hp100_start_interface( dev ); /* sets mac modes, enables interrupts */
+	hp100_start_interface(dev);	/* sets mac modes, enables interrupts */
 
-  return 0;
+	return 0;
 }
 
-
 /* The close function is called when the interface is to be brought down */
-static int hp100_close( struct net_device *dev )
+static int hp100_close(struct net_device *dev)
 {
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4205, TRACE );
-  printk("hp100: %s: close\n", dev->name);
+	hp100_outw(0x4205, TRACE);
+	printk("hp100: %s: close\n", dev->name);
 #endif
 
-  hp100_page( PERFORMANCE );
-  hp100_outw( 0xfefe, IRQ_MASK );    /* mask off all IRQs */
+	hp100_page(PERFORMANCE);
+	hp100_outw(0xfefe, IRQ_MASK);	/* mask off all IRQs */
 
-  hp100_stop_interface( dev );
+	hp100_stop_interface(dev);
 
-  if ( lp->lan_type == HP100_LAN_100 ) 
-    lp->hub_status=hp100_login_to_vg_hub( dev, FALSE );
+	if (lp->lan_type == HP100_LAN_100)
+		lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
 
-  netif_stop_queue(dev);
+	netif_stop_queue(dev);
 
-  free_irq( dev->irq, dev );
+	free_irq(dev->irq, dev);
 
 #ifdef HP100_DEBUG
-  printk( "hp100: %s: close LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW) );
+	printk("hp100: %s: close LSW = 0x%x\n", dev->name,
+	       hp100_inw(OPTION_LSW));
 #endif
 
-  return 0;
+	return 0;
 }
-
 
+
 /*
  * Configure the PDL Rx rings and LAN 
  */
-static void hp100_init_pdls( struct net_device *dev )
+static void hp100_init_pdls(struct net_device *dev)
 {
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  hp100_ring_t         *ringptr;
-  u_int                *pageptr;
-  int                  i;
-
-#ifdef HP100_DEBUG_B
-  int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	hp100_ring_t *ringptr;
+	u_int *pageptr;
+	int i;
+
+#ifdef HP100_DEBUG_B
+	int ioaddr = dev->base_addr;
 #endif
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4206, TRACE );
-  printk("hp100: %s: init pdls\n", dev->name);
-#endif
-
-  if(0==lp->page_vaddr_algn)
-    printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n",dev->name);
-  else
-    {
-      /* pageptr shall point into the DMA accessible memory region  */
-      /* we use this pointer to status the upper limit of allocated */
-      /* memory in the allocated page. */
-      /* note: align the pointers to the pci cache line size */
-      memset(lp->page_vaddr_algn, 0, MAX_RINGSIZE); /* Zero  Rx/Tx ring page */
-      pageptr=lp->page_vaddr_algn;
-						
-      lp->rxrcommit =0;
-      ringptr = lp->rxrhead = lp-> rxrtail = &(lp->rxring[0]);
-      
-      /* Initialise Rx Ring */
-      for (i=MAX_RX_PDL-1; i>=0; i--)
-        {
-          lp->rxring[i].next = ringptr;
-          ringptr=&(lp->rxring[i]);
-          pageptr+=hp100_init_rxpdl(dev, ringptr, pageptr);
-        }
-      
-      /* Initialise Tx Ring */
-      lp->txrcommit = 0;
-      ringptr = lp->txrhead = lp->txrtail = &(lp->txring[0]);
-      for (i=MAX_TX_PDL-1; i>=0; i--)
-        {
-          lp->txring[i].next = ringptr;
-          ringptr=&(lp->txring[i]);
-          pageptr+=hp100_init_txpdl(dev, ringptr, pageptr);
-        }
-    }
-}
+	hp100_outw(0x4206, TRACE);
+	printk("hp100: %s: init pdls\n", dev->name);
+#endif
+
+	if (0 == lp->page_vaddr_algn)
+		printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n", dev->name);
+	else {
+		/* pageptr shall point into the DMA accessible memory region  */
+		/* we use this pointer to status the upper limit of allocated */
+		/* memory in the allocated page. */
+		/* note: align the pointers to the pci cache line size */
+		memset(lp->page_vaddr_algn, 0, MAX_RINGSIZE);	/* Zero  Rx/Tx ring page */
+		pageptr = lp->page_vaddr_algn;
+
+		lp->rxrcommit = 0;
+		ringptr = lp->rxrhead = lp->rxrtail = &(lp->rxring[0]);
 
+		/* Initialise Rx Ring */
+		for (i = MAX_RX_PDL - 1; i >= 0; i--) {
+			lp->rxring[i].next = ringptr;
+			ringptr = &(lp->rxring[i]);
+			pageptr += hp100_init_rxpdl(dev, ringptr, pageptr);
+		}
+
+		/* Initialise Tx Ring */
+		lp->txrcommit = 0;
+		ringptr = lp->txrhead = lp->txrtail = &(lp->txring[0]);
+		for (i = MAX_TX_PDL - 1; i >= 0; i--) {
+			lp->txring[i].next = ringptr;
+			ringptr = &(lp->txring[i]);
+			pageptr += hp100_init_txpdl(dev, ringptr, pageptr);
+		}
+	}
+}
 
+
 /* These functions "format" the entries in the pdl structure   */
 /* They return how much memory the fragments need.            */
-static int hp100_init_rxpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr )
+static int hp100_init_rxpdl(struct net_device *dev,
+			    register hp100_ring_t * ringptr,
+			    register u32 * pdlptr)
 {
-  /* pdlptr is starting address for this pdl */
+	/* pdlptr is starting address for this pdl */
 
-  if( 0!=( ((unsigned)pdlptr) & 0xf) )
-    printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned)pdlptr);
+	if (0 != (((unsigned) pdlptr) & 0xf))
+		printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%x.\n",
+		       dev->name, (unsigned) pdlptr);
 
-  ringptr->pdl       = pdlptr+1; 
-  ringptr->pdl_paddr = virt_to_bus(pdlptr+1);
-  ringptr->skb       = (void *) NULL; 
+	ringptr->pdl = pdlptr + 1;
+	ringptr->pdl_paddr = virt_to_bus(pdlptr + 1);
+	ringptr->skb = (void *) NULL;
 
-  /* 
-   * Write address and length of first PDL Fragment (which is used for
-   * storing the RX-Header
-   * We use the 4 bytes _before_ the PDH in the pdl memory area to 
-   * store this information. (PDH is at offset 0x04)
-   */
-  /* Note that pdlptr+1 and not pdlptr is the pointer to the PDH */
+	/* 
+	 * Write address and length of first PDL Fragment (which is used for
+	 * storing the RX-Header
+	 * We use the 4 bytes _before_ the PDH in the pdl memory area to 
+	 * store this information. (PDH is at offset 0x04)
+	 */
+	/* Note that pdlptr+1 and not pdlptr is the pointer to the PDH */
 
-  *(pdlptr+2) =(u_int) virt_to_bus(pdlptr);  /* Address Frag 1 */ 
-  *(pdlptr+3) = 4;                           /* Length  Frag 1 */
+	*(pdlptr + 2) = (u_int) virt_to_bus(pdlptr);	/* Address Frag 1 */
+	*(pdlptr + 3) = 4;	/* Length  Frag 1 */
 
-  return( ( ((MAX_RX_FRAG*2+2)+3) /4)*4 );
+	return ((((MAX_RX_FRAG * 2 + 2) + 3) / 4) * 4);
 }
 
 
-static int hp100_init_txpdl( struct net_device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr )
+static int hp100_init_txpdl(struct net_device *dev,
+			    register hp100_ring_t * ringptr,
+			    register u32 * pdlptr)
 {
-  if( 0!=( ((unsigned)pdlptr) & 0xf) )
-    printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned) pdlptr);
+	if (0 != (((unsigned) pdlptr) & 0xf))
+		printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n", dev->name, (unsigned) pdlptr);
 
-  ringptr->pdl       = pdlptr; /* +1; */  
-  ringptr->pdl_paddr = virt_to_bus(pdlptr); /* +1 */
-  ringptr->skb = (void *) NULL;
-  
-  return((((MAX_TX_FRAG*2+2)+3)/4)*4);
+	ringptr->pdl = pdlptr;	/* +1; */
+	ringptr->pdl_paddr = virt_to_bus(pdlptr);	/* +1 */
+	ringptr->skb = (void *) NULL;
+
+	return ((((MAX_TX_FRAG * 2 + 2) + 3) / 4) * 4);
 }
 
-
 /*
  * hp100_build_rx_pdl allocates an skb_buff of maximum size plus two bytes 
  * for possible odd word alignment rounding up to next dword and set PDL
@@ -1321,80 +1283,76 @@
  * Returns: 0 if unable to allocate skb_buff
  *          1 if successful
  */
-static int hp100_build_rx_pdl( hp100_ring_t *ringptr, struct net_device *dev )
+static int hp100_build_rx_pdl(hp100_ring_t * ringptr,
+			      struct net_device *dev)
 {
 #ifdef HP100_DEBUG_B
-  int ioaddr = dev->base_addr;
+	int ioaddr = dev->base_addr;
 #endif
 #ifdef HP100_DEBUG_BM
-  u_int *p;
+	u_int *p;
 #endif
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4207, TRACE );
-  printk("hp100: %s: build rx pdl\n", dev->name);
+	hp100_outw(0x4207, TRACE);
+	printk("hp100: %s: build rx pdl\n", dev->name);
 #endif
 
-  /* Allocate skb buffer of maximum size */
-  /* Note: This depends on the alloc_skb functions allocating more 
-   * space than requested, i.e. aligning to 16bytes */
-
-  ringptr->skb = dev_alloc_skb( ((MAX_ETHER_SIZE+2+3)/4)*4 );
-		
-  if(NULL!=ringptr->skb)
-    {
-      /* 
-       * Reserve 2 bytes at the head of the buffer to land the IP header
-       * on a long word boundary (According to the Network Driver section
-       * in the Linux KHG, this should help to increase performance.)
-       */
-      skb_reserve(ringptr->skb, 2);
-
-      ringptr->skb->dev=dev; 
-      ringptr->skb->data=(u_char *)skb_put(ringptr->skb, MAX_ETHER_SIZE );
-						
-      /* ringptr->pdl points to the beginning of the PDL, i.e. the PDH */
-      /* Note: 1st Fragment is used for the 4 byte packet status
-       * (receive header). Its PDL entries are set up by init_rxpdl. So 
-       * here we only have to set up the PDL fragment entries for the data
-       * part. Those 4 bytes will be stored in the DMA memory region 
-       * directly before the PDL. 
-       */
+	/* Allocate skb buffer of maximum size */
+	/* Note: This depends on the alloc_skb functions allocating more 
+	 * space than requested, i.e. aligning to 16bytes */
+
+	ringptr->skb = dev_alloc_skb(((MAX_ETHER_SIZE + 2 + 3) / 4) * 4);
+
+	if (NULL != ringptr->skb) {
+		/* 
+		 * Reserve 2 bytes at the head of the buffer to land the IP header
+		 * on a long word boundary (According to the Network Driver section
+		 * in the Linux KHG, this should help to increase performance.)
+		 */
+		skb_reserve(ringptr->skb, 2);
+
+		ringptr->skb->dev = dev;
+		ringptr->skb->data = (u_char *) skb_put(ringptr->skb, MAX_ETHER_SIZE);
+
+		/* ringptr->pdl points to the beginning of the PDL, i.e. the PDH */
+		/* Note: 1st Fragment is used for the 4 byte packet status
+		 * (receive header). Its PDL entries are set up by init_rxpdl. So 
+		 * here we only have to set up the PDL fragment entries for the data
+		 * part. Those 4 bytes will be stored in the DMA memory region 
+		 * directly before the PDL. 
+		 */
 #ifdef HP100_DEBUG_BM
-      printk("hp100: %s: build_rx_pdl: PDH@0x%x, skb->data (len %d) at 0x%x\n",
-      	     dev->name,
-	     (u_int) ringptr->pdl,
-	     ((MAX_ETHER_SIZE+2+3)/4)*4,
-	     (unsigned int) ringptr->skb->data);
+		printk("hp100: %s: build_rx_pdl: PDH@0x%x, skb->data (len %d) at 0x%x\n",
+				     dev->name, (u_int) ringptr->pdl,
+				     ((MAX_ETHER_SIZE + 2 + 3) / 4) * 4,
+				     (unsigned int) ringptr->skb->data);
 #endif
 
-      ringptr->pdl[0] = 0x00020000;                          /* Write PDH */
-      ringptr->pdl[3] = ((u_int)virt_to_bus(ringptr->skb->data)); 
-      ringptr->pdl[4] = MAX_ETHER_SIZE;                 /* Length of Data */
-						
+		ringptr->pdl[0] = 0x00020000;	/* Write PDH */
+		ringptr->pdl[3] = ((u_int) virt_to_bus(ringptr->skb->data));
+		ringptr->pdl[4] = MAX_ETHER_SIZE;	/* Length of Data */
+
 #ifdef HP100_DEBUG_BM
-      for(p=(ringptr->pdl); p<(ringptr->pdl+5); p++)
-        printk("hp100: %s: Adr 0x%.8x = 0x%.8x\n",dev->name,(u_int) p,(u_int) *p );
+		for (p = (ringptr->pdl); p < (ringptr->pdl + 5); p++)
+			printk("hp100: %s: Adr 0x%.8x = 0x%.8x\n", dev->name, (u_int) p, (u_int) * p);
 #endif
-      return(1);
-    }
-  /* else: */
-  /* alloc_skb failed (no memory) -> still can receive the header
-   * fragment into PDL memory. make PDL safe by clearing msgptr and
-   * making the PDL only 1 fragment (i.e. the 4 byte packet status)
-   */
+		return (1);
+	}
+	/* else: */
+	/* alloc_skb failed (no memory) -> still can receive the header
+	 * fragment into PDL memory. make PDL safe by clearing msgptr and
+	 * making the PDL only 1 fragment (i.e. the 4 byte packet status)
+	 */
 #ifdef HP100_DEBUG_BM
-  printk("hp100: %s: build_rx_pdl: PDH@0x%x, No space for skb.\n",
-  	 dev->name,
-	 (u_int) ringptr->pdl);
+	printk("hp100: %s: build_rx_pdl: PDH@0x%x, No space for skb.\n", dev->name, (u_int) ringptr->pdl);
 #endif
 
-  ringptr->pdl[0]=0x00010000;   /* PDH: Count=1 Fragment */
+	ringptr->pdl[0] = 0x00010000;	/* PDH: Count=1 Fragment */
 
-  return(0);
+	return (0);
 }
 
-
 /*
  *  hp100_rxfill - attempt to fill the Rx Ring will empty skb's
  *
@@ -1405,275 +1363,250 @@
  *      b.  Put the physical address of the buffer into the PDL.
  *      c.  Output physical address of PDL to adapter.
  */
-static void hp100_rxfill( struct net_device *dev )
+static void hp100_rxfill(struct net_device *dev)
 {
-  int ioaddr=dev->base_addr; 
+	int ioaddr = dev->base_addr;
 
-  struct hp100_private  *lp      = (struct hp100_private *)dev->priv;
-  hp100_ring_t    *ringptr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	hp100_ring_t *ringptr;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4208, TRACE );
-  printk("hp100: %s: rxfill\n",dev->name);
-#endif
-		
-  hp100_page( PERFORMANCE );
-
-  while (lp->rxrcommit < MAX_RX_PDL)
-    {
-      /*
-      ** Attempt to get a buffer and build a Rx PDL.
-      */
-      ringptr = lp->rxrtail;
-      if (0 == hp100_build_rx_pdl( ringptr, dev ))
-        {
-          return;      /* None available, return */
-        }
-      
-      /* Hand this PDL over to the card */
-      /* Note: This needs performance page selected! */
+	hp100_outw(0x4208, TRACE);
+	printk("hp100: %s: rxfill\n", dev->name);
+#endif
+
+	hp100_page(PERFORMANCE);
+
+	while (lp->rxrcommit < MAX_RX_PDL) {
+		/*
+		   ** Attempt to get a buffer and build a Rx PDL.
+		 */
+		ringptr = lp->rxrtail;
+		if (0 == hp100_build_rx_pdl(ringptr, dev)) {
+			return;	/* None available, return */
+		}
+
+		/* Hand this PDL over to the card */
+		/* Note: This needs performance page selected! */
 #ifdef HP100_DEBUG_BM
-      printk("hp100: %s: rxfill: Hand to card: pdl #%d @0x%x phys:0x%x, buffer: 0x%x\n",
-      	     dev->name,
-             lp->rxrcommit,
-             (u_int)ringptr->pdl,
-             (u_int)ringptr->pdl_paddr,
-             (u_int)ringptr->pdl[3]);
+		printk("hp100: %s: rxfill: Hand to card: pdl #%d @0x%x phys:0x%x, buffer: 0x%x\n",
+				     dev->name, lp->rxrcommit, (u_int) ringptr->pdl,
+				     (u_int) ringptr->pdl_paddr, (u_int) ringptr->pdl[3]);
 #endif
 
-      hp100_outl( (u32)ringptr->pdl_paddr, RX_PDA); 
-      
-      lp->rxrcommit += 1;
-      lp->rxrtail = ringptr->next;
-    }
+		hp100_outl((u32) ringptr->pdl_paddr, RX_PDA);
+
+		lp->rxrcommit += 1;
+		lp->rxrtail = ringptr->next;
+	}
 }
 
-
 /*
  * BM_shutdown - shutdown bus mastering and leave chip in reset state
  */
 
-static void hp100_BM_shutdown( struct net_device *dev )
+static void hp100_BM_shutdown(struct net_device *dev)
 {
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  unsigned long time;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4209, TRACE );
-  printk("hp100: %s: bm shutdown\n",dev->name);
-#endif
-
-  hp100_page( PERFORMANCE );
-  hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */
-  hp100_outw( 0xffff, IRQ_STATUS ); /* Ack all ints */
-
-  /* Ensure Interrupts are off */
-  hp100_outw( HP100_INT_EN | HP100_RESET_LB , OPTION_LSW );
-
-  /* Disable all MAC activity */
-  hp100_page( MAC_CTRL );
-  hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );  /* stop rx/tx */
-
-  /* If cascade MMU is not already in reset */
-  if (0 != (hp100_inw(OPTION_LSW)&HP100_HW_RST) )
-    {
-      /* Wait 1.3ms (10Mb max packet time) to ensure MAC is idle so
-       * MMU pointers will not be reset out from underneath
-       */
-      hp100_page( MAC_CTRL );
-      for(time=0; time<5000; time++)
-        {
-          if( (hp100_inb(MAC_CFG_1)&(HP100_TX_IDLE|HP100_RX_IDLE))==
-              (HP100_TX_IDLE|HP100_RX_IDLE) ) break;
-        }
-      
-      /* Shutdown algorithm depends on the generation of Cascade */
-      if( lp->chip==HP100_CHIPID_LASSEN )
-        { /* ETR shutdown/reset */
-          /* Disable Busmaster mode and wait for bit to go to zero. */
-          hp100_page(HW_MAP);
-          hp100_andb( ~HP100_BM_MASTER, BM );
-          /* 100 ms timeout */
-          for(time=0; time<32000; time++)
-            {
-              if ( 0 == (hp100_inb( BM ) & HP100_BM_MASTER) ) break;
-            }
-        }
-      else
-        { /* Shasta or Rainier Shutdown/Reset */
-          /* To ensure all bus master inloading activity has ceased,
-           * wait for no Rx PDAs or no Rx packets on card. 
-           */
-          hp100_page( PERFORMANCE );
-          /* 100 ms timeout */
-          for(time=0; time<10000; time++)
-            {
-              /* RX_PDL: PDLs not executed. */
-              /* RX_PKT_CNT: RX'd packets on card. */
-              if ( (hp100_inb( RX_PDL ) == 0) &&
-                   (hp100_inb( RX_PKT_CNT ) == 0) ) break;
-            }
-          
-          if(time>=10000)
-            printk("hp100: %s: BM shutdown error.\n", dev->name);
-          
-          /* To ensure all bus master outloading activity has ceased,
-           * wait until the Tx PDA count goes to zero or no more Tx space
-           * available in the Tx region of the card. 
-           */
-          /* 100 ms timeout */
-          for(time=0; time<10000; time++) {
-            if ( (0 == hp100_inb( TX_PKT_CNT )) &&
-                 (0 != (hp100_inb( TX_MEM_FREE )&HP100_AUTO_COMPARE))) break;
-          } 
-          
-          /* Disable Busmaster mode */
-          hp100_page(HW_MAP);
-          hp100_andb( ~HP100_BM_MASTER, BM );
-        } /* end of shutdown procedure for non-etr parts */  
-						
-      hp100_cascade_reset( dev, TRUE );
-    }
-  hp100_page( PERFORMANCE );
-  /* hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_RESET_HB, OPTION_LSW ); */
-  /* Busmaster mode should be shut down now. */
-}
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	unsigned long time;
 
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4209, TRACE);
+	printk("hp100: %s: bm shutdown\n", dev->name);
+#endif
+
+	hp100_page(PERFORMANCE);
+	hp100_outw(0xfefe, IRQ_MASK);	/* mask off all ints */
+	hp100_outw(0xffff, IRQ_STATUS);	/* Ack all ints */
+
+	/* Ensure Interrupts are off */
+	hp100_outw(HP100_INT_EN | HP100_RESET_LB, OPTION_LSW);
+
+	/* Disable all MAC activity */
+	hp100_page(MAC_CTRL);
+	hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1);	/* stop rx/tx */
+
+	/* If cascade MMU is not already in reset */
+	if (0 != (hp100_inw(OPTION_LSW) & HP100_HW_RST)) {
+		/* Wait 1.3ms (10Mb max packet time) to ensure MAC is idle so
+		 * MMU pointers will not be reset out from underneath
+		 */
+		hp100_page(MAC_CTRL);
+		for (time = 0; time < 5000; time++) {
+			if ((hp100_inb(MAC_CFG_1) & (HP100_TX_IDLE | HP100_RX_IDLE)) == (HP100_TX_IDLE | HP100_RX_IDLE))
+				break;
+		}
+
+		/* Shutdown algorithm depends on the generation of Cascade */
+		if (lp->chip == HP100_CHIPID_LASSEN) {	/* ETR shutdown/reset */
+			/* Disable Busmaster mode and wait for bit to go to zero. */
+			hp100_page(HW_MAP);
+			hp100_andb(~HP100_BM_MASTER, BM);
+			/* 100 ms timeout */
+			for (time = 0; time < 32000; time++) {
+				if (0 == (hp100_inb(BM) & HP100_BM_MASTER))
+					break;
+			}
+		} else {	/* Shasta or Rainier Shutdown/Reset */
+			/* To ensure all bus master inloading activity has ceased,
+			 * wait for no Rx PDAs or no Rx packets on card. 
+			 */
+			hp100_page(PERFORMANCE);
+			/* 100 ms timeout */
+			for (time = 0; time < 10000; time++) {
+				/* RX_PDL: PDLs not executed. */
+				/* RX_PKT_CNT: RX'd packets on card. */
+				if ((hp100_inb(RX_PDL) == 0) && (hp100_inb(RX_PKT_CNT) == 0))
+					break;
+			}
+
+			if (time >= 10000)
+				printk("hp100: %s: BM shutdown error.\n", dev->name);
+
+			/* To ensure all bus master outloading activity has ceased,
+			 * wait until the Tx PDA count goes to zero or no more Tx space
+			 * available in the Tx region of the card. 
+			 */
+			/* 100 ms timeout */
+			for (time = 0; time < 10000; time++) {
+				if ((0 == hp100_inb(TX_PKT_CNT)) &&
+				    (0 != (hp100_inb(TX_MEM_FREE) & HP100_AUTO_COMPARE)))
+					break;
+			}
+
+			/* Disable Busmaster mode */
+			hp100_page(HW_MAP);
+			hp100_andb(~HP100_BM_MASTER, BM);
+		}	/* end of shutdown procedure for non-etr parts */
+
+		hp100_cascade_reset(dev, TRUE);
+	}
+	hp100_page(PERFORMANCE);
+	/* hp100_outw( HP100_BM_READ | HP100_BM_WRITE | HP100_RESET_HB, OPTION_LSW ); */
+	/* Busmaster mode should be shut down now. */
+}
 
-
 /* 
  *  transmit functions
  */
 
 /* tx function for busmaster mode */
-static int hp100_start_xmit_bm( struct sk_buff *skb, struct net_device *dev )
+static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
 {
-  unsigned long flags;
-  int i, ok_flag;
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  hp100_ring_t *ringptr;
+	unsigned long flags;
+	int i, ok_flag;
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	hp100_ring_t *ringptr;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4210, TRACE );
-  printk("hp100: %s: start_xmit_bm\n",dev->name);
+	hp100_outw(0x4210, TRACE);
+	printk("hp100: %s: start_xmit_bm\n", dev->name);
 #endif
 
-  if ( skb==NULL )
-    {
-      return 0;
-    }
-	
-  if ( skb->len <= 0 ) return 0;
-	
-  /* Get Tx ring tail pointer */
-  if( lp->txrtail->next==lp->txrhead )
-    {
-      /* No memory. */
-#ifdef HP100_DEBUG
-      printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name);
-#endif
-      /* not waited long enough since last tx? */
-      if ( jiffies - dev->trans_start < HZ ) return -EAGAIN;
-
-      if ( lp->lan_type < 0 ) /* no LAN type detected yet? */
-	{
-	  hp100_stop_interface( dev );
-	  if ( ( lp->lan_type = hp100_sense_lan( dev ) ) < 0 )
-	    {
-	      printk( "hp100: %s: no connection found - check wire\n", dev->name );
-	      hp100_start_interface( dev );  /* 10Mb/s RX pkts maybe handled */
-	      return -EIO;
-	    }
-	  if ( lp->lan_type == HP100_LAN_100 )
-	    lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); /* relogin */
-	  hp100_start_interface( dev );
-	}
-				
-      if ( lp->lan_type == HP100_LAN_100 && lp->hub_status < 0 )
-	/* we have a 100Mb/s adapter but it isn't connected to hub */
-	{
-	  printk( "hp100: %s: login to 100Mb/s hub retry\n", dev->name );
-	  hp100_stop_interface( dev );
-	  lp->hub_status = hp100_login_to_vg_hub( dev, FALSE );
-	  hp100_start_interface( dev );
-	}
-      else
-	{
-	  spin_lock_irqsave (&lp->lock, flags);
-	  hp100_ints_off();	/* Useful ? Jean II */
-	  i = hp100_sense_lan( dev );
-	  hp100_ints_on();
-	  spin_unlock_irqrestore (&lp->lock, flags);
-	  if ( i == HP100_LAN_ERR )
-	    printk( "hp100: %s: link down detected\n", dev->name );
-	  else
-	    if ( lp->lan_type != i ) /* cable change! */
-	      {
-		/* it's very hard - all network setting must be changed!!! */
-		printk( "hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name );
-		lp->lan_type = i;
-		hp100_stop_interface( dev );
-		if ( lp->lan_type == HP100_LAN_100 )
-		  lp->hub_status = hp100_login_to_vg_hub( dev, FALSE );
-		hp100_start_interface( dev );
-	      }
-	    else
-	      {
-		printk( "hp100: %s: interface reset\n", dev->name );
-		hp100_stop_interface( dev );
-		if ( lp->lan_type == HP100_LAN_100 )
-		  lp->hub_status = hp100_login_to_vg_hub( dev, FALSE );
-		hp100_start_interface( dev );
-	      }
-	}
-
-      dev->trans_start = jiffies;
-      return -EAGAIN;
-    }
-	
-  /*
-   * we have to turn int's off before modifying this, otherwise
-   * a tx_pdl_cleanup could occur at the same time
-   */
-  spin_lock_irqsave (&lp->lock, flags);
-  ringptr=lp->txrtail;
-  lp->txrtail=ringptr->next;
-	
-  /* Check whether packet has minimal packet size */
-  ok_flag = skb->len >= HP100_MIN_PACKET_SIZE;
-  i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE;
-					
-  ringptr->skb=skb;
-  ringptr->pdl[0]=((1<<16) | i);                /* PDH: 1 Fragment & length */
-  ringptr->pdl[1]=(u32)virt_to_bus(skb->data);  /* 1st Frag: Adr. of data */
-  if(lp->chip==HP100_CHIPID_SHASTA)
-    {
-      /* TODO:Could someone who has the EISA card please check if this works? */
-      ringptr->pdl[2]=i;
-    }
-  else /* Lassen */
-    {
-      /* In the PDL, don't use the padded size but the real packet size: */
-      ringptr->pdl[2]=skb->len;              /* 1st Frag: Length of frag */
-    }
+	if (skb == NULL) {
+		return 0;
+	}
 
-  /* Hand this PDL to the card. */
-  hp100_outl( ringptr->pdl_paddr, TX_PDA_L ); /* Low Prio. Queue */
-	
-  lp->txrcommit++;
-  spin_unlock_irqrestore (&lp->lock, flags);
-	
-  /* Update statistics */	
-  lp->stats.tx_packets++;
-  lp->stats.tx_bytes += skb->len;
-  dev->trans_start = jiffies;
-	
-  return 0;
-}
+	if (skb->len <= 0)
+		return 0;
+
+	/* Get Tx ring tail pointer */
+	if (lp->txrtail->next == lp->txrhead) {
+		/* No memory. */
+#ifdef HP100_DEBUG
+		printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name);
+#endif
+		/* not waited long enough since last tx? */
+		if (jiffies - dev->trans_start < HZ)
+			return -EAGAIN;
+
+		if (lp->lan_type < 0) {	/* no LAN type detected yet? */
+			hp100_stop_interface(dev);
+			if ((lp->lan_type = hp100_sense_lan(dev)) < 0) {
+				printk("hp100: %s: no connection found - check wire\n", dev->name);
+				hp100_start_interface(dev);	/* 10Mb/s RX pkts maybe handled */
+				return -EIO;
+			}
+			if (lp->lan_type == HP100_LAN_100)
+				lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);	/* relogin */
+			hp100_start_interface(dev);
+		}
+
+		if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) {
+			/* we have a 100Mb/s adapter but it isn't connected to hub */
+			printk("hp100: %s: login to 100Mb/s hub retry\n", dev->name);
+			hp100_stop_interface(dev);
+			lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
+			hp100_start_interface(dev);
+		} else {
+			spin_lock_irqsave(&lp->lock, flags);
+			hp100_ints_off();	/* Useful ? Jean II */
+			i = hp100_sense_lan(dev);
+			hp100_ints_on();
+			spin_unlock_irqrestore(&lp->lock, flags);
+			if (i == HP100_LAN_ERR)
+				printk("hp100: %s: link down detected\n", dev->name);
+			else if (lp->lan_type != i) {	/* cable change! */
+				/* it's very hard - all network setting must be changed!!! */
+				printk("hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name);
+				lp->lan_type = i;
+				hp100_stop_interface(dev);
+				if (lp->lan_type == HP100_LAN_100)
+					lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
+				hp100_start_interface(dev);
+			} else {
+				printk("hp100: %s: interface reset\n", dev->name);
+				hp100_stop_interface(dev);
+				if (lp->lan_type == HP100_LAN_100)
+					lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
+				hp100_start_interface(dev);
+			}
+		}
+
+		dev->trans_start = jiffies;
+		return -EAGAIN;
+	}
+
+	/*
+	 * we have to turn int's off before modifying this, otherwise
+	 * a tx_pdl_cleanup could occur at the same time
+	 */
+	spin_lock_irqsave(&lp->lock, flags);
+	ringptr = lp->txrtail;
+	lp->txrtail = ringptr->next;
+
+	/* Check whether packet has minimal packet size */
+	ok_flag = skb->len >= HP100_MIN_PACKET_SIZE;
+	i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE;
+
+	ringptr->skb = skb;
+	ringptr->pdl[0] = ((1 << 16) | i);	/* PDH: 1 Fragment & length */
+	ringptr->pdl[1] = (u32) virt_to_bus(skb->data);	/* 1st Frag: Adr. of data */
+	if (lp->chip == HP100_CHIPID_SHASTA) {
+		/* TODO:Could someone who has the EISA card please check if this works? */
+		ringptr->pdl[2] = i;
+	} else {		/* Lassen */
+		/* In the PDL, don't use the padded size but the real packet size: */
+		ringptr->pdl[2] = skb->len;	/* 1st Frag: Length of frag */
+	}
+
+	/* Hand this PDL to the card. */
+	hp100_outl(ringptr->pdl_paddr, TX_PDA_L);	/* Low Prio. Queue */
+
+	lp->txrcommit++;
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	/* Update statistics */
+	lp->stats.tx_packets++;
+	lp->stats.tx_bytes += skb->len;
+	dev->trans_start = jiffies;
 
+	return 0;
+}
 
+
 /* clean_txring checks if packets have been sent by the card by reading
  * the TX_PDL register from the performance page and comparing it to the
  * number of commited packets. It then frees the skb's of the packets that
@@ -1681,201 +1614,181 @@
  *
  * Needs the PERFORMANCE page selected. 
  */
-static void hp100_clean_txring( struct net_device *dev )
+static void hp100_clean_txring(struct net_device *dev)
 {
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  int    ioaddr = dev->base_addr;
-  int    donecount;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	int ioaddr = dev->base_addr;
+	int donecount;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4211, TRACE );
-  printk("hp100: %s: clean txring\n", dev->name);
+	hp100_outw(0x4211, TRACE);
+	printk("hp100: %s: clean txring\n", dev->name);
 #endif
 
-  /* How many PDLs have been transmitted? */
-  donecount=(lp->txrcommit)-hp100_inb(TX_PDL);
+	/* How many PDLs have been transmitted? */
+	donecount = (lp->txrcommit) - hp100_inb(TX_PDL);
 
 #ifdef HP100_DEBUG
-  if(donecount>MAX_TX_PDL)
-    printk("hp100: %s: Warning: More PDLs transmitted than commited to card???\n",dev->name);
+	if (donecount > MAX_TX_PDL)
+		printk("hp100: %s: Warning: More PDLs transmitted than commited to card???\n", dev->name);
 #endif
 
-  for( ; 0!=donecount; donecount-- )
-    {
+	for (; 0 != donecount; donecount--) {
 #ifdef HP100_DEBUG_BM
-      printk("hp100: %s: Free skb: data @0x%.8x txrcommit=0x%x TXPDL=0x%x, done=0x%x\n",
-             dev->name,
-	     (u_int) lp->txrhead->skb->data,
-	     lp->txrcommit,
-	     hp100_inb(TX_PDL),
-	     donecount);
-#endif
-      dev_kfree_skb_any( lp->txrhead->skb );
-      lp->txrhead->skb=(void *)NULL;
-      lp->txrhead=lp->txrhead->next;
-      lp->txrcommit--;
-    }
+		printk("hp100: %s: Free skb: data @0x%.8x txrcommit=0x%x TXPDL=0x%x, done=0x%x\n",
+				dev->name, (u_int) lp->txrhead->skb->data,
+				lp->txrcommit, hp100_inb(TX_PDL), donecount);
+#endif
+		dev_kfree_skb_any(lp->txrhead->skb);
+		lp->txrhead->skb = (void *) NULL;
+		lp->txrhead = lp->txrhead->next;
+		lp->txrcommit--;
+	}
 }
 
-
 /* tx function for slave modes */
-static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev )
+static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-  unsigned long flags;
-  int i, ok_flag;
-  int ioaddr = dev->base_addr;
-  u_short val;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	unsigned long flags;
+	int i, ok_flag;
+	int ioaddr = dev->base_addr;
+	u_short val;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4212, TRACE );
-  printk("hp100: %s: start_xmit\n", dev->name);
+	hp100_outw(0x4212, TRACE);
+	printk("hp100: %s: start_xmit\n", dev->name);
 #endif
 
-  if ( skb==NULL )
-    {
-      return 0;
-    }
-	
-  if ( skb->len <= 0 ) return 0;
-	
-  if ( lp->lan_type < 0 ) /* no LAN type detected yet? */
-    {
-      hp100_stop_interface( dev );
-      if ( ( lp->lan_type = hp100_sense_lan( dev ) ) < 0 )
-        {
-          printk( "hp100: %s: no connection found - check wire\n", dev->name );
-          hp100_start_interface( dev );  /* 10Mb/s RX packets maybe handled */
-          return -EIO;
-        }
-      if ( lp->lan_type == HP100_LAN_100 )
-        lp->hub_status = hp100_login_to_vg_hub( dev, FALSE ); /* relogin */
-      hp100_start_interface( dev );
-    }
-
-  /* If there is not enough free memory on the card... */
-  i=hp100_inl(TX_MEM_FREE)&0x7fffffff;
-  if ( !(((i/2)-539)>(skb->len+16) && (hp100_inb(TX_PKT_CNT)<255)) )
-    {
-#ifdef HP100_DEBUG
-      printk( "hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i );
-#endif
-      /* not waited long enough since last failed tx try? */
-      if ( jiffies - dev->trans_start < HZ ) 
-	{
-#ifdef HP100_DEBUG
-	  printk("hp100: %s: trans_start timing problem\n", dev->name);
-#endif
-	  return -EAGAIN;
-	}
-      if ( lp->lan_type == HP100_LAN_100 && lp->hub_status < 0 )
-	/* we have a 100Mb/s adapter but it isn't connected to hub */
-        {
-          printk( "hp100: %s: login to 100Mb/s hub retry\n", dev->name );
-          hp100_stop_interface( dev );
-          lp->hub_status = hp100_login_to_vg_hub( dev, FALSE );
-          hp100_start_interface( dev );
-        }
-      else
-        {
-	  spin_lock_irqsave (&lp->lock, flags);
-          hp100_ints_off();	/* Useful ? Jean II */
-          i = hp100_sense_lan( dev );
-          hp100_ints_on();
-	  spin_unlock_irqrestore (&lp->lock, flags);
-          if ( i == HP100_LAN_ERR )
-            printk( "hp100: %s: link down detected\n", dev->name );
-	  else
-	    if ( lp->lan_type != i ) /* cable change! */
-	      {
-		/* it's very hard - all network setting must be changed!!! */
-		printk( "hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name );
-		lp->lan_type = i;
-		hp100_stop_interface( dev );
-		if ( lp->lan_type == HP100_LAN_100 )
-		  lp->hub_status = hp100_login_to_vg_hub( dev, FALSE );
-		hp100_start_interface( dev );
-	      }
-	    else
-	      {
-		printk( "hp100: %s: interface reset\n", dev->name );
-		hp100_stop_interface( dev );
-		if ( lp->lan_type == HP100_LAN_100 )
-		  lp->hub_status = hp100_login_to_vg_hub( dev, FALSE );
-		hp100_start_interface( dev );
-		mdelay(1);
-	      }
-        }
-      dev->trans_start = jiffies;
-      return -EAGAIN;
-    }
+	if (skb == NULL) {
+		return 0;
+	}
+
+	if (skb->len <= 0)
+		return 0;
+
+	if (lp->lan_type < 0) {	/* no LAN type detected yet? */
+		hp100_stop_interface(dev);
+		if ((lp->lan_type = hp100_sense_lan(dev)) < 0) {
+			printk("hp100: %s: no connection found - check wire\n", dev->name);
+			hp100_start_interface(dev);	/* 10Mb/s RX packets maybe handled */
+			return -EIO;
+		}
+		if (lp->lan_type == HP100_LAN_100)
+			lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);	/* relogin */
+		hp100_start_interface(dev);
+	}
 
-  for ( i=0; i<6000 && ( hp100_inb( OPTION_MSW ) & HP100_TX_CMD ); i++ )
-    {
+	/* If there is not enough free memory on the card... */
+	i = hp100_inl(TX_MEM_FREE) & 0x7fffffff;
+	if (!(((i / 2) - 539) > (skb->len + 16) && (hp100_inb(TX_PKT_CNT) < 255))) {
+#ifdef HP100_DEBUG
+		printk("hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i);
+#endif
+		/* not waited long enough since last failed tx try? */
+		if (jiffies - dev->trans_start < HZ) {
+#ifdef HP100_DEBUG
+			printk("hp100: %s: trans_start timing problem\n",
+			       dev->name);
+#endif
+			return -EAGAIN;
+		}
+		if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) {
+			/* we have a 100Mb/s adapter but it isn't connected to hub */
+			printk("hp100: %s: login to 100Mb/s hub retry\n", dev->name);
+			hp100_stop_interface(dev);
+			lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
+			hp100_start_interface(dev);
+		} else {
+			spin_lock_irqsave(&lp->lock, flags);
+			hp100_ints_off();	/* Useful ? Jean II */
+			i = hp100_sense_lan(dev);
+			hp100_ints_on();
+			spin_unlock_irqrestore(&lp->lock, flags);
+			if (i == HP100_LAN_ERR)
+				printk("hp100: %s: link down detected\n", dev->name);
+			else if (lp->lan_type != i) {	/* cable change! */
+				/* it's very hard - all network setting must be changed!!! */
+				printk("hp100: %s: cable change 10Mb/s <-> 100Mb/s detected\n", dev->name);
+				lp->lan_type = i;
+				hp100_stop_interface(dev);
+				if (lp->lan_type == HP100_LAN_100)
+					lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
+				hp100_start_interface(dev);
+			} else {
+				printk("hp100: %s: interface reset\n", dev->name);
+				hp100_stop_interface(dev);
+				if (lp->lan_type == HP100_LAN_100)
+					lp->hub_status = hp100_login_to_vg_hub(dev, FALSE);
+				hp100_start_interface(dev);
+				mdelay(1);
+			}
+		}
+		dev->trans_start = jiffies;
+		return -EAGAIN;
+	}
+
+	for (i = 0; i < 6000 && (hp100_inb(OPTION_MSW) & HP100_TX_CMD); i++) {
 #ifdef HP100_DEBUG_TX
-      printk( "hp100: %s: start_xmit: busy\n", dev->name );
+		printk("hp100: %s: start_xmit: busy\n", dev->name);
 #endif
-    }
-	
-  spin_lock_irqsave (&lp->lock, flags);
-  hp100_ints_off();
-  val = hp100_inw( IRQ_STATUS );
-  /* Ack / clear the interrupt TX_COMPLETE interrupt - this interrupt is set
-   * when the current packet being transmitted on the wire is completed. */
-  hp100_outw( HP100_TX_COMPLETE, IRQ_STATUS ); 
+	}
+
+	spin_lock_irqsave(&lp->lock, flags);
+	hp100_ints_off();
+	val = hp100_inw(IRQ_STATUS);
+	/* Ack / clear the interrupt TX_COMPLETE interrupt - this interrupt is set
+	 * when the current packet being transmitted on the wire is completed. */
+	hp100_outw(HP100_TX_COMPLETE, IRQ_STATUS);
 #ifdef HP100_DEBUG_TX
-  printk("hp100: %s: start_xmit: irq_status=0x%.4x, irqmask=0x%.4x, len=%d\n",dev->name,val,hp100_inw(IRQ_MASK),(int)skb->len );
+	printk("hp100: %s: start_xmit: irq_status=0x%.4x, irqmask=0x%.4x, len=%d\n",
+			dev->name, val, hp100_inw(IRQ_MASK), (int) skb->len);
 #endif
 
-  ok_flag = skb->len >= HP100_MIN_PACKET_SIZE;
-  i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE;
+	ok_flag = skb->len >= HP100_MIN_PACKET_SIZE;
+	i = ok_flag ? skb->len : HP100_MIN_PACKET_SIZE;
+
+	hp100_outw(i, DATA32);	/* tell card the total packet length */
+	hp100_outw(i, FRAGMENT_LEN);	/* and first/only fragment length    */
+
+	if (lp->mode == 2) {	/* memory mapped */
+		if (lp->mem_ptr_virt) {	/* high pci memory was remapped */
+			/* Note: The J2585B needs alignment to 32bits here!  */
+			memcpy_toio(lp->mem_ptr_virt, skb->data, (skb->len + 3) & ~3);
+			if (!ok_flag)
+				memset_io(lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len);
+		} else {
+			/* Note: The J2585B needs alignment to 32bits here!  */
+			isa_memcpy_toio(lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3);
+			if (!ok_flag)
+				isa_memset_io(lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len);
+		}
+	} else {		/* programmed i/o */
+		outsl(ioaddr + HP100_REG_DATA32, skb->data,
+		      (skb->len + 3) >> 2);
+		if (!ok_flag)
+			for (i = (skb->len + 3) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4)
+				hp100_outl(0, DATA32);
+	}
+
+	hp100_outb(HP100_TX_CMD | HP100_SET_LB, OPTION_MSW);	/* send packet */
+
+	lp->stats.tx_packets++;
+	lp->stats.tx_bytes += skb->len;
+	dev->trans_start = jiffies;
+	hp100_ints_on();
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	dev_kfree_skb_any(skb);
 
-  hp100_outw( i, DATA32 );       /* tell card the total packet length */
-  hp100_outw( i, FRAGMENT_LEN ); /* and first/only fragment length    */
-	
-  if ( lp->mode==2 ) /* memory mapped */
-    {
-      if ( lp->mem_ptr_virt ) /* high pci memory was remapped */
-	{
-	  /* Note: The J2585B needs alignment to 32bits here!  */
-	  memcpy_toio( lp->mem_ptr_virt, skb->data, ( skb->len + 3 ) & ~3 );
-	  if ( !ok_flag )
-	    memset_io( lp->mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb->len );
-	}
-      else
-	{
-	  /* Note: The J2585B needs alignment to 32bits here!  */
-	  isa_memcpy_toio( lp->mem_ptr_phys, skb->data, (skb->len + 3) & ~3 );
-	  if ( !ok_flag )
-	    isa_memset_io( lp->mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb->len );
-	}
-    }
-  else /* programmed i/o */
-    {
-      outsl( ioaddr + HP100_REG_DATA32, skb->data, ( skb->len + 3 ) >> 2 );
-      if ( !ok_flag )
-	for ( i = ( skb->len + 3 ) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4 )
-	  hp100_outl( 0, DATA32 );
-    }
-	
-  hp100_outb( HP100_TX_CMD | HP100_SET_LB, OPTION_MSW ); /* send packet */
-	
-  lp->stats.tx_packets++;
-  lp->stats.tx_bytes += skb->len;
-  dev->trans_start=jiffies;
-  hp100_ints_on();
-  spin_unlock_irqrestore (&lp->lock, flags);
-	
-  dev_kfree_skb_any( skb );
-	
 #ifdef HP100_DEBUG_TX
-  printk( "hp100: %s: start_xmit: end\n", dev->name );
+	printk("hp100: %s: start_xmit: end\n", dev->name);
 #endif
-	
-  return 0;
-}
 
+	return 0;
+}
 
+
 /*
  * Receive Function (Non-Busmaster mode)
  * Called when an "Receive Packet" interrupt occurs, i.e. the receive 
@@ -1885,323 +1798,295 @@
  * and netif_rx. 
  */
 
-static void hp100_rx( struct net_device *dev )
+static void hp100_rx(struct net_device *dev)
 {
-  int packets, pkt_len;
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  u_int header;
-  struct sk_buff *skb;
+	int packets, pkt_len;
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	u_int header;
+	struct sk_buff *skb;
 
 #ifdef DEBUG_B
-  hp100_outw( 0x4213, TRACE );
-  printk("hp100: %s: rx\n", dev->name);
+	hp100_outw(0x4213, TRACE);
+	printk("hp100: %s: rx\n", dev->name);
 #endif
 
-  /* First get indication of received lan packet */
-  /* RX_PKT_CND indicates the number of packets which have been fully */
-  /* received onto the card but have not been fully transferred of the card */
-  packets = hp100_inb( RX_PKT_CNT );
+	/* First get indication of received lan packet */
+	/* RX_PKT_CND indicates the number of packets which have been fully */
+	/* received onto the card but have not been fully transferred of the card */
+	packets = hp100_inb(RX_PKT_CNT);
 #ifdef HP100_DEBUG_RX
-  if ( packets > 1 )
-    printk( "hp100: %s: rx: waiting packets = %d\n", dev->name,packets );
+	if (packets > 1)
+		printk("hp100: %s: rx: waiting packets = %d\n", dev->name, packets);
 #endif
 
-  while ( packets-- > 0 )
-    {
-      /* If ADV_NXT_PKT is still set, we have to wait until the card has */
-      /* really advanced to the next packet. */
-      for (pkt_len=0; pkt_len<6000 &&(hp100_inb(OPTION_MSW)&HP100_ADV_NXT_PKT);
-	   pkt_len++ )
-        {
+	while (packets-- > 0) {
+		/* If ADV_NXT_PKT is still set, we have to wait until the card has */
+		/* really advanced to the next packet. */
+		for (pkt_len = 0; pkt_len < 6000 && (hp100_inb(OPTION_MSW) & HP100_ADV_NXT_PKT); pkt_len++) {
 #ifdef HP100_DEBUG_RX
-          printk( "hp100: %s: rx: busy, remaining packets = %d\n", dev->name, packets );
-#endif    
-        }
-
-      /* First we get the header, which contains information about the */
-      /* actual length of the received packet. */
-      if( lp->mode==2 ) /* memory mapped mode */
-        {
-          if ( lp->mem_ptr_virt )    /* if memory was remapped */
-            header = readl(lp->mem_ptr_virt);
-          else
-            header = isa_readl( lp->mem_ptr_phys );
-        }
-      else /* programmed i/o */
-        header = hp100_inl( DATA32 );
-      
-      pkt_len = ((header & HP100_PKT_LEN_MASK) + 3) & ~3;
+			printk ("hp100: %s: rx: busy, remaining packets = %d\n", dev->name, packets);
+#endif
+		}
+
+		/* First we get the header, which contains information about the */
+		/* actual length of the received packet. */
+		if (lp->mode == 2) {	/* memory mapped mode */
+			if (lp->mem_ptr_virt)	/* if memory was remapped */
+				header = readl(lp->mem_ptr_virt);
+			else
+				header = isa_readl(lp->mem_ptr_phys);
+		} else		/* programmed i/o */
+			header = hp100_inl(DATA32);
+
+		pkt_len = ((header & HP100_PKT_LEN_MASK) + 3) & ~3;
 
 #ifdef HP100_DEBUG_RX
-      printk( "hp100: %s: rx: new packet - length=%d, errors=0x%x, dest=0x%x\n",
-      	      dev->name,
-              header & HP100_PKT_LEN_MASK, (header>>16)&0xfff8,
-              (header>>16)&7);
-#endif
-    
-      /* Now we allocate the skb and transfer the data into it. */  
-      skb = dev_alloc_skb( pkt_len );
-      if ( skb == NULL ) /* Not enough memory->drop packet */
-	{
-#ifdef HP100_DEBUG
-	  printk( "hp100: %s: rx: couldn't allocate a sk_buff of size %d\n", dev->name, pkt_len );
-#endif
-	  lp->stats.rx_dropped++;
-	}
-      else /* skb successfully allocated */
-	{
-	  u_char *ptr;
-      
-	  skb->dev = dev;
-      
-	  /* ptr to start of the sk_buff data area */
-	  ptr = (u_char *)skb_put( skb, pkt_len );
-      
-	  /* Now transfer the data from the card into that area */
-	  if ( lp->mode==2 )
-            {
-              if ( lp->mem_ptr_virt )
-                memcpy_fromio( ptr, lp->mem_ptr_virt, pkt_len );
-              /* Note alignment to 32bit transfers */
-              else
-                isa_memcpy_fromio( ptr, lp->mem_ptr_phys, pkt_len );
-            }
-	  else /* io mapped */
-	    insl( ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2 );
-      
-	  skb->protocol = eth_type_trans( skb, dev );
-      
+		printk("hp100: %s: rx: new packet - length=%d, errors=0x%x, dest=0x%x\n",
+				     dev->name, header & HP100_PKT_LEN_MASK,
+				     (header >> 16) & 0xfff8, (header >> 16) & 7);
+#endif
+
+		/* Now we allocate the skb and transfer the data into it. */
+		skb = dev_alloc_skb(pkt_len);
+		if (skb == NULL) {	/* Not enough memory->drop packet */
+#ifdef HP100_DEBUG
+			printk("hp100: %s: rx: couldn't allocate a sk_buff of size %d\n",
+					     dev->name, pkt_len);
+#endif
+			lp->stats.rx_dropped++;
+		} else {	/* skb successfully allocated */
+
+			u_char *ptr;
+
+			skb->dev = dev;
+
+			/* ptr to start of the sk_buff data area */
+			ptr = (u_char *) skb_put(skb, pkt_len);
+
+			/* Now transfer the data from the card into that area */
+			if (lp->mode == 2) {
+				if (lp->mem_ptr_virt)
+					memcpy_fromio(ptr, lp->mem_ptr_virt,pkt_len);
+				/* Note alignment to 32bit transfers */
+				else
+					isa_memcpy_fromio(ptr, lp->mem_ptr_phys, pkt_len);
+			} else	/* io mapped */
+				insl(ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2);
+
+			skb->protocol = eth_type_trans(skb, dev);
+
 #ifdef HP100_DEBUG_RX
-	  printk( "hp100: %s: rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-	  	  dev->name,
-		  ptr[ 0 ], ptr[ 1 ], ptr[ 2 ], ptr[ 3 ], ptr[ 4 ], ptr[ 5 ],
-		  ptr[ 6 ], ptr[ 7 ], ptr[ 8 ], ptr[ 9 ], ptr[ 10 ], ptr[ 11 ] );
-#endif
-	  netif_rx( skb );
-	  dev->last_rx = jiffies;
-	  lp->stats.rx_packets++;
-	  lp->stats.rx_bytes += pkt_len;
-	}
-  
-      /* Indicate the card that we have got the packet */
-      hp100_outb( HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW );
-
-      switch ( header & 0x00070000 ) {
-      case (HP100_MULTI_ADDR_HASH<<16):
-      case (HP100_MULTI_ADDR_NO_HASH<<16):
-	lp->stats.multicast++; break;
-      }
-    } /* end of while(there are packets) loop */
+			printk("hp100: %s: rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+					dev->name, ptr[0], ptr[1], ptr[2], ptr[3],
+		 			ptr[4], ptr[5], ptr[6], ptr[7], ptr[8],
+					ptr[9], ptr[10], ptr[11]);
+#endif
+			netif_rx(skb);
+			dev->last_rx = jiffies;
+			lp->stats.rx_packets++;
+			lp->stats.rx_bytes += pkt_len;
+		}
+
+		/* Indicate the card that we have got the packet */
+		hp100_outb(HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW);
+
+		switch (header & 0x00070000) {
+		case (HP100_MULTI_ADDR_HASH << 16):
+		case (HP100_MULTI_ADDR_NO_HASH << 16):
+			lp->stats.multicast++;
+			break;
+		}
+	}			/* end of while(there are packets) loop */
 #ifdef HP100_DEBUG_RX
-  printk( "hp100_rx: %s: end\n", dev->name );
+	printk("hp100_rx: %s: end\n", dev->name);
 #endif
 }
 
-
 /* 
  * Receive Function for Busmaster Mode
  */
-static void hp100_rx_bm( struct net_device *dev )
+static void hp100_rx_bm(struct net_device *dev)
 {
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  hp100_ring_t *ptr;
-  u_int header;
-  int pkt_len;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4214, TRACE );
-  printk("hp100: %s: rx_bm\n", dev->name);
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	hp100_ring_t *ptr;
+	u_int header;
+	int pkt_len;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4214, TRACE);
+	printk("hp100: %s: rx_bm\n", dev->name);
 #endif
 
 #ifdef HP100_DEBUG
-  if(0==lp->rxrcommit)
-    {
-      printk("hp100: %s: rx_bm called although no PDLs were committed to adapter?\n", dev->name); 
-      return;
-    }
-  else
-
-    /* RX_PKT_CNT states how many PDLs are currently formatted and available to 
-     * the cards BM engine */
-    if( (hp100_inw(RX_PKT_CNT)&0x00ff) >= lp->rxrcommit)
-      {
-	printk("hp100: %s: More packets received than commited? RX_PKT_CNT=0x%x, commit=0x%x\n", dev->name, hp100_inw(RX_PKT_CNT)&0x00ff, lp->rxrcommit);
-	return;
-      }
-#endif
-
-  while( (lp->rxrcommit > hp100_inb(RX_PDL)) )
-    {
-      /*
-       * The packet was received into the pdl pointed to by lp->rxrhead (
-       * the oldest pdl in the ring 
-       */
-						
-      /* First we get the header, which contains information about the */
-      /* actual length of the received packet. */
-      
-      ptr=lp->rxrhead;
-      
-      header = *(ptr->pdl-1);
-      pkt_len = (header & HP100_PKT_LEN_MASK);
+	if (0 == lp->rxrcommit) {
+		printk("hp100: %s: rx_bm called although no PDLs were committed to adapter?\n", dev->name);
+		return;
+	} else
+		/* RX_PKT_CNT states how many PDLs are currently formatted and available to 
+		 * the cards BM engine */
+	if ((hp100_inw(RX_PKT_CNT) & 0x00ff) >= lp->rxrcommit) {
+		printk("hp100: %s: More packets received than commited? RX_PKT_CNT=0x%x, commit=0x%x\n",
+				     dev->name, hp100_inw(RX_PKT_CNT) & 0x00ff,
+				     lp->rxrcommit);
+		return;
+	}
+#endif
+
+	while ((lp->rxrcommit > hp100_inb(RX_PDL))) {
+		/*
+		 * The packet was received into the pdl pointed to by lp->rxrhead (
+		 * the oldest pdl in the ring 
+		 */
+
+		/* First we get the header, which contains information about the */
+		/* actual length of the received packet. */
+
+		ptr = lp->rxrhead;
+
+		header = *(ptr->pdl - 1);
+		pkt_len = (header & HP100_PKT_LEN_MASK);
 
 #ifdef HP100_DEBUG_BM
-      printk( "hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n",
-      	      dev->name,
-              (u_int) (ptr->pdl-1),(u_int) header,
-              pkt_len, 
-              (header>>16)&0xfff8,
-              (header>>16)&7);
-      printk( "hp100: %s: RX_PDL_COUNT:0x%x TX_PDL_COUNT:0x%x, RX_PKT_CNT=0x%x PDH=0x%x, Data@0x%x len=0x%x\n",
-      	      dev->name,
-	      hp100_inb( RX_PDL ),
-	      hp100_inb( TX_PDL ),
-	      hp100_inb( RX_PKT_CNT ),
-	      (u_int) *(ptr->pdl),
-	      (u_int) *(ptr->pdl+3),
-	      (u_int) *(ptr->pdl+4));
-#endif
-      
-      if( (pkt_len>=MIN_ETHER_SIZE) &&
-          (pkt_len<=MAX_ETHER_SIZE) )  
-        {
-	  if(ptr->skb==NULL)
-	    {
-	      printk("hp100: %s: rx_bm: skb null\n", dev->name);
-	      /* can happen if we only allocated room for the pdh due to memory shortage. */
-	      lp->stats.rx_dropped++;
-	    }
-	  else
-	    {
-	      skb_trim( ptr->skb, pkt_len );     /* Shorten it */
-	      ptr->skb->protocol = eth_type_trans( ptr->skb, dev );
-														
-	      netif_rx( ptr->skb );              /* Up and away... */
-
-	      dev->last_rx = jiffies;
-	      lp->stats.rx_packets++;
-	      lp->stats.rx_bytes += pkt_len;
-	    }
-
-          switch ( header & 0x00070000 ) {
-          case (HP100_MULTI_ADDR_HASH<<16):
-          case (HP100_MULTI_ADDR_NO_HASH<<16):
-            lp->stats.multicast++; break;
-          }
-        }
-      else
-        {
-#ifdef HP100_DEBUG
-          printk("hp100: %s: rx_bm: Received bad packet (length=%d)\n",dev->name,pkt_len);
-#endif
-	  if(ptr->skb!=NULL)
-	    dev_kfree_skb_any( ptr->skb );
-          lp->stats.rx_errors++;
-        }
-						
-      lp->rxrhead=lp->rxrhead->next;
-
-      /* Allocate a new rx PDL (so lp->rxrcommit stays the same) */
-      if (0 == hp100_build_rx_pdl( lp->rxrtail, dev ))
-        {
-	  /* No space for skb, header can still be received. */
-#ifdef HP100_DEBUG
-          printk("hp100: %s: rx_bm: No space for new PDL.\n", dev->name);
-#endif
-	  return;
-        } 
-      else
-        { /* successfully allocated new PDL - put it in ringlist at tail. */
-	  hp100_outl((u32)lp->rxrtail->pdl_paddr, RX_PDA);
-          lp->rxrtail=lp->rxrtail->next;
+		printk("hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n",
+				dev->name, (u_int) (ptr->pdl - 1), (u_int) header,
+				pkt_len, (header >> 16) & 0xfff8, (header >> 16) & 7);
+		printk("hp100: %s: RX_PDL_COUNT:0x%x TX_PDL_COUNT:0x%x, RX_PKT_CNT=0x%x PDH=0x%x, Data@0x%x len=0x%x\n",
+		   		dev->name, hp100_inb(RX_PDL), hp100_inb(TX_PDL),
+				hp100_inb(RX_PKT_CNT), (u_int) * (ptr->pdl),
+				(u_int) * (ptr->pdl + 3), (u_int) * (ptr->pdl + 4));
+#endif
+
+		if ((pkt_len >= MIN_ETHER_SIZE) &&
+		    (pkt_len <= MAX_ETHER_SIZE)) {
+			if (ptr->skb == NULL) {
+				printk("hp100: %s: rx_bm: skb null\n", dev->name);
+				/* can happen if we only allocated room for the pdh due to memory shortage. */
+				lp->stats.rx_dropped++;
+			} else {
+				skb_trim(ptr->skb, pkt_len);	/* Shorten it */
+				ptr->skb->protocol =
+				    eth_type_trans(ptr->skb, dev);
+
+				netif_rx(ptr->skb);	/* Up and away... */
+
+				dev->last_rx = jiffies;
+				lp->stats.rx_packets++;
+				lp->stats.rx_bytes += pkt_len;
+			}
+
+			switch (header & 0x00070000) {
+			case (HP100_MULTI_ADDR_HASH << 16):
+			case (HP100_MULTI_ADDR_NO_HASH << 16):
+				lp->stats.multicast++;
+				break;
+			}
+		} else {
+#ifdef HP100_DEBUG
+			printk("hp100: %s: rx_bm: Received bad packet (length=%d)\n", dev->name, pkt_len);
+#endif
+			if (ptr->skb != NULL)
+				dev_kfree_skb_any(ptr->skb);
+			lp->stats.rx_errors++;
+		}
+
+		lp->rxrhead = lp->rxrhead->next;
+
+		/* Allocate a new rx PDL (so lp->rxrcommit stays the same) */
+		if (0 == hp100_build_rx_pdl(lp->rxrtail, dev)) {
+			/* No space for skb, header can still be received. */
+#ifdef HP100_DEBUG
+			printk("hp100: %s: rx_bm: No space for new PDL.\n", dev->name);
+#endif
+			return;
+		} else {	/* successfully allocated new PDL - put it in ringlist at tail. */
+			hp100_outl((u32) lp->rxrtail->pdl_paddr, RX_PDA);
+			lp->rxrtail = lp->rxrtail->next;
+		}
+
 	}
-						
-    }
 }
 
-
-
 /*
  *  statistics
  */
-static hp100_stats_t *hp100_get_stats( struct net_device *dev )
+static hp100_stats_t *hp100_get_stats(struct net_device *dev)
 {
-  unsigned long flags;
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	unsigned long flags;
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4215, TRACE );
+	hp100_outw(0x4215, TRACE);
 #endif
 
-  spin_lock_irqsave (&lp->lock, flags);
-  hp100_ints_off();	/* Useful ? Jean II */
-  hp100_update_stats( dev );
-  hp100_ints_on();
-  spin_unlock_irqrestore (&lp->lock, flags);
-  return &(lp->stats);
+	spin_lock_irqsave(&lp->lock, flags);
+	hp100_ints_off();	/* Useful ? Jean II */
+	hp100_update_stats(dev);
+	hp100_ints_on();
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return &(lp->stats);
 }
 
-static void hp100_update_stats( struct net_device *dev )
+static void hp100_update_stats(struct net_device *dev)
 {
-  int ioaddr = dev->base_addr;
-  u_short val;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	int ioaddr = dev->base_addr;
+	u_short val;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4216, TRACE );
-  printk("hp100: %s: update-stats\n", dev->name);
+	hp100_outw(0x4216, TRACE);
+	printk("hp100: %s: update-stats\n", dev->name);
 #endif
 
-  /* Note: Statistics counters clear when read. */
-  hp100_page( MAC_CTRL ); 
-  val = hp100_inw( DROPPED ) & 0x0fff;
-  lp->stats.rx_errors += val;
-  lp->stats.rx_over_errors += val;
-  val = hp100_inb( CRC );
-  lp->stats.rx_errors += val;
-  lp->stats.rx_crc_errors += val;
-  val = hp100_inb( ABORT );
-  lp->stats.tx_errors += val;
-  lp->stats.tx_aborted_errors += val;
-  hp100_page( PERFORMANCE );
+	/* Note: Statistics counters clear when read. */
+	hp100_page(MAC_CTRL);
+	val = hp100_inw(DROPPED) & 0x0fff;
+	lp->stats.rx_errors += val;
+	lp->stats.rx_over_errors += val;
+	val = hp100_inb(CRC);
+	lp->stats.rx_errors += val;
+	lp->stats.rx_crc_errors += val;
+	val = hp100_inb(ABORT);
+	lp->stats.tx_errors += val;
+	lp->stats.tx_aborted_errors += val;
+	hp100_page(PERFORMANCE);
 }
 
-static void hp100_misc_interrupt( struct net_device *dev )
+static void hp100_misc_interrupt(struct net_device *dev)
 {
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4216, TRACE );
-  printk("hp100: %s: misc_interrupt\n", dev->name);
+	hp100_outw(0x4216, TRACE);
+	printk("hp100: %s: misc_interrupt\n", dev->name);
 #endif
 
-  /* Note: Statistics counters clear when read. */
-  lp->stats.rx_errors++;
-  lp->stats.tx_errors++;
+	/* Note: Statistics counters clear when read. */
+	lp->stats.rx_errors++;
+	lp->stats.tx_errors++;
 }
 
-static void hp100_clear_stats( struct hp100_private *lp, int ioaddr )
+static void hp100_clear_stats(struct hp100_private *lp, int ioaddr)
 {
-  unsigned long flags;
+	unsigned long flags;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4217, TRACE );
-  printk("hp100: %s: clear_stats\n", dev->name);
+	hp100_outw(0x4217, TRACE);
+	printk("hp100: %s: clear_stats\n", dev->name);
 #endif
 
-  spin_lock_irqsave (&lp->lock, flags);
-  hp100_page( MAC_CTRL );    /* get all statistics bytes */
-  hp100_inw( DROPPED );
-  hp100_inb( CRC );
-  hp100_inb( ABORT );
-  hp100_page( PERFORMANCE );
-  spin_unlock_irqrestore (&lp->lock, flags);
+	spin_lock_irqsave(&lp->lock, flags);
+	hp100_page(MAC_CTRL);	/* get all statistics bytes */
+	hp100_inw(DROPPED);
+	hp100_inb(CRC);
+	hp100_inb(ABORT);
+	hp100_page(PERFORMANCE);
+	spin_unlock_irqrestore(&lp->lock, flags);
 }
-
 
+
 /*
  *  multicast setup
  */
@@ -2209,838 +2094,821 @@
 /*
  *  Set or clear the multicast filter for this adapter.
  */
-                                                          
-static void hp100_set_multicast_list( struct net_device *dev )
+
+static void hp100_set_multicast_list(struct net_device *dev)
 {
-  unsigned long flags;
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4218, TRACE );
-  printk("hp100: %s: set_mc_list\n", dev->name);
-#endif
-
-  spin_lock_irqsave (&lp->lock, flags);
-  hp100_ints_off();
-  hp100_page( MAC_CTRL );
-  hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );  /* stop rx/tx */
-
-  if ( dev->flags & IFF_PROMISC )
-    {
-      lp->mac2_mode = HP100_MAC2MODE6;  /* promiscuous mode = get all good */
-      lp->mac1_mode = HP100_MAC1MODE6;  /* packets on the net */
-      memset( &lp->hash_bytes, 0xff, 8 );
-    }
-  else if ( dev->mc_count || (dev->flags&IFF_ALLMULTI) )
-    {
-      lp->mac2_mode = HP100_MAC2MODE5;  /* multicast mode = get packets for */
-      lp->mac1_mode = HP100_MAC1MODE5;  /* me, broadcasts and all multicasts */
-#ifdef HP100_MULTICAST_FILTER		/* doesn't work!!! */
-      if ( dev -> flags & IFF_ALLMULTI )
-        {
-          /* set hash filter to receive all multicast packets */
-          memset( &lp->hash_bytes, 0xff, 8 );
-        }
-       else
-        {
-          int i, j, idx;
-          u_char *addrs;
-          struct dev_mc_list *dmi;
-
-          memset( &lp->hash_bytes, 0x00, 8 );
-#ifdef HP100_DEBUG
-          printk("hp100: %s: computing hash filter - mc_count = %i\n", dev -> name, dev -> mc_count );
-#endif 
-          for ( i = 0, dmi = dev -> mc_list; i < dev -> mc_count; i++, dmi = dmi -> next )
-            {
-              addrs = dmi -> dmi_addr;
-              if ( ( *addrs & 0x01 ) == 0x01 )	/* multicast address? */
-                {
-#ifdef HP100_DEBUG
-                  printk("hp100: %s: multicast = %02x:%02x:%02x:%02x:%02x:%02x, ",
-                  	dev -> name,
-        		addrs[ 0 ], addrs[ 1 ], addrs[ 2 ],
-        		addrs[ 3 ], addrs[ 4 ], addrs[ 5 ] );
-#endif 
-                  for ( j = idx = 0; j < 6; j++ )
-                    {
-                      idx ^= *addrs++ & 0x3f;
-                      printk( ":%02x:", idx );
-                    }
-#ifdef HP100_DEBUG
-                  printk("idx = %i\n", idx );
-#endif
-		  lp->hash_bytes[ idx >> 3 ] |= ( 1 << ( idx & 7 ) );
-                }
-            }
-        }
+	unsigned long flags;
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4218, TRACE);
+	printk("hp100: %s: set_mc_list\n", dev->name);
+#endif
+
+	spin_lock_irqsave(&lp->lock, flags);
+	hp100_ints_off();
+	hp100_page(MAC_CTRL);
+	hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1);	/* stop rx/tx */
+
+	if (dev->flags & IFF_PROMISC) {
+		lp->mac2_mode = HP100_MAC2MODE6;	/* promiscuous mode = get all good */
+		lp->mac1_mode = HP100_MAC1MODE6;	/* packets on the net */
+		memset(&lp->hash_bytes, 0xff, 8);
+	} else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
+		lp->mac2_mode = HP100_MAC2MODE5;	/* multicast mode = get packets for */
+		lp->mac1_mode = HP100_MAC1MODE5;	/* me, broadcasts and all multicasts */
+#ifdef HP100_MULTICAST_FILTER	/* doesn't work!!! */
+		if (dev->flags & IFF_ALLMULTI) {
+			/* set hash filter to receive all multicast packets */
+			memset(&lp->hash_bytes, 0xff, 8);
+		} else {
+			int i, j, idx;
+			u_char *addrs;
+			struct dev_mc_list *dmi;
+
+			memset(&lp->hash_bytes, 0x00, 8);
+#ifdef HP100_DEBUG
+			printk("hp100: %s: computing hash filter - mc_count = %i\n", dev->name, dev->mc_count);
+#endif
+			for (i = 0, dmi = dev->mc_list; i < dev->mc_count; i++, dmi = dmi->next) {
+				addrs = dmi->dmi_addr;
+				if ((*addrs & 0x01) == 0x01) {	/* multicast address? */
+#ifdef HP100_DEBUG
+					printk("hp100: %s: multicast = %02x:%02x:%02x:%02x:%02x:%02x, ",
+						     dev->name, addrs[0], addrs[1], addrs[2],
+						     addrs[3], addrs[4], addrs[5]);
+#endif
+					for (j = idx = 0; j < 6; j++) {
+						idx ^= *addrs++ & 0x3f;
+						printk(":%02x:", idx);
+					}
+#ifdef HP100_DEBUG
+					printk("idx = %i\n", idx);
+#endif
+					lp->hash_bytes[idx >> 3] |= (1 << (idx & 7));
+				}
+			}
+		}
 #else
-      memset( &lp->hash_bytes, 0xff, 8 );
+		memset(&lp->hash_bytes, 0xff, 8);
+#endif
+	} else {
+		lp->mac2_mode = HP100_MAC2MODE3;	/* normal mode = get packets for me */
+		lp->mac1_mode = HP100_MAC1MODE3;	/* and broadcasts */
+		memset(&lp->hash_bytes, 0x00, 8);
+	}
+
+	if (((hp100_inb(MAC_CFG_1) & 0x0f) != lp->mac1_mode) ||
+	    (hp100_inb(MAC_CFG_2) != lp->mac2_mode)) {
+		int i;
+
+		hp100_outb(lp->mac2_mode, MAC_CFG_2);
+		hp100_andb(HP100_MAC1MODEMASK, MAC_CFG_1);	/* clear mac1 mode bits */
+		hp100_orb(lp->mac1_mode, MAC_CFG_1);	/* and set the new mode */
+
+		hp100_page(MAC_ADDRESS);
+		for (i = 0; i < 8; i++)
+			hp100_outb(lp->hash_bytes[i], HASH_BYTE0 + i);
+#ifdef HP100_DEBUG
+		printk("hp100: %s: mac1 = 0x%x, mac2 = 0x%x, multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+				     dev->name, lp->mac1_mode, lp->mac2_mode,
+				     lp->hash_bytes[0], lp->hash_bytes[1],
+				     lp->hash_bytes[2], lp->hash_bytes[3],
+				     lp->hash_bytes[4], lp->hash_bytes[5],
+				     lp->hash_bytes[6], lp->hash_bytes[7]);
+#endif
+
+		if (lp->lan_type == HP100_LAN_100) {
+#ifdef HP100_DEBUG
+			printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name);
 #endif
-    }
-  else
-    {
-      lp->mac2_mode = HP100_MAC2MODE3;  /* normal mode = get packets for me */
-      lp->mac1_mode = HP100_MAC1MODE3;  /* and broadcasts */
-      memset( &lp->hash_bytes, 0x00, 8 );
-    }
-
-  if ( ( (hp100_inb(MAC_CFG_1) & 0x0f)!=lp->mac1_mode ) ||
-        ( hp100_inb(MAC_CFG_2)!=lp->mac2_mode ) ) 
-    {
-      int i;
-    
-      hp100_outb( lp->mac2_mode, MAC_CFG_2 );
-      hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 ); /* clear mac1 mode bits */
-      hp100_orb( lp->mac1_mode, MAC_CFG_1 );       /* and set the new mode */
-
-      hp100_page( MAC_ADDRESS );
-      for ( i = 0; i < 8; i++ )
-        hp100_outb( lp->hash_bytes[ i ], HASH_BYTE0 + i );
-#ifdef HP100_DEBUG
-      printk("hp100: %s: mac1 = 0x%x, mac2 = 0x%x, multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 
-      		dev->name, lp->mac1_mode, lp->mac2_mode,
-      		lp->hash_bytes[ 0 ], lp->hash_bytes[ 1 ],
-      		lp->hash_bytes[ 2 ], lp->hash_bytes[ 3 ],
-      		lp->hash_bytes[ 4 ], lp->hash_bytes[ 5 ],
-      		lp->hash_bytes[ 6 ], lp->hash_bytes[ 7 ]
-      		);
-#endif 
-
-      if(lp->lan_type==HP100_LAN_100)
-        {
-#ifdef HP100_DEBUG
-  	  printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name);
-#endif 
-	  lp->hub_status=hp100_login_to_vg_hub( dev, TRUE );  /* force a relogin to the hub */
-        }
-    }
-   else
-    {
-      int i;
-      u_char old_hash_bytes[ 8 ];
-
-      hp100_page( MAC_ADDRESS );
-      for ( i = 0; i < 8; i++ )
-        old_hash_bytes[ i ] = hp100_inb( HASH_BYTE0 + i );
-      if ( memcmp( old_hash_bytes, &lp->hash_bytes, 8 ) )
-        {
-          for ( i = 0; i < 8; i++ )
-            hp100_outb( lp->hash_bytes[ i ], HASH_BYTE0 + i );
-#ifdef HP100_DEBUG
-          printk("hp100: %s: multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 
-          	dev->name,
-      		lp->hash_bytes[ 0 ], lp->hash_bytes[ 1 ],
-      		lp->hash_bytes[ 2 ], lp->hash_bytes[ 3 ],
-      		lp->hash_bytes[ 4 ], lp->hash_bytes[ 5 ],
-      		lp->hash_bytes[ 6 ], lp->hash_bytes[ 7 ]
-      		);
-#endif 
-
-          if(lp->lan_type==HP100_LAN_100)
-            {
-#ifdef HP100_DEBUG
-  	      printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name);
-#endif 
-   	      lp->hub_status=hp100_login_to_vg_hub( dev, TRUE );  /* force a relogin to the hub */
-            }
-        }
-    }
-
-  hp100_page( MAC_CTRL );
-  hp100_orb( HP100_RX_EN | HP100_RX_IDLE |              /* enable rx */
-	     HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 );  /* enable tx */
-
-  hp100_page( PERFORMANCE );
-  hp100_ints_on();
-  spin_unlock_irqrestore (&lp->lock, flags);
+			lp->hub_status = hp100_login_to_vg_hub(dev, TRUE);	/* force a relogin to the hub */
+		}
+	} else {
+		int i;
+		u_char old_hash_bytes[8];
+
+		hp100_page(MAC_ADDRESS);
+		for (i = 0; i < 8; i++)
+			old_hash_bytes[i] = hp100_inb(HASH_BYTE0 + i);
+		if (memcmp(old_hash_bytes, &lp->hash_bytes, 8)) {
+			for (i = 0; i < 8; i++)
+				hp100_outb(lp->hash_bytes[i], HASH_BYTE0 + i);
+#ifdef HP100_DEBUG
+			printk("hp100: %s: multicast hash = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+					dev->name, lp->hash_bytes[0],
+					lp->hash_bytes[1], lp->hash_bytes[2],
+					lp->hash_bytes[3], lp->hash_bytes[4],
+					lp->hash_bytes[5], lp->hash_bytes[6],
+					lp->hash_bytes[7]);
+#endif
+
+			if (lp->lan_type == HP100_LAN_100) {
+#ifdef HP100_DEBUG
+				printk("hp100: %s: 100VG MAC settings have changed - relogin.\n", dev->name);
+#endif
+				lp->hub_status = hp100_login_to_vg_hub(dev, TRUE);	/* force a relogin to the hub */
+			}
+		}
+	}
+
+	hp100_page(MAC_CTRL);
+	hp100_orb(HP100_RX_EN | HP100_RX_IDLE |	/* enable rx */
+		  HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1);	/* enable tx */
+
+	hp100_page(PERFORMANCE);
+	hp100_ints_on();
+	spin_unlock_irqrestore(&lp->lock, flags);
 }
 
-
 /*
  *  hardware interrupt handling
  */
 
-static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs )
+static void hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-  struct net_device *dev = (struct net_device *)dev_id;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
-  int ioaddr;
-  u_int val;
+	int ioaddr;
+	u_int val;
 
-  if ( dev == NULL ) return;
-  ioaddr = dev->base_addr;
-  
-  spin_lock (&lp->lock);
+	if (dev == NULL)
+		return;
+	ioaddr = dev->base_addr;
 
-  hp100_ints_off();
+	spin_lock(&lp->lock);
+
+	hp100_ints_off();
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4219, TRACE );
+	hp100_outw(0x4219, TRACE);
 #endif
 
-  /*  hp100_page( PERFORMANCE ); */
-  val = hp100_inw( IRQ_STATUS );
+	/*  hp100_page( PERFORMANCE ); */
+	val = hp100_inw(IRQ_STATUS);
 #ifdef HP100_DEBUG_IRQ
-  printk( "hp100: %s: mode=%x,IRQ_STAT=0x%.4x,RXPKTCNT=0x%.2x RXPDL=0x%.2x TXPKTCNT=0x%.2x TXPDL=0x%.2x\n",
-  	  dev->name,
-          lp->mode,
-	  (u_int)val,
-          hp100_inb( RX_PKT_CNT ),
-          hp100_inb( RX_PDL ),
-	  hp100_inb( TX_PKT_CNT ),
-	  hp100_inb( TX_PDL )
-	  );
-#endif
-
-  if(val==0) /* might be a shared interrupt */ 
-    {
-      spin_unlock (&lp->lock);
-      hp100_ints_on();
-      return;
-    }
-  /* We're only interested in those interrupts we really enabled. */
-  /* val &= hp100_inw( IRQ_MASK ); */
-
-  /* 
-   * RX_PDL_FILL_COMPL is set whenever a RX_PDL has been executed. A RX_PDL 
-   * is considered executed whenever the RX_PDL data structure is no longer 
-   * needed.
-   */
-  if ( val & HP100_RX_PDL_FILL_COMPL )
-    {
-      if(lp->mode==1)
-	hp100_rx_bm( dev );
-      else
-	{
-	  printk("hp100: %s: rx_pdl_fill_compl interrupt although not busmaster?\n", dev->name);
-	}
-    }
-		
-  /* 
-   * The RX_PACKET interrupt is set, when the receive packet counter is
-   * non zero. We use this interrupt for receiving in slave mode. In
-   * busmaster mode, we use it to make sure we did not miss any rx_pdl_fill
-   * interrupts. If rx_pdl_fill_compl is not set and rx_packet is set, then
-   * we somehow have missed a rx_pdl_fill_compl interrupt.
-   */
-
-  if ( val & HP100_RX_PACKET  ) /* Receive Packet Counter is non zero */
-    {
-      if(lp->mode!=1) /* non busmaster */
-        hp100_rx( dev );
-      else if ( !(val & HP100_RX_PDL_FILL_COMPL ))
-	{
-	  /* Shouldnt happen - maybe we missed a RX_PDL_FILL Interrupt?  */
-	  hp100_rx_bm( dev );
-	}
-    }
-
-  /*
-   * Ack. that we have noticed the interrupt and thereby allow next one.
-   * Note that this is now done after the slave rx function, since first
-   * acknowledging and then setting ADV_NXT_PKT caused an extra interrupt
-   * on the J2573.
-   */
-  hp100_outw( val, IRQ_STATUS );
-
-  /*
-   * RX_ERROR is set when a packet is dropped due to no memory resources on 
-   * the card or when a RCV_ERR occurs. 
-   * TX_ERROR is set when a TX_ABORT condition occurs in the MAC->exists  
-   * only in the 802.3 MAC and happens when 16 collisions occur during a TX 
-   */
-  if ( val & ( HP100_TX_ERROR | HP100_RX_ERROR ) )
-    {
+	printk("hp100: %s: mode=%x,IRQ_STAT=0x%.4x,RXPKTCNT=0x%.2x RXPDL=0x%.2x TXPKTCNT=0x%.2x TXPDL=0x%.2x\n",
+			     dev->name, lp->mode, (u_int) val, hp100_inb(RX_PKT_CNT),
+			     hp100_inb(RX_PDL), hp100_inb(TX_PKT_CNT), hp100_inb(TX_PDL));
+#endif
+
+	if (val == 0) {		/* might be a shared interrupt */
+		spin_unlock(&lp->lock);
+		hp100_ints_on();
+		return;
+	}
+	/* We're only interested in those interrupts we really enabled. */
+	/* val &= hp100_inw( IRQ_MASK ); */
+
+	/* 
+	 * RX_PDL_FILL_COMPL is set whenever a RX_PDL has been executed. A RX_PDL 
+	 * is considered executed whenever the RX_PDL data structure is no longer 
+	 * needed.
+	 */
+	if (val & HP100_RX_PDL_FILL_COMPL) {
+		if (lp->mode == 1)
+			hp100_rx_bm(dev);
+		else {
+			printk("hp100: %s: rx_pdl_fill_compl interrupt although not busmaster?\n", dev->name);
+		}
+	}
+
+	/* 
+	 * The RX_PACKET interrupt is set, when the receive packet counter is
+	 * non zero. We use this interrupt for receiving in slave mode. In
+	 * busmaster mode, we use it to make sure we did not miss any rx_pdl_fill
+	 * interrupts. If rx_pdl_fill_compl is not set and rx_packet is set, then
+	 * we somehow have missed a rx_pdl_fill_compl interrupt.
+	 */
+
+	if (val & HP100_RX_PACKET) {	/* Receive Packet Counter is non zero */
+		if (lp->mode != 1)	/* non busmaster */
+			hp100_rx(dev);
+		else if (!(val & HP100_RX_PDL_FILL_COMPL)) {
+			/* Shouldnt happen - maybe we missed a RX_PDL_FILL Interrupt?  */
+			hp100_rx_bm(dev);
+		}
+	}
+
+	/*
+	 * Ack. that we have noticed the interrupt and thereby allow next one.
+	 * Note that this is now done after the slave rx function, since first
+	 * acknowledging and then setting ADV_NXT_PKT caused an extra interrupt
+	 * on the J2573.
+	 */
+	hp100_outw(val, IRQ_STATUS);
+
+	/*
+	 * RX_ERROR is set when a packet is dropped due to no memory resources on 
+	 * the card or when a RCV_ERR occurs. 
+	 * TX_ERROR is set when a TX_ABORT condition occurs in the MAC->exists  
+	 * only in the 802.3 MAC and happens when 16 collisions occur during a TX 
+	 */
+	if (val & (HP100_TX_ERROR | HP100_RX_ERROR)) {
 #ifdef HP100_DEBUG_IRQ
-      printk("hp100: %s: TX/RX Error IRQ\n", dev->name);
+		printk("hp100: %s: TX/RX Error IRQ\n", dev->name);
 #endif
-      hp100_update_stats( dev );
-      if(lp->mode==1)
-	{
-	  hp100_rxfill( dev );
-	  hp100_clean_txring( dev );
-	}
-    }
-				
-  /* 
-   * RX_PDA_ZERO is set when the PDA count goes from non-zero to zero. 
-   */
-  if ( (lp->mode==1)&&(val &(HP100_RX_PDA_ZERO)) )
-    hp100_rxfill( dev );
-		
-  /* 
-   * HP100_TX_COMPLETE interrupt occurs when packet transmitted on wire 
-   * is completed 
-   */
-  if ( (lp->mode==1) && ( val & ( HP100_TX_COMPLETE )) )
-    hp100_clean_txring( dev );
-
-  /* 
-   * MISC_ERROR is set when either the LAN link goes down or a detected
-   * bus error occurs.
-   */
-  if ( val & HP100_MISC_ERROR ) /* New for J2585B */
-    {
+		hp100_update_stats(dev);
+		if (lp->mode == 1) {
+			hp100_rxfill(dev);
+			hp100_clean_txring(dev);
+		}
+	}
+
+	/* 
+	 * RX_PDA_ZERO is set when the PDA count goes from non-zero to zero. 
+	 */
+	if ((lp->mode == 1) && (val & (HP100_RX_PDA_ZERO)))
+		hp100_rxfill(dev);
+
+	/* 
+	 * HP100_TX_COMPLETE interrupt occurs when packet transmitted on wire 
+	 * is completed 
+	 */
+	if ((lp->mode == 1) && (val & (HP100_TX_COMPLETE)))
+		hp100_clean_txring(dev);
+
+	/* 
+	 * MISC_ERROR is set when either the LAN link goes down or a detected
+	 * bus error occurs.
+	 */
+	if (val & HP100_MISC_ERROR) {	/* New for J2585B */
 #ifdef HP100_DEBUG_IRQ
-      printk("hp100: %s: Misc. Error Interrupt - Check cabling.\n", dev->name);
-#endif
-      if(lp->mode==1)
-	{
-	  hp100_clean_txring( dev );
-	  hp100_rxfill( dev );
+		printk
+		    ("hp100: %s: Misc. Error Interrupt - Check cabling.\n",
+		     dev->name);
+#endif
+		if (lp->mode == 1) {
+			hp100_clean_txring(dev);
+			hp100_rxfill(dev);
+		}
+		hp100_misc_interrupt(dev);
 	}
-      hp100_misc_interrupt( dev );
-    }
 
-  spin_unlock (&lp->lock);	
-  hp100_ints_on();
+	spin_unlock(&lp->lock);
+	hp100_ints_on();
 }
 
-
 /*
  *  some misc functions
  */
 
-static void hp100_start_interface( struct net_device *dev )
+static void hp100_start_interface(struct net_device *dev)
 {
-  unsigned long flags;
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4220, TRACE );
-  printk("hp100: %s: hp100_start_interface\n",dev->name);
-#endif
-
-  spin_lock_irqsave (&lp->lock, flags);
-
-  /* Ensure the adapter does not want to request an interrupt when */
-  /* enabling the IRQ line to be active on the bus (i.e. not tri-stated) */
-  hp100_page( PERFORMANCE );
-  hp100_outw( 0xfefe, IRQ_MASK );  /* mask off all ints */
-  hp100_outw( 0xffff, IRQ_STATUS );  /* ack all IRQs */
-  hp100_outw( HP100_FAKE_INT|HP100_INT_EN|HP100_RESET_LB, OPTION_LSW);
-  /* Un Tri-state int. TODO: Check if shared interrupts can be realised? */
-  hp100_outw( HP100_TRI_INT | HP100_RESET_HB, OPTION_LSW ); 
-
-  if(lp->mode==1)
-    {
-      /* Make sure BM bit is set... */
-      hp100_page(HW_MAP);
-      hp100_orb( HP100_BM_MASTER, BM );
-      hp100_rxfill( dev );
-    }
-  else if(lp->mode==2)
-    {
-      /* Enable memory mapping. Note: Don't do this when busmaster. */
-      hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );
-    }
-
-  hp100_page(PERFORMANCE);
-  hp100_outw( 0xfefe, IRQ_MASK );  /* mask off all ints */
-  hp100_outw( 0xffff, IRQ_STATUS );  /* ack IRQ */
-
-  /* enable a few interrupts: */
-  if(lp->mode==1) /* busmaster mode */
-    {
-      hp100_outw( HP100_RX_PDL_FILL_COMPL |
-		  HP100_RX_PDA_ZERO  |  
-		  HP100_RX_ERROR     |  
-		  /* HP100_RX_PACKET    | */    
-		  /* HP100_RX_EARLY_INT |  */     HP100_SET_HB  |  
-		  /* HP100_TX_PDA_ZERO  |  */
-		  HP100_TX_COMPLETE  |  
-		  /* HP100_MISC_ERROR   |  */
-		  HP100_TX_ERROR     | HP100_SET_LB, IRQ_MASK );
-    } 
-  else
-    {  
-      hp100_outw( HP100_RX_PACKET  |
-		  HP100_RX_ERROR   | HP100_SET_HB |
-                  HP100_TX_ERROR   | HP100_SET_LB , IRQ_MASK );
-    }
-	
-  /* Note : before hp100_set_multicast_list(), because it will play with
-   * spinlock itself... Jean II */
-  spin_unlock_irqrestore (&lp->lock, flags);
+	unsigned long flags;
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4220, TRACE);
+	printk("hp100: %s: hp100_start_interface\n", dev->name);
+#endif
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	/* Ensure the adapter does not want to request an interrupt when */
+	/* enabling the IRQ line to be active on the bus (i.e. not tri-stated) */
+	hp100_page(PERFORMANCE);
+	hp100_outw(0xfefe, IRQ_MASK);	/* mask off all ints */
+	hp100_outw(0xffff, IRQ_STATUS);	/* ack all IRQs */
+	hp100_outw(HP100_FAKE_INT | HP100_INT_EN | HP100_RESET_LB,
+		   OPTION_LSW);
+	/* Un Tri-state int. TODO: Check if shared interrupts can be realised? */
+	hp100_outw(HP100_TRI_INT | HP100_RESET_HB, OPTION_LSW);
+
+	if (lp->mode == 1) {
+		/* Make sure BM bit is set... */
+		hp100_page(HW_MAP);
+		hp100_orb(HP100_BM_MASTER, BM);
+		hp100_rxfill(dev);
+	} else if (lp->mode == 2) {
+		/* Enable memory mapping. Note: Don't do this when busmaster. */
+		hp100_outw(HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW);
+	}
 
-  /* Enable MAC Tx and RX, set MAC modes, ... */
-  hp100_set_multicast_list( dev );
+	hp100_page(PERFORMANCE);
+	hp100_outw(0xfefe, IRQ_MASK);	/* mask off all ints */
+	hp100_outw(0xffff, IRQ_STATUS);	/* ack IRQ */
+
+	/* enable a few interrupts: */
+	if (lp->mode == 1) {	/* busmaster mode */
+		hp100_outw(HP100_RX_PDL_FILL_COMPL |
+			   HP100_RX_PDA_ZERO | HP100_RX_ERROR |
+			   /* HP100_RX_PACKET    | */
+			   /* HP100_RX_EARLY_INT |  */ HP100_SET_HB |
+			   /* HP100_TX_PDA_ZERO  |  */
+			   HP100_TX_COMPLETE |
+			   /* HP100_MISC_ERROR   |  */
+			   HP100_TX_ERROR | HP100_SET_LB, IRQ_MASK);
+	} else {
+		hp100_outw(HP100_RX_PACKET |
+			   HP100_RX_ERROR | HP100_SET_HB |
+			   HP100_TX_ERROR | HP100_SET_LB, IRQ_MASK);
+	}
+
+	/* Note : before hp100_set_multicast_list(), because it will play with
+	 * spinlock itself... Jean II */
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	/* Enable MAC Tx and RX, set MAC modes, ... */
+	hp100_set_multicast_list(dev);
 }
 
-
-static void hp100_stop_interface( struct net_device *dev )
+static void hp100_stop_interface(struct net_device *dev)
 {
-  struct hp100_private *lp = (struct hp100_private *)dev->priv; 
-  int ioaddr = dev->base_addr;
-  u_int val;
-
-#ifdef HP100_DEBUG_B
-  printk("hp100: %s: hp100_stop_interface\n",dev->name);
-  hp100_outw( 0x4221, TRACE );
-#endif
-
-  if (lp->mode==1) 
-    hp100_BM_shutdown( dev );
-  else
-    {
-      /* Note: MMAP_DIS will be reenabled by start_interface */
-      hp100_outw( HP100_INT_EN | HP100_RESET_LB | 
-                  HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
-      val = hp100_inw( OPTION_LSW );
-   
-      hp100_page( MAC_CTRL );
-      hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );
-
-      if ( !(val & HP100_HW_RST) ) return; /* If reset, imm. return ... */
-      /* ... else: busy wait until idle */
-      for ( val = 0; val < 6000; val++ )
-	if ( ( hp100_inb( MAC_CFG_1 ) & (HP100_TX_IDLE | HP100_RX_IDLE) ) ==
-	     (HP100_TX_IDLE | HP100_RX_IDLE) )
-	  {
-	    hp100_page(PERFORMANCE);
-	    return;
-	  }
-      printk( "hp100: %s: hp100_stop_interface - timeout\n", dev->name );
-      hp100_page(PERFORMANCE);
-    }
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	int ioaddr = dev->base_addr;
+	u_int val;
+
+#ifdef HP100_DEBUG_B
+	printk("hp100: %s: hp100_stop_interface\n", dev->name);
+	hp100_outw(0x4221, TRACE);
+#endif
+
+	if (lp->mode == 1)
+		hp100_BM_shutdown(dev);
+	else {
+		/* Note: MMAP_DIS will be reenabled by start_interface */
+		hp100_outw(HP100_INT_EN | HP100_RESET_LB |
+			   HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB,
+			   OPTION_LSW);
+		val = hp100_inw(OPTION_LSW);
+
+		hp100_page(MAC_CTRL);
+		hp100_andb(~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1);
+
+		if (!(val & HP100_HW_RST))
+			return;	/* If reset, imm. return ... */
+		/* ... else: busy wait until idle */
+		for (val = 0; val < 6000; val++)
+			if ((hp100_inb(MAC_CFG_1) & (HP100_TX_IDLE | HP100_RX_IDLE)) == (HP100_TX_IDLE | HP100_RX_IDLE)) {
+				hp100_page(PERFORMANCE);
+				return;
+			}
+		printk("hp100: %s: hp100_stop_interface - timeout\n", dev->name);
+		hp100_page(PERFORMANCE);
+	}
 }
 
-
-static void hp100_load_eeprom( struct net_device *dev, u_short probe_ioaddr )
+static void hp100_load_eeprom(struct net_device *dev, u_short probe_ioaddr)
 {
-  int i;
-  int ioaddr = probe_ioaddr > 0 ? probe_ioaddr : dev->base_addr;
+	int i;
+	int ioaddr = probe_ioaddr > 0 ? probe_ioaddr : dev->base_addr;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4222, TRACE );
+	hp100_outw(0x4222, TRACE);
 #endif
 
-  hp100_page( EEPROM_CTRL );
-  hp100_andw( ~HP100_EEPROM_LOAD, EEPROM_CTRL );
-  hp100_orw( HP100_EEPROM_LOAD, EEPROM_CTRL );
-  for ( i = 0; i < 10000; i++ )
-    if ( !( hp100_inb( OPTION_MSW ) & HP100_EE_LOAD ) ) return;
-  printk( "hp100: %s: hp100_load_eeprom - timeout\n", dev->name );
+	hp100_page(EEPROM_CTRL);
+	hp100_andw(~HP100_EEPROM_LOAD, EEPROM_CTRL);
+	hp100_orw(HP100_EEPROM_LOAD, EEPROM_CTRL);
+	for (i = 0; i < 10000; i++)
+		if (!(hp100_inb(OPTION_MSW) & HP100_EE_LOAD))
+			return;
+	printk("hp100: %s: hp100_load_eeprom - timeout\n", dev->name);
 }
 
-
 /*  Sense connection status.
  *  return values: LAN_10  - Connected to 10Mbit/s network
  *                 LAN_100 - Connected to 100Mbit/s network
  *                 LAN_ERR - not connected or 100Mbit/s Hub down
  */
-static int hp100_sense_lan( struct net_device *dev )
+static int hp100_sense_lan(struct net_device *dev)
 {
-  int ioaddr = dev->base_addr;
-  u_short val_VG, val_10;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
+	int ioaddr = dev->base_addr;
+	u_short val_VG, val_10;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
 
 #ifdef HP100_DEBUG_B
-  hp100_outw( 0x4223, TRACE );
+	hp100_outw(0x4223, TRACE);
 #endif
 
-  hp100_page( MAC_CTRL );
-  val_10 = hp100_inb( 10_LAN_CFG_1 );
-  val_VG = hp100_inb( VG_LAN_CFG_1 );
-  hp100_page( PERFORMANCE );
+	hp100_page(MAC_CTRL);
+	val_10 = hp100_inb(10_LAN_CFG_1);
+	val_VG = hp100_inb(VG_LAN_CFG_1);
+	hp100_page(PERFORMANCE);
 #ifdef HP100_DEBUG
-  printk( "hp100: %s: sense_lan: val_VG = 0x%04x, val_10 = 0x%04x\n", dev->name, val_VG, val_10 );
+	printk("hp100: %s: sense_lan: val_VG = 0x%04x, val_10 = 0x%04x\n",
+	       dev->name, val_VG, val_10);
 #endif
 
-  if ( val_10 & HP100_LINK_BEAT_ST )	/* 10Mb connection is active */
-    return HP100_LAN_10;
+	if (val_10 & HP100_LINK_BEAT_ST)	/* 10Mb connection is active */
+		return HP100_LAN_10;
 
-  if ( val_10 & HP100_AUI_ST )		/* have we BNC or AUI onboard? */
-    {
-      val_10 |= HP100_AUI_SEL | HP100_LOW_TH;
-      hp100_page( MAC_CTRL );
-      hp100_outb( val_10, 10_LAN_CFG_1 );
-      hp100_page( PERFORMANCE );
-      return HP100_LAN_10;
-    }
+	if (val_10 & HP100_AUI_ST) {	/* have we BNC or AUI onboard? */
+		val_10 |= HP100_AUI_SEL | HP100_LOW_TH;
+		hp100_page(MAC_CTRL);
+		hp100_outb(val_10, 10_LAN_CFG_1);
+		hp100_page(PERFORMANCE);
+		return HP100_LAN_10;
+	}
 
-  if ( (lp->id->id == 0x02019F022) || 
-       (lp->id->id == 0x01042103c) ||
-       (lp->id->id == 0x01040103c) )
-    return HP100_LAN_ERR; /* Those cards don't have a 100 Mbit connector */
+	if ((lp->id->id == 0x02019F022) ||
+	    (lp->id->id == 0x01042103c) || (lp->id->id == 0x01040103c))
+		return HP100_LAN_ERR;	/* Those cards don't have a 100 Mbit connector */
 
-  if ( val_VG & HP100_LINK_CABLE_ST ) /* Can hear the HUBs tone. */ 
-    return HP100_LAN_100;
-  return HP100_LAN_ERR;
+	if (val_VG & HP100_LINK_CABLE_ST)	/* Can hear the HUBs tone. */
+		return HP100_LAN_100;
+	return HP100_LAN_ERR;
 }
 
-
-
-static int hp100_down_vg_link( struct net_device *dev )
+static int hp100_down_vg_link(struct net_device *dev)
 {
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  int ioaddr = dev->base_addr;
-  unsigned long time;
-  long savelan, newlan;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4224, TRACE );
-  printk("hp100: %s: down_vg_link\n", dev->name);
-#endif
-
-  hp100_page( MAC_CTRL );
-  time=jiffies+(HZ/4);
-  do{
-    if ( hp100_inb( VG_LAN_CFG_1 ) & HP100_LINK_CABLE_ST ) break;
-  } while (time_after(time, jiffies));
-
-  if ( time_after_eq(jiffies, time) )       /* no signal->no logout */
-    return 0;
-
-  /* Drop the VG Link by clearing the link up cmd and load addr.*/
-
-  hp100_andb( ~( HP100_LOAD_ADDR| HP100_LINK_CMD), VG_LAN_CFG_1); 
-  hp100_orb( HP100_VG_SEL, VG_LAN_CFG_1); 
-
-  /* Conditionally stall for >250ms on Link-Up Status (to go down) */
-  time=jiffies+(HZ/2);
-  do{
-    if ( !(hp100_inb( VG_LAN_CFG_1) & HP100_LINK_UP_ST) ) break;
-  } while(time_after(time, jiffies));
-
-#ifdef HP100_DEBUG
-  if (time_after_eq(jiffies, time))
-    printk("hp100: %s: down_vg_link: Link does not go down?\n", dev->name);
-#endif
-
-  /* To prevent condition where Rev 1 VG MAC and old hubs do not complete */
-  /* logout under traffic (even though all the status bits are cleared),  */
-  /* do this workaround to get the Rev 1 MAC in its idle state */
-  if ( lp->chip==HP100_CHIPID_LASSEN )
-    {
-      /* Reset VG MAC to insure it leaves the logoff state even if */
-      /* the Hub is still emitting tones */
-      hp100_andb(~HP100_VG_RESET, VG_LAN_CFG_1);
-      udelay(1500); /* wait for >1ms */
-      hp100_orb(HP100_VG_RESET, VG_LAN_CFG_1); /* Release Reset */
-      udelay(1500);
-    }
-
-  /* New: For lassen, switch to 10 Mbps mac briefly to clear training ACK */
-  /* to get the VG mac to full reset. This is not req.d with later chips */
-  /* Note: It will take the between 1 and 2 seconds for the VG mac to be */
-  /* selected again! This will be left to the connect hub function to */
-  /* perform if desired.  */
-  if (lp->chip==HP100_CHIPID_LASSEN)
-    {
-      /* Have to write to 10 and 100VG control registers simultaneously */
-      savelan=newlan=hp100_inl(10_LAN_CFG_1); /* read 10+100 LAN_CFG regs */
-      newlan &= ~(HP100_VG_SEL<<16);
-      newlan |= (HP100_DOT3_MAC)<<8;
-      hp100_andb( ~HP100_AUTO_MODE, MAC_CFG_3); /* Autosel off */
-      hp100_outl(newlan, 10_LAN_CFG_1);
-
-      /* Conditionally stall for 5sec on VG selected. */
-      time=jiffies+(HZ*5);
-      do{
-        if( !(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST) ) break;
-      } while(time_after(time, jiffies));
-
-      hp100_orb( HP100_AUTO_MODE, MAC_CFG_3); /* Autosel back on */
-      hp100_outl(savelan, 10_LAN_CFG_1);
-    }
-
-  time=jiffies+(3*HZ); /* Timeout 3s */
-  do {
-    if ( (hp100_inb( VG_LAN_CFG_1 )&HP100_LINK_CABLE_ST) == 0) break;
-  } while (time_after(time, jiffies));
-  
-  if(time_before_eq(time, jiffies))
-    {
-#ifdef HP100_DEBUG
-      printk( "hp100: %s: down_vg_link: timeout\n", dev->name );
-#endif
-      return -EIO;
-    }
-  
-  time=jiffies+(2*HZ); /* This seems to take a while.... */
-  do {} while (time_after(time, jiffies));
-  
-  return 0;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	int ioaddr = dev->base_addr;
+	unsigned long time;
+	long savelan, newlan;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4224, TRACE);
+	printk("hp100: %s: down_vg_link\n", dev->name);
+#endif
+
+	hp100_page(MAC_CTRL);
+	time = jiffies + (HZ / 4);
+	do {
+		if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
+			break;
+		if (!in_interrupt()) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		}
+	} while (time_after(time, jiffies));
+
+	if (time_after_eq(jiffies, time))	/* no signal->no logout */
+		return 0;
+
+	/* Drop the VG Link by clearing the link up cmd and load addr. */
+
+	hp100_andb(~(HP100_LOAD_ADDR | HP100_LINK_CMD), VG_LAN_CFG_1);
+	hp100_orb(HP100_VG_SEL, VG_LAN_CFG_1);
+
+	/* Conditionally stall for >250ms on Link-Up Status (to go down) */
+	time = jiffies + (HZ / 2);
+	do {
+		if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
+			break;
+		if (!in_interrupt()) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		}
+	} while (time_after(time, jiffies));
+
+#ifdef HP100_DEBUG
+	if (time_after_eq(jiffies, time))
+		printk("hp100: %s: down_vg_link: Link does not go down?\n", dev->name);
+#endif
+
+	/* To prevent condition where Rev 1 VG MAC and old hubs do not complete */
+	/* logout under traffic (even though all the status bits are cleared),  */
+	/* do this workaround to get the Rev 1 MAC in its idle state */
+	if (lp->chip == HP100_CHIPID_LASSEN) {
+		/* Reset VG MAC to insure it leaves the logoff state even if */
+		/* the Hub is still emitting tones */
+		hp100_andb(~HP100_VG_RESET, VG_LAN_CFG_1);
+		udelay(1500);	/* wait for >1ms */
+		hp100_orb(HP100_VG_RESET, VG_LAN_CFG_1);	/* Release Reset */
+		udelay(1500);
+	}
+
+	/* New: For lassen, switch to 10 Mbps mac briefly to clear training ACK */
+	/* to get the VG mac to full reset. This is not req.d with later chips */
+	/* Note: It will take the between 1 and 2 seconds for the VG mac to be */
+	/* selected again! This will be left to the connect hub function to */
+	/* perform if desired.  */
+	if (lp->chip == HP100_CHIPID_LASSEN) {
+		/* Have to write to 10 and 100VG control registers simultaneously */
+		savelan = newlan = hp100_inl(10_LAN_CFG_1);	/* read 10+100 LAN_CFG regs */
+		newlan &= ~(HP100_VG_SEL << 16);
+		newlan |= (HP100_DOT3_MAC) << 8;
+		hp100_andb(~HP100_AUTO_MODE, MAC_CFG_3);	/* Autosel off */
+		hp100_outl(newlan, 10_LAN_CFG_1);
+
+		/* Conditionally stall for 5sec on VG selected. */
+		time = jiffies + (HZ * 5);
+		do {
+			if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST))
+				break;
+			if (!in_interrupt()) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(1);
+			}
+		} while (time_after(time, jiffies));
+
+		hp100_orb(HP100_AUTO_MODE, MAC_CFG_3);	/* Autosel back on */
+		hp100_outl(savelan, 10_LAN_CFG_1);
+	}
+
+	time = jiffies + (3 * HZ);	/* Timeout 3s */
+	do {
+		if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0)
+			break;
+		if (!in_interrupt()) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		}
+	} while (time_after(time, jiffies));
+
+	if (time_before_eq(time, jiffies)) {
+#ifdef HP100_DEBUG
+		printk("hp100: %s: down_vg_link: timeout\n", dev->name);
+#endif
+		return -EIO;
+	}
+
+	time = jiffies + (2 * HZ);	/* This seems to take a while.... */
+	do {
+		if (!in_interrupt()) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(1);
+		}
+	} while (time_after(time, jiffies));
+
+	return 0;
 }
 
-
-static int hp100_login_to_vg_hub( struct net_device *dev, u_short force_relogin )
+static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
 {
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  u_short val=0;
-  unsigned long time;
-  int startst;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4225, TRACE );
-  printk("hp100: %s: login_to_vg_hub\n", dev->name);
-#endif
-
-  /* Initiate a login sequence iff VG MAC is enabled and either Load Address
-   * bit is zero or the force relogin flag is set (e.g. due to MAC address or
-   * promiscuous mode change)
-   */
-  hp100_page( MAC_CTRL );
-  startst=hp100_inb( VG_LAN_CFG_1 );
-  if((force_relogin==TRUE)||(hp100_inb( MAC_CFG_4 )&HP100_MAC_SEL_ST))
-    {
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+	u_short val = 0;
+	unsigned long time;
+	int startst;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4225, TRACE);
+	printk("hp100: %s: login_to_vg_hub\n", dev->name);
+#endif
+
+	/* Initiate a login sequence iff VG MAC is enabled and either Load Address
+	 * bit is zero or the force relogin flag is set (e.g. due to MAC address or
+	 * promiscuous mode change)
+	 */
+	hp100_page(MAC_CTRL);
+	startst = hp100_inb(VG_LAN_CFG_1);
+	if ((force_relogin == TRUE) || (hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST)) {
 #ifdef HP100_DEBUG_TRAINING
-      printk("hp100: %s: Start training\n", dev->name);
+		printk("hp100: %s: Start training\n", dev->name);
 #endif
 
-      /* Ensure VG Reset bit is 1 (i.e., do not reset)*/
-      hp100_orb( HP100_VG_RESET , VG_LAN_CFG_1 );
+		/* Ensure VG Reset bit is 1 (i.e., do not reset) */
+		hp100_orb(HP100_VG_RESET, VG_LAN_CFG_1);
+
+		/* If Lassen AND auto-select-mode AND VG tones were sensed on */
+		/* entry then temporarily put them into force 100Mbit mode */
+		if ((lp->chip == HP100_CHIPID_LASSEN) && (startst & HP100_LINK_CABLE_ST))
+			hp100_andb(~HP100_DOT3_MAC, 10_LAN_CFG_2);
 
-      /* If Lassen AND auto-select-mode AND VG tones were sensed on */
-      /* entry then temporarily put them into force 100Mbit mode */
-      if((lp->chip==HP100_CHIPID_LASSEN)&&( startst & HP100_LINK_CABLE_ST ) )
-        hp100_andb( ~HP100_DOT3_MAC, 10_LAN_CFG_2 );
-						
-      /* Drop the VG link by zeroing Link Up Command and Load Address  */
-      hp100_andb( ~(HP100_LINK_CMD/* |HP100_LOAD_ADDR */), VG_LAN_CFG_1);
+		/* Drop the VG link by zeroing Link Up Command and Load Address  */
+		hp100_andb(~(HP100_LINK_CMD /* |HP100_LOAD_ADDR */ ), VG_LAN_CFG_1);
 
 #ifdef HP100_DEBUG_TRAINING
-      printk("hp100: %s: Bring down the link\n", dev->name);
+		printk("hp100: %s: Bring down the link\n", dev->name);
 #endif
 
-      /* Wait for link to drop */
-      time = jiffies + (HZ/10); 
-      do {
-        if (~(hp100_inb( VG_LAN_CFG_1 )& HP100_LINK_UP_ST) ) break;
-      } while (time_after(time, jiffies));
-
-      /* Start an addressed training and optionally request promiscuous port */
-      if ( (dev->flags) & IFF_PROMISC )
-	{
-	  hp100_orb( HP100_PROM_MODE, VG_LAN_CFG_2);
-	  if(lp->chip==HP100_CHIPID_LASSEN)
-	    hp100_orw( HP100_MACRQ_PROMSC, TRAIN_REQUEST );
-	}
-      else
-	{
-	  hp100_andb( ~HP100_PROM_MODE, VG_LAN_CFG_2);
-	  /* For ETR parts we need to reset the prom. bit in the training
-	   * register, otherwise promiscious mode won't be disabled.
-	   */
-	  if(lp->chip==HP100_CHIPID_LASSEN)
-	    {
-	      hp100_andw( ~HP100_MACRQ_PROMSC, TRAIN_REQUEST );
-	    }
-	}
-
-      /* With ETR parts, frame format request bits can be set. */
-      if(lp->chip==HP100_CHIPID_LASSEN)
-        hp100_orb( HP100_MACRQ_FRAMEFMT_EITHER, TRAIN_REQUEST);
-
-      hp100_orb( HP100_LINK_CMD|HP100_LOAD_ADDR|HP100_VG_RESET, VG_LAN_CFG_1);
-
-      /* Note: Next wait could be omitted for Hood and earlier chips under */
-      /* certain circumstances */
-      /* TODO: check if hood/earlier and skip wait. */
-
-      /* Wait for either short timeout for VG tones or long for login    */
-      /* Wait for the card hardware to signalise link cable status ok... */
-      hp100_page( MAC_CTRL );
-      time = jiffies + ( 1*HZ ); /* 1 sec timeout for cable st */
-      do {
-        if ( hp100_inb( VG_LAN_CFG_1 ) & HP100_LINK_CABLE_ST ) break;
-      } while ( time_before(jiffies, time) );
-      
-      if ( time_after_eq(jiffies, time) )
-	{
+		/* Wait for link to drop */
+		time = jiffies + (HZ / 10);
+		do {
+			if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
+				break;
+			if (!in_interrupt()) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(1);
+			}
+		} while (time_after(time, jiffies));
+
+		/* Start an addressed training and optionally request promiscuous port */
+		if ((dev->flags) & IFF_PROMISC) {
+			hp100_orb(HP100_PROM_MODE, VG_LAN_CFG_2);
+			if (lp->chip == HP100_CHIPID_LASSEN)
+				hp100_orw(HP100_MACRQ_PROMSC, TRAIN_REQUEST);
+		} else {
+			hp100_andb(~HP100_PROM_MODE, VG_LAN_CFG_2);
+			/* For ETR parts we need to reset the prom. bit in the training
+			 * register, otherwise promiscious mode won't be disabled.
+			 */
+			if (lp->chip == HP100_CHIPID_LASSEN) {
+				hp100_andw(~HP100_MACRQ_PROMSC, TRAIN_REQUEST);
+			}
+		}
+
+		/* With ETR parts, frame format request bits can be set. */
+		if (lp->chip == HP100_CHIPID_LASSEN)
+			hp100_orb(HP100_MACRQ_FRAMEFMT_EITHER, TRAIN_REQUEST);
+
+		hp100_orb(HP100_LINK_CMD | HP100_LOAD_ADDR | HP100_VG_RESET, VG_LAN_CFG_1);
+
+		/* Note: Next wait could be omitted for Hood and earlier chips under */
+		/* certain circumstances */
+		/* TODO: check if hood/earlier and skip wait. */
+
+		/* Wait for either short timeout for VG tones or long for login    */
+		/* Wait for the card hardware to signalise link cable status ok... */
+		hp100_page(MAC_CTRL);
+		time = jiffies + (1 * HZ);	/* 1 sec timeout for cable st */
+		do {
+			if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
+				break;
+			if (!in_interrupt()) {
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(1);
+			}
+		} while (time_before(jiffies, time));
+
+		if (time_after_eq(jiffies, time)) {
 #ifdef HP100_DEBUG_TRAINING
-	  printk( "hp100: %s: Link cable status not ok? Training aborted.\n", dev->name );
-#endif  
-	}
-      else
-	{
+			printk("hp100: %s: Link cable status not ok? Training aborted.\n", dev->name);
+#endif
+		} else {
 #ifdef HP100_DEBUG_TRAINING
-	  printk( "hp100: %s: HUB tones detected. Trying to train.\n", dev->name);
+			printk
+			    ("hp100: %s: HUB tones detected. Trying to train.\n",
+			     dev->name);
 #endif
 
-	  time = jiffies + ( 2*HZ ); /* again a timeout */
-	  do {
-	    val = hp100_inb( VG_LAN_CFG_1 );
-	    if ( (val & ( HP100_LINK_UP_ST )) )
-	      {
+			time = jiffies + (2 * HZ);	/* again a timeout */
+			do {
+				val = hp100_inb(VG_LAN_CFG_1);
+				if ((val & (HP100_LINK_UP_ST))) {
 #ifdef HP100_DEBUG_TRAINING
-		printk( "hp100: %s: Passed training.\n", dev->name);
+					printk("hp100: %s: Passed training.\n", dev->name);
 #endif
-		break;
-	      }
-	  } while ( time_after(time, jiffies) );
-	}
-      
-      /* If LINK_UP_ST is set, then we are logged into the hub. */
-      if ( time_before_eq(jiffies, time) && (val & HP100_LINK_UP_ST) )
-        {
+					break;
+				}
+				if (!in_interrupt()) {
+					set_current_state(TASK_INTERRUPTIBLE);
+					schedule_timeout(1);
+				}
+			} while (time_after(time, jiffies));
+		}
+
+		/* If LINK_UP_ST is set, then we are logged into the hub. */
+		if (time_before_eq(jiffies, time) && (val & HP100_LINK_UP_ST)) {
 #ifdef HP100_DEBUG_TRAINING
-          printk( "hp100: %s: Successfully logged into the HUB.\n", dev->name);
-          if(lp->chip==HP100_CHIPID_LASSEN)
-            {
-	      val = hp100_inw(TRAIN_ALLOW);
-              printk( "hp100: %s: Card supports 100VG MAC Version \"%s\" ",
-              	      dev->name,(hp100_inw(TRAIN_REQUEST)&HP100_CARD_MACVER) ? "802.12" : "Pre");
-	      printk( "Driver will use MAC Version \"%s\"\n",
-                      ( val & HP100_HUB_MACVER) ? "802.12" : "Pre" ); 
-              printk( "hp100: %s: Frame format is %s.\n",dev->name,(val&HP100_MALLOW_FRAMEFMT)?"802.5":"802.3");
-            }
-#endif
-        }
-      else
-        {
-          /* If LINK_UP_ST is not set, login was not successful */
-          printk("hp100: %s: Problem logging into the HUB.\n",dev->name);
-          if(lp->chip==HP100_CHIPID_LASSEN)
-            {
-              /* Check allowed Register to find out why there is a problem. */
-              val = hp100_inw( TRAIN_ALLOW ); /* wont work on non-ETR card */
+			printk("hp100: %s: Successfully logged into the HUB.\n", dev->name);
+			if (lp->chip == HP100_CHIPID_LASSEN) {
+				val = hp100_inw(TRAIN_ALLOW);
+				printk("hp100: %s: Card supports 100VG MAC Version \"%s\" ",
+					     dev->name, (hp100_inw(TRAIN_REQUEST) & HP100_CARD_MACVER) ? "802.12" : "Pre");
+				printk("Driver will use MAC Version \"%s\"\n", (val & HP100_HUB_MACVER) ? "802.12" : "Pre");
+				printk("hp100: %s: Frame format is %s.\n", dev->name, (val & HP100_MALLOW_FRAMEFMT) ? "802.5" : "802.3");
+			}
+#endif
+		} else {
+			/* If LINK_UP_ST is not set, login was not successful */
+			printk("hp100: %s: Problem logging into the HUB.\n", dev->name);
+			if (lp->chip == HP100_CHIPID_LASSEN) {
+				/* Check allowed Register to find out why there is a problem. */
+				val = hp100_inw(TRAIN_ALLOW);	/* wont work on non-ETR card */
 #ifdef HP100_DEBUG_TRAINING
-              printk("hp100: %s: MAC Configuration requested: 0x%04x, HUB allowed: 0x%04x\n", dev->name, hp100_inw(TRAIN_REQUEST), val);
+				printk("hp100: %s: MAC Configuration requested: 0x%04x, HUB allowed: 0x%04x\n", dev->name, hp100_inw(TRAIN_REQUEST), val);
 #endif
-              if ( val & HP100_MALLOW_ACCDENIED )
-                printk("hp100: %s: HUB access denied.\n", dev->name);
-              if ( val & HP100_MALLOW_CONFIGURE )
-                printk("hp100: %s: MAC Configuration is incompatible with the Network.\n", dev->name);
-              if ( val & HP100_MALLOW_DUPADDR )
-                printk("hp100: %s: Duplicate MAC Address on the Network.\n", dev->name);
-            }
-        }
-      
-      /* If we have put the chip into forced 100 Mbit mode earlier, go back */
-      /* to auto-select mode */
-      
-      if( (lp->chip==HP100_CHIPID_LASSEN)&&(startst & HP100_LINK_CABLE_ST) )
-        {
-          hp100_page( MAC_CTRL );
-          hp100_orb( HP100_DOT3_MAC, 10_LAN_CFG_2 );
-        }
-     
-      val=hp100_inb(VG_LAN_CFG_1);
-
-      /* Clear the MISC_ERROR Interrupt, which might be generated when doing the relogin */
-      hp100_page(PERFORMANCE);
-      hp100_outw( HP100_MISC_ERROR, IRQ_STATUS);
-					
-      if (val&HP100_LINK_UP_ST)
-        return(0); /* login was ok */
-      else
-        {
-          printk("hp100: %s: Training failed.\n", dev->name);
-          hp100_down_vg_link( dev );
-          return -EIO;
-        }
-    }
-  /* no forced relogin & already link there->no training. */
-  return -EIO;
+				if (val & HP100_MALLOW_ACCDENIED)
+					printk("hp100: %s: HUB access denied.\n", dev->name);
+				if (val & HP100_MALLOW_CONFIGURE)
+					printk("hp100: %s: MAC Configuration is incompatible with the Network.\n", dev->name);
+				if (val & HP100_MALLOW_DUPADDR)
+					printk("hp100: %s: Duplicate MAC Address on the Network.\n", dev->name);
+			}
+		}
+
+		/* If we have put the chip into forced 100 Mbit mode earlier, go back */
+		/* to auto-select mode */
+
+		if ((lp->chip == HP100_CHIPID_LASSEN) && (startst & HP100_LINK_CABLE_ST)) {
+			hp100_page(MAC_CTRL);
+			hp100_orb(HP100_DOT3_MAC, 10_LAN_CFG_2);
+		}
+
+		val = hp100_inb(VG_LAN_CFG_1);
+
+		/* Clear the MISC_ERROR Interrupt, which might be generated when doing the relogin */
+		hp100_page(PERFORMANCE);
+		hp100_outw(HP100_MISC_ERROR, IRQ_STATUS);
+
+		if (val & HP100_LINK_UP_ST)
+			return (0);	/* login was ok */
+		else {
+			printk("hp100: %s: Training failed.\n", dev->name);
+			hp100_down_vg_link(dev);
+			return -EIO;
+		}
+	}
+	/* no forced relogin & already link there->no training. */
+	return -EIO;
 }
 
-
-static void hp100_cascade_reset( struct net_device *dev, u_short enable )
+static void hp100_cascade_reset(struct net_device *dev, u_short enable)
 {
-  int ioaddr = dev->base_addr;
-  struct hp100_private *lp = (struct hp100_private *)dev->priv;
-  int i;
-
-#ifdef HP100_DEBUG_B
-  hp100_outw( 0x4226, TRACE );
-  printk("hp100: %s: cascade_reset\n", dev->name);
-#endif
-
-  if (enable==TRUE) 
-    {
-      hp100_outw( HP100_HW_RST | HP100_RESET_LB, OPTION_LSW );
-      if(lp->chip==HP100_CHIPID_LASSEN)
-	{
-	  /* Lassen requires a PCI transmit fifo reset */
-	  hp100_page( HW_MAP );
-	  hp100_andb( ~HP100_PCI_RESET, PCICTRL2 );
-	  hp100_orb( HP100_PCI_RESET, PCICTRL2 );
-	  /* Wait for min. 300 ns */
-	  /* we cant use jiffies here, because it may be */
-	  /* that we have disabled the timer... */
-	  for (i=0; i<0xffff; i++);
-	  hp100_andb( ~HP100_PCI_RESET, PCICTRL2 );
-	  hp100_page( PERFORMANCE );
-	}	
-    }
-  else
-    { /* bring out of reset */
-      hp100_outw(HP100_HW_RST|HP100_SET_LB, OPTION_LSW);
-      for (i=0; i<0xffff; i++ );
-      hp100_page(PERFORMANCE);
-    }
-}
-
-#ifdef HP100_DEBUG		
-void hp100_RegisterDump( struct net_device *dev )
-{
-  int ioaddr=dev->base_addr;
-  int Page;
-  int Register;
-
-  /* Dump common registers */
-  printk("hp100: %s: Cascade Register Dump\n", dev->name);
-  printk("hardware id #1: 0x%.2x\n",hp100_inb(HW_ID));
-  printk("hardware id #2/paging: 0x%.2x\n",hp100_inb(PAGING));
-  printk("option #1: 0x%.4x\n",hp100_inw(OPTION_LSW));
-  printk("option #2: 0x%.4x\n",hp100_inw(OPTION_MSW));
-
-  /* Dump paged registers */
-  for (Page = 0; Page < 8; Page++) 
-    {
-      /* Dump registers */
-      printk("page: 0x%.2x\n",Page);
-      outw( Page, ioaddr+0x02);
-      for (Register = 0x8; Register < 0x22; Register += 2)
-	{
-	  /* Display Register contents except data port */
-	  if (((Register != 0x10) && (Register != 0x12)) || (Page > 0))
-	    {
-	      printk("0x%.2x = 0x%.4x\n",Register,inw(ioaddr+Register));
-	    }
+	int ioaddr = dev->base_addr;
+	struct hp100_private *lp = (struct hp100_private *) dev->priv;
+
+#ifdef HP100_DEBUG_B
+	hp100_outw(0x4226, TRACE);
+	printk("hp100: %s: cascade_reset\n", dev->name);
+#endif
+
+	if (enable == TRUE) {
+		hp100_outw(HP100_HW_RST | HP100_RESET_LB, OPTION_LSW);
+		if (lp->chip == HP100_CHIPID_LASSEN) {
+			/* Lassen requires a PCI transmit fifo reset */
+			hp100_page(HW_MAP);
+			hp100_andb(~HP100_PCI_RESET, PCICTRL2);
+			hp100_orb(HP100_PCI_RESET, PCICTRL2);
+			/* Wait for min. 300 ns */
+			/* we cant use jiffies here, because it may be */
+			/* that we have disabled the timer... */
+			udelay(400);
+			hp100_andb(~HP100_PCI_RESET, PCICTRL2);
+			hp100_page(PERFORMANCE);
+		}
+	} else {		/* bring out of reset */
+		hp100_outw(HP100_HW_RST | HP100_SET_LB, OPTION_LSW);
+		udelay(400);
+		hp100_page(PERFORMANCE);
+	}
+}
+
+#ifdef HP100_DEBUG
+void hp100_RegisterDump(struct net_device *dev)
+{
+	int ioaddr = dev->base_addr;
+	int Page;
+	int Register;
+
+	/* Dump common registers */
+	printk("hp100: %s: Cascade Register Dump\n", dev->name);
+	printk("hardware id #1: 0x%.2x\n", hp100_inb(HW_ID));
+	printk("hardware id #2/paging: 0x%.2x\n", hp100_inb(PAGING));
+	printk("option #1: 0x%.4x\n", hp100_inw(OPTION_LSW));
+	printk("option #2: 0x%.4x\n", hp100_inw(OPTION_MSW));
+
+	/* Dump paged registers */
+	for (Page = 0; Page < 8; Page++) {
+		/* Dump registers */
+		printk("page: 0x%.2x\n", Page);
+		outw(Page, ioaddr + 0x02);
+		for (Register = 0x8; Register < 0x22; Register += 2) {
+			/* Display Register contents except data port */
+			if (((Register != 0x10) && (Register != 0x12)) || (Page > 0)) {
+				printk("0x%.2x = 0x%.4x\n", Register, inw(ioaddr + Register));
+			}
+		}
 	}
-    }
-  hp100_page(PERFORMANCE);
+	hp100_page(PERFORMANCE);
 }
 #endif
 
 
-
 /*
  *  module section
  */
- 
+
 #ifdef MODULE
 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, "
+              "Siegfried \"Frieder\" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>");
+MODULE_DESCRIPTION("HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters");
+
+/*
+ * Note: if you have more than five 100vg cards in your pc, feel free to
+ * increase this value 
+ */
+
+#define HP100_DEVICES 5
+
+/*
+ * Note: to register three eisa or pci devices, use:
+ * option hp100 hp100_port=0,0,0
+ *        to register one card at io 0x280 as eth239, use:
+ * option hp100 hp100_port=0x280 hp100_name=eth239
+ */
+
 /* Parameters set by insmod */
-static int hp100_port[5] = { 0, -1, -1, -1, -1 };
-MODULE_PARM(hp100_port, "1-5i");
+static int hp100_port[HP100_DEVICES] = { 0, [1 ... (HP100_DEVICES-1)] = -1 };
+MODULE_PARM(hp100_port, "1-" __MODULE_STRING(HP100_DEVICES) "i");
 
-/* Allocate 5 string of length IFNAMSIZ, one string for each device */
-static char hp100_name[5][IFNAMSIZ] = { "", "", "", "", "" };
-/* Allow insmod to write those 5 strings individually */
-MODULE_PARM(hp100_name, "1-5c" __MODULE_STRING(IFNAMSIZ));
+/* Allocate HP100_DEVICES strings of length IFNAMSIZ, one string for each device */
+static char hp100_name[HP100_DEVICES][IFNAMSIZ] = { "", "", "", "", "" };
+/* Allow insmod to write those HP100_DEVICES strings individually */
+MODULE_PARM(hp100_name, "1-" __MODULE_STRING(HP100_DEVICES) "c" __MODULE_STRING(IFNAMSIZ));
 
 /* List of devices */
-static struct net_device *hp100_devlist[5];
+static struct net_device *hp100_devlist[HP100_DEVICES];
 
 static void release_dev(int i)
 {
 	struct net_device *d = hp100_devlist[i];
-	struct hp100_private *p = (struct hp100_private *)d->priv;
+	struct hp100_private *p = (struct hp100_private *) d->priv;
 
 	unregister_netdev(d);
 	release_region(d->base_addr, HP100_REGION_SIZE);
 
-	if (p->mode == 1) /* busmaster */
-		kfree(p->page_vaddr); 
+	if (p->mode == 1)	/* busmaster */
+		kfree(p->page_vaddr);
 	if (p->mem_ptr_virt)
 		iounmap(p->mem_ptr_virt);
 	kfree(d->priv);
@@ -3049,78 +2917,66 @@
 	hp100_devlist[i] = NULL;
 }
 
-/*
- * Note: if you have more than five 100vg cards in your pc, feel free to
- * increase this value 
- */
-
-/*
- * Note: to register three eisa or pci devices, use:
- * option hp100 hp100_port=0,0,0
- *        to register one card at io 0x280 as eth239, use:
- * option hp100 hp100_port=0x280 hp100_name=eth239
- */
-
-int init_module( void )
+static int __init hp100_module_init(void)
 {
-  int	i, cards;
+	int i, cards;
 
-  if (hp100_port == 0 && !EISA_bus && !pcibios_present())
-    printk("hp100: You should not use auto-probing with insmod!\n");
+	if (hp100_port == 0 && !EISA_bus && !pcibios_present())
+		printk("hp100: You should not use auto-probing with insmod!\n");
 
-  /* Loop on all possible base addresses */
-  i = -1; cards = 0;
-  while((hp100_port[++i] != -1) && (i < 5))
-    {
-      /* Create device and set basics args */
-      hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-      if (!hp100_devlist[i])
-	goto fail;
-      memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
+	/* Loop on all possible base addresses */
+	i = -1;
+	cards = 0;
+	while ((hp100_port[++i] != -1) && (i < HP100_DEVICES)) {
+		/* Create device and set basics args */
+		hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+		if (!hp100_devlist[i])
+			goto fail;
+		memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
 #if LINUX_VERSION_CODE >= 0x020362	/* 2.3.99-pre7 */
-      memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ);	/* Copy name */
+		memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ);	/* Copy name */
 #else
-      hp100_devlist[i]->name = hp100_name[i];
-#endif /* LINUX_VERSION_CODE >= 0x020362 */
-      hp100_devlist[i]->base_addr = hp100_port[i];
-      hp100_devlist[i]->init = &hp100_probe;
-
-      /* Try to create the device */
-      if(register_netdev(hp100_devlist[i]) != 0)
-	{
-	  /* DeAllocate everything */
-	  /* Note: if dev->priv is mallocated, there is no way to fail */
-	  kfree(hp100_devlist[i]);
-	  hp100_devlist[i] = (struct net_device *) NULL;
-	}
-       else
-        cards++;
-    }			/* Loop over all devices */
-
-  return cards > 0 ? 0 : -ENODEV;
- fail:
-  while (cards && --i)
-	  if (hp100_devlist[i]) {
-		release_dev(i);
-		--cards;
-	  }
-  return -ENOMEM;
-}
-
-void cleanup_module( void )
-{
-  int		i;
-
-  /* TODO: Check if all skb's are released/freed. */
-  for(i = 0; i < 5; i++)
-    if(hp100_devlist[i] != (struct net_device *) NULL)
-	    release_dev(i);
+		hp100_devlist[i]->name = hp100_name[i];
+#endif				/* LINUX_VERSION_CODE >= 0x020362 */
+		hp100_devlist[i]->base_addr = hp100_port[i];
+		hp100_devlist[i]->init = &hp100_probe;
+
+		/* Try to create the device */
+		if (register_netdev(hp100_devlist[i]) != 0) {
+			/* DeAllocate everything */
+			/* Note: if dev->priv is mallocated, there is no way to fail */
+			kfree(hp100_devlist[i]);
+			hp100_devlist[i] = (struct net_device *) NULL;
+		} else
+			cards++;
+	}			/* Loop over all devices */
+
+	return cards > 0 ? 0 : -ENODEV;
+      fail:
+	while (cards && --i)
+		if (hp100_devlist[i]) {
+			release_dev(i);
+			--cards;
+		}
+	return -ENOMEM;
 }
 
-#endif		/* MODULE */
+static void __exit hp100_module_exit(void)
+{
+	int i;
+
+	/* TODO: Check if all skb's are released/freed. */
+	for (i = 0; i < HP100_DEVICES; i++)
+		if (hp100_devlist[i] != (struct net_device *) NULL)
+			release_dev(i);
+}
+
+module_init(hp100_module_init)
+module_exit(hp100_module_exit)
+
+#endif				/* MODULE */
 
 
-
 /*
  * Local variables:
  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c hp100.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/actisys.c linux/drivers/net/irda/actisys.c
--- v2.4.10/linux/drivers/net/irda/actisys.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/actisys.c	Sun Sep 30 12:26:06 2001
@@ -272,6 +272,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no> - Jean Tourrilhes <jt@hpl.hp.com>");
 MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver");	
+MODULE_LICENSE("GPL");
+
 		
 /*
  * Function init_module (void)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/ali-ircc.c linux/drivers/net/irda/ali-ircc.c
--- v2.4.10/linux/drivers/net/irda/ali-ircc.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/ali-ircc.c	Sun Sep 30 12:26:06 2001
@@ -2290,6 +2290,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Benjamin Kong <benjamin_kong@ali.com.tw>");
 MODULE_DESCRIPTION("ALi FIR Controller Driver");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(io,  "1-4i");
 MODULE_PARM_DESC(io, "Base I/O addresses");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/esi.c linux/drivers/net/irda/esi.c
--- v2.4.10/linux/drivers/net/irda/esi.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/esi.c	Sun Sep 30 12:26:06 2001
@@ -136,6 +136,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver");
+MODULE_LICENSE("GPL");
 
 /*
  * Function init_module (void)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/girbil.c linux/drivers/net/irda/girbil.c
--- v2.4.10/linux/drivers/net/irda/girbil.c	Wed Jun 21 10:10:02 2000
+++ linux/drivers/net/irda/girbil.c	Sun Sep 30 12:26:06 2001
@@ -234,6 +234,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver");
+MODULE_LICENSE("GPL");
+
 	
 /*
  * Function init_module (void)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c
--- v2.4.10/linux/drivers/net/irda/irda-usb.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/irda-usb.c	Thu Oct  4 18:41:09 2001
@@ -1,7 +1,7 @@
 /*****************************************************************************
  *
  * Filename:      irda-usb.c
- * Version:       0.9a
+ * Version:       0.9b
  * Description:   IrDA-USB Driver
  * Status:        Experimental 
  * Author:        Dag Brattli <dag@brattli.net>
@@ -26,6 +26,31 @@
  *
  *****************************************************************************/
 
+/*
+ *			    IMPORTANT NOTE
+ *			    --------------
+ *
+ * As of kernel 2.4.10, this is the state of compliance and testing of
+ * this driver (irda-usb) with regards to the USB low level drivers...
+ *
+ * This driver has been tested SUCCESSFULLY with the following drivers :
+ *	o usb-uhci	(For Intel/Via USB controllers)
+ *	o usb-ohci	(For other USB controllers)
+ *
+ * This driver has NOT been tested with the following drivers :
+ *	o usb-ehci	(USB 2.0 controllers)
+ *
+ * This driver WON'T WORK with the following drivers :
+ *	o uhci		(Alternate/JE driver for Intel/Via USB controllers)
+ * Amongst the reasons :
+ *	o uhci doesn't implement USB_ZERO_PACKET
+ *	o uhci non-compliant use of urb->timeout
+ *
+ * Jean II
+ */
+
+/*------------------------------------------------------------------*/
+
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -44,6 +69,8 @@
 
 #include <net/irda/irda-usb.h>
 
+/*------------------------------------------------------------------*/
+
 static int qos_mtt_bits = 0;
 
 /* Master instance for each hardware found */
@@ -66,6 +93,15 @@
 	{ }, /* The end */
 };
 
+/*
+ * Important note :
+ * Devices based on the SigmaTel chipset (0x66f, 0x4200) are not compliant
+ * with the USB-IrDA specification (and actually very very different), and
+ * there is no way this driver can support those devices, apart from
+ * a complete rewrite...
+ * Jean II
+ */
+
 MODULE_DEVICE_TABLE(usb, dongles);
 
 /*------------------------------------------------------------------*/
@@ -239,7 +275,7 @@
                       frame, IRDA_USB_SPEED_MTU,
                       speed_bulk_callback, self);
 	purb->transfer_buffer_length = USB_IRDA_HEADER;
-	purb->transfer_flags = USB_QUEUE_BULK;
+	purb->transfer_flags = USB_QUEUE_BULK | USB_ASYNC_UNLINK;
 	purb->timeout = MSECS_TO_JIFFIES(100);
 
 	if ((ret = usb_submit_urb(purb))) {
@@ -248,42 +284,6 @@
 	spin_unlock_irqrestore(&self->lock, flags);
 }
 
-#ifdef IU_BUG_KICK_TX
-/*------------------------------------------------------------------*/
-/*
- * Send an empty URB to the dongle
- * The goal there is to try to resynchronise with the dongle. An empty
- * frame signify the end of a Tx frame. Jean II
- */
-static inline void irda_usb_send_empty(struct irda_usb_cb *self)
-{
-	purb_t purb;
-	int ret;
-
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
-	/* Grab the empty URB */
-	purb = &self->empty_urb;
-	if (purb->status != USB_ST_NOERROR) {
-		WARNING(__FUNCTION__ "(), Empty URB still in use!\n");
-		return;
-	}
-
-	/* Submit the Empty URB */
-        FILL_BULK_URB(purb, self->usbdev,
-		      usb_sndbulkpipe(self->usbdev, self->bulk_out_ep),
-                      self->speed_buff, IRDA_USB_SPEED_MTU,
-                      speed_bulk_callback, self);
-	purb->transfer_buffer_length = 0;
-	purb->transfer_flags = USB_QUEUE_BULK;
-	purb->timeout = MSECS_TO_JIFFIES(100);
-
-	if ((ret = usb_submit_urb(purb))) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), failed Empty URB\n");
-	}
-}
-#endif /* IU_BUG_KICK_TX */
-
 /*------------------------------------------------------------------*/
 /*
  * Note : this function will be called with both speed_urb and empty_urb...
@@ -397,19 +397,21 @@
                       skb->data, IRDA_USB_MAX_MTU,
                       write_bulk_callback, skb);
 	purb->transfer_buffer_length = skb->len;
-	purb->transfer_flags = USB_QUEUE_BULK;
-#ifdef IU_USE_USB_ZERO_FLAG
-	/* This flag indicates that what we send is not a continuous stream
-	 * of data but separate frames. In this case, the USB layer will
-	 * insert empty packet to separate our frames.
-	 * This flag was previously called USB_DISABLE_SPD - Jean II */
+	/* Note : unlink *must* be Asynchronous because of the code in 
+	 * irda_usb_net_timeout() -> call in irq - Jean II */
+	purb->transfer_flags = USB_QUEUE_BULK | USB_ASYNC_UNLINK;
+	/* This flag (USB_ZERO_PACKET) indicates that what we send is not
+	 * a continuous stream of data but separate packets.
+	 * In this case, the USB layer will insert an empty USB frame (TD)
+	 * after each of our packets that is exact multiple of the frame size.
+	 * This is how the dongle will detect the end of packet - Jean II */
 	purb->transfer_flags |= USB_ZERO_PACKET;
-#endif /* IU_USE_USB_ZERO_FLAG */
-	purb->timeout = MSECS_TO_JIFFIES(100);
-	
+	/* Timeout need to be shorter than NET watchdog timer */
+	purb->timeout = MSECS_TO_JIFFIES(200);
+
 	/* Generate min turn time. FIXME: can we do better than this? */
 	/* Trying to a turnaround time at this level is trying to measure
-	 * processor clock cycle with a watch, approximate at best...
+	 * processor clock cycle with a wrist-watch, approximate at best...
 	 *
 	 * What we know is the last time we received a frame over USB.
 	 * Due to latency over USB that depend on the USB load, we don't
@@ -427,6 +429,11 @@
 			int diff;
 			get_fast_time(&self->now);
 			diff = self->now.tv_usec - self->stamp.tv_usec;
+#ifdef IU_USB_MIN_RTT
+			/* Factor in USB delays -> Get rid of udelay() that
+			 * would be lost in the noise - Jean II */
+			diff -= IU_USB_MIN_RTT;
+#endif /* IU_USB_MIN_RTT */
 			if (diff < 0)
 				diff += 1000000;
 
@@ -443,6 +450,7 @@
 		}
 	}
 	
+	/* Ask USB to send the packet */
 	if ((res = usb_submit_urb(purb))) {
 		IRDA_DEBUG(0, __FUNCTION__ "(), failed Tx URB\n");
 		self->stats.tx_errors++;
@@ -454,25 +462,6 @@
                 self->stats.tx_bytes += skb->len;
 		
 		netdev->trans_start = jiffies;
-
-#ifdef IU_BUG_KICK_TX
-		/* Kick Tx?
-		 * If the packet is a multiple of 64, the USB layer
-		 * should send an empty frame (a short packet) to signal
-		 * the end of frame (that's part of the USB spec).
-		 * If we enable USB_ZERO_PACKET, the USB layer will just do
-		 * that (more efficiently) and this code is useless.
-		 * Better keep this code until USB code clear up this mess...
-		 *
-		 * Note : we can't use the speed URB, because the frame
-		 * might contain a speed change that may be deferred
-		 * (so we have hard_xmit => tx_urb+empty_urb+speed_urb).
-		 * Jean II */
-		if ((skb->len % self->bulk_out_mtu) == 0) {
-			IRDA_DEBUG(2, __FUNCTION__ "(), Kick Tx...\n");
-			irda_usb_send_empty(self);
-		}
-#endif /* IU_BUG_KICK_TX */
 	}
 	spin_unlock_irqrestore(&self->lock, flags);
 	
@@ -556,54 +545,28 @@
 		return;
 	}
 
-#ifdef IU_BUG_KICK_TX
-	/* Check empty URB */
-	purb = &(self->empty_urb);
+	/* Check speed URB */
+	purb = &(self->speed_urb);
 	if (purb->status != USB_ST_NOERROR) {
-		WARNING("%s: Empty change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags);
+		WARNING("%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags);
 
 		switch (purb->status) {
-		case -ECONNABORTED:		/* -103 */
-		case -ECONNRESET:		/* -104 */
-		case -ENOENT:			/* -2 */
-			purb->status = USB_ST_NOERROR;
-			done = 1;
-			break;
 		case USB_ST_URB_PENDING:	/* -EINPROGRESS == -115 */
 			usb_unlink_urb(purb);
-			/* Note : above will *NOT* call netif_wake_queue()
-			 * in completion handler - Jean II */
+			/* Note : above will  *NOT* call netif_wake_queue()
+			 * in completion handler, we will come back here.
+			 * Jean II */
 			done = 1;
 			break;
-		default:
-			/* ??? */
-			break;
-		}
-	}
-#endif /* IU_BUG_KICK_TX */
-
-	/* Check speed URB */
-	purb = &(self->speed_urb);
-	if (purb->status != USB_ST_NOERROR) {
-		WARNING("%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags);
-
-		switch (purb->status) {
 		case -ECONNABORTED:		/* -103 */
 		case -ECONNRESET:		/* -104 */
-		case -ENOENT:			/* -2 */
+		case -ETIMEDOUT:		/* -110 */
+		case -ENOENT:			/* -2 (urb unlinked by us)  */
+		default:			/* ??? - Play safe */
 			purb->status = USB_ST_NOERROR;
 			netif_wake_queue(self->netdev);
 			done = 1;
 			break;
-		case USB_ST_URB_PENDING:	/* -EINPROGRESS == -115 */
-			usb_unlink_urb(purb);
-			/* Note : above will call netif_wake_queue()
-			 * in completion handler - Jean II */
-			done = 1;
-			break;
-		default:
-			/* ??? */
-			break;
 		}
 	}
 
@@ -627,9 +590,22 @@
 #endif /* IU_BUG_KICK_TIMEOUT */
 
 		switch (purb->status) {
+		case USB_ST_URB_PENDING:	/* -EINPROGRESS == -115 */
+			usb_unlink_urb(purb);
+			/* Note : above will  *NOT* call netif_wake_queue()
+			 * in completion handler, because purb->status will
+			 * be -ENOENT. We will fix that at the next watchdog,
+			 * leaving more time to USB to recover...
+			 * Also, we are in interrupt, so we need to have
+			 * USB_ASYNC_UNLINK to work properly...
+			 * Jean II */
+			done = 1;
+			break;
 		case -ECONNABORTED:		/* -103 */
 		case -ECONNRESET:		/* -104 */
-		case -ENOENT:			/* -2 */
+		case -ETIMEDOUT:		/* -110 */
+		case -ENOENT:			/* -2 (urb unlinked by us)  */
+		default:			/* ??? - Play safe */
 			if(skb != NULL) {
 				dev_kfree_skb_any(skb);
 				purb->context = NULL;
@@ -638,15 +614,6 @@
 			netif_wake_queue(self->netdev);
 			done = 1;
 			break;
-		case USB_ST_URB_PENDING:	/* -EINPROGRESS == -115 */
-			usb_unlink_urb(purb);
-			/* Note : above will call netif_wake_queue()
-			 * in completion handler - Jean II */
-			done = 1;
-			break;
-		default:
-			/* ??? */
-			break;
 		}
 	}
 
@@ -664,6 +631,24 @@
  * Try to work around USB failures...
  */
 
+/*
+ * Note :
+ * Some of you may have noticed that most dongle have an interrupt in pipe
+ * that we don't use. Here is the little secret...
+ * When we hang a Rx URB on the bulk in pipe, it generates some USB traffic
+ * in every USB frame. This is unnecessary overhead.
+ * The interrupt in pipe will generate an event every time a packet is
+ * received. Reading an interrupt pipe adds minimal overhead, but has some
+ * latency (~1ms).
+ * If we are connected (speed != 9600), we want to minimise latency, so
+ * we just always hang the Rx URB and ignore the interrupt.
+ * If we are not connected (speed == 9600), there is usually no Rx traffic,
+ * and we want to minimise the USB overhead. In this case we should wait
+ * on the interrupt pipe and hang the Rx URB only when an interrupt is
+ * received.
+ * Jean II
+ */
+
 /*------------------------------------------------------------------*/
 /*
  * Submit a Rx URB to the USB layer to handle reception of a frame
@@ -740,6 +725,8 @@
 		      skb->data, skb->truesize,
                       irda_usb_receive, skb);
 	purb->transfer_flags = USB_QUEUE_BULK;
+	/* Note : unlink *must* be synchronous because of the code in 
+	 * irda_usb_net_close() -> free the skb - Jean II */
 	purb->status = USB_ST_NOERROR;
 	purb->next = NULL;	/* Don't auto resubmit URBs */
 	
@@ -1185,7 +1172,7 @@
 	netdev->init            = irda_usb_net_init;
 	netdev->hard_start_xmit = irda_usb_hard_xmit;
 	netdev->tx_timeout	= irda_usb_net_timeout;
-	netdev->watchdog_timeo  = 110*HZ/1000;	/* 110 ms > USB timeout */
+	netdev->watchdog_timeo  = 250*HZ/1000;	/* 250 ms > USB timeout */
 	netdev->open            = irda_usb_net_open;
 	netdev->stop            = irda_usb_net_close;
 	netdev->get_stats	= irda_usb_net_get_stats;
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- v2.4.10/linux/drivers/net/irda/irport.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/irport.c	Sun Sep 30 12:26:06 2001
@@ -1035,6 +1035,8 @@
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode");
+MODULE_LICENSE("GPL");
+
 
 void cleanup_module(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- v2.4.10/linux/drivers/net/irda/irtty.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/irtty.c	Sun Sep 30 12:26:06 2001
@@ -1049,6 +1049,8 @@
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("IrDA TTY device driver");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(qos_mtt_bits, "i");
 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/litelink.c linux/drivers/net/irda/litelink.c
--- v2.4.10/linux/drivers/net/irda/litelink.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/litelink.c	Sun Sep 30 12:26:06 2001
@@ -166,6 +166,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Parallax Litelink dongle driver");	
+MODULE_LICENSE("GPL");
+
 		
 /*
  * Function init_module (void)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/nsc-ircc.c linux/drivers/net/irda/nsc-ircc.c
--- v2.4.10/linux/drivers/net/irda/nsc-ircc.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/nsc-ircc.c	Thu Oct  4 18:41:09 2001
@@ -112,7 +112,7 @@
 	"Reserved",
 	"Reserved",
 	"HP HSDL-1100/HSDL-2100",
-	"HP HSDL-1100/HSDL-2100"
+	"HP HSDL-1100/HSDL-2100",
 	"Supports SIR Mode only",
 	"No dongle connected",
 };
@@ -2042,6 +2042,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("NSC IrDA Device Driver");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(qos_mtt_bits, "i");
 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/old_belkin.c linux/drivers/net/irda/old_belkin.c
--- v2.4.10/linux/drivers/net/irda/old_belkin.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/old_belkin.c	Sun Sep 30 12:26:06 2001
@@ -152,6 +152,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Jean Tourrilhes <jt@hpl.hp.com>");
 MODULE_DESCRIPTION("Belkin (old) SmartBeam dongle driver");	
+MODULE_LICENSE("GPL");
+
 
 /*
  * Function init_module (void)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- v2.4.10/linux/drivers/net/irda/smc-ircc.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/irda/smc-ircc.c	Thu Oct  4 18:41:09 2001
@@ -99,7 +99,7 @@
 #define	SERx4	8	/* SuperIO Chip supports 115,2 KBaud * 4=460,8 KBaud */
 
 /* These are the currently known SMC SuperIO chipsets */
-static const smc_chip_t __init fdc_chips_flat[]=
+static smc_chip_t __initdata fdc_chips_flat[]=
 {
 	/* Base address 0x3f0 or 0x370 */
 	{ "37C44",	KEY55_1|NoIRDA,		0x00, 0x00 }, /* This chip can not detected */
@@ -113,7 +113,7 @@
 	{ NULL }
 };
 
-static const smc_chip_t __init fdc_chips_paged[]=
+static smc_chip_t __initdata fdc_chips_paged[]=
 {
 	/* Base address 0x3f0 or 0x370 */
 	{ "37B72X",	KEY55_1|SIR|SERx4,	0x4c, 0x00 },
@@ -127,12 +127,12 @@
 	{ "37M707",	KEY55_1|SIR|SERx4,	0x42, 0x00 },
 	{ "37M81X",	KEY55_1|SIR|SERx4,	0x4d, 0x00 },
 	{ "37N958FR",	KEY55_1|FIR|SERx4,	0x09, 0x04 },
-	{ "37N972",	KEY55_1|FIR|SERx4,	0x0a, 0x00 },
+	{ "37N971",	KEY55_1|FIR|SERx4,	0x0a, 0x00 },
 	{ "37N972",	KEY55_1|FIR|SERx4,	0x0b, 0x00 },
 	{ NULL }
 };
 
-static const smc_chip_t __init lpc_chips_flat[]=
+static smc_chip_t __initdata lpc_chips_flat[]=
 {
 	/* Base address 0x2E or 0x4E */
 	{ "47N227",	KEY55_1|FIR|SERx4,	0x5a, 0x00 },
@@ -140,7 +140,7 @@
 	{ NULL }
 };
 
-static const smc_chip_t __init lpc_chips_paged[]=
+static smc_chip_t __initdata lpc_chips_paged[]=
 {
 	/* Base address 0x2E or 0x4E */
 	{ "47B27X",	KEY55_1|SIR|SERx4,	0x51, 0x00 },
@@ -158,6 +158,7 @@
 static int ircc_dma=255;
 static int ircc_fir=0;
 static int ircc_sir=0;
+static int ircc_cfg=0;
 
 static unsigned short	dev_count=0;
 
@@ -393,6 +394,13 @@
 		return -ENODEV;
 	}
 
+	/* try user provided configuration register base address */
+	if (ircc_cfg>0) {
+	        MESSAGE(" Overriding configuration address 0x%04x\n", ircc_cfg);
+		if (!smc_superio_fdc(ircc_cfg))
+			ret=0;
+	}
+
 	/* Trys to open for all the SMC chipsets we know about */
 
 	IRDA_DEBUG(0, __FUNCTION__ 
@@ -402,6 +410,8 @@
 		ret=0;
 	if (!smc_superio_fdc(0x370))
 		ret=0;
+	if (!smc_superio_fdc(0xe0))
+		ret=0;
 	if (!smc_superio_lpc(0x2e))
 		ret=0;
 	if (!smc_superio_lpc(0x4e))
@@ -1219,6 +1229,8 @@
  
 MODULE_AUTHOR("Thomas Davis <tadavis@jps.net>");
 MODULE_DESCRIPTION("SMC IrCC controller driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(ircc_dma, "1i");
 MODULE_PARM_DESC(ircc_dma, "DMA channel");
 MODULE_PARM(ircc_irq, "1i");
@@ -1227,5 +1239,7 @@
 MODULE_PARM_DESC(ircc_fir, "FIR Base Address");
 MODULE_PARM(ircc_sir, "1-4i");
 MODULE_PARM_DESC(ircc_sir, "SIR Base Address");
+MODULE_PARM(ircc_cfg, "1-4i");
+MODULE_PARM_DESC(ircc_cfg, "Configuration register base address");
 
 #endif /* MODULE */
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/tekram.c linux/drivers/net/irda/tekram.c
--- v2.4.10/linux/drivers/net/irda/tekram.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/tekram.c	Sun Sep 30 12:26:06 2001
@@ -267,6 +267,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver");
+MODULE_LICENSE("GPL");
 		
 /*
  * Function init_module (void)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c
--- v2.4.10/linux/drivers/net/irda/toshoboe.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/toshoboe.c	Sun Sep 30 12:26:06 2001
@@ -643,6 +643,8 @@
 
 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM (max_baud, "i");
 MODULE_PARM_DESC(max_baus, "Maximum baud rate");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/vlsi_ir.c linux/drivers/net/irda/vlsi_ir.c
--- v2.4.10/linux/drivers/net/irda/vlsi_ir.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/vlsi_ir.c	Thu Oct  4 18:41:09 2001
@@ -2,7 +2,7 @@
  *
  *	vlsi_ir.c:	VLSI82C147 PCI IrDA controller driver for Linux
  *
- *	Version:	0.1, Aug 6, 2001
+ *	Version:	0.3, Sep 30, 2001
  *
  *	Copyright (c) 2001 Martin Diehl
  *
@@ -32,6 +32,7 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
+#include <linux/time.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irda_device.h>
@@ -46,16 +47,17 @@
 
 MODULE_DESCRIPTION("IrDA SIR/MIR/FIR driver for VLSI 82C147");
 MODULE_AUTHOR("Martin Diehl <info@mdiehl.de>");
+MODULE_LICENSE("GPL");
 
 
 static /* const */ char drivername[] = "vlsi_ir";
 
 
-#define PCI_CLASS_IRDA_GENERIC 0x0d00
+#define PCI_CLASS_WIRELESS_IRDA 0x0d00
 
 static struct pci_device_id vlsi_irda_table [] __devinitdata = { {
 
-	class:          PCI_CLASS_IRDA_GENERIC << 8,
+	class:          PCI_CLASS_WIRELESS_IRDA << 8,
 	vendor:         PCI_VENDOR_ID_VLSI,
 	device:         PCI_DEVICE_ID_VLSI_82C147,
 	}, { /* all zeroes */ }
@@ -81,37 +83,45 @@
 
 
 MODULE_PARM(ringsize, "1-2i");
-MODULE_PARM_DESC(ringsize, "tx, rx ring descriptor size");
+MODULE_PARM_DESC(ringsize, "TX, RX ring descriptor size");
 
 /*	ringsize: size of the tx and rx descriptor rings
  *		independent for tx and rx
  *		specify as ringsize=tx[,rx]
  *		allowed values: 4, 8, 16, 32, 64
+ *		Due to the IrDA 1.x max. allowed window size=7,
+ *		there should be no gain when using rings larger than 8
  */
 
-static int ringsize[] = {16,16};	/* default is tx=rx=16 */
+static int ringsize[] = {8,8};		/* default is tx=rx=8 */
 
 
 MODULE_PARM(sirpulse, "i");
-MODULE_PARM_DESC(sirpulse, "sir pulse width tuning");
+MODULE_PARM_DESC(sirpulse, "SIR pulse width tuning");
 
-/*	sirpulse: tuning of the sir pulse width within IrPHY 1.3 limits
- *		0: real short, 1.5us (exception 6us at 2.4kb/s)
+/*	sirpulse: tuning of the SIR pulse width within IrPHY 1.3 limits
+ *		0: very short, 1.5us (exception: 6us at 2.4 kbaud)
  *		1: nominal 3/16 bittime width
+ *	note: IrDA compliant peer devices should be happy regardless
+ *		which one is used. Primary goal is to save some power
+ *		on the sender's side - at 9.6kbaud for example the short
+ *		pulse width saves more than 90% of the transmitted IR power.
  */
 
 static int sirpulse = 1;		/* default is 3/16 bittime */
 
 
-MODULE_PARM(mtt_bits, "i");
-MODULE_PARM_DESC(mtt_bits, "IrLAP bitfield representing min-turn-time");
+MODULE_PARM(qos_mtt_bits, "i");
+MODULE_PARM_DESC(qos_mtt_bits, "IrLAP bitfield representing min-turn-time");
 
-/*	mtt_bit: encoded min-turn-time values we accept for connections
- *		 according to IrLAP definition (section 6.6.8)
- *		 the widespreadly used HP HDLS-1100 requires 1 msec
+/*	qos_mtt_bits: encoded min-turn-time value we require the peer device
+ *		 to use before transmitting to us. "Type 1" (per-station)
+ *		 bitfield according to IrLAP definition (section 6.6.8)
+ *		 The HP HDLS-1100 requires 1 msec - don't even know
+ *		 if this is the one which is used by my OB800
  */
 
-static int mtt_bits = 0x07;		/* default is 1 ms or more */
+static int qos_mtt_bits = 0x04;		/* default is 1 ms */
 
 
 /********************************************************/
@@ -120,68 +130,81 @@
 /* some helpers for operations on ring descriptors */
 
 
-static inline int rd_is_active(struct ring_descr *rd)
+static inline int rd_is_active(struct vlsi_ring *r, unsigned i)
 {
-	return ((rd->rd_status & RD_STAT_ACTIVE) != 0);
+	return ((r->hw[i].rd_status & RD_STAT_ACTIVE) != 0);
 }
 
-static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s)
+static inline void rd_activate(struct vlsi_ring *r, unsigned i)
 {
-	/* overlayed - order is important! */
+	r->hw[i].rd_status |= RD_STAT_ACTIVE;
+}
+
+static inline void rd_set_addr_status(struct vlsi_ring *r, unsigned i, dma_addr_t a, u8 s)
+{
+	struct ring_descr *rd = r->hw +i;
+
+	/* ordering is important for two reasons:
+	 *  - overlayed: writing addr overwrites status
+	 *  - we want to write status last so we have valid address in
+	 *    case status has RD_STAT_ACTIVE set
+	 */
+
+	if ((a & ~DMA_MASK_MSTRPAGE) != MSTRPAGE_VALUE)
+		BUG();
 
+	a &= DMA_MASK_MSTRPAGE;  /* clear highbyte to make sure we won't write
+				  * to status - just in case MSTRPAGE_VALUE!=0
+				  */
 	rd->rd_addr = a;
-	rd->rd_status = s;
+	wmb();
+	rd->rd_status = s;	 /* potentially passes ownership to the hardware */
 }
 
-static inline void rd_set_status(struct ring_descr *rd, u8 s)
+static inline void rd_set_status(struct vlsi_ring *r, unsigned i, u8 s)
 {
-	rd->rd_status = s;
+	r->hw[i].rd_status = s;
 }
 
-static inline void rd_set_count(struct ring_descr *rd, u16 c)
+static inline void rd_set_count(struct vlsi_ring *r, unsigned i, u16 c)
 {
-	rd->rd_count = c;
+	r->hw[i].rd_count = c;
 }
 
-static inline u8 rd_get_status(struct ring_descr *rd)
+static inline u8 rd_get_status(struct vlsi_ring *r, unsigned i)
 {
-	return rd->rd_status;
+	return r->hw[i].rd_status;
 }
 
-static inline dma_addr_t rd_get_addr(struct ring_descr *rd)
+static inline dma_addr_t rd_get_addr(struct vlsi_ring *r, unsigned i)
 {
 	dma_addr_t	a;
 
-	a = (rd->rd_addr & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24);
+	a = (r->hw[i].rd_addr & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24);
 	return a;
 }
 
-static inline u16 rd_get_count(struct ring_descr *rd)
+static inline u16 rd_get_count(struct vlsi_ring *r, unsigned i)
 {
-	return rd->rd_count;
+	return r->hw[i].rd_count;
 }
 
+/* producer advances r->head when descriptor was added for processing by hw */
 
-/* advancing indices pointing into descriptor rings */
-
-static inline void ring_ptr_inc(unsigned *ptr, unsigned mask)
+static inline void ring_put(struct vlsi_ring *r)
 {
-	*ptr = (*ptr + 1) & mask;
+	r->head = (r->head + 1) & r->mask;
 }
 
+/* consumer advances r->tail when descriptor was removed after getting processed by hw */
 
-/********************************************************/
-
-
-#define MAX_PACKET_LEN		2048	/* IrDA MTU */
+static inline void ring_get(struct vlsi_ring *r)
+{
+	r->tail = (r->tail + 1) & r->mask;
+}
 
-/* increase transfer buffer size somewhat so we have enough space left
- * when packet size increases during wrapping due to XBOFs and escapes.
- * well, this wastes some memory - anyway, later we will
- * either map skb's directly or use pci_pool allocator...
- */
 
-#define XFER_BUF_SIZE		(MAX_PACKET_LEN+512)
+/********************************************************/
 
 /* the memory required to hold the 2 descriptor rings */
 
@@ -191,12 +214,11 @@
 
 #define RING_ENTRY_SIZE		(2 * MAX_RING_DESCR * sizeof(struct ring_entry))
 
-
 /********************************************************/
 
 /* just dump all registers */
 
-static void vlsi_reg_debug(int iobase, const char *s)
+static void vlsi_reg_debug(unsigned iobase, const char *s)
 {
 	int	i;
 
@@ -215,15 +237,14 @@
 	u8	clkctl, lock;
 	int	i, count;
 
-	if (clksrc < 0  ||  clksrc > 3) {
-		printk(KERN_ERR "%s: invalid clksrc=%d\n", __FUNCTION__, clksrc);
-		return -1;
-	}
 	if (clksrc < 2) { /* auto or PLL: try PLL */
 		clkctl = CLKCTL_NO_PD | CLKCTL_CLKSTP;
 		pci_write_config_byte(pdev, VLSI_PCI_CLKCTL, clkctl);
 
-		/* protocol to detect PLL lock synchronisation */
+		/* procedure to detect PLL lock synchronisation:
+		 * after 0.5 msec initial delay we expect to find 3 PLL lock
+		 * indications within 10 msec for successful PLL detection.
+		 */
 		udelay(500);
 		count = 0;
 		for (i = 500; i <= 10000; i += 50) { /* max 10 msec */
@@ -242,20 +263,20 @@
 				pci_write_config_byte(pdev, VLSI_PCI_CLKCTL, clkctl);
 				return -1;
 			}
-			else /* was: clksrc=0(auto) */
-				clksrc = 3; /* fallback to 40MHz XCLK (OB800) */
+			else			/* was: clksrc=0(auto) */
+				clksrc = 3;	/* fallback to 40MHz XCLK (OB800) */
 
 			printk(KERN_INFO "%s: PLL not locked, fallback to clksrc=%d\n",
 				__FUNCTION__, clksrc);
 		}
-		else { /* got succesful PLL lock */
+		else { /* got successful PLL lock */
 			clksrc = 1;
 			return 0;
 		}
 	}
 
 	/* we get here if either no PLL detected in auto-mode or
-	   the external clock source explicitly specified */
+	   the external clock source was explicitly specified */
 
 	clkctl = CLKCTL_EXTCLK | CLKCTL_CLKSTP;
 	if (clksrc == 3)
@@ -308,80 +329,93 @@
 
 /* ### FIXME: don't use old virt_to_bus() anymore! */
 
-static int vlsi_alloc_buffers_init(vlsi_irda_dev_t *idev)
+
+static void vlsi_arm_rx(struct vlsi_ring *r)
 {
-	void *buf;
-	int i, j;
+	unsigned	i;
+	dma_addr_t	ba;
 
-	idev->ring_buf = kmalloc(RING_ENTRY_SIZE,GFP_KERNEL);
-	if (!idev->ring_buf)
-		return -ENOMEM;
-	memset(idev->ring_buf, 0, RING_ENTRY_SIZE);
+	for (i = 0; i < r->size; i++) {
+		if (r->buf[i].data == NULL)
+			BUG();
+		ba = virt_to_bus(r->buf[i].data);
+		rd_set_addr_status(r, i, ba, RD_STAT_ACTIVE);
+	}
+}
 
-	for (i = MAX_RING_DESCR; i < MAX_RING_DESCR+ringsize[0]; i++) {
-		buf = kmalloc(XFER_BUF_SIZE, GFP_KERNEL|GFP_DMA);
-		if (!buf) {
-			for (j = MAX_RING_DESCR; j < i; j++)
-				kfree(idev->ring_buf[j].head);
-			kfree(idev->ring_buf);
-			idev->ring_buf = NULL;
+static int vlsi_alloc_ringbuf(struct vlsi_ring *r)
+{
+	unsigned	i, j;
+
+	r->head = r->tail = 0;
+	r->mask = r->size - 1;
+	for (i = 0; i < r->size; i++) {
+		r->buf[i].skb = NULL;
+		r->buf[i].data = kmalloc(XFER_BUF_SIZE, GFP_KERNEL|GFP_DMA);
+		if (r->buf[i].data == NULL) {
+			for (j = 0; j < i; j++) {
+				kfree(r->buf[j].data);
+				r->buf[j].data = NULL;
+			}
 			return -ENOMEM;
 		}
-		idev->ring_buf[i].head = buf;
-		idev->ring_buf[i].skb = NULL;
-		rd_set_addr_status(idev->ring_hw+i,virt_to_bus(buf), 0);
 	}
+	return 0;
+}
 
-	for (i = 0; i < ringsize[1]; i++) {
-		buf = kmalloc(XFER_BUF_SIZE, GFP_KERNEL|GFP_DMA);
-		if (!buf) {
-			for (j = 0; j < i; j++)
-				kfree(idev->ring_buf[j].head);
-			for (j = MAX_RING_DESCR; j < MAX_RING_DESCR+ringsize[0]; j++)
-				kfree(idev->ring_buf[j].head);
-			kfree(idev->ring_buf);
-			idev->ring_buf = NULL;
-			return -ENOMEM;
+static void vlsi_free_ringbuf(struct vlsi_ring *r)
+{
+	unsigned	i;
+
+	for (i = 0; i < r->size; i++) {
+		if (r->buf[i].data == NULL)
+			continue;
+		if (r->buf[i].skb) {
+			dev_kfree_skb(r->buf[i].skb);
+			r->buf[i].skb = NULL;
 		}
-		idev->ring_buf[i].head = buf;
-		idev->ring_buf[i].skb = NULL;
-		rd_set_addr_status(idev->ring_hw+i,virt_to_bus(buf), RD_STAT_ACTIVE);
+		else
+			kfree(r->buf[i].data);
+		r->buf[i].data = NULL;
 	}
-
-	return 0;
 }
 
 
 static int vlsi_init_ring(vlsi_irda_dev_t *idev)
 {
+	char 		 *ringarea;
 
-	idev->tx_mask = MAX_RING_DESCR | (ringsize[0] - 1);
-	idev->rx_mask = ringsize[1] - 1;
-
-	idev->ring_hw = pci_alloc_consistent(idev->pdev,
-		RING_AREA_SIZE, &idev->busaddr);
-	if (!idev->ring_hw) {
+	ringarea = pci_alloc_consistent(idev->pdev, RING_AREA_SIZE, &idev->busaddr);
+	if (!ringarea) {
 		printk(KERN_ERR "%s: insufficient memory for descriptor rings\n",
 			__FUNCTION__);
 		return -ENOMEM;
 	}
+	memset(ringarea, 0, RING_AREA_SIZE);
+
 #if 0
 	printk(KERN_DEBUG "%s: (%d,%d)-ring %p / %p\n", __FUNCTION__,
-		ringsize[0], ringsize[1], idev->ring_hw, 
+		ringsize[0], ringsize[1], ringarea, 
 		(void *)(unsigned)idev->busaddr);
 #endif
-	memset(idev->ring_hw, 0, RING_AREA_SIZE);
 
-	if (vlsi_alloc_buffers_init(idev)) {
-		
-		pci_free_consistent(idev->pdev, RING_AREA_SIZE,
-			idev->ring_hw, idev->busaddr);
-		printk(KERN_ERR "%s: insufficient memory for ring buffers\n",
-			__FUNCTION__);
-		return -1;
+	idev->rx_ring.size = ringsize[1];
+	idev->rx_ring.hw = (struct ring_descr *)ringarea;
+	if (!vlsi_alloc_ringbuf(&idev->rx_ring)) {
+		idev->tx_ring.size = ringsize[0];
+		idev->tx_ring.hw = idev->rx_ring.hw + MAX_RING_DESCR;
+		if (!vlsi_alloc_ringbuf(&idev->tx_ring)) {
+			idev->virtaddr = ringarea;
+			return 0;
+		}
+		vlsi_free_ringbuf(&idev->rx_ring);
 	}
 
-	return 0;
+	pci_free_consistent(idev->pdev, RING_AREA_SIZE,
+		ringarea, idev->busaddr);
+	printk(KERN_ERR "%s: insufficient memory for ring buffers\n",
+		__FUNCTION__);
+	return -1;
 }
 
 
@@ -395,7 +429,7 @@
 	vlsi_irda_dev_t *idev = ndev->priv;
 	unsigned long flags;
 	u16 nphyctl;
-	int iobase; 
+	unsigned iobase; 
 	u16 config;
 	unsigned mode;
 	int	ret;
@@ -418,7 +452,7 @@
 	else if (baudrate == 1152000) {
 		mode = IFF_MIR;
 		config = IRCFG_MIR | IRCFG_CRC16;
-		nphyctl = PHYCTL_MIR(baudrate);
+		nphyctl = PHYCTL_MIR(clksrc==3);
 	}
 	else {
 		mode = IFF_SIR;
@@ -447,7 +481,8 @@
 	outw(nphyctl, iobase+VLSI_PIO_NPHYCTL);
 	wmb();
 	outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE);
-		/* chip fetches IRCFG on next rising edge of its 8MHz clock */
+
+	/* chip fetches IRCFG on next rising edge of its 8MHz clock */
 
 	mb();
 	config = inw(iobase+VLSI_PIO_IRENABLE) & IRENABLE_MASK;
@@ -491,16 +526,15 @@
 static int vlsi_init_chip(struct net_device *ndev)
 {
 	vlsi_irda_dev_t *idev = ndev->priv;
+	unsigned	iobase;
 	u16 ptr;
-	unsigned  iobase;
-
 
 	iobase = ndev->base_addr;
 
-	outw(0, iobase+VLSI_PIO_IRENABLE);
-
 	outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR); /* w/c pending IRQ, disable all INT */
 
+	outw(0, iobase+VLSI_PIO_IRENABLE);	/* disable IrPHY-interface */
+
 	/* disable everything, particularly IRCFG_MSTR - which resets the RING_PTR */
 
 	outw(0, iobase+VLSI_PIO_IRCFG);
@@ -511,16 +545,16 @@
 
 	outw(0, iobase+VLSI_PIO_IRENABLE);
 
-	outw(MAX_PACKET_LEN, iobase+VLSI_PIO_MAXPKT);
+	outw(MAX_PACKET_LENGTH, iobase+VLSI_PIO_MAXPKT);  /* max possible value=0x0fff */
 
 	outw(BUS_TO_RINGBASE(idev->busaddr), iobase+VLSI_PIO_RINGBASE);
 
-	outw(TX_RX_TO_RINGSIZE(ringsize[0], ringsize[1]), iobase+VLSI_PIO_RINGSIZE);	
-
+	outw(TX_RX_TO_RINGSIZE(idev->tx_ring.size, idev->rx_ring.size),
+		iobase+VLSI_PIO_RINGSIZE);	
 
 	ptr = inw(iobase+VLSI_PIO_RINGPTR);
-	idev->rx_put = idev->rx_get = RINGPTR_GET_RX(ptr);
-	idev->tx_put = idev->tx_get = RINGPTR_GET_TX(ptr);
+	idev->rx_ring.head = idev->rx_ring.tail = RINGPTR_GET_RX(ptr);
+	idev->tx_ring.head = idev->tx_ring.tail = RINGPTR_GET_TX(ptr);
 
 	outw(IRCFG_MSTR, iobase+VLSI_PIO_IRCFG);		/* ready for memory access */
 	wmb();
@@ -531,12 +565,12 @@
 	idev->new_baud = 9600;		/* start with IrPHY using 9600(SIR) mode */
 	vlsi_set_baud(ndev);
 
-	outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR);
+	outb(IRINTR_INT_MASK, iobase+VLSI_PIO_IRINTR);	/* just in case - w/c pending IRQ's */
 	wmb();
 
 	/* DO NOT BLINDLY ENABLE IRINTR_ACTEN!
 	 * basically every received pulse fires an ACTIVITY-INT
-	 * leading to >1000 INT's per second instead of few 10
+	 * leading to >>1000 INT's per second instead of few 10
 	 */
 
 	outb(IRINTR_RPKTEN|IRINTR_TPKTEN, iobase+VLSI_PIO_IRINTR);
@@ -549,97 +583,82 @@
 /**************************************************************/
 
 
+static void vlsi_refill_rx(struct vlsi_ring *r)
+{
+	do {
+		if (rd_is_active(r, r->head))
+			BUG();
+		rd_activate(r, r->head);
+		ring_put(r);
+	} while (r->head != r->tail);
+}
+
+
 static int vlsi_rx_interrupt(struct net_device *ndev)
 {
 	vlsi_irda_dev_t *idev = ndev->priv;
-	int	iobase;
-	int	entry;
+	struct vlsi_ring *r;
 	int	len;
 	u8	status;
-	u16	word;
 	struct sk_buff	*skb;
 	int	crclen;
 
-	iobase = ndev->base_addr;
-
-	entry = idev->rx_get;
-
-	while ( !rd_is_active(idev->ring_hw+idev->rx_get) ) {
-
-		ring_ptr_inc(&idev->rx_get, idev->rx_mask);
+	r = &idev->rx_ring;
+	while (!rd_is_active(r, r->tail)) {
 
-		while (entry != idev->rx_get) {
-
-			status = rd_get_status(idev->ring_hw+entry);
-
-			if (status & RD_STAT_ACTIVE) {
-				printk(KERN_CRIT "%s: rx still active!!!\n",
-					__FUNCTION__);
-				break;
-			}
-			if (status & RX_STAT_ERROR) {
-				idev->stats.rx_errors++;
-				if (status & RX_STAT_OVER)  
-					idev->stats.rx_over_errors++;
-				if (status & RX_STAT_LENGTH)  
-					idev->stats.rx_length_errors++;
-				if (status & RX_STAT_PHYERR)  
-					idev->stats.rx_frame_errors++;
-				if (status & RX_STAT_CRCERR)  
-					idev->stats.rx_crc_errors++;
+		status = rd_get_status(r, r->tail);
+		if (status & RX_STAT_ERROR) {
+			idev->stats.rx_errors++;
+			if (status & RX_STAT_OVER)  
+				idev->stats.rx_over_errors++;
+			if (status & RX_STAT_LENGTH)  
+				idev->stats.rx_length_errors++;
+			if (status & RX_STAT_PHYERR)  
+				idev->stats.rx_frame_errors++;
+			if (status & RX_STAT_CRCERR)  
+				idev->stats.rx_crc_errors++;
+		}
+		else {
+			len = rd_get_count(r, r->tail);
+			crclen = (idev->mode==IFF_FIR) ? sizeof(u32) : sizeof(u16);
+			if (len < crclen)
+				printk(KERN_ERR "%s: strange frame (len=%d)\n",
+					__FUNCTION__, len);
+			else
+				len -= crclen;		/* remove trailing CRC */
+
+			skb = dev_alloc_skb(len+1);
+			if (skb) {
+				skb->dev = ndev;
+				skb_reserve(skb,1);
+				memcpy(skb_put(skb,len), r->buf[r->tail].data, len);
+				idev->stats.rx_packets++;
+				idev->stats.rx_bytes += len;
+				skb->mac.raw = skb->data;
+				skb->protocol = htons(ETH_P_IRDA);
+				netif_rx(skb);				
 			}
 			else {
-				len = rd_get_count(idev->ring_hw+entry);
-				crclen = (idev->mode==IFF_FIR) ? 4 : 2;
-				if (len < crclen)
-					printk(KERN_ERR "%s: strange frame (len=%d)\n",
-						__FUNCTION__, len);
-				else
-					len -= crclen;		/* remove trailing CRC */
-
-				skb = dev_alloc_skb(len+1);
-				if (skb) {
-					skb->dev = ndev;
-					skb_reserve(skb,1);
-					memcpy(skb_put(skb,len), idev->ring_buf[entry].head, len);
-					idev->stats.rx_packets++;
-					idev->stats.rx_bytes += len;
-					skb->mac.raw = skb->data;
-					skb->protocol = htons(ETH_P_IRDA);
-					netif_rx(skb);				
-				}
-				else {
-					idev->stats.rx_dropped++;
-					printk(KERN_ERR "%s: rx packet dropped\n", __FUNCTION__);
-				}
+				idev->stats.rx_dropped++;
+				printk(KERN_ERR "%s: rx packet dropped\n", __FUNCTION__);
 			}
-			rd_set_count(idev->ring_hw+entry, 0);
-			rd_set_status(idev->ring_hw+entry, RD_STAT_ACTIVE);
-			ring_ptr_inc(&entry, idev->rx_mask);
+		}
+		rd_set_count(r, r->tail, 0);
+		rd_set_status(r, r->tail, 0);
+		ring_get(r);
+		if (r->tail == r->head) {
+			printk(KERN_WARNING "%s: rx ring exhausted\n", __FUNCTION__);
+			break;
 		}
 	}
-	idev->rx_put = idev->rx_get;
-	idev->rx_get = entry;
 
-	word = inw(iobase+VLSI_PIO_IRENABLE);
-	if (!(word & IRENABLE_ENTXST)) {
+	do_gettimeofday(&idev->last_rx); /* remember "now" for later mtt delay */
 
-		/* only rewrite ENRX, if tx not running!
-		 * rewriting ENRX during tx in progress wouldn't hurt
-		 * but would be racy since we would also have to rewrite
-		 * ENTX then (same register) - which might get disabled meanwhile.
-		 */
-
-		outw(0, iobase+VLSI_PIO_IRENABLE);
+	vlsi_refill_rx(r);
 
-		word = inw(iobase+VLSI_PIO_IRCFG);
-		mb();
-		outw(word | IRCFG_ENRX, iobase+VLSI_PIO_IRCFG);
-		wmb();
-		outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE);
-	}
 	mb();
-	outw(0, iobase+VLSI_PIO_PROMPT);
+	outw(0, ndev->base_addr+VLSI_PIO_PROMPT);
+
 	return 0;
 }
 
@@ -647,64 +666,55 @@
 static int vlsi_tx_interrupt(struct net_device *ndev)
 {
 	vlsi_irda_dev_t *idev = ndev->priv;
-	int	iobase;
-	int	entry;
+	struct vlsi_ring	*r;
+	unsigned	iobase;
 	int	ret;
 	u16	config;
 	u16	status;
 
-	ret = 0;
-	iobase = ndev->base_addr;
-
-	entry = idev->tx_get;
-
-	while ( !rd_is_active(idev->ring_hw+idev->tx_get) ) {
-
-		if (idev->tx_get == idev->tx_put) { /* tx ring empty */
-			/* sth more to do here? */
-			break;
+	r = &idev->tx_ring;
+	while (!rd_is_active(r, r->tail)) {
+		if (r->tail == r->head)
+			break;	/* tx ring empty - nothing to send anymore */
+
+		status = rd_get_status(r, r->tail);
+		if (status & TX_STAT_UNDRN) {
+			idev->stats.tx_errors++;
+			idev->stats.tx_fifo_errors++;
 		}
-		ring_ptr_inc(&idev->tx_get, idev->tx_mask);
-		while (entry != idev->tx_get) {
-			status = rd_get_status(idev->ring_hw+entry);
-			if (status & RD_STAT_ACTIVE) {
-				printk(KERN_CRIT "%s: tx still active!!!\n",
-					__FUNCTION__);
-				break;
-			}
-			if (status & TX_STAT_UNDRN) {
-				idev->stats.tx_errors++;
-				idev->stats.tx_fifo_errors++;
-			}
-			else {
-				idev->stats.tx_packets++;
-				idev->stats.tx_bytes += rd_get_count(idev->ring_hw+entry);
-			}
-			rd_set_count(idev->ring_hw+entry, 0);
-			rd_set_status(idev->ring_hw+entry, 0);
-			ring_ptr_inc(&entry, idev->tx_mask);
+		else {
+			idev->stats.tx_packets++;
+			idev->stats.tx_bytes += rd_get_count(r, r->tail); /* not correct for SIR */
+		}
+		rd_set_count(r, r->tail, 0);
+		rd_set_status(r, r->tail, 0);
+		if (r->buf[r->tail].skb) {
+			rd_set_addr_status(r, r->tail, 0, 0);
+			dev_kfree_skb(r->buf[r->tail].skb);
+			r->buf[r->tail].skb = NULL;
+			r->buf[r->tail].data = NULL;
 		}
+		ring_get(r);
 	}
 
-	outw(0, iobase+VLSI_PIO_IRENABLE);
-	config = inw(iobase+VLSI_PIO_IRCFG);
-	mb();
+	ret = 0;
+	iobase = ndev->base_addr;
 
-	if (idev->tx_get != idev->tx_put) {	/* tx ring not empty */
-		outw(config | IRCFG_ENTX, iobase+VLSI_PIO_IRCFG);
-		ret = 1;			/* no speed-change-check */
+	if (r->head == r->tail) {	/* tx ring empty: re-enable rx */
+
+		outw(0, iobase+VLSI_PIO_IRENABLE);
+		config = inw(iobase+VLSI_PIO_IRCFG);
+		mb();
+		outw((config & ~IRCFG_ENTX) | IRCFG_ENRX, iobase+VLSI_PIO_IRCFG);
+		wmb();
+		outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE);
 	}
 	else
-		outw((config & ~IRCFG_ENTX) | IRCFG_ENRX, iobase+VLSI_PIO_IRCFG);
-	wmb();
-	outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE);
+		ret = 1;			/* no speed-change-check */
 
 	mb();
-
 	outw(0, iobase+VLSI_PIO_PROMPT);
-	wmb();
 
-	idev->tx_get = entry;
 	if (netif_queue_stopped(ndev)) {
 		netif_wake_queue(ndev);
 		printk(KERN_DEBUG "%s: queue awoken\n", __FUNCTION__);
@@ -713,24 +723,27 @@
 }
 
 
+#if 0	/* disable ACTIVITY handling for now */
+
 static int vlsi_act_interrupt(struct net_device *ndev)
 {
 	printk(KERN_DEBUG "%s\n", __FUNCTION__);
 	return 0;
 }
-
+#endif
 
 static void vlsi_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
 	struct net_device *ndev = dev_instance;
 	vlsi_irda_dev_t *idev = ndev->priv;
-	int		iobase;
+	unsigned	iobase;
 	u8		irintr;
-	int 		boguscount = 20;
+	int 		boguscount = 32;
 	int		no_speed_check = 0;
+	unsigned	got_act;
 	unsigned long	flags;
 
-
+	got_act = 0;
 	iobase = ndev->base_addr;
 	spin_lock_irqsave(&idev->lock,flags);
 	do {
@@ -750,9 +763,16 @@
 		if (irintr&IRINTR_TPKTINT)
 			no_speed_check |= vlsi_tx_interrupt(ndev);
 
-		if ((irintr&IRINTR_ACTIVITY) && !(irintr^IRINTR_ACTIVITY) )
-			no_speed_check |= vlsi_act_interrupt(ndev);
+#if 0	/* disable ACTIVITY handling for now */
+
+		if (got_act  &&  irintr==IRINTR_ACTIVITY) /* nothing new */
+			break;
 
+		if ((irintr&IRINTR_ACTIVITY) && !(irintr^IRINTR_ACTIVITY) ) {
+			no_speed_check |= vlsi_act_interrupt(ndev);
+			got_act = 1;
+		}
+#endif
 		if (irintr & ~(IRINTR_RPKTINT|IRINTR_TPKTINT|IRINTR_ACTIVITY))
 			printk(KERN_DEBUG "%s: IRINTR = %02x\n",
 				__FUNCTION__, (unsigned)irintr);
@@ -772,27 +792,51 @@
 
 /**************************************************************/
 
+
+/* writing all-zero to the VLSI PCI IO register area seems to prevent
+ * some occasional situations where the hardware fails (symptoms are 
+ * what appears as stalled tx/rx state machines, i.e. everything ok for
+ * receive or transmit but hw makes no progress or is unable to access
+ * the bus memory locations).
+ * Best place to call this is immediately after/before the internal clock
+ * gets started/stopped.
+ */
+
+static inline void vlsi_clear_regs(unsigned iobase)
+{
+	unsigned	i;
+	const unsigned	chip_io_extent = 32;
+
+	for (i = 0; i < chip_io_extent; i += sizeof(u16))
+		outw(0, iobase + i);
+}
+
+
 static int vlsi_open(struct net_device *ndev)
 {
 	vlsi_irda_dev_t *idev = ndev->priv;
 	struct pci_dev *pdev = idev->pdev;
-	char	hwname[32];
 	int	err;
-
-	MOD_INC_USE_COUNT;		/* still needed? - we have SET_MODULE_OWNER! */
+	char	hwname[32];
 
 	if (pci_request_regions(pdev,drivername)) {
 		printk(KERN_ERR "%s: io resource busy\n", __FUNCTION__);
-		MOD_DEC_USE_COUNT;
 		return -EAGAIN;
 	}
 
-	if (request_irq(ndev->irq, vlsi_interrupt, SA_SHIRQ|SA_INTERRUPT,
+	/* under some rare occasions the chip apparently comes up
+	 * with IRQ's pending. So we get interrupts invoked much too early
+	 * which will immediately kill us again :-(
+	 * so we better w/c pending IRQ and disable them all
+	 */
+
+	outb(IRINTR_INT_MASK, ndev->base_addr+VLSI_PIO_IRINTR);
+
+	if (request_irq(ndev->irq, vlsi_interrupt, SA_SHIRQ,
 			drivername, ndev)) {
 		printk(KERN_ERR "%s: couldn't get IRQ: %d\n",
 			__FUNCTION__, ndev->irq);
 		pci_release_regions(pdev);
-		MOD_DEC_USE_COUNT;
 		return -EAGAIN;
 	}
 	printk(KERN_INFO "%s: got resources for %s - irq=%d / io=%04lx\n",
@@ -803,18 +847,18 @@
 			__FUNCTION__);
 		free_irq(ndev->irq,ndev);
 		pci_release_regions(pdev);
-		MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 
 	vlsi_start_clock(pdev);
 
+	vlsi_clear_regs(ndev->base_addr);
+
 	err = vlsi_init_ring(idev);
 	if (err) {
 		vlsi_unset_clock(pdev);
 		free_irq(ndev->irq,ndev);
 		pci_release_regions(pdev);
-		MOD_DEC_USE_COUNT;
 		return err;
 	}
 
@@ -825,7 +869,11 @@
 		(idev->mode==IFF_SIR)?"SIR":((idev->mode==IFF_MIR)?"MIR":"FIR"),
 		(sirpulse)?"3/16 bittime":"short");
 
-	sprintf(hwname, "VLSI-FIR");
+	vlsi_arm_rx(&idev->rx_ring);
+
+	do_gettimeofday(&idev->last_rx);  /* first mtt may start from now on */
+
+	sprintf(hwname, "VLSI-FIR @ 0x%04x", (unsigned)ndev->base_addr);
 	idev->irlap = irlap_open(ndev,&idev->qos,hwname);
 
 	netif_start_queue(ndev);
@@ -841,7 +889,6 @@
 {
 	vlsi_irda_dev_t *idev = ndev->priv;
 	struct pci_dev *pdev = idev->pdev;
-	int	i;
 	u8	cmd;
 	unsigned iobase;
 
@@ -859,30 +906,26 @@
 	outw(0, iobase+VLSI_PIO_IRCFG);			/* disable everything */
 	wmb();
 	outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE);
-	mb();				/* from now on */
+	mb();						/* ... from now on */
 
 	outw(0, iobase+VLSI_PIO_IRENABLE);
 	wmb();
 
+	vlsi_clear_regs(ndev->base_addr);
+
 	vlsi_stop_clock(pdev);
 
 	vlsi_unset_clock(pdev);
 
 	free_irq(ndev->irq,ndev);
 
-	if (idev->ring_buf) {
-		for (i = 0; i < 2*MAX_RING_DESCR; i++) {
-			if (idev->ring_buf[i].head)
-				kfree(idev->ring_buf[i].head);
-		}
-		kfree(idev->ring_buf);
-	}
+	vlsi_free_ringbuf(&idev->rx_ring);
+	vlsi_free_ringbuf(&idev->tx_ring);
 
 	if (idev->busaddr)
-		pci_free_consistent(idev->pdev,RING_AREA_SIZE,idev->ring_hw,idev->busaddr);
+		pci_free_consistent(idev->pdev,RING_AREA_SIZE,idev->virtaddr,idev->busaddr);
 
-	idev->ring_buf = NULL;
-	idev->ring_hw = NULL;
+	idev->virtaddr = NULL;
 	idev->busaddr = 0;
 
 	pci_read_config_byte(pdev, PCI_COMMAND, &cmd);
@@ -893,7 +936,6 @@
 
 	printk(KERN_INFO "%s: device %s stopped\n", __FUNCTION__, ndev->name);
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -907,16 +949,17 @@
 static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
 	vlsi_irda_dev_t *idev = ndev->priv;
+	struct vlsi_ring	*r;
 	unsigned long flags;
-	int iobase;
+	unsigned iobase;
 	u8 status;
 	u16 config;
 	int mtt;
-	int entry;
 	int len, speed;
+	struct timeval  now, ready;
 
 
-	iobase = ndev->base_addr;
+	status = 0;
 
 	speed = irda_get_next_speed(skb);
 
@@ -929,71 +972,88 @@
 		}
 		status = TX_STAT_CLRENTX;  /* stop tx-ring after this frame */
 	}
-	else
-		status = 0;
 
+	if (skb->len == 0) {
+		printk(KERN_ERR "%s: blocking 0-size packet???\n",
+			__FUNCTION__);
+		dev_kfree_skb(skb);
+		return 0;
+	}
 
-	spin_lock_irqsave(&idev->lock,flags);
+	r = &idev->tx_ring;
 
-	entry = idev->tx_put;
+	if (rd_is_active(r, r->head))
+		BUG();
 
 	if (idev->mode == IFF_SIR) {
 		status |= TX_STAT_DISCRC;
-		len = async_wrap_skb(skb, idev->ring_buf[entry].head,
-			XFER_BUF_SIZE);
+		len = async_wrap_skb(skb, r->buf[r->head].data, XFER_BUF_SIZE);
 	}
 	else {				/* hw deals with MIR/FIR mode */
 		len = skb->len;
-		memcpy(idev->ring_buf[entry].head, skb->data, len);
+		memcpy(r->buf[r->head].data, skb->data, len);
 	}
 
-	if (len == 0)
-		printk(KERN_ERR "%s: sending 0-size packet???\n",
-			__FUNCTION__);
-
-	status |= RD_STAT_ACTIVE;
-
-	rd_set_count(idev->ring_hw+entry, len);
-	rd_set_status(idev->ring_hw+entry, status);
-	ring_ptr_inc(&idev->tx_put, idev->tx_mask);
+	rd_set_count(r, r->head, len);
+	rd_set_addr_status(r, r->head, virt_to_bus(r->buf[r->head].data), status);
 
-	dev_kfree_skb(skb);	
+	/* new entry not yet activated! */
 
 #if 0
 	printk(KERN_DEBUG "%s: dump entry %d: %u %02x %08x\n",
-		__FUNCTION__, entry,
-		idev->ring_hw[entry].rd_count,
-		(unsigned)idev->ring_hw[entry].rd_status,
-		idev->ring_hw[entry].rd_addr & 0xffffffff);
+		__FUNCTION__, r->head,
+		idev->ring_hw[r->head].rd_count,
+		(unsigned)idev->ring_hw[r->head].rd_status,
+		idev->ring_hw[r->head].rd_addr & 0xffffffff);
 	vlsi_reg_debug(iobase,__FUNCTION__);
 #endif
 
+
+	/* let mtt delay pass before we need to acquire the spinlock! */
+
+	if ((mtt = irda_get_mtt(skb)) > 0) {
+	
+		ready.tv_usec = idev->last_rx.tv_usec + mtt;
+		ready.tv_sec = idev->last_rx.tv_sec;
+		if (ready.tv_usec >= 1000000) {
+			ready.tv_usec -= 1000000;
+			ready.tv_sec++;		/* IrLAP 1.1: mtt always < 1 sec */
+		}
+		for(;;) {
+			do_gettimeofday(&now);
+			if (now.tv_sec > ready.tv_sec
+			    ||  (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
+			    	break;
+			udelay(100);
+		}
+	}
+
 /*
- *	race window due to concurrent controller processing!
+ *	race window ahead, due to concurrent controller processing!
  *
- *	we may loose ENTX at any time when the controller
- *	fetches an inactive descr or one with CLR_ENTX set.
- *	therefore we only rely on the controller telling us
- *	tx is already stopped because (cannot restart without PROMPT).
- *	instead we depend on the tx-complete-isr to detect the
- *	false negatives and retrigger the tx ring.
- *	that's why we need interrupts disabled till tx has been
- *	kicked, so the tx-complete-isr was either already finished
- *	before we've put the new active descriptor on the ring - or
- *	the isr will be called after the new active descr is on the
- *	ring _and_ the ring was prompted. Making these two steps
- *	atomic allows to resolve the race.
+ *	We need to disable IR output in order to switch to TX mode.
+ *	Better not do this blindly anytime we want to transmit something
+ *	because TX may already run. However the controller may stop TX
+ *	at any time when fetching an inactive descriptor or one with
+ *	CLR_ENTX set. So we switch on TX only, if TX was not running
+ *	_after_ the new descriptor was activated on the ring. This ensures
+ *	we will either find TX already stopped or we can be sure, there
+ *	will be a TX-complete interrupt even if the chip stopped doing
+ *	TX just after we found it still running. The ISR will then find
+ *	the non-empty ring and restart TX processing. The enclosing
+ *	spinlock is required to get serialization with the ISR right.
  */
 
+
 	iobase = ndev->base_addr;
 
-	if (!(inw(iobase+VLSI_PIO_IRENABLE) & IRENABLE_ENTXST)) {
+	spin_lock_irqsave(&idev->lock,flags);
 
-		mtt = irda_get_mtt(skb);
-		if (mtt) {
-			udelay(mtt);		/* ### FIXME ... */
-		}
+	rd_activate(r, r->head);
+	ring_put(r);
 
+	if (!(inw(iobase+VLSI_PIO_IRENABLE) & IRENABLE_ENTXST)) {
+	
 		outw(0, iobase+VLSI_PIO_IRENABLE);
 
 		config = inw(iobase+VLSI_PIO_IRCFG);
@@ -1001,29 +1061,28 @@
 		outw(config | IRCFG_ENTX, iobase+VLSI_PIO_IRCFG);
 		wmb();
 		outw(IRENABLE_IREN, iobase+VLSI_PIO_IRENABLE);
-
 		mb();
-
 		outw(0, iobase+VLSI_PIO_PROMPT);
 		wmb();
 	}
 
-	spin_unlock_irqrestore(&idev->lock, flags);
-
-	if (idev->tx_put == idev->tx_get) {
+	if (r->head == r->tail) {
 		netif_stop_queue(ndev);
 		printk(KERN_DEBUG "%s: tx ring full - queue stopped: %d/%d\n",
-			__FUNCTION__, idev->tx_put, idev->tx_get);
-		entry = idev->tx_get;
+			__FUNCTION__, r->head, r->tail);
+#if 0
 		printk(KERN_INFO "%s: dump stalled entry %d: %u %02x %08x\n",
-			__FUNCTION__, entry,
-			idev->ring_hw[entry].rd_count,
-			(unsigned)idev->ring_hw[entry].rd_status,
-			idev->ring_hw[entry].rd_addr & 0xffffffff);
+			__FUNCTION__, r->tail,
+			r->hw[r->tail].rd_count,
+			(unsigned)r->hw[r->tail].rd_status,
+			r->hw[r->tail].rd_addr & 0xffffffff);
+#endif
 		vlsi_reg_debug(iobase,__FUNCTION__);
 	}
 
-//	vlsi_reg_debug(iobase, __FUNCTION__);
+	spin_unlock_irqrestore(&idev->lock, flags);
+
+	dev_kfree_skb(skb);	
 
 	return 0;
 }
@@ -1054,6 +1113,10 @@
 			irda_device_set_media_busy(ndev, TRUE);
 			break;
 		case SIOCGRECEIVING:
+			/* the best we can do: check whether there are any bytes in rx fifo.
+			 * The trustable window (in case some data arrives just afterwards)
+			 * may be as short as 1usec or so at 4Mbps - no way for future-telling.
+			 */
 			fifocnt = inw(ndev->base_addr+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK;
 			irq->ifr_receiving = (fifocnt!=0) ? 1 : 0;
 			break;
@@ -1089,7 +1152,6 @@
 		return -1;
 	}
 	pci_set_master(pdev);
-
 	pdev->dma_mask = DMA_MASK_MSTRPAGE;
 	pci_write_config_byte(pdev, VLSI_PCI_MSTRPAGE, MSTRPAGE_VALUE);
 
@@ -1108,13 +1170,13 @@
 		| IR_19200 | IR_38400 | IR_57600 | IR_115200
 		| IR_1152000 | (IR_4000000 << 8);
 
-	idev->qos.min_turn_time.bits = mtt_bits;
+	idev->qos.min_turn_time.bits = qos_mtt_bits;
 
 	irda_qos_bits_to_value(&idev->qos);
 
 	irda_device_setup(ndev);
 
-	/* currently no media definitions for SIR/MIR/FIR */
+	/* currently no public media definitions for IrDA */
 
 	ndev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA;
 	ndev->if_port = IF_PORT_UNKNOWN;
@@ -1137,15 +1199,18 @@
 	vlsi_irda_dev_t		*idev;
 	int			alloc_size;
 
-	printk(KERN_INFO "%s: found IrDA PCI controler %s\n", drivername, pdev->name);
 
+	vlsi_reg_debug(0x3000, "vlsi initial state");
 	if (pci_enable_device(pdev))
 		goto out;
 
+	printk(KERN_INFO "%s: IrDA PCI controller %s detected\n",
+		drivername, pdev->name);
+
 	if ( !pci_resource_start(pdev,0)
 	     || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) {
 		printk(KERN_ERR "%s: bar 0 invalid", __FUNCTION__);
-		goto out;
+		goto out_disable;
 	}
 
 	alloc_size = sizeof(*ndev) + sizeof(*idev);
@@ -1154,7 +1219,7 @@
 	if (ndev==NULL) {
 		printk(KERN_ERR "%s: Unable to allocate device memory.\n",
 			__FUNCTION__);
-		goto out;
+		goto out_disable;
 	}
 
 	memset(ndev, 0, alloc_size);
@@ -1179,6 +1244,8 @@
 
 out_freedev:
 	kfree(ndev);
+out_disable:
+	pci_disable_device(pdev);
 out:
 	pdev->driver_data = NULL;
 	return -ENODEV;
@@ -1231,23 +1298,32 @@
 
 static int __init vlsi_mod_init(void)
 {
+	int	i;
+
 	if (clksrc < 0  ||  clksrc > 3) {
-		printk(KERN_ERR "%s: invalid clksrc=%d\n", __FUNCTION__, clksrc);
+		printk(KERN_ERR "%s: invalid clksrc=%d\n", drivername, clksrc);
 		return -1;
 	}
-	if ( ringsize[0]==0  ||  (ringsize[0] & ~(64|32|16|8|4))
-	     ||  ((ringsize[0]-1)&ringsize[0])) {
-		printk(KERN_INFO "%s: invalid tx ringsize %d - using default=16\n",
-			__FUNCTION__, ringsize[0]);
-		ringsize[0] = 16;
+
+	for (i = 0; i < 2; i++) {
+		switch(ringsize[i]) {
+			case 4:
+			case 8:
+			case 16:
+			case 32:
+			case 64:
+				break;
+			default:
+				printk(KERN_WARNING "%s: invalid %s ringsize %d",
+					drivername, (i)?"rx":"tx", ringsize[i]);
+				printk(", using default=8\n");
+				ringsize[i] = 8;
+				break;
+		}
 	} 
-	if ( ringsize[1]==0  ||  (ringsize[1] & ~(64|32|16|8|4))
-	     ||  ((ringsize[1]-1)&ringsize[1])) {
-		printk(KERN_INFO "%s: invalid rx ringsize %d - using default=16\n",
-			__FUNCTION__, ringsize[1]);
-		ringsize[1] = 16;
-	}
+
 	sirpulse = !!sirpulse;
+
 	return pci_module_init(&vlsi_irda_driver);
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
--- v2.4.10/linux/drivers/net/irda/w83977af_ir.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/irda/w83977af_ir.c	Sun Sep 30 12:26:06 2001
@@ -1378,6 +1378,8 @@
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(qos_mtt_bits, "i");
 MODULE_PARM_DESC(qos_mtt_bits, "Mimimum Turn Time");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v2.4.10/linux/drivers/net/lance.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/lance.c	Sun Sep 30 12:26:06 2001
@@ -347,6 +347,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /* Starting in v2.1.*, the LANCE/PCnet probe is now similar to the other
    board probes now that kmalloc() can allocate ISA DMA-able regions.
diff -u --recursive --new-file v2.4.10/linux/drivers/net/lne390.c linux/drivers/net/lne390.c
--- v2.4.10/linux/drivers/net/lne390.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/lne390.c	Sun Sep 30 12:26:06 2001
@@ -384,6 +384,7 @@
 MODULE_PARM_DESC(io, "LNE390 I/O base address(es)");
 MODULE_PARM_DESC(irq, "LNE390 IRQ number(s)");
 MODULE_PARM_DESC(mem, "LNE390 memory base address(es)");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/net/lp486e.c linux/drivers/net/lp486e.c
--- v2.4.10/linux/drivers/net/lp486e.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/lp486e.c	Sun Sep 30 12:26:06 2001
@@ -1324,6 +1324,8 @@
 
 MODULE_AUTHOR("Ard van Breemen <ard@cstmel.nl.eu.org>");
 MODULE_DESCRIPTION("Intel Panther onboard i82596 driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug, "i");
 //MODULE_PARM(max_interrupt_work, "i");
 //MODULE_PARM(reverse_probe, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/mac89x0.c linux/drivers/net/mac89x0.c
--- v2.4.10/linux/drivers/net/mac89x0.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/mac89x0.c	Sun Sep 30 12:26:08 2001
@@ -524,7 +524,7 @@
 		lp->stats.rx_dropped++;
 		return;
 	}
-	skb->len = length;
+	skb_put(skb, length);
 	skb->dev = dev;
 
 	memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length);
diff -u --recursive --new-file v2.4.10/linux/drivers/net/natsemi.c linux/drivers/net/natsemi.c
--- v2.4.10/linux/drivers/net/natsemi.c	Mon Aug 27 12:41:42 2001
+++ linux/drivers/net/natsemi.c	Tue Oct  9 15:13:03 2001
@@ -65,6 +65,27 @@
 		* Wake on lan support (Erik Gilling)
 		* MXDMA fixes for serverworks
 		* EEPROM reload
+
+	version 1.0.9 (Manfred Spraul)
+		* Main change: fix lack of synchronize
+		netif_close/netif_suspend against a last interrupt
+		or packet.
+		* do not enable superflous interrupts (e.g. the
+		drivers relies on TxDone - TxIntr not needed)
+		* wait that the hardware has really stopped in close
+		and suspend.
+		* workaround for the (at least) gcc-2.95.1 compiler
+		problem. Also simplifies the code a bit.
+		* disable_irq() in tx_timeout - needed to protect
+		against rx interrupts.
+		* stop the nic before switching into silent rx mode
+		for wol (required according to docu).
+
+	version 1.0.10:
+		* use long for ee_addr (various)
+		* print pointers properly (DaveM)
+		* include asm/irq.h (?)
+
 	TODO:
 	* big endian support with CFG:BEM instead of cpu_to_le32
 	* support for an external PHY
@@ -72,8 +93,8 @@
 */
 
 #define DRV_NAME	"natsemi"
-#define DRV_VERSION	"1.07+LK1.0.8"
-#define DRV_RELDATE	"Aug 07, 2001"
+#define DRV_VERSION	"1.07+LK1.0.10"
+#define DRV_RELDATE	"Oct 09, 2001"
 
 
 /* Updated to recommendations in pci-skeleton v2.03. */
@@ -161,6 +182,7 @@
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/uaccess.h>
 
 /* These identify the driver base version and may not be removed. */
@@ -171,6 +193,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
@@ -343,6 +367,8 @@
 	IntrNormalSummary=0x025f, IntrAbnormalSummary=0xCD20,
 };
 
+#define DEFAULT_INTR 0x00f1cd65
+
 /* Bits in the RxMode register. */
 enum rx_mode_bits {
 	AcceptErr=0x20, AcceptRunt=0x10,
@@ -433,6 +459,7 @@
 static int  eeprom_read(long ioaddr, int location);
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void natsemi_reset(struct net_device *dev);
+static void natsemi_stop_rxtx(struct net_device *dev);
 static int  netdev_open(struct net_device *dev);
 static void check_link(struct net_device *dev);
 static void netdev_timer(unsigned long data);
@@ -458,6 +485,7 @@
 static int netdev_get_sopass(struct net_device *dev, u8 *data);
 static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd);
 static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd);
+static void enable_wol_mode(struct net_device *dev, int enable_intr);
 static int  netdev_close(struct net_device *dev);
 
 
@@ -633,7 +661,7 @@
 {
 	int i;
 	int retval = 0;
-	int ee_addr = addr + EECtrl;
+	long ee_addr = addr + EECtrl;
 	int read_cmd = location | EE_ReadCmd;
 	writel(EE_Write0, ee_addr);
 
@@ -707,7 +735,26 @@
 	}
 }
 
-
+static void natsemi_stop_rxtx(struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	int i;
+
+	writel(RxOff | TxOff, ioaddr + ChipCmd);
+	for(i=0;i< NATSEMI_HW_TIMEOUT;i++) {
+		if ((readl(ioaddr + ChipCmd) & (TxOn|RxOn)) == 0)
+			break;
+		udelay(5);
+	}
+	if (i==NATSEMI_HW_TIMEOUT && debug) {
+		printk(KERN_INFO "%s: Tx/Rx process did not stop in %d usec.\n",
+				dev->name, i*5);
+	} else if (debug > 2) {
+		printk(KERN_DEBUG "%s: Tx/Rx process stopped in %d usec.\n",
+				dev->name, i*5);
+	}
+}
+
 static int netdev_open(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
@@ -729,7 +776,9 @@
 		return i;
 	}
 	init_ring(dev);
+	spin_lock_irq(&np->lock);
 	init_registers(dev);
+	spin_unlock_irq(&np->lock);
 
 	netif_start_queue(dev);
 
@@ -863,7 +912,7 @@
 	__set_rx_mode(dev);
 
 	/* Enable interrupts by setting the interrupt mask. */
-	writel(IntrNormalSummary | IntrAbnormalSummary, ioaddr + IntrMask);
+ 	writel(DEFAULT_INTR, ioaddr + IntrMask);
 	writel(1, ioaddr + IntrEnable);
 
 	writel(RxOn | TxOn, ioaddr + ChipCmd);
@@ -890,30 +939,49 @@
 	add_timer(&np->timer);
 }
 
-static void tx_timeout(struct net_device *dev)
+static void dump_ring(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
-
-	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
-		   " resetting...\n", dev->name, (int)readl(ioaddr + TxRingPtr));
 
-	{
+	if (debug > 2) {
 		int i;
-		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
-		for (i = 0; i < RX_RING_SIZE; i++)
-			printk(" %8.8x", (unsigned int)np->rx_ring[i].cmd_status);
-		printk("\n"KERN_DEBUG"  Tx ring %p: ", np->tx_ring);
+		printk(KERN_DEBUG "  Tx ring at %p:\n", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(" %4.4x", np->tx_ring[i].cmd_status);
-		printk("\n");
+			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x %8.8x.\n",
+				   i, np->tx_ring[i].next_desc,
+				   np->tx_ring[i].cmd_status, np->tx_ring[i].addr);
+		printk(KERN_DEBUG "  Rx ring %p:\n", np->rx_ring);
+		for (i = 0; i < RX_RING_SIZE; i++) {
+			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x %8.8x.\n",
+				   i, np->rx_ring[i].next_desc,
+				   np->rx_ring[i].cmd_status, np->rx_ring[i].addr);
+		}
 	}
+}
+
+static void tx_timeout(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+
+
+	disable_irq(dev->irq);
 	spin_lock_irq(&np->lock);
-	natsemi_reset(dev);
-	drain_ring(dev);
-	init_ring(dev);
-	init_registers(dev);
+	if (netif_device_present(dev)) {
+		printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
+			   " resetting...\n", dev->name, readl(ioaddr + IntrStatus));
+		dump_ring(dev);
+
+		natsemi_reset(dev);
+		drain_ring(dev);
+		init_ring(dev);
+		init_registers(dev);
+	} else {
+		printk(KERN_WARNING "%s: tx_timeout while in suspended state?\n",
+		   		dev->name);
+	}
 	spin_unlock_irq(&np->lock);
+	enable_irq(dev->irq);
 
 	dev->trans_start = jiffies;
 	np->stats.tx_errors++;
@@ -944,14 +1012,17 @@
 	np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
 	np->rx_head_desc = &np->rx_ring[0];
 
+	/* Please be carefull before changing this loop - at least gcc-2.95.1
+	 * miscompiles it otherwise.
+	 */
 	/* Initialize all Rx descriptors. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		np->rx_ring[i].next_desc = cpu_to_le32(np->ring_dma+sizeof(struct netdev_desc)*(i+1));
+		np->rx_ring[i].next_desc = cpu_to_le32(np->ring_dma
+				+sizeof(struct netdev_desc)
+				 *((i+1)%RX_RING_SIZE));
 		np->rx_ring[i].cmd_status = cpu_to_le32(DescOwn);
 		np->rx_skbuff[i] = NULL;
 	}
-	/* Mark the last entry as wrapping the ring. */
-	np->rx_ring[i-1].next_desc = cpu_to_le32(np->ring_dma);
 
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
@@ -963,18 +1034,18 @@
 		np->rx_dma[i] = pci_map_single(np->pci_dev,
 						skb->data, skb->len, PCI_DMA_FROMDEVICE);
 		np->rx_ring[i].addr = cpu_to_le32(np->rx_dma[i]);
-		np->rx_ring[i].cmd_status = cpu_to_le32(DescIntr | np->rx_buf_sz);
+		np->rx_ring[i].cmd_status = cpu_to_le32(np->rx_buf_sz);
 	}
 	np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		np->tx_skbuff[i] = NULL;
 		np->tx_ring[i].next_desc = cpu_to_le32(np->ring_dma
-					+sizeof(struct netdev_desc)*(i+1+RX_RING_SIZE));
+					+sizeof(struct netdev_desc)
+					 *((i+1)%TX_RING_SIZE+RX_RING_SIZE));
 		np->tx_ring[i].cmd_status = 0;
 	}
-	np->tx_ring[i-1].next_desc = cpu_to_le32(np->ring_dma
-					+sizeof(struct netdev_desc)*(RX_RING_SIZE));
+	dump_ring(dev);
 }
 
 static void drain_ring(struct net_device *dev)
@@ -1033,25 +1104,25 @@
 	np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]);
 
 	spin_lock_irq(&np->lock);
-
-#if 0
-	np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | DescIntr | skb->len);
-#else
-	np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | skb->len);
-#endif
-	/* StrongARM: Explicitly cache flush np->tx_ring and skb->data,skb->len. */
-	wmb();
-	np->cur_tx++;
-	if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) {
-		netdev_tx_done(dev);
-		if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1)
-			netif_stop_queue(dev);
+	
+	if (netif_device_present(dev)) {
+		np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | skb->len);
+		/* StrongARM: Explicitly cache flush np->tx_ring and skb->data,skb->len. */
+		wmb();
+		np->cur_tx++;
+		if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) {
+			netdev_tx_done(dev);
+			if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1)
+				netif_stop_queue(dev);
+		}
+		/* Wake the potentially-idle transmit channel. */
+		writel(TxOn, dev->base_addr + ChipCmd);
+	} else {
+		dev_kfree_skb_irq(skb);
+		np->stats.tx_dropped++;
 	}
 	spin_unlock_irq(&np->lock);
 
-	/* Wake the potentially-idle transmit channel. */
-	writel(TxOn, dev->base_addr + ChipCmd);
-
 	dev->trans_start = jiffies;
 
 	if (debug > 4) {
@@ -1113,7 +1184,9 @@
 
 	ioaddr = dev->base_addr;
 	np = dev->priv;
-
+	
+	if (!netif_device_present(dev))
+		return;
 	do {
 		/* Reading automatically acknowledges all int sources. */
 		u32 intr_status = readl(ioaddr + IntrStatus);
@@ -1237,7 +1310,7 @@
 			np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
 		}
 		np->rx_ring[entry].cmd_status =
-			cpu_to_le32(DescIntr | np->rx_buf_sz);
+			cpu_to_le32(np->rx_buf_sz);
 	}
 
 	/* Restart Rx engine if stopped. */
@@ -1303,11 +1376,13 @@
 
 	/* The chip only need report frame silently dropped. */
 	spin_lock_irq(&np->lock);
-	__get_stats(dev);
+ 	if (netif_running(dev) && netif_device_present(dev))
+ 		__get_stats(dev);
 	spin_unlock_irq(&np->lock);
 
 	return &np->stats;
 }
+
 /* The little-endian AUTODIN II ethernet CRC calculations.
    A big-endian version is also available.
    This is slow but compact code.  Do not use this routine for bulk data,
@@ -1406,7 +1481,8 @@
 {
 	struct netdev_private *np = dev->priv;
 	spin_lock_irq(&np->lock);
-	__set_rx_mode(dev);
+	if (netif_device_present(dev))
+		__set_rx_mode(dev);
 	spin_unlock_irq(&np->lock);
 }
 
@@ -1716,76 +1792,94 @@
 	}
 }
 
+static void enable_wol_mode(struct net_device *dev, int enable_intr)
+{
+	long ioaddr = dev->base_addr;
+
+	if (debug > 1)
+		printk(KERN_INFO "%s: remaining active for wake-on-lan\n", 
+			dev->name);
+	/* For WOL we must restart the rx process in silent mode.
+	 * Write NULL to the RxRingPtr. Only possible if
+	 * rx process is stopped
+	 */
+	writel(0, ioaddr + RxRingPtr);
+
+	/* and restart the rx process */
+	writel(RxOn, ioaddr + ChipCmd);
+
+	if (enable_intr) {
+		/* enable the WOL interrupt.
+		 * Could be used to send a netlink message.
+		 */
+		writel(readl(ioaddr + IntrMask) | WOLPkt, ioaddr + IntrMask);
+	}
+}
+
 static int netdev_close(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
-	u32 wol = readl(ioaddr + WOLCmd) & WakeOptsSummary;
-	u32 clkrun;
 
 	netif_stop_queue(dev);
-	netif_carrier_off(dev);
 
 	if (debug > 1) {
-		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.",
+ 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
 			   dev->name, (int)readl(ioaddr + ChipCmd));
 		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
 			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
 	}
 
-	/* Only shut down chip if wake on lan is not set */
-	if (!wol) {
-		/* Disable interrupts using the mask. */
-		writel(0, ioaddr + IntrMask);
-		writel(0, ioaddr + IntrEnable);
-		writel(2, ioaddr + StatsCtrl); 	/* Freeze Stats */
-	    
-		/* Stop the chip's Tx and Rx processes. */
-		writel(RxOff | TxOff, ioaddr + ChipCmd);
-	} else if (debug > 1) {
-		printk(KERN_INFO "%s: remaining active for wake-on-lan\n", 
-			dev->name);
-		/* spec says write 0 here */
-		writel(0, ioaddr + RxRingPtr);
-		/* allow wake-event interrupts now */
-		writel(readl(ioaddr + IntrMask) | WOLPkt, ioaddr + IntrMask);
-	}
 	del_timer_sync(&np->timer);
 
-#ifdef __i386__
-	if (debug > 2) {
-		int i;
-		printk("\n"KERN_DEBUG"  Tx ring at %8.8x:\n",
-			   (int)np->tx_ring);
-		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(" #%d desc. %8.8x %8.8x.\n",
-				   i, np->tx_ring[i].cmd_status, np->tx_ring[i].addr);
-		printk("\n"KERN_DEBUG "  Rx ring %8.8x:\n",
-			   (int)np->rx_ring);
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x\n",
-				   i, np->rx_ring[i].cmd_status, np->rx_ring[i].addr);
-		}
-	}
-#endif /* __i386__ debugging only */
+	disable_irq(dev->irq);
+	spin_lock_irq(&np->lock);
+
+	writel(0, ioaddr + IntrEnable);
+	writel(0, ioaddr + IntrMask);
+	writel(2, ioaddr + StatsCtrl); 	/* Freeze Stats */
+	    
+	/* Stop the chip's Tx and Rx processes. */
+	natsemi_stop_rxtx(dev);
+
+	__get_stats(dev);
+	spin_unlock_irq(&np->lock);
 
+	/* race: shared irq and as most nics the DP83815
+	 * reports _all_ interrupt conditions in IntrStatus, even
+	 * disabled ones.
+	 * packet received after disable_irq, but before stop_rxtx
+	 * --> race. intr_handler would restart the rx process.
+	 * netif_device_{de,a}tach around {enable,free}_irq.
+	 */
+	netif_device_detach(dev);
+	enable_irq(dev->irq);
 	free_irq(dev->irq, dev);
+	netif_device_attach(dev);
+	/* clear the carrier last - an interrupt could reenable it otherwise */
+	netif_carrier_off(dev);
+
+	dump_ring(dev);
 	drain_ring(dev);
 	free_ring(dev);
 
-	clkrun = np->SavedClkRun;
-	if (wol) {
-		/* make sure to enable PME */
-		clkrun |= 0x100;
-	}
-
-	/* Restore PME enable bit */
-	writel(np->SavedClkRun, ioaddr + ClkRun);
-	
+	 {
+		u32 wol = readl(ioaddr + WOLCmd) & WakeOptsSummary;
+		u32 clkrun = np->SavedClkRun;
+		/* Restore PME enable bit */
+		if (wol) {
+			/* restart the NIC in WOL mode.
+			 * The nic must be stopped for this.
+			 */
+			enable_wol_mode(dev, 0);
+			/* make sure to enable PME */
+			clkrun |= 0x100;
+		}
+		writel(clkrun, ioaddr + ClkRun);
 #if 0
-	writel(0x0200, ioaddr + ChipConfig); /* Power down Xcvr. */
+		writel(0x0200, ioaddr + ChipConfig); /* Power down Xcvr. */
 #endif
-
+	}
 	return 0;
 }
 
@@ -1803,49 +1897,71 @@
 
 #ifdef CONFIG_PM
 
+/*
+ * suspend/resume synchronization:
+ * entry points:
+ *   netdev_open, netdev_close, netdev_ioctl, set_rx_mode, intr_handler,
+ *   start_tx, tx_timeout
+ * Reading from some registers can restart the nic!
+ * No function accesses the hardware without checking netif_device_present().
+ * 	the check occurs under spin_lock_irq(&np->lock);
+ * exceptions:
+ * 	* netdev_ioctl, netdev_open.
+ * 		net/core checks netif_device_present() before calling them.
+ * 	* netdev_close: doesn't hurt.
+ *	* netdev_timer: timer stopped by natsemi_suspend.
+ *	* intr_handler: doesn't acquire the spinlock. suspend calls
+ *		disable_irq() to enforce synchronization.
+ *
+ * netif_device_detach must occur under spin_unlock_irq(), interrupts from a detached
+ * device would cause an irq storm.
+ */
+
 static int natsemi_suspend (struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 
-	netif_device_detach(dev);
-	/* no more calls to tx_timeout, hard_start_xmit, set_rx_mode */
 	rtnl_lock();
-	rtnl_unlock();
-	/* noone within ->open */
 	if (netif_running (dev)) {
-		int i;
 		del_timer_sync(&np->timer);
-		/* no more link beat timer calls */
+
+		disable_irq(dev->irq);
 		spin_lock_irq(&np->lock);
-		writel(RxOff | TxOff, ioaddr + ChipCmd);
-		for(i=0;i< NATSEMI_HW_TIMEOUT;i++) {
-			if ((readl(ioaddr + ChipCmd) & (TxOn|RxOn)) == 0)
-				break;
-			udelay(5);
-		}
-		if (i==NATSEMI_HW_TIMEOUT && debug) {
-			printk(KERN_INFO "%s: Tx/Rx process did not stop in %d usec.\n",
-					dev->name, i*5);
-		} else if (debug > 2) {
-			printk(KERN_DEBUG "%s: Tx/Rx process stopped in %d usec.\n",
-					dev->name, i*5);
-		}
-		/* Tx and Rx processes stopped */
 
 		writel(0, ioaddr + IntrEnable);
-		/* all irq events disabled. */
-		spin_unlock_irq(&np->lock);
-
-		synchronize_irq();
+		natsemi_stop_rxtx(dev);
+		netif_stop_queue(dev);
+		netif_device_detach(dev);
 
+		spin_unlock_irq(&np->lock);
+		enable_irq(dev->irq);
+		
 		/* Update the error counts. */
 		__get_stats(dev);
 
 		/* pci_power_off(pdev, -1); */
 		drain_ring(dev);
+		{
+			u32 wol = readl(ioaddr + WOLCmd) & WakeOptsSummary;
+			u32 clkrun = np->SavedClkRun;
+			/* Restore PME enable bit */
+			if (wol) {
+				/* restart the NIC in WOL mode.
+				 * The nic must be stopped for this.
+				 * FIXME: use the WOL interupt 
+				 */
+				enable_wol_mode(dev, 0);
+				/* make sure to enable PME */
+				clkrun |= 0x100;
+			}
+			writel(clkrun, ioaddr + ClkRun);
+		}
+	} else {
+		netif_device_detach(dev);
 	}
+	rtnl_unlock();
 	return 0;
 }
 
@@ -1855,18 +1971,27 @@
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct netdev_private *np = dev->priv;
 
-	if (netif_running (dev)) {
+	rtnl_lock();
+	if (netif_device_present(dev))
+		goto out;
+	if (netif_running(dev)) {
 		pci_enable_device(pdev);
 	/*	pci_power_on(pdev); */
 		
 		natsemi_reset(dev);
 		init_ring(dev);
+		spin_lock_irq(&np->lock);
 		init_registers(dev);
+		netif_device_attach(dev);
+		spin_unlock_irq(&np->lock);
 
 		np->timer.expires = jiffies + 1*HZ;
 		add_timer(&np->timer);
+	} else {
+		netif_device_attach(dev);
 	}
-	netif_device_attach(dev);
+out:
+	rtnl_unlock();
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v2.4.10/linux/drivers/net/ne.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/ne.c	Sun Sep 30 12:26:07 2001
@@ -788,6 +788,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
--- v2.4.10/linux/drivers/net/ne2k-pci.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/ne2k-pci.c	Sun Sep 30 12:26:07 2001
@@ -77,6 +77,8 @@
 
 MODULE_AUTHOR("Donald Becker / Paul Gortmaker");
 MODULE_DESCRIPTION("PCI NE2000 clone driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ne3210.c linux/drivers/net/ne3210.c
--- v2.4.10/linux/drivers/net/ne3210.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/ne3210.c	Sun Sep 30 12:26:07 2001
@@ -415,5 +415,7 @@
 		}
 	}
 }
+MODULE_LICENSE("GPL");
+
 #endif /* MODULE */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ni5010.c linux/drivers/net/ni5010.c
--- v2.4.10/linux/drivers/net/ni5010.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/ni5010.c	Sun Sep 30 12:26:07 2001
@@ -783,6 +783,7 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v2.4.10/linux/drivers/net/ni52.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/ni52.c	Sun Sep 30 12:26:07 2001
@@ -1362,6 +1362,7 @@
 	printk("\n");
 }
 #endif
+MODULE_LICENSE("GPL");
 
 /*
  * END: linux/drivers/net/ni52.c
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v2.4.10/linux/drivers/net/ni65.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/ni65.c	Sun Sep 30 12:26:07 2001
@@ -1214,6 +1214,7 @@
 	dev_ni65.priv = NULL;
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
 
 /*
  * END of ni65.c
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ns83820.c linux/drivers/net/ns83820.c
--- v2.4.10/linux/drivers/net/ns83820.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/ns83820.c	Tue Oct  9 15:13:03 2001
@@ -1,7 +1,7 @@
-#define VERSION "0.11"
+#define VERSION "0.13"
 /* ns83820.c by Benjamin LaHaise <bcrl@redhat.com>
  *
- * $Revision: 1.34.2.2 $
+ * $Revision: 1.34.2.8 $
  *
  * Copyright 2001 Benjamin LaHaise.
  * Copyright 2001 Red Hat.
@@ -41,7 +41,10 @@
  *	20010827	0.10 - fix ia64 unaligned access.
  *	20010906	0.11 - accept all packets with checksum errors as
  *			       otherwise fragments get lost
-			     - fix >> 32 bugs
+ *			     - fix >> 32 bugs
+ *			0.12 - add statistics counters
+ *			     - add allmulti/promisc support
+ *	20011009	0.13 - hotplug support, other smaller pci api cleanups
  *
  * Driver Overview
  * ===============
@@ -61,7 +64,9 @@
  *	Cameo		SOHO-GA2000T	SOHO-GA2500T
  *	D-Link		DGE-500T
  *	PureData	PDP8023Z-TG
- *	SMC		SMC9462TX
+ *	SMC		SMC9452TX	SMC9462TX
+ *
+ * Special thanks to SMC for providing hardware to test this driver on.
  *
  * Reports of success or failure would be greatly appreciated.
  */
@@ -366,10 +371,10 @@
 
 struct ns83820 {
 	struct net_device	net_dev;
+	struct net_device_stats	stats;
 	u8			*base;
 
 	struct pci_dev		*pci_dev;
-	struct ns83820		*next_dev;
 
 	struct rx_info		rx_info;
 
@@ -405,8 +410,6 @@
 #define start_tx_okay(dev)	\
 	(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > NR_TX_DESC/2)
 
-static struct ns83820	*ns83820_chain;
-
 
 /* Packet Receiver
  *
@@ -732,39 +735,22 @@
 			kfree_skb(skb);
 			skb = tmp;
 #endif
+			if (cmdsts & CMDSTS_DEST_MULTI)
+				dev->stats.multicast ++;
+			dev->stats.rx_packets ++;
+			dev->stats.rx_bytes += len;
 			if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) {
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
 			} else {
 				skb->ip_summed = CHECKSUM_NONE;
 			}
 			skb->protocol = eth_type_trans(skb, &dev->net_dev);
-			switch (netif_rx(skb)) {
-			case NET_RX_SUCCESS:
-				dev->ihr = 3;
-				break;
-			case NET_RX_CN_LOW:
-				dev->ihr = 3;
-				break;
-			case NET_RX_CN_MOD:
-				dev->ihr = dev->ihr + 1;
-				break;
-			case NET_RX_CN_HIGH:
-				dev->ihr += dev->ihr/2 + 1;
-				break;
-			case NET_RX_DROP:
-				dev->ihr = 255;
-				break;
-			}
-			if (dev->ihr > 255)
-				dev->ihr = 255;
+			if (NET_RX_DROP == netif_rx(skb))
+				dev->stats.rx_dropped ++;
 #ifndef __i386__
 		done:;
 #endif
 		} else {
-			static int err;
-			if (err++ < 20) {
-				Dprintk("error packet: cmdsts: %08x extsts: %08x\n", cmdsts, extsts);
-			}
 			kfree_skb(skb);
 		}
 
@@ -807,6 +793,13 @@
 	       !(CMDSTS_OWN & (cmdsts = desc[CMDSTS])) ) {
 		struct sk_buff *skb;
 
+		if (cmdsts & CMDSTS_ERR)
+			dev->stats.tx_errors ++;
+		if (cmdsts & CMDSTS_OK)
+			dev->stats.tx_packets ++;
+		if (cmdsts & CMDSTS_OK)
+			dev->stats.tx_bytes += cmdsts & 0xffff;
+
 		dprintk("tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
 			tx_done_idx, dev->tx_free_idx, desc[CMDSTS]);
 		skb = dev->tx_skbs[tx_done_idx];
@@ -985,6 +978,35 @@
 	return 0;
 }
 
+static void ns83820_update_stats(struct ns83820 *dev)
+{
+	u8 *base = dev->base;
+
+	dev->stats.rx_errors		+= readl(base + 0x60) & 0xffff;
+	dev->stats.rx_crc_errors	+= readl(base + 0x64) & 0xffff;
+	dev->stats.rx_missed_errors	+= readl(base + 0x68) & 0xffff;
+	dev->stats.rx_frame_errors	+= readl(base + 0x6c) & 0xffff;
+	/*dev->stats.rx_symbol_errors +=*/ readl(base + 0x70);
+	dev->stats.rx_length_errors	+= readl(base + 0x74) & 0xffff;
+	dev->stats.rx_length_errors	+= readl(base + 0x78) & 0xffff;
+	/*dev->stats.rx_badopcode_errors += */ readl(base + 0x7c);
+	/*dev->stats.rx_pause_count += */  readl(base + 0x80);
+	/*dev->stats.tx_pause_count += */  readl(base + 0x84);
+	dev->stats.tx_carrier_errors	+= readl(base + 0x88) & 0xff;
+}
+
+static struct net_device_stats *ns83820_get_stats(struct net_device *_dev)
+{
+	struct ns83820 *dev = (void *)_dev;
+
+	/* somewhat overkill */
+	spin_lock_irq(&dev->misc_lock);
+	ns83820_update_stats(dev);
+	spin_unlock_irq(&dev->misc_lock);
+
+	return &dev->stats;
+}
+
 static void ns83820_irq(int foo, void *data, struct pt_regs *regs)
 {
 	struct ns83820 *dev = data;
@@ -1060,6 +1082,12 @@
 	if ((ISR_TXDESC | ISR_TXIDLE) & isr)
 		do_tx_done(dev);
 
+	if (ISR_MIB & isr) {
+		spin_lock(&dev->misc_lock);
+		ns83820_update_stats(dev);
+		spin_unlock(&dev->misc_lock);
+	}
+
 	if (ISR_PHY & isr)
 		phy_intr(dev);
 	}
@@ -1178,7 +1206,29 @@
 	return 0;
 }
 
-static int ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
+static void ns83820_set_multicast(struct net_device *_dev)
+{
+	struct ns83820 *dev = (void *)_dev;
+	u8 *rfcr = dev->base + RFCR;
+	u32 and_mask = 0xffffffff;
+	u32 or_mask = 0;
+
+	if (dev->net_dev.flags & IFF_PROMISC)
+		or_mask |= RFCR_AAU | RFCR_AAM;
+	else
+		and_mask &= ~(RFCR_AAU | RFCR_AAM);
+
+	if (dev->net_dev.flags & IFF_ALLMULTI)
+		or_mask |= RFCR_AAM;
+	else
+		and_mask &= ~RFCR_AAM;
+
+	spin_lock_irq(&dev->misc_lock);
+	writel((readl(rfcr) & and_mask) | or_mask, rfcr);
+	spin_unlock_irq(&dev->misc_lock);
+}
+
+static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_device_id *id)
 {
 	struct ns83820 *dev;
 	long addr;
@@ -1241,12 +1291,12 @@
 	dev->net_dev.stop = ns83820_stop;
 	dev->net_dev.hard_start_xmit = ns83820_hard_start_xmit;
 	dev->net_dev.change_mtu = ns83820_change_mtu;
+	dev->net_dev.get_stats = ns83820_get_stats;
+	dev->net_dev.change_mtu = ns83820_change_mtu;
+	dev->net_dev.set_multicast_list = ns83820_set_multicast;
 	//FIXME: dev->net_dev.tx_timeout = ns83820_tx_timeout;
 
-	lock_kernel();
-	dev->next_dev = ns83820_chain;
-	ns83820_chain = dev;
-	unlock_kernel();
+	pci_set_drvdata(pci_dev, dev);
 
 	ns83820_do_reset(dev, CR_RST);
 
@@ -1368,21 +1418,45 @@
 	pci_disable_device(pci_dev);
 out_free:
 	kfree(dev);
+	pci_set_drvdata(pci_dev, NULL);
 out:
 	return err;
 }
 
-static struct pci_device_id pci_device_id[] __devinitdata = {
+static void __devexit ns83820_remove_one(struct pci_dev *pci_dev)
+{
+	struct ns83820	*dev = pci_get_drvdata(pci_dev);
+
+	if (!dev)			/* paranoia */
+		return;
+
+	writel(0, dev->base + IMR);	/* paranoia */
+	writel(0, dev->base + IER);
+	readl(dev->base + IER);
+
+	unregister_netdev(&dev->net_dev);
+	free_irq(dev->pci_dev->irq, dev);
+	iounmap(dev->base);
+	pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC,
+			dev->tx_descs, dev->tx_phy_descs);
+	pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC,
+			dev->rx_info.descs, dev->rx_info.phy_descs);
+	pci_disable_device(dev->pci_dev);
+	kfree(dev);
+	pci_set_drvdata(pci_dev, NULL);
+}
+
+static struct pci_device_id ns83820_pci_tbl[] __devinitdata = {
 	{ 0x100b, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
 	{ 0, },
 };
 
 static struct pci_driver driver = {
 	name:		"ns83820",
-	id_table:	pci_device_id,
-	probe:		ns83820_probe,
+	id_table:	ns83820_pci_tbl,
+	probe:		ns83820_init_one,
+	remove:		ns83820_remove_one,
 #if 0	/* FIXME: implement */
-	remove:		,
 	suspend:	,
 	resume:		,
 #endif
@@ -1395,34 +1469,16 @@
 	return pci_module_init(&driver);
 }
 
-static void ns83820_exit(void)
+static void __exit ns83820_exit(void)
 {
-	struct ns83820	*dev;
-
-	for (dev = ns83820_chain; dev; ) {
-		struct ns83820 *next = dev->next_dev;
-
-		writel(0, dev->base + IMR);	/* paranoia */
-		writel(0, dev->base + IER);
-		readl(dev->base + IER);
-
-		unregister_netdev(&dev->net_dev);
-		free_irq(dev->pci_dev->irq, dev);
-		iounmap(dev->base);
-		pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC,
-				dev->tx_descs, dev->tx_phy_descs);
-		pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC,
-				dev->rx_info.descs, dev->rx_info.phy_descs);
-		pci_disable_device(dev->pci_dev);
-		kfree(dev);
-		dev = next;
-	}
 	pci_unregister_driver(&driver);
-	ns83820_chain = NULL;
 }
 
 MODULE_AUTHOR("Benjamin LaHaise <bcrl@redhat.com>");
 MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver");
-MODULE_DEVICE_TABLE(pci, pci_device_id);
+MODULE_LICENSE("GPL");
+
+MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl);
+
 module_init(ns83820_init);
 module_exit(ns83820_exit);
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/3c574_cs.c linux/drivers/net/pcmcia/3c574_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/3c574_cs.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/pcmcia/3c574_cs.c	Sun Sep 30 12:26:07 2001
@@ -1312,6 +1312,7 @@
 
 module_init(init_3c574_cs);
 module_exit(exit_3c574_cs);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/3c589_cs.c linux/drivers/net/pcmcia/3c589_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/3c589_cs.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/pcmcia/3c589_cs.c	Sun Sep 30 12:26:07 2001
@@ -1097,3 +1097,4 @@
 
 module_init(init_3c589_cs);
 module_exit(exit_3c589_cs);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/aironet4500_cs.c linux/drivers/net/pcmcia/aironet4500_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/aironet4500_cs.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/pcmcia/aironet4500_cs.c	Sun Sep 30 12:26:07 2001
@@ -644,4 +644,4 @@
 
 module_init(aironet_cs_init);
 module_exit(aironet_cs_exit);
-
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/fmvj18x_cs.c linux/drivers/net/pcmcia/fmvj18x_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/fmvj18x_cs.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/pcmcia/fmvj18x_cs.c	Sun Sep 30 12:26:07 2001
@@ -1257,3 +1257,4 @@
     }
     restore_flags(flags);
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/ibmtr_cs.c linux/drivers/net/pcmcia/ibmtr_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/ibmtr_cs.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/pcmcia/ibmtr_cs.c	Sun Sep 30 12:26:07 2001
@@ -107,6 +107,7 @@
 MODULE_PARM(srambase, "i");
 MODULE_PARM(sramsize, "i");
 MODULE_PARM(ringspeed, "i");
+MODULE_LICENSE("GPL");
 
 /*====================================================================*/
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/netwave_cs.c linux/drivers/net/pcmcia/netwave_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/netwave_cs.c	Wed Apr 25 14:36:23 2001
+++ linux/drivers/net/pcmcia/netwave_cs.c	Sun Sep 30 12:26:07 2001
@@ -1590,3 +1590,4 @@
     writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
     writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/nmclan_cs.c linux/drivers/net/pcmcia/nmclan_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/nmclan_cs.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/pcmcia/nmclan_cs.c	Sun Sep 30 12:26:07 2001
@@ -409,6 +409,8 @@
 MODULE_PARM(if_port, "i");
 MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
+MODULE_LICENSE("GPL");
+
 
 /* ----------------------------------------------------------------------------
 Function Prototypes
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/pcnet_cs.c linux/drivers/net/pcmcia/pcnet_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/pcnet_cs.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/pcmcia/pcnet_cs.c	Sun Sep 30 12:26:07 2001
@@ -1522,3 +1522,4 @@
 
 module_init(init_pcnet_cs);
 module_exit(exit_pcnet_cs);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/ray_cs.c	Wed Apr 25 14:36:23 2001
+++ linux/drivers/net/pcmcia/ray_cs.c	Sun Sep 30 12:26:07 2001
@@ -221,6 +221,8 @@
 
 MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
 MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(irq_mask,"i");
 MODULE_PARM(net_type,"i");
 MODULE_PARM(hop_dwell,"i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/smc91c92_cs.c linux/drivers/net/pcmcia/smc91c92_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/smc91c92_cs.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/pcmcia/smc91c92_cs.c	Sun Sep 30 12:26:07 2001
@@ -85,6 +85,7 @@
 MODULE_PARM(if_port, "i");
 MODULE_PARM(irq_mask, "i");
 MODULE_PARM(irq_list, "1-4i");
+MODULE_LICENSE("GPL");
 
 /* Operational parameter that usually are not changed. */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/wavelan_cs.c linux/drivers/net/pcmcia/wavelan_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/wavelan_cs.c	Wed Apr 25 14:36:23 2001
+++ linux/drivers/net/pcmcia/wavelan_cs.c	Sun Sep 30 12:26:07 2001
@@ -4832,3 +4832,4 @@
 
 module_init(init_wavelan_cs);
 module_exit(exit_wavelan_cs);
+MODULE_LICENSE("BSD without advertisement clause");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/xirc2ps_cs.c linux/drivers/net/pcmcia/xirc2ps_cs.c
--- v2.4.10/linux/drivers/net/pcmcia/xirc2ps_cs.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/pcmcia/xirc2ps_cs.c	Sun Sep 30 12:26:07 2001
@@ -2090,3 +2090,4 @@
 
 __setup("xirc2ps_cs=", setup_xirc2ps_cs);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/xircom_cb.c linux/drivers/net/pcmcia/xircom_cb.c
--- v2.4.10/linux/drivers/net/pcmcia/xircom_cb.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/pcmcia/xircom_cb.c	Sun Sep 30 12:26:07 2001
@@ -37,6 +37,7 @@
 
 MODULE_DESCRIPTION("Xircom Cardbus ethernet driver");
 MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>");
+MODULE_LICENSE("GPL");
 
 
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcmcia/xircom_tulip_cb.c linux/drivers/net/pcmcia/xircom_tulip_cb.c
--- v2.4.10/linux/drivers/net/pcmcia/xircom_tulip_cb.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/pcmcia/xircom_tulip_cb.c	Tue Oct  9 15:59:03 2001
@@ -1,45 +1,33 @@
-/* tulip.c: A DEC 21040-family ethernet driver for Linux. */
+/* xircom_tulip_cb.c: A Xircom CBE-100 ethernet driver for Linux. */
 /*
 	Written/copyright 1994-1999 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	This driver is for the Digital "Tulip" Ethernet adapter interface.
-	It should work with most DEC 21*4*-based chips/ethercards, as well as
-	with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and ASIX.
-
 	The author may be reached as becker@scyld.com, or C/O
 	Scyld Computing Corporation
 	410 Severn Ave., Suite 210
 	Annapolis MD 21403
-
-	Support and updates available at
-	http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
 */
 
+#define DRV_NAME	"xircom_tulip_cb"
+#define DRV_VERSION	"0.91+LK"
+#define DRV_RELDATE	"July 19, 2001"
+
 #define CARDBUS 1
-static const char version[] = "xircom_tulip_cb.c:v0.91 4/14/99 becker@scyld.com (modified by danilo@cs.uni-magdeburg.de for XIRCOM CBE, fixed by Doug Ledford)\n";
 
 /* A few user-configurable values. */
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 25;
 
-#define MAX_UNITS 8
+#define MAX_UNITS 4
 /* Used to pass the full-duplex flag, etc. */
 static int full_duplex[MAX_UNITS];
 static int options[MAX_UNITS];
 static int mtu[MAX_UNITS];			/* Jumbo MTU for interfaces. */
 
-/*  The possible media types that can be set in options[] are: */
-static const char * const medianame[] = {
-	"10baseT", "10base2", "AUI", "100baseTx",
-	"10baseT-FD", "100baseTx-FD", "100baseT4", "100baseFx",
-	"100baseFx-FD", "MII 10baseT", "MII 10baseT-FD", "MII",
-	"10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FD", "MII 100baseT4",
-};
-
 /* Keep the ring sizes a power of two for efficiency.
    Making the Tx ring too large decreases the effectiveness of channel
    bonding and packet priority.
@@ -82,16 +70,14 @@
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (4*HZ)
+#define TX_TIMEOUT		(4 * HZ)
 #define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
+#define PKT_SETUP_SZ		192			/* Size of the setup frame */
 
-#if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
-#warning  You must compile this file with the correct options!
-#warning  See the last lines of the source file.
-#error You must compile this driver with "-O".
-#endif
+/* PCI registers */
+#define PCI_POWERMGMT 	0x40
 
-#include <linux/version.h>
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -99,13 +85,22 @@
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
+#include <asm/uaccess.h>
+
 
-/* Kernel compatibility defines, some common to David Hinds' PCMCIA package.
-   This is only in the support-all-kernels source code. */
+/* These identify the driver base version and may not be removed. */
+static char version[] __devinitdata =
+KERN_INFO DRV_NAME ".c derived from tulip.c:v0.91 4/14/99 becker@scyld.com\n"
+KERN_INFO " modified by danilo@cs.uni-magdeburg.de for XIRCOM CBE, fixed by Doug Ledford\n"
+KERN_INFO " unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE "\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
-MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
+MODULE_DESCRIPTION("Xircom CBE-100 ethernet driver");
+MODULE_LICENSE("GPL v2");
+
 MODULE_PARM(debug, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(rx_copybreak, "i");
@@ -115,11 +110,11 @@
 
 #define RUN_AT(x) (jiffies + (x))
 
-#define tulip_debug debug
-#ifdef TULIP_DEBUG
-static int tulip_debug = TULIP_DEBUG;
+#define xircom_debug debug
+#ifdef XIRCOM_DEBUG
+static int xircom_debug = XIRCOM_DEBUG;
 #else
-static int tulip_debug = 1;
+static int xircom_debug = 1;
 #endif
 
 /*
@@ -127,17 +122,9 @@
 
 I. Board Compatibility
 
-This device driver is designed for the DECchip "Tulip", Digital's
-single-chip ethernet controllers for PCI.  Supported members of the family
-are the 21040, 21041, 21140, 21140A, 21142, and 21143.  Similar work-alike
-chips from Lite-On, Macronics, ASIX, Compex and other listed below are also
-supported. 
-
-These chips are used on at least 140 unique PCI board designs.  The great
-number of chips and board designs supported is the reason for the
-driver size and complexity.  Almost of the increasing complexity is in the
-board configuration and media selection code.  There is very little
-increasing in the operational critical path length.
+This device driver was forked from the driver for the DECchip "Tulip",
+Digital's single-chip ethernet controllers for PCI.  It supports Xircom's
+almost-Tulip-compatible CBE-100 CardBus adapters.
 
 II. Board-specific settings
 
@@ -149,11 +136,11 @@
 
 IIIa. Ring buffers
 
-The Tulip can use either ring buffers or lists of Tx and Rx descriptors.
+The Xircom can use either ring buffers or lists of Tx and Rx descriptors.
 This driver uses statically allocated rings of Rx and Tx descriptors, set at
 compile time by RX/TX_RING_SIZE.  This version of the driver allocates skbuffs
 for the Rx ring buffers at open() time and passes the skb->data field to the
-Tulip as receive data buffers.  When an incoming frame is less than
+Xircom as receive data buffers.  When an incoming frame is less than
 RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is
 copied to the new skbuff.  When the incoming frame is larger, the skbuff is
 passed directly up the protocol stack and replaced by a newly allocated
@@ -165,7 +152,7 @@
 that we are pre-loading the cache with immediately useful header
 information).  For large frames the copying cost is non-trivial, and the
 larger copy might flush the cache of useful data.  A subtle aspect of this
-choice is that the Tulip only receives into longword aligned buffers, thus
+choice is that the Xircom only receives into longword aligned buffers, thus
 the IP header at offset 14 isn't longword aligned for further processing.
 Copied frames are put into the new skbuff at an offset of "+2", thus copying
 has the beneficial effect of aligning the IP header and preloading the
@@ -199,32 +186,8 @@
 
 IVc. Errata
 
-We cannot use MII interrupts because there is no defined GPIO pin to attach
-them.  The MII transceiver status is polled using an kernel timer.
-
 */
 
-static void tulip_timer(unsigned long data);
-
-enum tbl_flag {
-	HAS_MII=1, HAS_ACPI=2,
-};
-static struct tulip_chip_table {
-	char *chip_name;
-	int io_size;
-	int valid_intrs;			/* CSR7 interrupt enable settings */
-	int flags;
-	void (*media_timer)(unsigned long data);
-} tulip_tbl[] = {
-  { "Xircom Cardbus Adapter (DEC 21143 compatible mode)", 128, 0x0801fbff,
-       HAS_MII | HAS_ACPI, tulip_timer }, 
-  {0},
-};
-/* This matches the table above. */
-enum chips {
-	X3201_3,
-};
-
 /* A full-duplex map for media types. */
 enum MediaIs {
 	MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8,
@@ -234,75 +197,113 @@
 
 /* Offsets to the Command and Status Registers, "CSRs".  All accesses
    must be longword instructions and quadword aligned. */
-enum tulip_offsets {
+enum xircom_offsets {
 	CSR0=0,    CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
 	CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
-	CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
+	CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x04, };
 
 /* The bits in the CSR5 status registers, mostly interrupt sources. */
 enum status_bits {
-	TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10,
-	NormalIntr=0x10000, AbnormalIntr=0x8000,
-	RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
-	TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
+	LinkChange=0x08000000,
+	NormalIntr=0x10000, NormalIntrMask=0x00014045,
+	AbnormalIntr=0x8000, AbnormalIntrMask=0x0a00a5a2,
+	ReservedIntrMask=0xe0001a18,
+	EarlyRxIntr=0x4000, BusErrorIntr=0x2000,
+	EarlyTxIntr=0x400, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
+	TxFIFOUnderflow=0x20, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
+};
+
+enum csr0_control_bits {
+	EnableMWI=0x01000000, EnableMRL=0x00800000,
+	EnableMRM=0x00200000, EqualBusPrio=0x02,
+	SoftwareReset=0x01,
+};
+
+enum csr6_control_bits {
+	ReceiveAllBit=0x40000000, AllMultiBit=0x80, PromiscBit=0x40,
+	HashFilterBit=0x01, FullDuplexBit=0x0200,
+	TxThresh10=0x400000, TxStoreForw=0x200000,
+	TxThreshMask=0xc000, TxThreshShift=14,
+	EnableTx=0x2000, EnableRx=0x02,
+	ReservedZeroMask=0x8d930134, ReservedOneMask=0x320c0000,
+	EnableTxRx=(EnableTx | EnableRx),
+};
+
+
+enum tbl_flag {
+	HAS_MII=1, HAS_ACPI=2,
+};
+static struct xircom_chip_table {
+	char *chip_name;
+	int valid_intrs;			/* CSR7 interrupt enable settings */
+	int flags;
+} xircom_tbl[] = {
+  { "Xircom Cardbus Adapter (DEC 21143 compatible mode)",
+	LinkChange | NormalIntr | AbnormalIntr | BusErrorIntr |
+	RxDied | RxNoBuf | RxIntr | TxFIFOUnderflow | TxNoBuf | TxDied | TxIntr,
+	HAS_MII | HAS_ACPI, },
+  { NULL, },
+};
+/* This matches the table above. */
+enum chips {
+	X3201_3,
 };
 
-/* The Tulip Rx and Tx buffer descriptors. */
-struct tulip_rx_desc {
+
+/* The Xircom Rx and Tx buffer descriptors. */
+struct xircom_rx_desc {
 	s32 status;
 	s32 length;
 	u32 buffer1, buffer2;
 };
 
-struct tulip_tx_desc {
+struct xircom_tx_desc {
 	s32 status;
 	s32 length;
 	u32 buffer1, buffer2;				/* We use only buffer 1.  */
 };
 
-enum desc_status_bits {
-	DescOwned=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
+enum tx_desc0_status_bits {
+	Tx0DescOwned=0x80000000, Tx0DescError=0x8000, Tx0NoCarrier=0x0800,
+	Tx0LateColl=0x0200, Tx0ManyColl=0x0100, Tx0Underflow=0x02,
+};
+enum tx_desc1_status_bits {
+	Tx1ComplIntr=0x80000000, Tx1LastSeg=0x40000000, Tx1FirstSeg=0x20000000,
+	Tx1SetupPkt=0x08000000, Tx1DisableCRC=0x04000000, Tx1RingWrap=0x02000000,
+	Tx1ChainDesc=0x01000000, Tx1NoPad=0x800000, Tx1HashSetup=0x400000,
+	Tx1WholePkt=(Tx1FirstSeg | Tx1LastSeg),
+};
+enum rx_desc0_status_bits {
+	Rx0DescOwned=0x80000000, Rx0DescError=0x8000, Rx0NoSpace=0x4000,
+	Rx0Runt=0x0800, Rx0McastPkt=0x0400, Rx0FirstSeg=0x0200, Rx0LastSeg=0x0100,
+	Rx0HugeFrame=0x80, Rx0CRCError=0x02,
+	Rx0WholePkt=(Rx0FirstSeg | Rx0LastSeg),
+};
+enum rx_desc1_status_bits {
+	Rx1RingWrap=0x02000000, Rx1ChainDesc=0x01000000,
 };
 
-/* Ring-wrap flag in length field, use for last ring entry.
-	0x01000000 means chain on buffer2 address,
-	0x02000000 means use the ring start address in CSR2/3.
-   Note: Some work-alike chips do not function correctly in chained mode.
-   The ASIX chip works only in chained mode.
-   Thus we indicates ring mode, but always write the 'next' field for
-   chained mode as well.
-*/
-#define DESC_RING_WRAP 0x02000000
-
-struct tulip_private {
-	char devname[8];			/* Used only for kernel debugging. */
-	const char *product_name;
-	struct tulip_rx_desc rx_ring[RX_RING_SIZE];
-	struct tulip_tx_desc tx_ring[TX_RING_SIZE];
+struct xircom_private {
+	struct xircom_rx_desc rx_ring[RX_RING_SIZE];
+	struct xircom_tx_desc tx_ring[TX_RING_SIZE];
 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
 #ifdef CARDBUS
-	/* The X3201-3 requires double word aligned tx bufs */
+	/* The X3201-3 requires 4-byte aligned tx bufs */
 	struct sk_buff* tx_aligned_skbuff[TX_RING_SIZE];
 #endif
 	/* The addresses of receive-in-place skbuffs. */
 	struct sk_buff* rx_skbuff[RX_RING_SIZE];
-	char *rx_buffs;				/* Address of temporary Rx buffers. */
-	u8 setup_buf[96*sizeof(u16) + 7];
-	u16 *setup_frame;		/* Pseudo-Tx frame to init address table. */
+	u16 setup_frame[PKT_SETUP_SZ / sizeof(u16)];	/* Pseudo-Tx frame to init address table. */
 	int chip_id;
-	int revision;
 	struct net_device_stats stats;
-	struct timer_list timer;	/* Media selection timer. */
-	int interrupt;				/* In-interrupt flag. */
 	unsigned int cur_rx, cur_tx;		/* The next free ring entry */
 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
 	unsigned int tx_full:1;				/* The Tx queue is full. */
+	unsigned int speed100:1;
 	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
-	unsigned int full_duplex_lock:1;
+	unsigned int autoneg:1;
 	unsigned int default_port:4;		/* Last dev->if_port value. */
-	unsigned int medialock:1;			/* Don't sense media type. */
-	unsigned int mediasense:1;			/* Media sensing in progress. */
 	unsigned int open:1;
 	unsigned int csr0;					/* CSR0 setting. */
 	unsigned int csr6;					/* Current CSR6 control settings. */
@@ -316,44 +317,44 @@
 
 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 void tulip_up(struct net_device *dev);
-static void tulip_down(struct net_device *dev);
-static int tulip_open(struct net_device *dev);
-static void tulip_timer(unsigned long data);
-static void tulip_tx_timeout(struct net_device *dev);
-static void tulip_init_ring(struct net_device *dev);
-static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int tulip_rx(struct net_device *dev);
-static void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static int tulip_close(struct net_device *dev);
-static struct net_device_stats *tulip_get_stats(struct net_device *dev);
-#ifdef HAVE_PRIVATE_IOCTL
-static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-#endif
+static void xircom_up(struct net_device *dev);
+static void xircom_down(struct net_device *dev);
+static int xircom_open(struct net_device *dev);
+static void xircom_tx_timeout(struct net_device *dev);
+static void xircom_init_ring(struct net_device *dev);
+static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int xircom_rx(struct net_device *dev);
+static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static int xircom_close(struct net_device *dev);
+static struct net_device_stats *xircom_get_stats(struct net_device *dev);
+static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void set_rx_mode(struct net_device *dev);
+static void check_duplex(struct net_device *dev);
+
 
 /* The Xircom cards are picky about when certain bits in CSR6 can be
    manipulated.  Keith Owens <kaos@ocs.com.au>. */
-
-static void outl_CSR6 (u32 newcsr6, long ioaddr, int chip_idx)
+static void outl_CSR6(u32 newcsr6, long ioaddr)
 {
-	const int strict_bits = 0x0060e202;
+	const int strict_bits =
+		TxThresh10 | TxStoreForw | TxThreshMask | EnableTxRx | FullDuplexBit;
     int csr5, csr5_22_20, csr5_19_17, currcsr6, attempts = 200;
     long flags;
     save_flags(flags);
     cli();
-    newcsr6 &= 0x726cfecb; /* mask out the reserved CSR6 bits that always */
-			   /* read 0 on the Xircom cards */
-    newcsr6 |= 0x320c0000; /* or in the reserved bits that always read 1 */
+	/* mask out the reserved bits that always read 0 on the Xircom cards */
+	newcsr6 &= ~ReservedZeroMask;
+	/* or in the reserved bits that always read 1 */
+	newcsr6 |= ReservedOneMask;
     currcsr6 = inl(ioaddr + CSR6);
     if (((newcsr6 & strict_bits) == (currcsr6 & strict_bits)) ||
-	((currcsr6 & ~0x2002) == 0)) {
+	((currcsr6 & ~EnableTxRx) == 0)) {
 		outl(newcsr6, ioaddr + CSR6);	/* safe */
 		restore_flags(flags);
 		return;
     }
     /* make sure the transmitter and receiver are stopped first */
-    currcsr6 &= ~0x2002;
+    currcsr6 &= ~EnableTxRx;
     while (1) {
 		csr5 = inl(ioaddr + CSR5);
 		if (csr5 == 0xffffffff)
@@ -364,7 +365,7 @@
 			(csr5_19_17 == 0 || csr5_19_17 == 0x80000 || csr5_19_17 == 0xc0000))
 			break;  /* both are stopped or suspended */
 		if (!--attempts) {
-			printk(KERN_INFO "tulip.c: outl_CSR6 too many attempts,"
+			printk(KERN_INFO DRV_NAME ": outl_CSR6 too many attempts,"
 				   "csr5=0x%08x\n", csr5);
 			outl(newcsr6, ioaddr + CSR6);  /* unsafe but do it anyway */
 			restore_flags(flags);
@@ -377,102 +378,205 @@
     outl(newcsr6, ioaddr + CSR6);
     restore_flags(flags);
 }
-
-static struct net_device *tulip_probe1(struct pci_dev *pdev,
-				       long ioaddr, int irq,
-				       int chip_idx, int board_idx)
-{
-	static int did_version;			/* Already printed version info. */
-	struct net_device *dev;
-	struct tulip_private *tp;
-	u8 chip_rev;
-	int i;
 
-	if (tulip_debug > 0  &&  did_version++ == 0)
-		printk(KERN_INFO "%s", version);
 
-	dev = alloc_etherdev(0);
-	if (!dev)
-		return NULL;
+static void __devinit read_mac_address(struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	int i, j;
+	unsigned char tuple, link, data_id, data_count;
 
-	pci_read_config_byte(pdev, PCI_REVISION_ID, &chip_rev);
-	/* Bring the 21143 out of sleep mode.
-	   Caution: Snooze mode does not work with some boards! */
-	if (tulip_tbl[chip_idx].flags & HAS_ACPI)
-		pci_write_config_dword(pdev, 0x40, 0x00000000);
+	/* Xircom has its address stored in the CIS;
+	 * we access it through the boot rom interface for now
+	 * this might not work, as the CIS is not parsed but I
+	 * (danilo) use the offset I found on my card's CIS !!!
+	 *
+	 * Doug Ledford: I changed this routine around so that it
+	 * walks the CIS memory space, parsing the config items, and
+	 * finds the proper lan_node_id tuple and uses the data
+	 * stored there.
+	 */
+	outl(1 << 12, ioaddr + CSR9); /* enable boot rom access */
+	for (i = 0x100; i < 0x1f7; i += link+2) {
+		outl(i, ioaddr + CSR10);
+		tuple = inl(ioaddr + CSR9) & 0xff;
+		outl(i + 1, ioaddr + CSR10);
+		link = inl(ioaddr + CSR9) & 0xff;
+		outl(i + 2, ioaddr + CSR10);
+		data_id = inl(ioaddr + CSR9) & 0xff;
+		outl(i + 3, ioaddr + CSR10);
+		data_count = inl(ioaddr + CSR9) & 0xff;
+		if ( (tuple == 0x22) &&
+			 (data_id == 0x04) && (data_count == 0x06) ) {
+			/*
+			 * This is it.  We have the data we want.
+			 */
+			for (j = 0; j < 6; j++) {
+				outl(i + j + 4, ioaddr + CSR10);
+				dev->dev_addr[j] = inl(ioaddr + CSR9) & 0xff;
+			}
+			break;
+		} else if (link == 0) {
+			break;
+		}
+	}
+}
 
-	/* Stop the chip's Tx and Rx processes. */
-	outl_CSR6(inl(ioaddr + CSR6) & ~0x2002, ioaddr, chip_idx);
-	/* Clear the missed-packet counter. */
-	(volatile int)inl(ioaddr + CSR8);
 
-	/* The station address ROM is read byte serially.  The register must
-	   be polled, waiting for the value to be read bit serially from the
-	   EEPROM.
-	   */
-	if (chip_idx == X3201_3) {
-		/* Xircom has its address stored in the CIS
-		 * we access it through the boot rom interface for now
-		 * this might not work, as the CIS is not parsed but I
-		 * (danilo) use the offset I found on my card's CIS !!!
-		 * 
-		 * Doug Ledford: I changed this routine around so that it
-		 * walks the CIS memory space, parsing the config items, and
-		 * finds the proper lan_node_id tuple and uses the data
-		 * stored there.
-		 */
-		unsigned char j, tuple, link, data_id, data_count;
-		outl(1<<12, ioaddr + CSR9); /* enable boot rom access */
-		for (i = 0x100; i < 0x1f7; i += link+2) {
-			outl(i, ioaddr + CSR10);
-			tuple = inl(ioaddr + CSR9) & 0xff;
-			outl(i + 1, ioaddr + CSR10);
-			link = inl(ioaddr + CSR9) & 0xff;
-			outl(i + 2, ioaddr + CSR10);
-			data_id = inl(ioaddr + CSR9) & 0xff;
-			outl(i + 3, ioaddr + CSR10);
-			data_count = inl(ioaddr + CSR9) & 0xff;
-			if ( (tuple == 0x22) &&
-				 (data_id == 0x04) && (data_count == 0x06) ) {
-				/*
-				 * This is it.  We have the data we want.
-				 */
-				for (j = 0; j < 6; j++) {
-					outl(i + j + 4, ioaddr + CSR10);
-					dev->dev_addr[j] = inl(ioaddr + CSR9) & 0xff;
-				}
-				break;
-			} else if (link == 0) {
-				break;
+/*
+ * locate the MII interfaces and initialize them.
+ */
+static void find_mii_transceivers(struct net_device *dev)
+{
+	struct xircom_private *tp = dev->priv;
+	int phy, phy_idx;
+
+	/* Find the connected MII xcvrs.
+	   Doing this in open() would allow detecting external xcvrs later,
+	   but takes much time. */
+	for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) {
+		int mii_status = mdio_read(dev, phy, MII_BMSR);
+		if ((mii_status & (BMSR_100BASE4 | BMSR_100HALF | BMSR_10HALF)) == BMSR_100BASE4 ||
+			((mii_status & BMSR_100BASE4) == 0 &&
+			 (mii_status & (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL | BMSR_10HALF)) != 0)) {
+			int mii_reg0 = mdio_read(dev, phy, MII_BMCR);
+			int mii_advert = mdio_read(dev, phy, MII_ADVERTISE);
+			int reg4 = ((mii_status >> 6) & tp->to_advertise) | ADVERTISE_CSMA;
+			tp->phys[phy_idx] = phy;
+			tp->advertising[phy_idx++] = reg4;
+			printk(KERN_INFO "%s:  MII transceiver #%d "
+				   "config %4.4x status %4.4x advertising %4.4x.\n",
+				   dev->name, phy, mii_reg0, mii_status, mii_advert);
+			/* Fixup for DLink with miswired PHY. */
+			if (mii_advert != reg4) {
+				printk(KERN_DEBUG "%s:  Advertising %4.4x on PHY %d,"
+					   " previously advertising %4.4x.\n",
+					   dev->name, reg4, phy, mii_advert);
+				mdio_write(dev, phy, MII_ADVERTISE, reg4);
 			}
+			/* Enable autonegotiation: some boards default to off. */
+			mdio_write(dev, phy, MII_BMCR, mii_reg0 | BMCR_ANENABLE |
+					   (tp->full_duplex ? BMCR_FULLDPLX : 0) |
+					   (media_cap[tp->default_port]&MediaIs100 ? BMCR_SPEED100 : 0));
 		}
 	}
+	tp->mii_cnt = phy_idx;
+	if (phy_idx == 0) {
+		printk(KERN_INFO "%s: ***WARNING***: No MII transceiver found!\n",
+			   dev->name);
+		tp->phys[0] = 0;
+	}
+}
 
-	/* We do a request_region() only to register /proc/ioports info. */
-	request_region(ioaddr, tulip_tbl[chip_idx].io_size, "xircom_tulip_cb");
+
+/*
+ * To quote Arjan van de Ven:
+ *   tranceiver_voodoo() enables the external UTP plug thingy.
+ *   it's called voodoo as I stole this code and cannot cross-reference
+ *   it with the specification.
+ * Actually it seems to go like this:
+ * - GPIO2 enables the MII itself so we can talk to it. The MII gets reset
+ *   so any prior MII settings are lost.
+ * - GPIO0 enables the TP port so the MII can talk to the network.
+ * - a software reset will reset both GPIO pins.
+ * I also moved the software reset here, because doing it in xircom_up()
+ * required enabling the GPIO pins each time, which reset the MII each time.
+ * Thus we couldn't control the MII -- which sucks because we don't know
+ * how to handle full-duplex modes so we *must* disable them.
+ */
+static void transceiver_voodoo(struct net_device *dev)
+{
+	struct xircom_private *tp = dev->priv;
+	long ioaddr = dev->base_addr;
+
+	/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
+	outl(SoftwareReset, ioaddr + CSR0);
+	udelay(2);
+
+	/* Deassert reset. */
+	outl(tp->csr0, ioaddr + CSR0);
+
+	/* Reset the xcvr interface and turn on heartbeat. */
+	outl(0x0008, ioaddr + CSR15);
+	udelay(5);  /* The delays are Xircom-recommended to give the
+				 * chipset time to reset the actual hardware
+				 * on the PCMCIA card
+				 */
+	outl(0xa8050000, ioaddr + CSR15);
+	udelay(5);
+	outl(0xa00f0000, ioaddr + CSR15);
+	udelay(5);
+
+	outl_CSR6(0, ioaddr);
+	//outl_CSR6(FullDuplexBit, ioaddr);
+}
+
+
+static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct net_device *dev;
+	struct xircom_private *tp;
+	static int board_idx = -1;
+	int chip_idx = id->driver_data;
+	long ioaddr;
+	int i;
+	u8 chip_rev;
+
+/* when built into the kernel, we only print version if device is found */
+#ifndef MODULE
+	static int printed_version;
+	if (!printed_version++)
+		printk(version);
+#endif
+
+	printk(KERN_INFO "xircom_init_one(%s)\n", pdev->slot_name);
+
+	board_idx++;
+
+	if (pci_enable_device(pdev))
+		return -ENODEV;
+
+	pci_set_master(pdev);
+
+	ioaddr = pci_resource_start(pdev, 0);
+	dev = alloc_etherdev(sizeof(*tp));
+	if (!dev) {
+		printk (KERN_ERR DRV_NAME "%d: cannot alloc etherdev, aborting\n", board_idx);
+		return -ENOMEM;
+	}
+	SET_MODULE_OWNER(dev);
 
 	dev->base_addr = ioaddr;
-	dev->irq = irq;
+	dev->irq = pdev->irq;
 
-	/* Make certain the data structures are quadword aligned. */
-	tp = (void *)(((long)kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA) + 7) & ~7);
-	memset(tp, 0, sizeof(*tp));
-	dev->priv = tp;
+	if (pci_request_regions(pdev, dev->name)) {
+		printk (KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", board_idx);
+		goto err_out_free_netdev;
+	}
+
+	/* Bring the chip out of sleep mode.
+	   Caution: Snooze mode does not work with some boards! */
+	if (xircom_tbl[chip_idx].flags & HAS_ACPI)
+		pci_write_config_dword(pdev, PCI_POWERMGMT, 0);
+
+	/* Stop the chip's Tx and Rx processes. */
+	outl_CSR6(inl(ioaddr + CSR6) & ~EnableTxRx, ioaddr);
+	/* Clear the missed-packet counter. */
+	(volatile int)inl(ioaddr + CSR8);
+
+	tp = dev->priv;
 
 	tp->lock = SPIN_LOCK_UNLOCKED;
 	tp->pdev = pdev;
 	tp->chip_id = chip_idx;
-	tp->revision = chip_rev;
-	tp->csr0 = csr0;
-	tp->setup_frame = (u16 *)(((unsigned long)tp->setup_buf + 7) & ~7);
-
-	/* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles.
-	   And the ASIX must have a burst limit or horrible things happen. */
-	if (chip_idx == X3201_3)
-		tp->csr0 &= ~0x01000000;
+	/* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles. */
+	/* XXX: is this necessary for Xircom? */
+	tp->csr0 = csr0 & ~EnableMWI;
+
+	pci_set_drvdata(pdev, dev);
 
 	/* The lower four bits are the media type. */
-	if (board_idx >= 0  &&  board_idx < MAX_UNITS) {
+	if (board_idx >= 0 && board_idx < MAX_UNITS) {
 		tp->default_port = options[board_idx] & 15;
 		if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0)
 			tp->full_duplex = 1;
@@ -482,104 +586,58 @@
 	if (dev->mem_start)
 		tp->default_port = dev->mem_start;
 	if (tp->default_port) {
-		tp->medialock = 1;
 		if (media_cap[tp->default_port] & MediaAlwaysFD)
 			tp->full_duplex = 1;
 	}
 	if (tp->full_duplex)
-		tp->full_duplex_lock = 1;
-
-	if (media_cap[tp->default_port] & MediaIsMII) {
-		u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
-		tp->to_advertise = media2advert[tp->default_port - 9];
-	} else
-		tp->to_advertise = 0x03e1;
-
-	if (tulip_tbl[chip_idx].flags & HAS_MII) {
-		int phy, phy_idx;
-		/* Find the connected MII xcvrs.
-		   Doing this in open() would allow detecting external xcvrs later,
-		   but takes much time. */
-		for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
-			 phy++) {
-			int mii_status = mdio_read(dev, phy, 1);
-			if ((mii_status & 0x8301) == 0x8001 ||
-				((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {
-				int mii_reg0 = mdio_read(dev, phy, 0);
-				int mii_advert = mdio_read(dev, phy, 4);
-				int reg4 = ((mii_status>>6) & tp->to_advertise) | 1;
-				tp->phys[phy_idx] = phy;
-				tp->advertising[phy_idx++] = reg4;
-				printk(KERN_INFO "xircom(%s):  MII transceiver #%d "
-					   "config %4.4x status %4.4x advertising %4.4x.\n",
-					   pdev->slot_name, phy, mii_reg0, mii_status, mii_advert);
-				/* Fixup for DLink with miswired PHY. */
-				if (mii_advert != reg4) {
-					printk(KERN_DEBUG "xircom(%s):  Advertising %4.4x on PHY %d,"
-						   " previously advertising %4.4x.\n",
-						   pdev->slot_name, reg4, phy, mii_advert);
-					mdio_write(dev, phy, 4, reg4);
-				}
-				/* Enable autonegotiation: some boards default to off. */
-				mdio_write(dev, phy, 0, mii_reg0 |
-						   (tp->full_duplex ? 0x1100 : 0x1000) |
-						   (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));
-			}
-		}
-		tp->mii_cnt = phy_idx;
-		if (phy_idx == 0) {
-			printk(KERN_INFO "xircom(%s): ***WARNING***: No MII transceiver found!\n",
-			       pdev->slot_name);
-			tp->phys[0] = 1;
-		}
-	}
+		tp->autoneg = 0;
+	else
+		tp->autoneg = 1;
+	tp->speed100 = 1;
 
-	/* The Tulip-specific entries in the device structure. */
-	dev->open = &tulip_open;
-	dev->hard_start_xmit = &tulip_start_xmit;
-	dev->stop = &tulip_close;
-	dev->get_stats = &tulip_get_stats;
-#ifdef HAVE_PRIVATE_IOCTL
-	dev->do_ioctl = &private_ioctl;
-#endif
+	/* The Xircom-specific entries in the device structure. */
+	dev->open = &xircom_open;
+	dev->hard_start_xmit = &xircom_start_xmit;
+	dev->stop = &xircom_close;
+	dev->get_stats = &xircom_get_stats;
+	dev->do_ioctl = &xircom_ioctl;
 #ifdef HAVE_MULTICAST
 	dev->set_multicast_list = &set_rx_mode;
 #endif
-	dev->tx_timeout = tulip_tx_timeout;
+	dev->tx_timeout = xircom_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
-	/* Reset the xcvr interface and turn on heartbeat. */
-	switch (chip_idx) {
-	case X3201_3:
-		outl(0x0008, ioaddr + CSR15);
-		udelay(5);  /* The delays are Xircom recommended to give the
-					 * chipset time to reset the actual hardware
-					 * on the PCMCIA card
-					 */
-		outl(0xa8050000, ioaddr + CSR15);
-		udelay(5);
-		outl(0xa00f0000, ioaddr + CSR15);
-		udelay(5);
-		outl_CSR6(0x32000200, ioaddr, chip_idx);
-		break;
-	}
-
-	if (register_netdev(dev)) {
-		request_region(ioaddr, tulip_tbl[chip_idx].io_size, "xircom_tulip_cb");
-		kfree(dev->priv);
-		kfree(dev);
-		return NULL;
-	}
+	transceiver_voodoo(dev);
+
+	read_mac_address(dev);
 
+	if (register_netdev(dev))
+		goto err_out_cleardev;
+
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &chip_rev);
 	printk(KERN_INFO "%s: %s rev %d at %#3lx,",
-	       dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
+	       dev->name, xircom_tbl[chip_idx].chip_name, chip_rev, ioaddr);
 	for (i = 0; i < 6; i++)
 		printk("%c%2.2X", i ? ':' : ' ', dev->dev_addr[i]);
-	printk(", IRQ %d.\n", irq);
+	printk(", IRQ %d.\n", dev->irq);
 
-	return dev;
+	if (xircom_tbl[chip_idx].flags & HAS_MII) {
+		find_mii_transceivers(dev);
+		check_duplex(dev);
+	}
+
+	return 0;
+
+err_out_cleardev:
+	pci_set_drvdata(pdev, NULL);
+	pci_release_regions(pdev);
+err_out_free_netdev:
+	unregister_netdev(dev);
+	kfree(dev);
+	return -ENODEV;
 }
 
+
 /* MII transceiver control section.
    Read and write the MII registers using software-generated serial
    MDIO protocol.  See the MII specifications or DP83840A data sheet
@@ -635,10 +693,11 @@
 	return (retval>>1) & 0xffff;
 }
 
+
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
 	int i;
-	int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+	int cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
 	long ioaddr = dev->base_addr;
 	long mdio_addr = ioaddr + CSR9;
 
@@ -667,58 +726,23 @@
 	return;
 }
 
+
 static void
-tulip_up(struct net_device *dev)
+xircom_up(struct net_device *dev)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	long ioaddr = dev->base_addr;
 	int i;
 
-	/* On some chip revs we must set the MII/SYM port before the reset!? */
-	if (tp->mii_cnt)
-		outl_CSR6(0x00040000, ioaddr, tp->chip_id);
-
-	/* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
-	outl(0x00000001, ioaddr + CSR0);
-
-	/* Deassert reset. */
-	outl(tp->csr0, ioaddr + CSR0);
-	udelay(2);
-
-	if (tulip_tbl[tp->chip_id].flags & HAS_ACPI)
-		pci_write_config_dword(tp->pdev, 0x40, 0x00000000);
-
 	/* Clear the tx ring */
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		tp->tx_skbuff[i] = 0;
-		tp->tx_ring[i].status = 0x00000000;
+		tp->tx_ring[i].status = 0;
 	}
 
-	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: tulip_open() irq %d.\n", dev->name, dev->irq);
+	if (xircom_debug > 1)
+		printk(KERN_DEBUG "%s: xircom_up() irq %d.\n", dev->name, dev->irq);
 
-	{ /* X3201_3 */
-		u16 *eaddrs = (u16 *)dev->dev_addr;
-		u16 *setup_frm = &tp->setup_frame[0*6];
-		
-		/* fill the table with the broadcast address */
-		memset(tp->setup_frame, 0xff, 96*sizeof(u16));
-		/* re-fill the first 14 table entries with our address */
-		for(i=0; i<14; i++) {
-			*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
-			*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
-			*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
-		}
-
-		/* Put the setup frame on the Tx list. */
-		tp->tx_ring[tp->cur_tx].length = 0x68000000 | 192;
-		/* Lie about the address of our setup frame to make the */
-		/* chip happy */
-		tp->tx_ring[tp->cur_tx].buffer1 = virt_to_bus(tp->setup_frame);
-		tp->tx_ring[tp->cur_tx].status = DescOwned;
-
-		tp->cur_tx++;
-	}
 	outl(virt_to_bus(tp->rx_ring), ioaddr + CSR3);
 	outl(virt_to_bus(tp->tx_ring), ioaddr + CSR4);
 
@@ -726,153 +750,65 @@
 	if (dev->if_port == 0)
 		dev->if_port = tp->default_port;
 
-	/* Allow selecting a default media. */
-	tp->csr6 = 0;
-	if (tp->chip_id == X3201_3) {
-		outl(0x0008, ioaddr + CSR15);
-		udelay(5);
-		outl(0xa8050000, ioaddr + CSR15);
-		udelay(5);
-		outl(0xa00f0000, ioaddr + CSR15); 
-		udelay(5);
-		tp->csr6  = 0x32400000;
-	}
+	tp->csr6 = TxThresh10 /*| FullDuplexBit*/;						/* XXX: why 10 and not 100? */
+
+	set_rx_mode(dev);
+
 	/* Start the chip's Tx to process setup frame. */
-	outl_CSR6(tp->csr6, ioaddr, tp->chip_id);
-	outl_CSR6(tp->csr6 | 0x2000, ioaddr, tp->chip_id);
+	outl_CSR6(tp->csr6, ioaddr);
+	outl_CSR6(tp->csr6 | EnableTx, ioaddr);
 
+	/* Acknowledge all outstanding interrupts sources */
+	outl(xircom_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
 	/* Enable interrupts by setting the interrupt mask. */
-	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
-	outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
-	outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
-	outl(0, ioaddr + CSR2);		/* Rx poll demand */
-	
+	outl(xircom_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+	/* Enable Rx */
+	outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
+	/* Rx poll demand */
+	outl(0, ioaddr + CSR2);
+
+	/* Tell the net layer we're ready */
 	netif_start_queue (dev);
 
-	if (tulip_debug > 2) {
-		printk(KERN_DEBUG "%s: Done tulip_open(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
+	if (xircom_debug > 2) {
+		printk(KERN_DEBUG "%s: Done xircom_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
 			   dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5),
 			   inl(ioaddr + CSR6));
 	}
-	/* Set the timer to switch to check for link beat and perhaps switch
-	   to an alternate media type. */
-	init_timer(&tp->timer);
-	tp->timer.expires = RUN_AT(5*HZ);
-	tp->timer.data = (unsigned long)dev;
-	tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
-	add_timer(&tp->timer);
 }
 
+
 static int
-tulip_open(struct net_device *dev)
+xircom_open(struct net_device *dev)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 
-	if (request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev))
+	if (request_irq(dev->irq, &xircom_interrupt, SA_SHIRQ, dev->name, dev))
 		return -EAGAIN;
 
-	tulip_init_ring(dev);
+	xircom_init_ring(dev);
 
-	tulip_up(dev);
+	xircom_up(dev);
 	tp->open = 1;
-	MOD_INC_USE_COUNT;
-
-	return 0;
-}
-
-/*
-  Check the MII negotiated duplex, and change the CSR6 setting if
-  required.
-  Return 0 if everything is OK.
-  Return < 0 if the transceiver is missing or has no link beat.
-  */
-#if 0
-static int check_duplex(struct net_device *dev)
-{
-	long ioaddr = dev->base_addr;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	int mii_reg1, mii_reg5, negotiated, duplex;
 
-	if (tp->full_duplex_lock)
-		return 0;
-	mii_reg1 = mdio_read(dev, tp->phys[0], 1);
-	mii_reg5 = mdio_read(dev, tp->phys[0], 5);
-	if (tulip_debug > 1)
-		printk(KERN_INFO "%s: MII status %4.4x, Link partner report "
-			   "%4.4x.\n", dev->name, mii_reg1, mii_reg5);
-	if (mii_reg1 == 0xffff)
-		return -2;
-	if ((mii_reg1 & 0x0004) == 0) {
-		int new_reg1 = mdio_read(dev, tp->phys[0], 1);
-		if ((new_reg1 & 0x0004) == 0) {
-			if (tulip_debug  > 1)
-				printk(KERN_INFO "%s: No link beat on the MII interface,"
-					   " status %4.4x.\n", dev->name, new_reg1);
-			return -1;
-		}
-	}
-	negotiated = mii_reg5 & tp->advertising[0];
-	duplex = ((negotiated & 0x0300) == 0x0100
-			  || (negotiated & 0x00C0) == 0x0040);
-	/* 100baseTx-FD  or  10T-FD, but not 100-HD */
-	if (tp->full_duplex != duplex) {
-		tp->full_duplex = duplex;
-		if (tp->full_duplex) tp->csr6 |= 0x0200;
-		else				 tp->csr6 &= ~0x0200;
-		outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id);
-		outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
-		if (tulip_debug > 0)
-			printk(KERN_INFO "%s: Setting %s-duplex based on MII"
-				   "#%d link partner capability of %4.4x.\n",
-				   dev->name, tp->full_duplex ? "full" : "half",
-				   tp->phys[0], mii_reg5);
-	}
 	return 0;
 }
-#endif
-
-static void tulip_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	long ioaddr = dev->base_addr;
-	u32 csr12 = inl(ioaddr + CSR12);
-	int next_tick = 2*HZ;
-
-	if (tulip_debug > 2) {
-		printk(KERN_DEBUG "%s: Media selection tick, status %8.8x mode %8.8x "
-			   "SIA %8.8x %8.8x %8.8x %8.8x.\n",
-			   dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR6),
-			   csr12, inl(ioaddr + CSR13),
-			   inl(ioaddr + CSR14), inl(ioaddr + CSR15));
-	}
 
-	/* Not much that can be done.
-	   Assume this a generic MII or SYM transceiver. */
-	next_tick = 60*HZ;
-	if (tulip_debug > 2)
-		printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "
-		       "CSR12 0x%2.2x.\n",
-		       dev->name, inl(ioaddr + CSR6), csr12 & 0xff);
-
-	tp->timer.expires = RUN_AT(next_tick);
-	add_timer(&tp->timer);
-}
 
-static void tulip_tx_timeout(struct net_device *dev)
+static void xircom_tx_timeout(struct net_device *dev)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	long ioaddr = dev->base_addr;
 
 	if (media_cap[dev->if_port] & MediaIsMII) {
 		/* Do nothing -- the media monitor should handle this. */
-		if (tulip_debug > 1)
+		if (xircom_debug > 1)
 			printk(KERN_WARNING "%s: Transmit timeout using MII device.\n",
 				   dev->name);
 	}
 
 #if defined(way_too_many_messages)
-	if (tulip_debug > 3) {
+	if (xircom_debug > 3) {
 		int i;
 		for (i = 0; i < RX_RING_SIZE; i++) {
 			u8 *buf = (u8 *)(tp->rx_ring[i].buffer1);
@@ -898,9 +834,9 @@
 	}
 #endif
 
-	/* Stop and restart the chip's Tx processes . */
-	outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id);
-	outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
+	/* Stop and restart the chip's Tx/Rx processes . */
+	outl_CSR6(tp->csr6 | EnableRx, ioaddr);
+	outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
 	/* Trigger an immediate transmit demand. */
 	outl(0, ioaddr + CSR1);
 
@@ -909,10 +845,11 @@
 	tp->stats.tx_errors++;
 }
 
+
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void tulip_init_ring(struct net_device *dev)
+static void xircom_init_ring(struct net_device *dev)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	int i;
 
 	tp->tx_full = 0;
@@ -920,13 +857,13 @@
 	tp->dirty_rx = tp->dirty_tx = 0;
 
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		tp->rx_ring[i].status = 0x00000000;
+		tp->rx_ring[i].status = 0;
 		tp->rx_ring[i].length = PKT_BUF_SZ;
 		tp->rx_ring[i].buffer2 = virt_to_bus(&tp->rx_ring[i+1]);
 		tp->rx_skbuff[i] = NULL;
 	}
 	/* Mark the last entry as wrapping the ring. */
-	tp->rx_ring[i-1].length = PKT_BUF_SZ | DESC_RING_WRAP;
+	tp->rx_ring[i-1].length = PKT_BUF_SZ | Rx1RingWrap;
 	tp->rx_ring[i-1].buffer2 = virt_to_bus(&tp->rx_ring[0]);
 
 	for (i = 0; i < RX_RING_SIZE; i++) {
@@ -938,7 +875,7 @@
 		if (skb == NULL)
 			break;
 		skb->dev = dev;			/* Mark as being used by this device. */
-		tp->rx_ring[i].status = DescOwned;	/* Owned by Tulip chip */
+		tp->rx_ring[i].status = Rx0DescOwned;	/* Owned by Xircom chip */
 		tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail);
 	}
 	tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -947,7 +884,7 @@
 	   do need to clear the ownership bit. */
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		tp->tx_skbuff[i] = 0;
-		tp->tx_ring[i].status = 0x00000000;
+		tp->tx_ring[i].status = 0;
 		tp->tx_ring[i].buffer2 = virt_to_bus(&tp->tx_ring[i+1]);
 #ifdef CARDBUS
 		if (tp->chip_id == X3201_3)
@@ -957,10 +894,11 @@
 	tp->tx_ring[i-1].buffer2 = virt_to_bus(&tp->tx_ring[0]);
 }
 
+
 static int
-tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
+xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	int entry;
 	u32 flag;
 
@@ -980,21 +918,21 @@
 		tp->tx_ring[entry].buffer1 = virt_to_bus(skb->data);
 
 	if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
-		flag = 0x60000000; /* No interrupt */
+		flag = Tx1WholePkt; /* No interrupt */
 	} else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) {
-		flag = 0xe0000000; /* Tx-done intr. */
+		flag = Tx1WholePkt | Tx1ComplIntr; /* Tx-done intr. */
 	} else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) {
-		flag = 0x60000000; /* No Tx-done intr. */
+		flag = Tx1WholePkt; /* No Tx-done intr. */
 	} else {
 		/* Leave room for set_rx_mode() to fill entries. */
-		flag = 0xe0000000; /* Tx-done intr. */
+		flag = Tx1WholePkt | Tx1ComplIntr; /* Tx-done intr. */
 		tp->tx_full = 1;
 	}
-	if (entry == TX_RING_SIZE-1)
-		flag |= 0xe0000000 | DESC_RING_WRAP;
+	if (entry == TX_RING_SIZE - 1)
+		flag |= Tx1WholePkt | Tx1ComplIntr | Tx1RingWrap;
 
 	tp->tx_ring[entry].length = skb->len | flag;
-	tp->tx_ring[entry].status = DescOwned;	/* Pass ownership to the chip. */
+	tp->tx_ring[entry].status = Tx0DescOwned;	/* Pass ownership to the chip. */
 	tp->cur_tx++;
 	if (tp->tx_full)
 		netif_stop_queue (dev);
@@ -1009,12 +947,102 @@
 	return 0;
 }
 
+
+static void xircom_media_change(struct net_device *dev)
+{
+	struct xircom_private *tp = dev->priv;
+	long ioaddr = dev->base_addr;
+	u16 reg0, reg1, reg4, reg5;
+	u32 csr6 = inl(ioaddr + CSR6), newcsr6;
+
+	/* reset status first */
+	mdio_read(dev, tp->phys[0], MII_BMCR);
+	mdio_read(dev, tp->phys[0], MII_BMSR);
+
+	reg0 = mdio_read(dev, tp->phys[0], MII_BMCR);
+	reg1 = mdio_read(dev, tp->phys[0], MII_BMSR);
+
+	if (reg1 & BMSR_LSTATUS) {
+		/* link is up */
+		if (reg0 & BMCR_ANENABLE) {
+			/* autonegotiation is enabled */
+			reg4 = mdio_read(dev, tp->phys[0], MII_ADVERTISE);
+			reg5 = mdio_read(dev, tp->phys[0], MII_LPA);
+			if (reg4 & ADVERTISE_100FULL && reg5 & LPA_100FULL) {
+				tp->speed100 = 1;
+				tp->full_duplex = 1;
+			} else if (reg4 & ADVERTISE_100HALF && reg5 & LPA_100HALF) {
+				tp->speed100 = 1;
+				tp->full_duplex = 0;
+			} else if (reg4 & ADVERTISE_10FULL && reg5 & LPA_10FULL) {
+				tp->speed100 = 0;
+				tp->full_duplex = 1;
+			} else {
+				tp->speed100 = 0;
+				tp->full_duplex = 0;
+			}
+		} else {
+			/* autonegotiation is disabled */
+			if (reg0 & BMCR_SPEED100)
+				tp->speed100 = 1;
+			else
+				tp->speed100 = 0;
+			if (reg0 & BMCR_FULLDPLX)
+				tp->full_duplex = 1;
+			else
+				tp->full_duplex = 0;
+		}
+		printk(KERN_DEBUG "%s: Link is up, running at %sMbit %s-duplex\n",
+		       dev->name,
+		       tp->speed100 ? "100" : "10",
+		       tp->full_duplex ? "full" : "half");
+		newcsr6 = csr6 & ~FullDuplexBit;
+		if (tp->full_duplex)
+			newcsr6 |= FullDuplexBit;
+		if (newcsr6 != csr6)
+			outl_CSR6(newcsr6, ioaddr + CSR6);
+	} else {
+		printk(KERN_DEBUG "%s: Link is down\n", dev->name);
+	}
+}
+
+
+static void check_duplex(struct net_device *dev)
+{
+	struct xircom_private *tp = dev->priv;
+	u16 reg0;
+
+	mdio_write(dev, tp->phys[0], MII_BMCR, BMCR_RESET);
+	udelay(500);
+	while (mdio_read(dev, tp->phys[0], MII_BMCR) & BMCR_RESET);
+
+	reg0 = mdio_read(dev, tp->phys[0], MII_BMCR);
+	mdio_write(dev, tp->phys[0], MII_ADVERTISE, tp->advertising[0]);
+
+	if (tp->autoneg) {
+		reg0 &= ~(BMCR_SPEED100 | BMCR_FULLDPLX);
+		reg0 |= BMCR_ANENABLE | BMCR_ANRESTART;
+	} else {
+		reg0 &= ~(BMCR_ANENABLE | BMCR_ANRESTART);
+		if (tp->speed100)
+			reg0 |= BMCR_SPEED100;
+		if (tp->full_duplex)
+			reg0 |= BMCR_FULLDPLX;
+		printk(KERN_DEBUG "%s: Link forced to %sMbit %s-duplex\n",
+		       dev->name,
+		       tp->speed100 ? "100" : "10",
+		       tp->full_duplex ? "full" : "half");
+	}
+	mdio_write(dev, tp->phys[0], MII_BMCR, reg0);
+}
+
+
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
-	struct net_device *dev = (struct net_device *)dev_instance;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct net_device *dev = dev_instance;
+	struct xircom_private *tp = dev->priv;
 	long ioaddr = dev->base_addr;
 	int csr5, work_budget = max_interrupt_work;
 
@@ -1025,7 +1053,7 @@
 		/* Acknowledge all of the current interrupt sources ASAP. */
 		outl(csr5 & 0x0001ffff, ioaddr + CSR5);
 
-		if (tulip_debug > 4)
+		if (xircom_debug > 4)
 			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
 				   dev->name, csr5, inl(dev->base_addr + CSR5));
 
@@ -1036,7 +1064,7 @@
 			break;
 
 		if (csr5 & (RxIntr | RxNoBuf))
-			work_budget -= tulip_rx(dev);
+			work_budget -= xircom_rx(dev);
 
 		if (csr5 & (TxNoBuf | TxDied | TxIntr)) {
 			unsigned int dirty_tx;
@@ -1052,27 +1080,24 @@
 				if (tp->tx_skbuff[entry] == NULL)
 				  continue;
 
-				if (status & 0x8000) {
+				if (status & Tx0DescError) {
 					/* There was an major error, log it. */
 #ifndef final_version
-					if (tulip_debug > 1)
+					if (xircom_debug > 1)
 						printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
 							   dev->name, status);
 #endif
 					tp->stats.tx_errors++;
-					if (status & 0x4104) tp->stats.tx_aborted_errors++;
-					if (status & 0x0C00) tp->stats.tx_carrier_errors++;
-					if (status & 0x0200) tp->stats.tx_window_errors++;
-					if (status & 0x0002) tp->stats.tx_fifo_errors++;
-					if ((status & 0x0080) && tp->full_duplex == 0)
-						tp->stats.tx_heartbeat_errors++;
+					if (status & Tx0ManyColl) {
+						tp->stats.tx_aborted_errors++;
 #ifdef ETHER_STATS
-					if (status & 0x0100) tp->stats.collisions16++;
+						tp->stats.collisions16++;
 #endif
+					}
+					if (status & Tx0NoCarrier) tp->stats.tx_carrier_errors++;
+					if (status & Tx0LateColl) tp->stats.tx_window_errors++;
+					if (status & Tx0Underflow) tp->stats.tx_fifo_errors++;
 				} else {
-#ifdef ETHER_STATS
-					if (status & 0x0001) tp->stats.tx_deferred++;
-#endif
 					tp->stats.tx_bytes += tp->tx_ring[entry].length & 0x7ff;
 					tp->stats.collisions += (status >> 3) & 15;
 					tp->stats.tx_packets++;
@@ -1091,11 +1116,11 @@
 			}
 #endif
 
-			if (tp->tx_full && 
+			if (tp->tx_full &&
 			    tp->cur_tx - dirty_tx  < TX_RING_SIZE - 2)
 				/* The ring is no longer full */
 				tp->tx_full = 0;
-			
+
 			if (tp->tx_full)
 				netif_stop_queue (dev);
 			else
@@ -1103,104 +1128,92 @@
 
 			tp->dirty_tx = dirty_tx;
 			if (csr5 & TxDied) {
-				if (tulip_debug > 2)
+				if (xircom_debug > 2)
 					printk(KERN_WARNING "%s: The transmitter stopped."
 						   "  CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
 						   dev->name, csr5, inl(ioaddr + CSR6), tp->csr6);
-				outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id);
-				outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
+				outl_CSR6(tp->csr6 | EnableRx, ioaddr);
+				outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
 			}
 		}
 
 		/* Log errors. */
 		if (csr5 & AbnormalIntr) {	/* Abnormal error summary bit. */
-			if (csr5 == 0xffffffff)
-				break;
-			if (csr5 & TxJabber) tp->stats.tx_errors++;
+			if (csr5 & LinkChange)
+				xircom_media_change(dev);
 			if (csr5 & TxFIFOUnderflow) {
-				if ((tp->csr6 & 0xC000) != 0xC000)
-					tp->csr6 += 0x4000;	/* Bump up the Tx threshold */
+				if ((tp->csr6 & TxThreshMask) != TxThreshMask)
+					tp->csr6 += (1 << TxThreshShift);	/* Bump up the Tx threshold */
 				else
-					tp->csr6 |= 0x00200000;  /* Store-n-forward. */
+					tp->csr6 |= TxStoreForw;  /* Store-n-forward. */
 				/* Restart the transmit process. */
-				outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id);
-				outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
+				outl_CSR6(tp->csr6 | EnableRx, ioaddr);
+				outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
 			}
 			if (csr5 & RxDied) {		/* Missed a Rx frame. */
 				tp->stats.rx_errors++;
 				tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
-				outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id);
-			}
-			if (csr5 & TimerInt) {
-				if (tulip_debug > 2)
-					printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
-						   dev->name, csr5);
-				outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+				outl_CSR6(tp->csr6 | EnableTxRx, ioaddr);
 			}
 			/* Clear all error sources, included undocumented ones! */
 			outl(0x0800f7ba, ioaddr + CSR5);
 		}
 		if (--work_budget < 0) {
-			if (tulip_debug > 1)
+			if (xircom_debug > 1)
 				printk(KERN_WARNING "%s: Too much work during an interrupt, "
 					   "csr5=0x%8.8x.\n", dev->name, csr5);
 			/* Acknowledge all interrupt sources. */
 			outl(0x8001ffff, ioaddr + CSR5);
-#ifdef notdef
-			/* Clear all but standard interrupt sources. */
-			outl((~csr5) & 0x0001ebef, ioaddr + CSR7);
-#endif
 			break;
 		}
 	} while (1);
 
-	if (tulip_debug > 3)
+	if (xircom_debug > 3)
 		printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
 			   dev->name, inl(ioaddr + CSR5));
 
 	spin_unlock (&tp->lock);
 }
 
+
 static int
-tulip_rx(struct net_device *dev)
+xircom_rx(struct net_device *dev)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	int entry = tp->cur_rx % RX_RING_SIZE;
 	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
 	int work_done = 0;
 
-	if (tulip_debug > 4)
-		printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
+	if (xircom_debug > 4)
+		printk(KERN_DEBUG " In xircom_rx(), entry %d %8.8x.\n", entry,
 			   tp->rx_ring[entry].status);
 	/* If we own the next entry, it's a new packet. Send it up. */
 	while (tp->rx_ring[entry].status >= 0) {
 		s32 status = tp->rx_ring[entry].status;
 
-		if (tulip_debug > 5)
-			printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
+		if (xircom_debug > 5)
+			printk(KERN_DEBUG " In xircom_rx(), entry %d %8.8x.\n", entry,
 				   tp->rx_ring[entry].status);
 		if (--rx_work_limit < 0)
 			break;
 		if ((status & 0x38008300) != 0x0300) {
 			if ((status & 0x38000300) != 0x0300) {
-				/* Ingore earlier buffers. */
+				/* Ignore earlier buffers. */
 				if ((status & 0xffff) != 0x7fff) {
-					if (tulip_debug > 1)
+					if (xircom_debug > 1)
 						printk(KERN_WARNING "%s: Oversized Ethernet frame "
 							   "spanned multiple buffers, status %8.8x!\n",
 							   dev->name, status);
 					tp->stats.rx_length_errors++;
 				}
-			} else if (status & RxDescFatalErr) {
+			} else if (status & Rx0DescError) {
 				/* There was a fatal error. */
-				if (tulip_debug > 2)
+				if (xircom_debug > 2)
 					printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
 						   dev->name, status);
 				tp->stats.rx_errors++; /* end of a packet.*/
-				if (status & 0x0890) tp->stats.rx_length_errors++;
-				if (status & 0x0004) tp->stats.rx_frame_errors++;
-				if (status & 0x0002) tp->stats.rx_crc_errors++;
-				if (status & 0x0001) tp->stats.rx_fifo_errors++;
+				if (status & (Rx0Runt | Rx0HugeFrame)) tp->stats.rx_length_errors++;
+				if (status & Rx0CRCError) tp->stats.rx_crc_errors++;
 			}
 		} else {
 			/* Omit the four octet CRC from the length. */
@@ -1231,15 +1244,8 @@
 #endif
 				work_done++;
 			} else { 	/* Pass up the skb already on the Rx ring. */
-				char *temp = skb_put(skb = tp->rx_skbuff[entry], pkt_len);
+				skb_put(skb = tp->rx_skbuff[entry], pkt_len);
 				tp->rx_skbuff[entry] = NULL;
-#ifndef final_version
-				if (bus_to_virt(tp->rx_ring[entry].buffer1) != temp)
-					printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
-						   "do not match in tulip_rx: %p vs. %p / %p.\n",
-						   dev->name, bus_to_virt(tp->rx_ring[entry].buffer1),
-						   skb->head, temp);
-#endif
 			}
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);
@@ -1262,24 +1268,23 @@
 			tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail);
 			work_done++;
 		}
-		tp->rx_ring[entry].status = DescOwned;
+		tp->rx_ring[entry].status = Rx0DescOwned;
 	}
 
 	return work_done;
 }
 
+
 static void
-tulip_down(struct net_device *dev)
+xircom_down(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-
-	del_timer_sync(&tp->timer);
+	struct xircom_private *tp = dev->priv;
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	outl(0x00000000, ioaddr + CSR7);
+	outl(0, ioaddr + CSR7);
 	/* Stop the chip's Tx and Rx processes. */
-	outl_CSR6(inl(ioaddr + CSR6) & ~0x2002, ioaddr, tp->chip_id);
+	outl_CSR6(inl(ioaddr + CSR6) & ~EnableTxRx, ioaddr);
 
 	if (inl(ioaddr + CSR6) != 0xffffffff)
 		tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
@@ -1287,23 +1292,22 @@
 	dev->if_port = tp->saved_if_port;
 }
 
+
 static int
-tulip_close(struct net_device *dev)
+xircom_close(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	int i;
 
-	if (tulip_debug > 1)
+	if (xircom_debug > 1)
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
 			   dev->name, inl(ioaddr + CSR5));
 
-	del_timer_sync(&tp->timer);
-
 	netif_stop_queue(dev);
 
 	if (netif_device_present(dev))
-		tulip_down(dev);
+		xircom_down(dev);
 
 	free_irq(dev->irq, dev);
 
@@ -1311,7 +1315,7 @@
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		struct sk_buff *skb = tp->rx_skbuff[i];
 		tp->rx_skbuff[i] = 0;
-		tp->rx_ring[i].status = 0;		/* Not owned by Tulip chip. */
+		tp->rx_ring[i].status = 0;		/* Not owned by Xircom chip. */
 		tp->rx_ring[i].length = 0;
 		tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */
 		if (skb) {
@@ -1324,14 +1328,14 @@
 		tp->tx_skbuff[i] = 0;
 	}
 
-	MOD_DEC_USE_COUNT;
 	tp->open = 0;
 	return 0;
 }
 
-static struct net_device_stats *tulip_get_stats(struct net_device *dev)
+
+static struct net_device_stats *xircom_get_stats(struct net_device *dev)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	long ioaddr = dev->base_addr;
 
 	if (netif_device_present(dev))
@@ -1340,44 +1344,158 @@
 	return &tp->stats;
 }
 
-#ifdef HAVE_PRIVATE_IOCTL
+
+static int xircom_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct ethtool_cmd ecmd;
+	struct xircom_private *tp = dev->priv;
+
+	if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+		return -EFAULT;
+
+	switch (ecmd.cmd) {
+	case ETHTOOL_GSET:
+		ecmd.supported =
+			SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full |
+			SUPPORTED_Autoneg |
+			SUPPORTED_MII;
+
+		ecmd.advertising = ADVERTISED_MII;
+		if (tp->advertising[0] & ADVERTISE_10HALF)
+			ecmd.advertising |= ADVERTISED_10baseT_Half;
+		if (tp->advertising[0] & ADVERTISE_10FULL)
+			ecmd.advertising |= ADVERTISED_10baseT_Full;
+		if (tp->advertising[0] & ADVERTISE_100HALF)
+			ecmd.advertising |= ADVERTISED_100baseT_Half;
+		if (tp->advertising[0] & ADVERTISE_100FULL)
+			ecmd.advertising |= ADVERTISED_100baseT_Full;
+		if (tp->autoneg) {
+			ecmd.advertising |= ADVERTISED_Autoneg;
+			ecmd.autoneg = AUTONEG_ENABLE;
+		} else
+			ecmd.autoneg = AUTONEG_DISABLE;
+
+		ecmd.port = PORT_MII;
+		ecmd.transceiver = XCVR_INTERNAL;
+		ecmd.phy_address = tp->phys[0];
+		ecmd.speed = tp->speed100 ? SPEED_100 : SPEED_10;
+		ecmd.duplex = tp->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+		ecmd.maxtxpkt = TX_RING_SIZE / 2;
+		ecmd.maxrxpkt = 0;
+
+		if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+			return -EFAULT;
+		return 0;
+
+	case ETHTOOL_SSET: {
+		u16 autoneg, speed100, full_duplex;
+
+		autoneg = (ecmd.autoneg == AUTONEG_ENABLE);
+		speed100 = (ecmd.speed == SPEED_100);
+		full_duplex = (ecmd.duplex == DUPLEX_FULL);
+
+		tp->autoneg = autoneg;
+		if (speed100 != tp->speed100 ||
+		    full_duplex != tp->full_duplex) {
+			tp->speed100 = speed100;
+			tp->full_duplex = full_duplex;
+			/* change advertising bits */
+			tp->advertising[0] &= ~(ADVERTISE_10HALF |
+					     ADVERTISE_10FULL |
+					     ADVERTISE_100HALF |
+					     ADVERTISE_100FULL |
+					     ADVERTISE_100BASE4);
+			if (speed100) {
+				if (full_duplex)
+					tp->advertising[0] |= ADVERTISE_100FULL;
+				else
+					tp->advertising[0] |= ADVERTISE_100HALF;
+			} else {
+				if (full_duplex)
+					tp->advertising[0] |= ADVERTISE_10FULL;
+				else
+					tp->advertising[0] |= ADVERTISE_10HALF;
+			}
+		}
+		check_duplex(dev);
+		return 0;
+	}
+
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info;
+		memset(&info, 0, sizeof(info));
+		info.cmd = ecmd.cmd;
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		*info.fw_version = 0;
+		strcpy(info.bus_info, tp->pdev->slot_name);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+		       return -EFAULT;
+		return 0;
+	}
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+
 /* Provide ioctl() calls to examine the MII xcvr state. */
-static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct xircom_private *tp = dev->priv;
 	u16 *data = (u16 *)&rq->ifr_data;
 	int phy = tp->phys[0] & 0x1f;
 	long flags;
 
 	switch(cmd) {
-	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
+	case SIOCETHTOOL:
+		return xircom_ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+	/* Legacy mii-diag interface */
+	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
+	case SIOCDEVPRIVATE:		/* for binary compat, remove in 2.5 */
 		if (tp->mii_cnt)
 			data[0] = phy;
 		else
 			return -ENODEV;
 		return 0;
-	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
-		{
-			save_flags(flags);
-			cli();
-			data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
-			restore_flags(flags);
-		}
+	case SIOCGMIIREG:		/* Read MII PHY register. */
+	case SIOCDEVPRIVATE+1:		/* for binary compat, remove in 2.5 */
+		save_flags(flags);
+		cli();
+		data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
+		restore_flags(flags);
 		return 0;
-	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
-#if defined(CAP_NET_ADMIN)
+	case SIOCSMIIREG:		/* Write MII PHY register. */
+	case SIOCDEVPRIVATE+2:		/* for binary compat, remove in 2.5 */
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-#else
-		if (!suser())
-			return -EPERM;
-#endif
-		{
-			save_flags(flags);
-			cli();
-			mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
-			restore_flags(flags);
+		save_flags(flags);
+		cli();
+		if (data[0] == tp->phys[0]) {
+			u16 value = data[2];
+			switch (data[1]) {
+			case 0:
+				if (value & (BMCR_RESET | BMCR_ANENABLE))
+					/* Autonegotiation. */
+					tp->autoneg = 1;
+				else {
+					tp->full_duplex = (value & BMCR_FULLDPLX) ? 1 : 0;
+					tp->autoneg = 0;
+				}
+				break;
+			case 4:
+				tp->advertising[0] = value;
+				break;
+			}
+			check_duplex(dev);
 		}
+		mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+		restore_flags(flags);
 		return 0;
 	default:
 		return -EOPNOTSUPP;
@@ -1385,12 +1503,7 @@
 
 	return -EOPNOTSUPP;
 }
-#endif  /* HAVE_PRIVATE_IOCTL */
 
-/* Set or clear the multicast filter for this adaptor.
-   Note that we only use exclusion around actually queueing the
-   new frame, not around filling tp->setup_frame.  This is non-deterministic
-   when re-entered but still correct. */
 
 /* The little-endian AUTODIN32 ethernet CRC calculation.
    N.B. Do not use for bulk data, use a table-based routine instead.
@@ -1427,191 +1540,229 @@
     return crc;
 }
 
+
+/* Set or clear the multicast filter for this adaptor.
+   Note that we only use exclusion around actually queueing the
+   new frame, not around filling tp->setup_frame.  This is non-deterministic
+   when re-entered but still correct. */
 static void set_rx_mode(struct net_device *dev)
 {
+	struct xircom_private *tp = dev->priv;
+	struct dev_mc_list *mclist;
 	long ioaddr = dev->base_addr;
-	int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	int csr6 = inl(ioaddr + CSR6);
+	u16 *eaddrs, *setup_frm;
+	u32 tx_flags;
+	int i;
 
-	tp->csr6 &= ~0x00D5;
+	tp->csr6 &= ~(AllMultiBit | PromiscBit | HashFilterBit);
+	csr6 &= ~(AllMultiBit | PromiscBit | HashFilterBit);
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
-		tp->csr6 |= 0x00C0;
-		csr6 |= 0x00C0;
-		/* Unconditionally log net taps. */
-		printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
-	} else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
+		tp->csr6 |= PromiscBit;
+		csr6 |= PromiscBit;
+		goto out;
+	}
+
+	if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter well -- accept all multicasts. */
-		tp->csr6 |= 0x0080;
-		csr6 |= 0x0080;
-	} else {
-		u16 *eaddrs, *setup_frm = tp->setup_frame;
-		struct dev_mc_list *mclist;
-		u32 tx_flags = 0x68000000 | 192;
-		int i;
+		tp->csr6 |= AllMultiBit;
+		csr6 |= AllMultiBit;
+		goto out;
+	}
+
+	tx_flags = Tx1WholePkt | Tx1SetupPkt | PKT_SETUP_SZ;
+
+	/* Note that only the low-address shortword of setup_frame is valid! */
+	setup_frm = tp->setup_frame;
+	mclist = dev->mc_list;
+
+	/* Fill the first entry with our physical address. */
+	eaddrs = (u16 *)dev->dev_addr;
+	*setup_frm = cpu_to_le16(eaddrs[0]); setup_frm += 2;
+	*setup_frm = cpu_to_le16(eaddrs[1]); setup_frm += 2;
+	*setup_frm = cpu_to_le16(eaddrs[2]); setup_frm += 2;
+
+	if (dev->mc_count > 14) { /* Must use a multicast hash table. */
+		u32 *hash_table = (u32 *)(tp->setup_frame + 4 * 12);
+		u32 hash, hash2;
+
+		tx_flags |= Tx1HashSetup;
+		tp->csr6 |= HashFilterBit;
+		csr6 |= HashFilterBit;
+
+		/* Fill the unused 3 entries with the broadcast address.
+		   At least one entry *must* contain the broadcast address!!!*/
+		for (i = 0; i < 3; i++) {
+			*setup_frm = 0xffff; setup_frm += 2;
+			*setup_frm = 0xffff; setup_frm += 2;
+			*setup_frm = 0xffff; setup_frm += 2;
+		}
 
-		/* Note that only the low-address shortword of setup_frame is valid!
-		   The values are doubled for big-endian architectures. */
-		if (dev->mc_count > 14) { /* Must use a multicast hash table. */
-			u16 hash_table[32];
-			tx_flags = 0x68400000 | 192;		/* Use hash filter. */
-			memset(hash_table, 0, sizeof(hash_table));
-			set_bit(255, hash_table); 			/* Broadcast entry */
-			/* This should work on big-endian machines as well. */
-			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-				 i++, mclist = mclist->next)
-				set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
-						hash_table);
-			for (i = 0; i < 32; i++) {
-				*setup_frm++ = hash_table[i];
-				*setup_frm++ = hash_table[i];
-			}
-			setup_frm = &tp->setup_frame[13*6];
-		} else {
-			/* We have <= 14 addresses so we can use the wonderful
-			   16 address perfect filtering of the Tulip. */
-			for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-				 i++, mclist = mclist->next) {
-				eaddrs = (u16 *)mclist->dmi_addr;
-				*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
-				*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
-				*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
+		/* Truly brain-damaged hash filter layout */
+		/* XXX: not sure if I should take the last or the first 9 bits */
+		for (i = 0; i < dev->mc_count; i++, mclist = mclist->next) {
+			u32 *hptr;
+			hash = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff;
+			if (hash < 384) {
+				hash2 = hash + ((hash >> 4) << 4) +
+					((hash >> 5) << 5);
+			} else {
+				hash -= 384;
+				hash2 = 64 + hash + (hash >> 4) * 80;
 			}
-			/* Fill the unused entries with the broadcast address. */
-			memset(setup_frm, 0xff, (15-i)*12);
-			setup_frm = &tp->setup_frame[15*6];
+			hptr = &hash_table[hash2 & ~0x1f];
+			*hptr |= cpu_to_le32(1 << (hash2 & 0x1f));
 		}
+	} else {
+		/* We have <= 14 mcast addresses so we can use Xircom's
+		   wonderful 16-address perfect filter. */
+		for (i = 0; i < dev->mc_count; i++, mclist = mclist->next) {
+			eaddrs = (u16 *)mclist->dmi_addr;
+			*setup_frm = cpu_to_le16(eaddrs[0]); setup_frm += 2;
+			*setup_frm = cpu_to_le16(eaddrs[1]); setup_frm += 2;
+			*setup_frm = cpu_to_le16(eaddrs[2]); setup_frm += 2;
+		}
+		/* Fill the unused entries with the broadcast address.
+		   At least one entry *must* contain the broadcast address!!!*/
+		for (; i < 15; i++) {
+			*setup_frm = 0xffff; setup_frm += 2;
+			*setup_frm = 0xffff; setup_frm += 2;
+			*setup_frm = 0xffff; setup_frm += 2;
+		}
+	}
 
-		/* Fill the final entry with our physical address. */
-		eaddrs = (u16 *)dev->dev_addr;
-		*setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
-		*setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
-		*setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
-		/* Now add this frame to the Tx list. */
-		if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
-			/* Same setup recently queued, we need not add it. */
-		} else {
-			unsigned long flags;
-			unsigned int entry;
-			int dummy = -1;
-
-			save_flags(flags); cli();
-			entry = tp->cur_tx++ % TX_RING_SIZE;
+	/* Now add this frame to the Tx list. */
+	if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
+		/* Same setup recently queued, we need not add it. */
+		/* XXX: Huh? All it means is that the Tx list is full...*/
+	} else {
+		unsigned long flags;
+		unsigned int entry;
+		int dummy = -1;
 
-			if (entry != 0) {
-				/* Avoid a chip errata by prefixing a dummy entry. */
-				tp->tx_skbuff[entry] = 0;
-				tp->tx_ring[entry].length =
-					(entry == TX_RING_SIZE-1) ? DESC_RING_WRAP : 0;
-				tp->tx_ring[entry].buffer1 = 0;
-				/* race with chip, set DescOwned later */
-				dummy = entry;
-				entry = tp->cur_tx++ % TX_RING_SIZE;
-			}
+		save_flags(flags); cli();
+		entry = tp->cur_tx++ % TX_RING_SIZE;
 
+		if (entry != 0) {
+			/* Avoid a chip errata by prefixing a dummy entry. */
 			tp->tx_skbuff[entry] = 0;
-			/* Put the setup frame on the Tx list. */
-			if (entry == TX_RING_SIZE-1)
-				tx_flags |= DESC_RING_WRAP;		/* Wrap ring. */
-			tp->tx_ring[entry].length = tx_flags;
-			tp->tx_ring[entry].buffer1 = virt_to_bus(tp->setup_frame);
-			tp->tx_ring[entry].status = DescOwned;
-			if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
-				tp->tx_full = 1;
-				netif_stop_queue (dev);
-			}
-			if (dummy >= 0)
-				tp->tx_ring[dummy].status = DescOwned;
-			restore_flags(flags);
-			/* Trigger an immediate transmit demand. */
-			outl(0, ioaddr + CSR1);
+			tp->tx_ring[entry].length =
+				(entry == TX_RING_SIZE - 1) ? Tx1RingWrap : 0;
+			tp->tx_ring[entry].buffer1 = 0;
+			/* race with chip, set Tx0DescOwned later */
+			dummy = entry;
+			entry = tp->cur_tx++ % TX_RING_SIZE;
 		}
+
+		tp->tx_skbuff[entry] = 0;
+		/* Put the setup frame on the Tx list. */
+		if (entry == TX_RING_SIZE - 1)
+			tx_flags |= Tx1RingWrap;		/* Wrap ring. */
+		tp->tx_ring[entry].length = tx_flags;
+		tp->tx_ring[entry].buffer1 = virt_to_bus(tp->setup_frame);
+		tp->tx_ring[entry].status = Tx0DescOwned;
+		if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
+			tp->tx_full = 1;
+			netif_stop_queue (dev);
+		}
+		if (dummy >= 0)
+			tp->tx_ring[dummy].status = Tx0DescOwned;
+		restore_flags(flags);
+		/* Trigger an immediate transmit demand. */
+		outl(0, ioaddr + CSR1);
 	}
-	outl_CSR6(csr6 | 0x0000, ioaddr, tp->chip_id);
+
+out:
+	outl_CSR6(csr6, ioaddr);
 }
-
-static  struct pci_device_id tulip_pci_table[] __devinitdata = {
+
+
+static struct pci_device_id xircom_pci_table[] __devinitdata = {
   { 0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, X3201_3 },
   {0},
 };
+MODULE_DEVICE_TABLE(pci, xircom_pci_table);
 
-MODULE_DEVICE_TABLE(pci, tulip_pci_table);
-
-static int __devinit tulip_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	struct net_device *dev;
-	static int board_idx;
-
-	printk(KERN_INFO "tulip_attach(%s)\n", pdev->slot_name);
-
-	if (pci_enable_device (pdev))
-		return -ENODEV;
-	pci_set_master (pdev);
-	dev = tulip_probe1(pdev, pci_resource_start (pdev, 0), pdev->irq,
-			   id->driver_data, board_idx++);
-	if (dev) {
-		pdev->driver_data = dev;
-		return 0;
-	}
-	return -ENODEV;
-}
 
-static int tulip_suspend(struct pci_dev *pdev, u32 state)
+#ifdef CONFIG_PM
+static int xircom_suspend(struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pdev->driver_data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	printk(KERN_INFO "tulip_suspend(%s)\n", dev->name);
-	if (tp->open) tulip_down(dev);
+	struct xircom_private *tp = dev->priv;
+	printk(KERN_INFO "xircom_suspend(%s)\n", dev->name);
+	if (tp->open)
+		xircom_down(dev);
 	return 0;
 }
 
-static int tulip_resume(struct pci_dev *pdev)
+
+/* XXX: resume isn't able to power up the MII/PHY! */
+static int xircom_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pdev->driver_data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
-	printk(KERN_INFO "tulip_resume(%s)\n", dev->name);
-	if (tp->open) tulip_up(dev);
+	struct xircom_private *tp = dev->priv;
+	printk(KERN_INFO "xircom_resume(%s)\n", dev->name);
+
+	/* Bring the chip out of sleep mode.
+	   Caution: Snooze mode does not work with some boards! */
+	if (xircom_tbl[tp->chip_id].flags & HAS_ACPI)
+		pci_write_config_dword(tp->pdev, PCI_POWERMGMT, 0);
+
+	transceiver_voodoo(dev);
+	if (xircom_tbl[tp->chip_id].flags & HAS_MII)
+		check_duplex(dev);
+
+	if (tp->open)
+		xircom_up(dev);
 	return 0;
 }
+#endif /* CONFIG_PM */
 
-static void __devexit tulip_remove(struct pci_dev *pdev)
+
+static void __devexit xircom_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pdev->driver_data;
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 
-	printk(KERN_INFO "tulip_detach(%s)\n", dev->name);
+	printk(KERN_INFO "xircom_remove_one(%s)\n", dev->name);
 	unregister_netdev(dev);
+	pci_release_regions(pdev);
 	kfree(dev);
-	kfree(tp);
+	pci_set_drvdata(pdev, NULL);
 }
 
-static struct pci_driver tulip_ops = {
-	name:		"tulip_cb",
-	id_table:	tulip_pci_table,
-	probe:		tulip_pci_probe,
-	remove:		tulip_remove,
-	suspend:	tulip_suspend,
-	resume:		tulip_resume
+
+static struct pci_driver xircom_driver = {
+	name:		DRV_NAME,
+	id_table:	xircom_pci_table,
+	probe:		xircom_init_one,
+	remove:		xircom_remove_one,
+#ifdef CONFIG_PM
+	suspend:	xircom_suspend,
+	resume:		xircom_resume
+#endif /* CONFIG_PM */
 };
 
-static int __init tulip_init(void)
+
+static int __init xircom_init(void)
 {
-	pci_register_driver(&tulip_ops);
-	return 0;
+/* when a module, this is printed whether or not devices are found in probe */
+#ifdef MODULE
+	printk(version);
+#endif
+	return pci_module_init(&xircom_driver);
 }
 
-static void __exit tulip_exit(void)
+
+static void __exit xircom_exit(void)
 {
-	pci_unregister_driver(&tulip_ops);
+	pci_unregister_driver(&xircom_driver);
 }
 
-module_init(tulip_init)
-module_exit(tulip_exit)
+module_init(xircom_init)
+module_exit(xircom_exit)
 
-
 /*
  * Local variables:
- *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c tulip.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
- *  cardbus-compile-command: "gcc -DCARDBUS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c tulip.c -o tulip_cb.o -I/usr/src/pcmcia-cs-3.0.9/include/"
  *  c-indent-level: 4
  *  c-basic-offset: 4
  *  tab-width: 4
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- v2.4.10/linux/drivers/net/pcnet32.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/pcnet32.c	Sun Sep 30 12:26:07 2001
@@ -1538,6 +1538,7 @@
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_AUTHOR("Thomas Bogendoerfer");
 MODULE_DESCRIPTION("Driver for PCnet32 and PCnetPCI based ethercards");
+MODULE_LICENSE("GPL");
 
 /* An additional parameter that may be passed in... */
 static int debug = -1;
diff -u --recursive --new-file v2.4.10/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v2.4.10/linux/drivers/net/plip.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/plip.c	Sun Sep 30 12:26:07 2001
@@ -1432,6 +1432,7 @@
 
 module_init(plip_init);
 module_exit(plip_cleanup_module);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ppp_async.c linux/drivers/net/ppp_async.c
--- v2.4.10/linux/drivers/net/ppp_async.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/ppp_async.c	Sun Sep 30 12:26:07 2001
@@ -81,6 +81,8 @@
 static int flag_time = HZ;
 MODULE_PARM(flag_time, "i");
 MODULE_PARM_DESC(flag_time, "ppp_async: interval between flagged packets (in clock ticks)");
+MODULE_LICENSE("GPL");
+
 
 /*
  * Prototypes.
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ppp_deflate.c linux/drivers/net/ppp_deflate.c
--- v2.4.10/linux/drivers/net/ppp_deflate.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/ppp_deflate.c	Sun Sep 30 12:26:07 2001
@@ -657,3 +657,4 @@
 
 module_init(deflate_init);
 module_exit(deflate_cleanup);
+MODULE_LICENSE("BSD without advertisement clause");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
--- v2.4.10/linux/drivers/net/ppp_generic.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/ppp_generic.c	Thu Sep 27 08:42:29 2001
@@ -2105,13 +2105,12 @@
 {
 	struct compressor_entry *ce;
 	int ret;
-
 	spin_lock(&compressor_list_lock);
 	ret = -EEXIST;
 	if (find_comp_entry(cp->compress_proto) != 0)
 		goto out;
 	ret = -ENOMEM;
-	ce = kmalloc(sizeof(struct compressor_entry), GFP_KERNEL);
+	ce = kmalloc(sizeof(struct compressor_entry), GFP_ATOMIC);
 	if (ce == 0)
 		goto out;
 	ret = 0;
@@ -2216,11 +2215,11 @@
 
 	/* Create a new ppp structure and link it before `list'. */
 	ret = -ENOMEM;
-	ppp = kmalloc(sizeof(struct ppp), GFP_KERNEL);
+	ppp = kmalloc(sizeof(struct ppp), GFP_ATOMIC);
 	if (ppp == 0)
 		goto out;
 	memset(ppp, 0, sizeof(struct ppp));
-	dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+	dev = kmalloc(sizeof(struct net_device), GFP_ATOMIC);
 	if (dev == 0) {
 		kfree(ppp);
 		goto out;
@@ -2285,6 +2284,7 @@
 static void ppp_destroy_interface(struct ppp *ppp)
 {
 	struct net_device *dev;
+	int n_channels ;
 
 	spin_lock(&all_ppp_lock);
 	list_del(&ppp->file.list);
@@ -2314,6 +2314,7 @@
 #endif /* CONFIG_PPP_FILTER */
 	dev = ppp->dev;
 	ppp->dev = 0;
+	n_channels = ppp->n_channels ;
 	ppp_unlock(ppp);
 
 	if (dev) {
@@ -2329,7 +2330,7 @@
 	 * ppp structure.  Otherwise we leave it around until the
 	 * last channel disconnects from it.
 	 */
-	if (ppp->n_channels == 0)
+	if (n_channels == 0) 
 		kfree(ppp);
 
 	spin_unlock(&all_ppp_lock);
diff -u --recursive --new-file v2.4.10/linux/drivers/net/pppoe.c linux/drivers/net/pppoe.c
--- v2.4.10/linux/drivers/net/pppoe.c	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/pppoe.c	Thu Sep 27 08:42:29 2001
@@ -541,11 +541,15 @@
 	sk->state = PPPOX_DEAD;
 
 	po = sk->protinfo.pppox;
-	if (po->pppoe_pa.sid)
+	if (po->pppoe_pa.sid) {
 		delete_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
+		po->pppoe_pa.sid = 0 ;
+	}
 
 	if (po->pppoe_dev)
 	    dev_put(po->pppoe_dev);
+
+	po->pppoe_dev = NULL ;
 
 	sock_orphan(sk);
 	sock->sk = NULL;
diff -u --recursive --new-file v2.4.10/linux/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c
--- v2.4.10/linux/drivers/net/rcpci45.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/rcpci45.c	Sun Sep 30 12:26:07 2001
@@ -111,6 +111,7 @@
 	{}
 };
 MODULE_DEVICE_TABLE (pci, rcpci45_pci_table);
+MODULE_LICENSE("GPL");
 
 static void __exit
 rcpci45_remove_one (struct pci_dev *pdev)
diff -u --recursive --new-file v2.4.10/linux/drivers/net/sb1000.c linux/drivers/net/sb1000.c
--- v2.4.10/linux/drivers/net/sb1000.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/sb1000.c	Sun Sep 30 12:26:07 2001
@@ -1209,6 +1209,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Franco Venturi <fventuri@mediaone.net>");
 MODULE_DESCRIPTION("General Instruments SB1000 driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "1-2i");
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(io, "SB1000 I/O base addresses");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/shaper.c linux/drivers/net/shaper.c
--- v2.4.10/linux/drivers/net/shaper.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/shaper.c	Sun Sep 30 12:26:07 2001
@@ -743,4 +743,5 @@
 
 module_init(shaper_init);
 module_exit(shaper_exit);
+MODULE_LICENSE("GPL");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/sis900.c linux/drivers/net/sis900.c
--- v2.4.10/linux/drivers/net/sis900.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/sis900.c	Tue Oct  9 15:13:03 2001
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:	1.08.00	Jun. 11 2001
+   Revision:	1.08.01	Aug. 25 2001
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -18,8 +18,9 @@
    preliminary Rev. 1.0 Jan. 18, 1998
    http://www.sis.com.tw/support/databook.htm
 
+   Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
    Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix
-   Rev 1.07.11 Apr.  2 2001 Hui-Fen Hsu  updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3
+   Rev 1.07.11 Apr.  2 2001 Hui-Fen Hsu updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3
    Rev 1.07.10 Mar.  1 2001 Hui-Fen Hsu <hfhsu@sis.com.tw> some bug fix & 635M/B support 
    Rev 1.07.09 Feb.  9 2001 Dave Jones <davej@suse.de> PCI enable cleanup
    Rev 1.07.08 Jan.  8 2001 Lei-Chun Chang added RTL8201 PHY support
@@ -65,7 +66,7 @@
 #include "sis900.h"
 
 static char version[] __devinitdata =
-KERN_INFO "sis900.c: v1.08.00  6/11/2001\n";
+KERN_INFO "sis900.c: v1.08.01  9/25/2001\n";
 
 static int max_interrupt_work = 40;
 static int multicast_filter_limit = 128;
@@ -161,6 +162,8 @@
 
 MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>");
 MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(multicast_filter_limit, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
@@ -404,8 +407,12 @@
 		ret = -ENODEV;
 		goto err_out_unregister;
 	}
+	
+	/* 630ET : set the mii access mode as software-mode */
+	if (revision == SIS630ET_900_REV)
+		outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
 
-	/* probe for mii transciver */
+	/* probe for mii transceiver */
 	if (sis900_mii_probe(net_dev) == 0) {
 		ret = -ENODEV;
 		goto err_out_unregister;
@@ -513,6 +520,11 @@
         if ((sis_priv->mii->phy_id0 == 0x001D) &&
 	    ((sis_priv->mii->phy_id1&0xFFF0) == 0x8000))
         	status = sis900_reset_phy(net_dev, sis_priv->cur_phy);
+        
+        /* workaround for ICS1893 PHY */
+        if ((sis_priv->mii->phy_id0 == 0x0015) &&
+            ((sis_priv->mii->phy_id1&0xFFF0) == 0xF440))
+            	mdio_write(net_dev, sis_priv->cur_phy, 0x0018, 0xD200);
 
 	if(status & MII_STAT_LINK){
 		while (poll_bit) {
@@ -860,7 +872,7 @@
 
 	/* Enable all known interrupts by setting the interrupt mask. */
 	outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
-	outl(RxENA, ioaddr + cr);
+	outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
 	outl(IE, ioaddr + ier);
 
 	sis900_check_mode(net_dev, sis_priv->mii);
@@ -1037,7 +1049,7 @@
 	struct pci_dev *dev=NULL;
 
 	if ( !(revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
-	       revision == SIS630A_900_REV) )
+	       revision == SIS630A_900_REV || revision ==  SIS630ET_900_REV) )
 		return;
 
 	dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, dev);
@@ -1055,7 +1067,8 @@
 			min_value=(eq_value < min_value) ? eq_value : min_value;
 		}
 		/* 630E rule to determine the equalizer value */
-		if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV) {
+		if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
+		    revision == SIS630ET_900_REV) {
 			if (max_value < 5)
 				eq_value=max_value;
 			else if (max_value >= 5 && max_value < 15)
@@ -1371,7 +1384,7 @@
 	net_dev->trans_start = jiffies;
 
 	/* FIXME: Should we restart the transmission thread here  ?? */
-	outl(TxENA, ioaddr + cr);
+	outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
 
 	/* Enable all known interrupts by setting the interrupt mask. */
 	outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
@@ -1406,7 +1419,7 @@
 	sis_priv->tx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev,
 		skb->data, skb->len, PCI_DMA_TODEVICE);
 	sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
-	outl(TxENA, ioaddr + cr);
+	outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
 
 	if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) {
 		/* Typical path, tell upper layer that more transmission is possible */
@@ -1622,7 +1635,7 @@
 		}
 	}
 	/* re-enable the potentially idle receive state matchine */
-	outl(RxENA , ioaddr + cr );
+	outl(RxENA | inl(ioaddr + cr), ioaddr + cr );
 
 	return 0;
 }
@@ -1720,7 +1733,7 @@
 	outl(0x0000, ioaddr + ier);
 
 	/* Stop the chip's Tx and Rx Status Machine */
-	outl(RxDIS | TxDIS, ioaddr + cr);
+	outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
 
 	del_timer(&sis_priv->timer);
 
@@ -2036,7 +2049,7 @@
 	outl(0, ioaddr + imr);
 	outl(0, ioaddr + rfcr);
 
-	outl(RxRESET | TxRESET | RESET, ioaddr + cr);
+	outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
 	
 	/* Check that the chip has finished the reset. */
 	while (status && (i++ < 1000)) {
diff -u --recursive --new-file v2.4.10/linux/drivers/net/sis900.h linux/drivers/net/sis900.h
--- v2.4.10/linux/drivers/net/sis900.h	Wed Jul 25 17:10:21 2001
+++ linux/drivers/net/sis900.h	Tue Oct  9 15:13:03 2001
@@ -41,7 +41,7 @@
 
 /* Symbolic names for bits in various registers */
 enum sis900_command_register_bits {
-	RELOAD  = 0x00000400,
+	RELOAD  = 0x00000400, ACCESSMODE = 0x00000200,/* ET */
 	RESET   = 0x00000100, SWI = 0x00000080, RxRESET = 0x00000020,
 	TxRESET = 0x00000010, RxDIS = 0x00000008, RxENA = 0x00000004,
 	TxDIS   = 0x00000002, TxENA = 0x00000001
@@ -239,7 +239,8 @@
 enum sis900_revision_id {
 	SIS630A_900_REV = 0x80,		SIS630E_900_REV = 0x81,
 	SIS630S_900_REV = 0x82,		SIS630EA1_900_REV = 0x83,
-	SIS635A_900_REV = 0x90,		SIS900B_900_REV = 0x03
+	SIS630ET_900_REV = 0x84,	SIS635A_900_REV = 0x90,
+	SIS900B_900_REV = 0x03
 };
 
 enum sis630_revision_id {
diff -u --recursive --new-file v2.4.10/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- v2.4.10/linux/drivers/net/sk98lin/skge.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/net/sk98lin/skge.c	Sun Sep 30 12:26:07 2001
@@ -591,6 +591,7 @@
 
 MODULE_AUTHOR("Christoph Goos <cgoos@syskonnect.de>");
 MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(AutoNeg_A,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
 MODULE_PARM(AutoNeg_B,  "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
 MODULE_PARM(DupCap_A,   "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/skfp/skfddi.c linux/drivers/net/skfp/skfddi.c
--- v2.4.10/linux/drivers/net/skfp/skfddi.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/skfp/skfddi.c	Sun Sep 30 12:26:07 2001
@@ -187,6 +187,7 @@
 	{ }			/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, skfddi_pci_tbl);
+MODULE_LICENSE("GPL");
 
 // Define module-wide (static) variables
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/slhc.c linux/drivers/net/slhc.c
--- v2.4.10/linux/drivers/net/slhc.c	Tue Mar  6 22:44:16 2001
+++ linux/drivers/net/slhc.c	Sun Sep 30 12:26:07 2001
@@ -797,3 +797,4 @@
 EXPORT_SYMBOL(slhc_toss);
 
 #endif /* CONFIG_INET */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v2.4.10/linux/drivers/net/slip.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/slip.c	Sun Sep 30 12:26:07 2001
@@ -1516,3 +1516,4 @@
 }
 
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- v2.4.10/linux/drivers/net/smc-ultra.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/smc-ultra.c	Sun Sep 30 12:26:07 2001
@@ -557,6 +557,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 
 /*
diff -u --recursive --new-file v2.4.10/linux/drivers/net/smc-ultra32.c linux/drivers/net/smc-ultra32.c
--- v2.4.10/linux/drivers/net/smc-ultra32.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/smc-ultra32.c	Sun Sep 30 12:26:07 2001
@@ -415,3 +415,5 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/net/starfire.c linux/drivers/net/starfire.c
--- v2.4.10/linux/drivers/net/starfire.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/starfire.c	Sun Sep 30 12:26:07 2001
@@ -250,6 +250,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/strip.c linux/drivers/net/strip.c
--- v2.4.10/linux/drivers/net/strip.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/strip.c	Sun Sep 30 12:26:07 2001
@@ -2871,5 +2871,7 @@
 
 MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>");
 MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver");
+MODULE_LICENSE("BSD without advertisement clause");
+
 MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/sundance.c linux/drivers/net/sundance.c
--- v2.4.10/linux/drivers/net/sundance.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/sundance.c	Sun Sep 30 12:26:07 2001
@@ -108,6 +108,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/sungem.c linux/drivers/net/sungem.c
--- v2.4.10/linux/drivers/net/sungem.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/sungem.c	Sun Sep 30 12:26:07 2001
@@ -48,6 +48,8 @@
 
 MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
 MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(gem_debug, "i");
 MODULE_PARM_DESC(gem_debug, "(ignored)");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- v2.4.10/linux/drivers/net/sunhme.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/sunhme.c	Sun Sep 30 12:26:07 2001
@@ -190,6 +190,8 @@
 };
 
 MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
+MODULE_LICENSE("GPL");
+
 #endif
 
 /* NOTE: In the descriptor writes one _must_ write the address
diff -u --recursive --new-file v2.4.10/linux/drivers/net/tlan.c linux/drivers/net/tlan.c
--- v2.4.10/linux/drivers/net/tlan.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/tlan.c	Sun Sep 30 12:26:08 2001
@@ -190,6 +190,8 @@
 
 MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>");
 MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(aui, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
 MODULE_PARM(duplex, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
 MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
@@ -452,7 +454,7 @@
 	
 	/* Use new style PCI probing. Now the kernel will
 	   do most of this for us */
-	pci_module_init(&tlan_driver);
+	pci_register_driver(&tlan_driver);
 
 	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
 	TLan_EisaProbe();
@@ -462,6 +464,7 @@
 		 tlan_have_pci, tlan_have_eisa);
 
 	if (TLanDevicesInstalled == 0) {
+		pci_unregister_driver(&tlan_driver);
 		kfree(TLanPadBuffer);
 		return -ENODEV;
 	}
@@ -643,8 +646,7 @@
 		
 static void __exit tlan_exit(void)
 {
-	if (tlan_have_pci)
-		pci_unregister_driver(&tlan_driver);
+	pci_unregister_driver(&tlan_driver);
 
 	if (tlan_have_eisa)
 		TLan_Eisa_Cleanup();
diff -u --recursive --new-file v2.4.10/linux/drivers/net/tokenring/lanstreamer.c linux/drivers/net/tokenring/lanstreamer.c
--- v2.4.10/linux/drivers/net/tokenring/lanstreamer.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/tokenring/lanstreamer.c	Sun Sep 30 12:26:07 2001
@@ -1825,3 +1825,4 @@
 
 module_init(streamer_init_module);
 module_exit(streamer_cleanup_module);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/tulip/eeprom.c linux/drivers/net/tulip/eeprom.c
--- v2.4.10/linux/drivers/net/tulip/eeprom.c	Wed May 16 10:25:39 2001
+++ linux/drivers/net/tulip/eeprom.c	Tue Oct  2 09:00:58 2001
@@ -148,10 +148,10 @@
 		for (i = 0; i < count; i++) {
 			unsigned char media_block = *p++;
 			int media_code = media_block & MEDIA_MASK;
-			if (media_code & 0x40)
+			if (media_block & 0x40)
 				p += 6;
 			printk(KERN_INFO "%s:  21041 media #%d, %s.\n",
-				   dev->name, media_code & 15, medianame[media_code & 15]);
+				   dev->name, media_code, medianame[media_code]);
 		}
 	} else {
 		unsigned char *p = (void *)ee_data + ee_data[27];
diff -u --recursive --new-file v2.4.10/linux/drivers/net/tulip/interrupt.c linux/drivers/net/tulip/interrupt.c
--- v2.4.10/linux/drivers/net/tulip/interrupt.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/tulip/interrupt.c	Tue Oct  2 09:00:58 2001
@@ -301,7 +301,7 @@
 	long ioaddr = dev->base_addr;
 	int csr5;
 	int entry;
-	int missed;
+	int csr8;
 	int rx = 0;
 	int tx = 0;
 	int oi = 0;
@@ -434,7 +434,6 @@
 				}
 			}
 			if (csr5 & RxDied) {		/* Missed a Rx frame. */
-                                tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
 #ifdef CONFIG_NET_HW_FLOWCONTROL
 				if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
 					tp->stats.rx_errors++;
@@ -548,9 +547,8 @@
 		}
 	}
 
-	if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
-		tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
-	}
+	csr8 = inl(ioaddr + CSR8);
+	tp->stats.rx_dropped += (csr8 & 0x1ffff) + ((csr8 >> 17) & 0xfff);
 
 	if (tulip_debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
diff -u --recursive --new-file v2.4.10/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- v2.4.10/linux/drivers/net/tulip/tulip_core.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/tulip/tulip_core.c	Tue Oct  2 09:00:58 2001
@@ -15,8 +15,8 @@
 */
 
 #define DRV_NAME	"tulip"
-#define DRV_VERSION	"0.9.15-pre6"
-#define DRV_RELDATE	"July 2, 2001"
+#define DRV_VERSION	"0.9.15-pre7"
+#define DRV_RELDATE	"Oct 2, 2001"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -101,6 +101,7 @@
 
 MODULE_AUTHOR("The Linux Kernel Team");
 MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(tulip_debug, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(rx_copybreak, "i");
@@ -1466,8 +1467,6 @@
 		goto err_out_free_res;
 #endif
 
-	pci_set_master(pdev);
-
 	pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
 
 	/*
@@ -1511,6 +1510,8 @@
 
 	/* Stop the chip's Tx and Rx processes. */
 	tulip_stop_rxtx(tp);
+
+	pci_set_master(pdev);
 
 	/* Clear the missed-packet counter. */
 	inl(ioaddr + CSR8);
diff -u --recursive --new-file v2.4.10/linux/drivers/net/tun.c linux/drivers/net/tun.c
--- v2.4.10/linux/drivers/net/tun.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/tun.c	Sun Sep 30 12:26:07 2001
@@ -581,3 +581,4 @@
 
 module_init(tun_init);
 module_exit(tun_cleanup);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- v2.4.10/linux/drivers/net/via-rhine.c	Sun Sep 23 11:40:58 2001
+++ linux/drivers/net/via-rhine.c	Sun Sep 30 12:26:07 2001
@@ -184,6 +184,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(rx_copybreak, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wan/cycx_drv.c linux/drivers/net/wan/cycx_drv.c
--- v2.4.10/linux/drivers/net/wan/cycx_drv.c	Mon Apr  3 19:32:57 2000
+++ linux/drivers/net/wan/cycx_drv.c	Sun Sep 30 12:26:07 2001
@@ -64,6 +64,8 @@
 
 MODULE_AUTHOR("Arnaldo Carvalho de Melo");
 MODULE_DESCRIPTION("Cyclom 2x Sync Card Driver");
+MODULE_LICENSE("GPL");
+
 
 /* Function Prototypes */
 /* Module entry points. These are called by the OS and must be public. */
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wan/hostess_sv11.c linux/drivers/net/wan/hostess_sv11.c
--- v2.4.10/linux/drivers/net/wan/hostess_sv11.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wan/hostess_sv11.c	Sun Sep 30 12:26:08 2001
@@ -1,5 +1,3 @@
-#define LINUX_21
-
 /*
  *	Comtrol SV11 card driver
  *
@@ -186,7 +184,6 @@
 	return z8530_queue_xmit(&sv11->sync.chanA, skb);
 }
 
-#ifdef LINUX_21
 static int hostess_neigh_setup(struct neighbour *n)
 {
 	if (n->nud_state == NUD_NONE) {
@@ -206,15 +203,6 @@
 	return 0;
 }
 
-#else
-
-static int return_0(struct net_device *d)
-{
-	return 0;
-}
-
-#endif
-
 /*
  *	Description block for a Comtrol Hostess SV11 card
  */
@@ -345,11 +333,7 @@
 		d->get_stats = hostess_get_stats;
 		d->set_multicast_list = NULL;
 		d->do_ioctl = hostess_ioctl;
-#ifdef LINUX_21			
 		d->neigh_setup = hostess_neigh_setup_dev;
-#else
-		d->init = return_0;
-#endif
 		d->set_mac_address = NULL;
 		
 		if(register_netdev(d)==-1)
@@ -416,7 +400,7 @@
 int init_module(void)
 {
 	printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n");
-	printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");	
+	printk(KERN_INFO "(c) Copyright 2001, Red Hat Inc.\n");	
 	if((sv11_unit=sv11_init(io,irq))==NULL)
 		return -ENODEV;
 	return 0;
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wan/sealevel.c linux/drivers/net/wan/sealevel.c
--- v2.4.10/linux/drivers/net/wan/sealevel.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wan/sealevel.c	Sun Sep 30 12:26:08 2001
@@ -1,5 +1,3 @@
-#define LINUX_21
-
 /*
  *	Sealevel Systems 4021 driver.
  *
@@ -8,8 +6,8 @@
  *	as published by the Free Software Foundation; either version
  *	2 of the License, or (at your option) any later version.
  *
- *	(c) Copyright 1999 Building Number Three Ltd
- *	(c) Copyright 2001 Alan Cox.
+ *	(c) Copyright 1999, 2001 Alan Cox
+ *	(c) Copyright 2001 Red Hat Inc.
  *
  */
 
@@ -185,7 +183,6 @@
 	return z8530_queue_xmit(slvl->chan, skb);
 }
 
-#ifdef LINUX_21
 static int sealevel_neigh_setup(struct neighbour *n)
 {
 	if (n->nud_state == NUD_NONE) {
@@ -205,15 +202,6 @@
 	return 0;
 }
 
-#else
-
-static int return_0(struct net_device *d)
-{
-	return 0;
-}
-
-#endif
-
 /*
  *	Description block for a Comtrol Hostess SV11 card
  */
@@ -374,11 +362,7 @@
 			d->get_stats = sealevel_get_stats;
 			d->set_multicast_list = NULL;
 			d->do_ioctl = sealevel_ioctl;
-#ifdef LINUX_21			
 			d->neigh_setup = sealevel_neigh_setup_dev;
-#else
-			d->init = return_0;
-#endif
 			d->set_mac_address = NULL;
 		
 			if(register_netdev(d)==-1)
@@ -444,7 +428,6 @@
 static int irq=5;
 static int slow=0;
 
-#ifdef LINUX_21
 MODULE_PARM(io,"i");
 MODULE_PARM_DESC(io, "The I/O base of the Sealevel card");
 MODULE_PARM(txdma,"i");
@@ -459,7 +442,6 @@
 MODULE_AUTHOR("Alan Cox");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Modular driver for the SeaLevel 4021");
-#endif
 
 static struct slvl_board *slvl_unit;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v2.4.10/linux/drivers/net/wavelan.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/wavelan.c	Sun Sep 30 12:26:08 2001
@@ -1545,8 +1545,7 @@
 	/* Setting by channel (same as wfreqsel) */
 	/* Warning: each channel is 22 MHz wide, so some of the channels
 	 * will interfere. */
-	if ((frequency->e == 0) &&
-	    (frequency->m >= 0) && (frequency->m < BAND_NUM)) {
+	if ((frequency->e == 0) && (frequency->m < BAND_NUM)) {
 		/* Get frequency offset. */
 		freq = channel_bands[frequency->m] >> 1;
 	}
@@ -4292,6 +4291,7 @@
 #endif
 }
 #endif				/* MODULE */
+MODULE_LICENSE("GPL");
 
 /*
  * This software may only be used and distributed
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wd.c linux/drivers/net/wd.c
--- v2.4.10/linux/drivers/net/wd.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/net/wd.c	Sun Sep 30 12:26:07 2001
@@ -454,6 +454,7 @@
 MODULE_PARM_DESC(irq, "WD80x3 IRQ number(s) (ignored for PureData boards)");
 MODULE_PARM_DESC(mem, "WD80x3 memory base address(es)(ignored for PureData boards)");
 MODULE_PARM_DESC(mem_end, "WD80x3 memory end address(es)");
+MODULE_LICENSE("GPL");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
diff -u --recursive --new-file v2.4.10/linux/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- v2.4.10/linux/drivers/net/winbond-840.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/winbond-840.c	Tue Oct  9 15:13:02 2001
@@ -149,6 +149,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(rx_copybreak, "i");
@@ -555,7 +557,7 @@
 {
 	int i;
 	int retval = 0;
-	int ee_addr = addr + EECtrl;
+	long ee_addr = addr + EECtrl;
 	int read_cmd = location | EE_ReadCmd;
 	writel(EE_ChipSelect, ee_addr);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/Config.in linux/drivers/net/wireless/Config.in
--- v2.4.10/linux/drivers/net/wireless/Config.in	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/wireless/Config.in	Tue Oct  9 15:13:03 2001
@@ -6,15 +6,21 @@
    tristate '  Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards' CONFIG_AIRO
 fi
 
+tristate '  Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)' CONFIG_HERMES
+
 if [ "$CONFIG_ALL_PPC" = "y" ]; then
-   tristate '  Apple Airport support (built-in)' CONFIG_APPLE_AIRPORT
+   dep_tristate '    Apple Airport support (built-in)' CONFIG_APPLE_AIRPORT $CONFIG_HERMES
+fi
+
+if [ "$CONFIG_PCI" = "y" ]; then
+   dep_tristate '    Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
 fi
 
 # If Pcmcia is compiled in, offer Pcmcia cards...
 if [ "$CONFIG_PCMCIA" != "n" ]; then
    comment 'Wireless Pcmcia cards support' 
 
-   tristate '  Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)' CONFIG_PCMCIA_HERMES
+   dep_tristate '  Hermes PCMCIA card support' CONFIG_PCMCIA_HERMES $CONFIG_HERMES
    tristate '  Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards' CONFIG_AIRO_CS
 fi
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/Makefile linux/drivers/net/wireless/Makefile
--- v2.4.10/linux/drivers/net/wireless/Makefile	Tue Jul  3 17:08:20 2001
+++ linux/drivers/net/wireless/Makefile	Tue Oct  9 15:13:03 2001
@@ -14,8 +14,10 @@
 # Things that need to export symbols
 export-objs	:= airo.o orinoco.o hermes.o
 
-obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o orinoco.o hermes.o
-obj-$(CONFIG_APPLE_AIRPORT)	+= airport.o orinoco.o hermes.o
+obj-$(CONFIG_HERMES)		+= orinoco.o hermes.o
+obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o
+obj-$(CONFIG_APPLE_AIRPORT)	+= airport.o
+obj-$(CONFIG_PLX_HERMES)	+= orinoco_plx.o
 
 obj-$(CONFIG_AIRO)		+= airo.o
 obj-$(CONFIG_AIRO_CS)		+= airo_cs.o airo.o
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/airo.c linux/drivers/net/wireless/airo.c
--- v2.4.10/linux/drivers/net/wireless/airo.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wireless/airo.c	Wed Oct  3 09:16:42 2001
@@ -341,6 +341,7 @@
 
 /* The RIDs */
 #define RID_CAPABILITIES 0xFF00
+#define RID_RSSI       0xFF04
 #define RID_CONFIG     0xFF10
 #define RID_SSID       0xFF11
 #define RID_APLIST     0xFF12
@@ -627,6 +628,16 @@
   u16 atimWindow;
 } BSSListRid;
 
+typedef struct {
+  u8 rssipct;
+  u8 rssidBm;
+} tdsRssiEntry;
+
+typedef struct {
+  u16 len;
+  tdsRssiEntry x[256];
+} tdsRssiRid;
+
 #pragma pack()
 
 #define TXCTL_TXOK (1<<1) /* report if tx is ok */
@@ -774,6 +785,7 @@
 			int whichbap);
 	int (*header_parse)(struct sk_buff*, unsigned char *);
 	unsigned short *flash;
+	tdsRssiEntry *rssi;
 #ifdef WIRELESS_EXT
 	int			need_commit;	// Need to set config
 	struct iw_statistics	wstats;		// wireless stats
@@ -1076,6 +1088,8 @@
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	if (ai->flash)
 		kfree(ai->flash);
+	if (ai->rssi)
+		kfree(ai->rssi);
 	takedown_proc_entry( dev, ai );
 	if (ai->registered) {
 		unregister_netdev( dev );
@@ -1382,7 +1396,10 @@
 					if (!memcmp(sa,apriv->spy_address[i],6))
 					{
 						apriv->spy_stat[i].qual = hdr.rssi[0];
-						apriv->spy_stat[i].level = hdr.rssi[1];
+						if (apriv->rssi)
+							apriv->spy_stat[i].level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
+						else
+							apriv->spy_stat[i].level = (hdr.rssi[1] + 321) / 2;
 						apriv->spy_stat[i].noise = 0;
 						apriv->spy_stat[i].updated = 3;
 						break;
@@ -1568,9 +1585,29 @@
 	if ( config->len ) {
 		cfg = *config;
 	} else {
+		tdsRssiRid rssi_rid;
+	
 		// general configuration (read/modify/write)
 		status = readConfigRid(ai, &cfg);
 		if ( status != SUCCESS ) return ERROR;
+
+		status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid));
+		if ( status == SUCCESS ) {
+			if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
+				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
+		}
+		else {
+			CapabilityRid cap_rid;
+			if (ai->rssi) {
+				kfree(ai->rssi);
+				ai->rssi = NULL;
+			}
+			status = readCapabilityRid(ai, &cap_rid);
+			if ((status == SUCCESS) && (cap_rid.softCap & 8))
+				cfg.rmode |= RXMODE_NORMALIZED_RSSI;
+			else
+				printk(KERN_WARNING "airo: unknown received signal level\n");
+		}
 		cfg.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
     
 		/* Save off the MAC */
@@ -3814,7 +3851,7 @@
 
 			/* Hum... Should put the right values there */
 			range.max_qual.qual = 10;
-			range.max_qual.level = 100;
+			range.max_qual.level = 0;
 			range.max_qual.noise = 0;
 			range.sensitivity = 65535;
 
@@ -3976,7 +4013,10 @@
 				loseSync = 0;
 				memcpy(s[i].sa_data, BSSList.bssid, 6);
 				s[i].sa_family = ARPHRD_ETHER;
-				qual[i].level = BSSList.rssi;
+				if (local->rssi)
+					qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
+				else
+					qual[i].level = (BSSList.rssi + 321) / 2;
 				qual[i].qual = qual[i].noise = 0;
 				qual[i].updated = 2;
 				if (BSSList.index == 0xffff) break;
@@ -4190,7 +4230,10 @@
 
 	/* Signal quality and co. But where is the noise level ??? */
 	local->wstats.qual.qual = status_rid.signalQuality;
-	local->wstats.qual.level = status_rid.normalizedSignalStrength;
+	if (local->rssi)
+		local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
+	else
+		local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
 	local->wstats.qual.noise = 0;
 	local->wstats.qual.updated = 3;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/hermes.c linux/drivers/net/wireless/hermes.c
--- v2.4.10/linux/drivers/net/wireless/hermes.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wireless/hermes.c	Tue Oct  9 15:13:03 2001
@@ -14,8 +14,31 @@
  * particular order).
  *
  * Copyright (C) 2000, David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au>
+ * Copyright (C) 2001, David Gibson, IBM <hermes@gibson.dropbear.id.au>
  * 
- * This file distributed under the GPL, version 2.  */
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+#include <linux/config.h>
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -30,10 +53,10 @@
 
 #include "hermes.h"
 
-static char version[] __initdata = "hermes.c: 1 Aug 2001 David Gibson <hermes@gibson.dropbear.id.au>";
+static char version[] __initdata = "hermes.c: 3 Oct 2001 David Gibson <hermes@gibson.dropbear.id.au>";
 MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("Dual MPL/GPL");
 
 /* These are maximum timeouts. Most often, card wil react much faster */
 #define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
@@ -42,9 +65,6 @@
 #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
 #define BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
 
-#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
-#define MIN(a, b) ( (a) < (b) ? (a) : (b) )
-
 /*
  * Debugging helpers
  */
@@ -76,9 +96,9 @@
 
    Callable from any context.
 */
-static int hermes_issue_cmd(hermes_t *hw, uint16_t cmd, uint16_t param0)
+static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0)
 {
-	uint16_t reg;
+	u16 reg;
 
 	/* First check that the command register is not busy */
 	reg = hermes_read_regn(hw, CMD);
@@ -106,7 +126,7 @@
 
 int hermes_reset(hermes_t *hw)
 {
-	uint16_t status, reg;
+	u16 status, reg;
 	int err = 0;
 	int k;
 
@@ -190,11 +210,11 @@
  * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
  *
  * Callable from any context, but locking is your problem. */
-int hermes_docmd_wait(hermes_t *hw, uint16_t cmd, uint16_t parm0, hermes_response_t *resp)
+int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp)
 {
 	int err;
 	int k;
-	uint16_t reg;
+	u16 reg;
 
 	err = hermes_issue_cmd(hw, cmd, parm0);
 	if (err) {
@@ -243,12 +263,12 @@
 	return err;
 }
 
-int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid)
+int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
 {
 	int err = 0;
 	hermes_response_t resp;
 	int k;
-	uint16_t reg;
+	u16 reg;
 	
 	if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
 		return -EINVAL;
@@ -292,12 +312,12 @@
  * from firmware
  *
  * Callable from any context */
-static int hermes_bap_seek(hermes_t *hw, int bap, uint16_t id, uint16_t offset)
+int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
 {
 	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
 	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
 	int k;
-	uint16_t reg;
+	u16 reg;
 
 	/* Paranoia.. */
 	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
@@ -305,9 +325,14 @@
 
 	k = BAP_BUSY_TIMEOUT;
 	reg = hermes_read_reg(hw, oreg);
+	while ((reg & HERMES_OFFSET_BUSY) & k) {
+		k--;
+		udelay(1);
+		reg = hermes_read_reg(hw, oreg);
+	}
 
 	if (reg & HERMES_OFFSET_BUSY)
-		return -EBUSY;
+		return -ETIMEDOUT;
 
 	/* Now we actually set up the transfer */
 	hermes_write_reg(hw, sreg, id);
@@ -342,8 +367,8 @@
  *
  * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
  */
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len,
-		     uint16_t id, uint16_t offset)
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
+		     u16 id, u16 offset)
 {
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
@@ -356,7 +381,7 @@
 		goto out;
 
 	/* Actually do the transfer */
-	hermes_read_data(hw, dreg, buf, len/2);
+	hermes_read_words(hw, dreg, buf, len/2);
 
  out:
 	return err;
@@ -368,8 +393,8 @@
  *
  * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
  */
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, uint16_t len,
-		      uint16_t id, uint16_t offset)
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
+		      u16 id, u16 offset)
 {
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
@@ -382,7 +407,7 @@
 		goto out;
 	
 	/* Actually do the transfer */
-	hermes_write_data(hw, dreg, buf, len/2);
+	hermes_write_words(hw, dreg, buf, len/2);
 
  out:	
 	return err;
@@ -396,16 +421,15 @@
  * practice.
  *
  * Callable from user or bh context.  */
-int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen,
-		    uint16_t *length, void *buf)
+int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int bufsize,
+		    u16 *length, void *buf)
 {
 	int err = 0;
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
-	uint16_t rlength, rtype;
+	u16 rlength, rtype;
 	hermes_response_t resp;
-	int count;
 
-	if (buflen % 2)
+	if (bufsize % 2)
 		return -EINVAL;
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, &resp);
@@ -425,33 +449,21 @@
 	if (rtype != rid)
 		printk(KERN_WARNING "hermes_read_ltv(): rid  (0x%04x) does "
 		       "not match type (0x%04x)\n", rid, rtype);
-	if (HERMES_RECLEN_TO_BYTES(rlength) > buflen)
+	if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
 		printk(KERN_WARNING "hermes @ 0x%x: Truncating LTV record from %d to %d bytes. "
 		       "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
-		       HERMES_RECLEN_TO_BYTES(rlength), buflen, rid, rlength);
+		       HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
 	
-	/* For now we always read the whole buffer, the
-	   lengths in the records seem to be wrong, frequently */
-	count = buflen / 2;
-
-#if 0
-	if (length)
-		count = (MIN(buflen, rlength) + 1) / 2;
-	else {
-		count = buflen / 2;
-		if (rlength != buflen)
-			printk(KERN_WARNING "hermes_read_ltv(): Incorrect \
-record length %d instead of %d on RID 0x%04x\n", rlength, buflen, rid);
-	}
-#endif
-	hermes_read_data(hw, dreg, buf, count);
+	/* FIXME: we should read the min of the requested length and
+           the actual record length */
+	hermes_read_words(hw, dreg, buf, bufsize / 2);
 
  out:
 	return err;
 }
 
-int hermes_write_ltv(hermes_t *hw, int bap, uint16_t rid, 
-		     uint16_t length, const void *value)
+int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 
+		     u16 length, const void *value)
 {
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
@@ -459,7 +471,7 @@
 	int count;
 	
 	DEBUG(3, "write_ltv(): bap=%d rid=0x%04x length=%d (value=0x%04x)\n",
-	      bap, rid, length, * ((uint16_t *)value));
+	      bap, rid, length, * ((u16 *)value));
 
 	err = hermes_bap_seek(hw, bap, rid, 0);
 	if (err)
@@ -470,7 +482,7 @@
 
 	count = length - 1;
 
-	hermes_write_data(hw, dreg, value, count);
+	hermes_write_words(hw, dreg, value, count);
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, 
 				rid, &resp);
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/hermes.h linux/drivers/net/wireless/hermes.h
--- v2.4.10/linux/drivers/net/wireless/hermes.h	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wireless/hermes.h	Tue Oct  9 15:13:03 2001
@@ -176,12 +176,12 @@
 #define		HERMES_RID_CNF_TX_KEY		(0xfcb1)
 #define		HERMES_RID_CNF_TICKTIME		(0xfce0)
 
-#define		HERMES_RID_CNF_PRISM2_WEP_ON	(0xfc28)
-#define		HERMES_RID_CNF_PRISM2_TX_KEY	(0xfc23)
-#define		HERMES_RID_CNF_PRISM2_KEY0	(0xfc24)
-#define		HERMES_RID_CNF_PRISM2_KEY1	(0xfc25)
-#define		HERMES_RID_CNF_PRISM2_KEY2	(0xfc26)
-#define		HERMES_RID_CNF_PRISM2_KEY3	(0xfc27)
+#define		HERMES_RID_CNF_INTERSIL_WEP_ON	(0xfc28)
+#define		HERMES_RID_CNF_INTERSIL_TX_KEY	(0xfc23)
+#define		HERMES_RID_CNF_INTERSIL_KEY0	(0xfc24)
+#define		HERMES_RID_CNF_INTERSIL_KEY1	(0xfc25)
+#define		HERMES_RID_CNF_INTERSIL_KEY2	(0xfc26)
+#define		HERMES_RID_CNF_INTERSIL_KEY3	(0xfc27)
 #define		HERMES_RID_CNF_SYMBOL_MANDATORY_BSSID	(0xfc21)
 #define		HERMES_RID_CNF_SYMBOL_AUTH_TYPE		(0xfc2A)
 #define		HERMES_RID_CNF_SYMBOL_BASIC_RATES	(0xfc8A)
@@ -202,24 +202,21 @@
 #define		HERMES_RID_WEP_AVAIL		(0xfd4f)
 #define		HERMES_RID_CURRENT_CHANNEL	(0xfdc1)
 #define		HERMES_RID_DATARATES		(0xfdc6)
-#define		HERMES_RID_SYMBOL_PRIMARY_VER	(0xfd03)
-#define		HERMES_RID_SYMBOL_SECONDARY_VER	(0xfd21)
+#define		HERMES_RID_SYMBOL_SECONDARY_VER	(0xfd24)
 #define		HERMES_RID_SYMBOL_KEY_LENGTH	(0xfc2B)
 
 /*
  * Frame structures and constants
  */
 
-#define __PACKED__ __attribute__ ((packed))
-
 typedef struct hermes_frame_desc {
 	/* Hermes - i.e. little-endian byte-order */
-	uint16_t status __PACKED__;
-	uint16_t res1, res2 __PACKED__;
-	uint16_t q_info __PACKED__;
-	uint16_t res3, res4 __PACKED__;
-	uint16_t tx_ctl __PACKED__;
-} hermes_frame_desc_t;
+	u16 status;
+	u16 res1, res2;
+	u16 q_info;
+	u16 res3, res4;
+	u16 tx_ctl;
+} __attribute__ ((packed)) hermes_frame_desc_t;
 
 #define		HERMES_RXSTAT_ERR		(0x0003)
 #define		HERMES_RXSTAT_MACPORT		(0x0700)
@@ -241,21 +238,21 @@
 typedef struct hermes {
 	uint iobase;
 
-	uint16_t inten; /* Which interrupts should be enabled? */
+	u16 inten; /* Which interrupts should be enabled? */
 } hermes_t;
 
 typedef struct hermes_response {
-	uint16_t status, resp0, resp1, resp2;
+	u16 status, resp0, resp1, resp2;
 } hermes_response_t;
 
 /* "ID" structure - used for ESSID and station nickname */
 typedef struct hermes_id {
-	uint16_t len;
-	uint16_t val[16];
+	u16 len;
+	u16 val[16];
 } __attribute__ ((packed)) hermes_id_t;
 
 typedef struct hermes_multicast {
-	uint8_t addr[HERMES_MAX_MULTICAST][ETH_ALEN];
+	u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
 } __attribute__ ((packed)) hermes_multicast_t;
 
 /* Register access convenience macros */
@@ -265,25 +262,21 @@
 #define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name))
 #define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val)))
 
-/* Note that for the next two, the count is in 16-bit words, not bytes */
-#define hermes_read_data(hw, off, buf, count) (insw((hw)->iobase + (off), (buf), (count)))
-#define hermes_write_data(hw, off, buf, count) (outsw((hw)->iobase + (off), (buf), (count)))
-
 /* Function prototypes */
 void hermes_struct_init(hermes_t *hw, uint io);
 int hermes_reset(hermes_t *hw);
-int hermes_docmd_wait(hermes_t *hw, uint16_t cmd, uint16_t parm0, hermes_response_t *resp);
-int hermes_allocate(hermes_t *hw, uint16_t size, uint16_t *fid);
+int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp);
+int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
 
-
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, uint16_t len,
-		       uint16_t id, uint16_t offset);
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, uint16_t len,
-			uint16_t id, uint16_t offset);
-int hermes_read_ltv(hermes_t *hw, int bap, uint16_t rid, int buflen,
-		    uint16_t *length, void *buf);
-int hermes_write_ltv(hermes_t *hw, int bap, uint16_t rid,
-		      uint16_t length, const void *value);
+int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset);
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
+		       u16 id, u16 offset);
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
+			u16 id, u16 offset);
+int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, int buflen,
+		    u16 *length, void *buf);
+int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
+		      u16 length, const void *value);
 
 /* Inline functions */
 
@@ -292,13 +285,13 @@
 	return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
 }
 
-static inline void hermes_enable_interrupt(hermes_t *hw, uint16_t events)
+static inline void hermes_enable_interrupt(hermes_t *hw, u16 events)
 {
 	hw->inten |= events;
 	hermes_write_regn(hw, INTEN, hw->inten);
 }
 
-static inline void hermes_set_irqmask(hermes_t *hw, uint16_t events)
+static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
 {
 	hw->inten = events;
 	hermes_write_regn(hw, INTEN, events);
@@ -323,14 +316,18 @@
 #define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 )
 #define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
 
+/* Note that for the next two, the count is in 16-bit words, not bytes */
+#define hermes_read_words(hw, off, buf, count) (insw((hw)->iobase + (off), (buf), (count)))
+#define hermes_write_words(hw, off, buf, count) (outsw((hw)->iobase + (off), (buf), (count)))
+
 #define HERMES_READ_RECORD(hw, bap, rid, buf) \
 	(hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
 #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
 	(hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
 
-static inline int hermes_read_wordrec(hermes_t *hw, int bap, uint16_t rid, uint16_t *word)
+static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
 {
-	uint16_t rec;
+	u16 rec;
 	int err;
 
 	err = HERMES_READ_RECORD(hw, bap, rid, &rec);
@@ -338,9 +335,9 @@
 	return err;
 }
 
-static inline int hermes_write_wordrec(hermes_t *hw, int bap, uint16_t rid, uint16_t word)
+static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
 {
-	uint16_t rec = cpu_to_le16(word);
+	u16 rec = cpu_to_le16(word);
 	return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/orinoco.c linux/drivers/net/wireless/orinoco.c
--- v2.4.10/linux/drivers/net/wireless/orinoco.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wireless/orinoco.c	Tue Oct  9 15:13:03 2001
@@ -1,4 +1,4 @@
-/* orinoco.c 0.07	- (formerly known as dldwd_cs.c and orinoco_cs.c)
+/* orinoco.c 0.08a	- (formerly known as dldwd_cs.c and orinoco_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -44,33 +44,6 @@
  * under either the MPL or the GPL.
  */
 
-/* Notes on locking:
- *
- * The basic principle of operation is that everything except the
- * interrupt handler is serialized through a single spinlock in the
- * dldwd_priv_t structure, using dldwd_lock() and
- * dldwd_unlock() (which in turn use spin_lock_bh() and spin_unlock_bh()).
- *
- * The kernel's IRQ handling stuff ensures that the interrupt handler
- * does not re-enter itself. The interrupt handler is written such
- * that everything it does is safe without a lock: chiefly this means
- * that the Rx path uses one of the Hermes chipset's BAPs while
- * everything else uses the other.
- *
- * For the moment access to the device statistics from the interrupt
- * handler is unsafe - we just put up with any resulting errors in the
- * statisics. FIXME: This should probably be changed to store the
- * stats in atomic types.
- *
- * EXCEPT that we don't want the irq handler running when we actually
- * reset or shut down the card, because strange things might happen
- * (probably the worst would be one packet of garbage, but you can't
- * be too careful). For this we use __dldwd_stop_irqs() which will set
- * a flag to disable the interrupt handler, and wait for any
- * outstanding instances of the handler to complete. THIS WILL LOSE
- * INTERRUPTS! so it shouldn't be used except for resets, when we
- * don't care about that.*/
-
 /*
  * Tentative changelog...
  *
@@ -180,9 +153,9 @@
  *
  * v0.06e -> v0.06f - 14/8/2001 - David Gibson
  *	o Wording fix to license
- *	o Added a 'use_alternate_encaps' module parameter for APs which need an oui of
- *	  00:00:00.  We really need a better way of handling this, but the module flag
- *	  is better than nothing for now.
+ *	o Added a 'use_alternate_encaps' module parameter for APs which need an
+ *	  oui of 00:00:00.  We really need a better way of handling this, but
+ *	  the module flag is better than nothing for now.
  *
  * v0.06f -> v0.07 - 20/8/2001 - David Gibson
  *	o Removed BAP error retries from hermes_bap_seek().  For Tx we now
@@ -190,12 +163,74 @@
  *	  Rx path, but don't make as much noise about it.
  *	o Firmware detection cleanups.
  *
+ * v0.07 -> v0.07a - 1/10/3001 - Jean II
+ *	o Add code to read Symbol firmware revision, inspired by latest code
+ *	  in Spectrum24 by Lee John Keyser-Allen - Thanks Lee !
+ *	o Thanks to Jared Valentine <hidden@xmission.com> for "providing" me
+ *	  a 3Com card with a recent firmware, fill out Symbol firmware
+ *	  capabilities of latest rev (2.20), as well as older Symbol cards.
+ *	o Disable Power Management in newer Symbol firmware, the API 
+ *	  has changed (documentation needed).
+ *
+ * v0.07a -> v0.08 - 3/10/2001 - David Gibson
+ *	o Fixed a possible buffer overrun found by the Stanford checker (in
+ *	  dldwd_ioctl_setiwencode()).  Can only be called by root anyway, so not
+ *	  a big problem.
+ *	o Turned has_big_wep on for Intersil cards.  That's not true for all of
+ *	  them but we should at least let the capable ones try.
+ *	o Wait for BUSY to clear at the beginning of hermes_bap_seek().  I
+ *	  realised that my assumption that the driver's serialization
+ *	  would prevent the BAP being busy on entry was possibly false, because
+ *	  things other than seeks may make the BAP busy.
+ *	o Use "alternate" (oui 00:00:00) encapsulation by default.
+ *	  Setting use_old_encaps will mimic the old behaviour, but I think we
+ *	  will be able to eliminate this.
+ *	o Don't try to make __initdata const (the version string).  This can't
+ *	  work because of the way the __initdata sectioning works.
+ *	o Added MODULE_LICENSE tags.
+ *	o Support for PLX (transparent PCMCIA->PCI brdge) cards.
+ *	o Changed to using the new type-facist min/max.
+ *
+ * v0.08 -> v0.08a - 9/10/2001 - David Gibson
+ *	o Inserted some missing acknowledgements/info into the Changelog.
+ *	o Fixed some bugs in the normalisation of signel level reporting.
+ *	o Fixed bad bug in WEP key handling on Intersil and Symbol firmware,
+ *	  which led to an instant crash on big-endian machines.
  *
  * TODO - Jean II
- *	o inline functions (lot's of candidate, need to reorder code)
+ *	o inline functions (lots of candidate, need to reorder code)
  *	o Test PrismII/Symbol cards & firmware versions
  *	o Mini-PCI support (some people have reported success - JII)
+ *	o Find and kill remaining Tx timeout problems
  */
+/* Notes on locking:
+ *
+ * The basic principle of operation is that everything except the
+ * interrupt handler is serialized through a single spinlock in the
+ * dldwd_priv_t structure, using dldwd_lock() and
+ * dldwd_unlock() (which in turn use spin_lock_bh() and spin_unlock_bh()).
+ *
+ * The kernel's IRQ handling stuff ensures that the interrupt handler
+ * does not re-enter itself. The interrupt handler is written such
+ * that everything it does is safe without a lock: chiefly this means
+ * that the Rx path uses one of the Hermes chipset's BAPs while
+ * everything else uses the other.
+ *
+ * Actually, the current updating of the statistics from the interrupt
+ * handler is unsafe.  However all it can do is perturb the
+ * packet/byte counts slightly, so we just put up with it.  We could
+ * fix this to use atomic types, but it's probably not worth it.
+ *
+ * The big exception is that that we don't want the irq handler
+ * running when we actually reset or shut down the card, because
+ * strange things might happen (probably the worst would be one packet
+ * of garbage, but you can't be too careful). For this we use
+ * __dldwd_stop_irqs() which will set a flag to disable the interrupt
+ * handler, and wait for any outstanding instances of the handler to
+ * complete. THIS WILL LOSE INTERRUPTS! so it shouldn't be used except
+ * for resets, where losing a few interrupts is acceptable. */
+
+#include <linux/config.h>
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -227,7 +262,7 @@
 #include "hermes.h"
 #include "orinoco.h"
 
-static char version[] __initdata = "orinoco.c 0.07 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco.c 0.08a (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
 MODULE_LICENSE("Dual MPL/GPL");
@@ -238,10 +273,10 @@
 MODULE_PARM(dldwd_debug, "i");
 #endif
 
-/* FIXME: We need a better way of handling this */
-/* Set this flag to use 00:00:00 for the encapsulation oui instead of 00:00:F8 */
-static int use_alternate_encaps; /* =0 */
-MODULE_PARM(use_alternate_encaps, "i");
+int use_old_encaps = 0;
+MODULE_PARM(use_old_encaps, "i");
+
+#define SYMBOL_MAX_VER_LEN	(14)
 
 const long channel_frequency[] = {
 	2412, 2417, 2422, 2427, 2432, 2437, 2442,
@@ -257,14 +292,14 @@
 #define NUM_RATES (sizeof(rate_list) / sizeof(rate_list[0]))
 
 struct p80211_hdr {
-	uint16_t frame_ctl;
-	uint16_t duration_id;
-	uint8_t addr1[ETH_ALEN];
-	uint8_t addr2[ETH_ALEN];
-	uint8_t addr3[ETH_ALEN];
-	uint16_t seq_ctl;
-	uint8_t addr4[ETH_ALEN];
-	uint16_t data_len;
+	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 data_len;
 } __attribute__ ((packed));
 
 /* Frame control field constants */
@@ -284,22 +319,20 @@
 #define DLDWD_FTYPE_CTL			0x0004
 #define DLDWD_FTYPE_DATA		0x0008
 
-#define __PACKED__ __attribute__ ((packed))
-
 struct p8022_hdr {
-	uint8_t dsap __PACKED__;
-	uint8_t ssap __PACKED__;
-	uint8_t ctrl __PACKED__;
-	uint8_t oui[3] __PACKED__;
-};
+	u8 dsap;
+	u8 ssap;
+	u8 ctrl;
+	u8 oui[3];
+} __attribute__ ((packed));
 
 struct dldwd_frame_hdr {
-	hermes_frame_desc_t desc __PACKED__;
-	struct p80211_hdr p80211 __PACKED__;
-	struct ethhdr p8023 __PACKED__;
-	struct p8022_hdr p8022 __PACKED__;
-	uint16_t ethertype __PACKED__;
-};
+	hermes_frame_desc_t desc;
+	struct p80211_hdr p80211;
+	struct ethhdr p8023;
+	struct p8022_hdr p8022;
+	u16 ethertype;
+} __attribute__ ((packed));
 
 #define P8023_OFFSET		(sizeof(hermes_frame_desc_t) + \
 				sizeof(struct p80211_hdr))
@@ -307,19 +340,19 @@
 
 /* 802.2 LLL header SNAP used for SNAP encapsulation over 802.11 */
 struct p8022_hdr encaps_hdr = {
-	0xaa, 0xaa, 0x03, {0x00, 0x00, 0xf8}
-};
-struct p8022_hdr alternate_encaps_hdr = {
 	0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}
 };
 
+struct p8022_hdr old_encaps_hdr = {
+	0xaa, 0xaa, 0x03, {0x00, 0x00, 0xf8}
+};
+
 /* How many times to retry if we get an EIO reading the BAP in the Rx path */
 #define RX_EIO_RETRY		10
 
 typedef struct dldwd_commsqual {
-	uint16_t qual, signal, noise;
-} __PACKED__ dldwd_commsqual_t;
-
+	u16 qual, signal, noise;
+} __attribute__ ((packed)) dldwd_commsqual_t;
 
 /*
  * Function prototypes
@@ -340,7 +373,7 @@
 static int dldwd_hw_get_essid(dldwd_priv_t *priv, int *active, char buf[IW_ESSID_MAX_SIZE+1]);
 static long dldwd_hw_get_freq(dldwd_priv_t *priv);
 static int dldwd_hw_get_bitratelist(dldwd_priv_t *priv, int *numrates,
-				    int32_t *rates, int max);
+				    s32 *rates, int max);
 
 /* Interrupt handling routines */
 static void __dldwd_ev_tick(dldwd_priv_t *priv, hermes_t *hw);
@@ -410,7 +443,7 @@
 }
 
 static inline void
-__dldwd_start_irqs(dldwd_priv_t *priv, uint16_t irqmask)
+__dldwd_start_irqs(dldwd_priv_t *priv, u16 irqmask)
 {
 	hermes_t *hw = &priv->hw;
 
@@ -556,8 +589,11 @@
 	/* Set up encryption */
 	if (priv->has_wep) {
 		err = __dldwd_hw_setup_wep(priv);
-		if (err)
+		if (err) {
+			printk(KERN_ERR "%s: Error %d activating WEP.\n",
+			       dev->name, err);
 			goto out;
+		}
 	}
 
 	/* Set the desired ESSID */
@@ -670,6 +706,8 @@
 	int	master_wep_flag;
 	int	auth_flag;
 
+	TRACE_ENTER(priv->ndev.name);
+
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_LUCENT: /* Lucent style WEP */
 		if (priv->wep_on) {
@@ -690,28 +728,34 @@
 	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
 		master_wep_flag = 0;		/* Off */
 		if (priv->wep_on) {
-			char keybuf[LARGE_KEY_SIZE+1];
-			int keylen;
+/*  			int keylen; */
 			int i;
 
 			/* Fudge around firmware weirdness */
-			keylen = priv->keys[priv->tx_key].len;
+/*  			keylen = priv->keys[priv->tx_key].len; */
 
 			/* Write all 4 keys */
 			for(i = 0; i < MAX_KEYS; i++) {
-				memset(keybuf, 0, sizeof(keybuf));
-				memcpy(keybuf, priv->keys[i].data,
-				       priv->keys[i].len);
+				int keylen = le16_to_cpu(priv->keys[i].len);
+
+				if (keylen > LARGE_KEY_SIZE) {
+					printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
+					       priv->ndev.name, i, keylen);
+					return -E2BIG;
+				}
+
+				printk("About to write key %d, keylen=%d\n",
+				       i, keylen);				     
 				err = hermes_write_ltv(hw, USER_BAP,
-						       HERMES_RID_CNF_PRISM2_KEY0 + i,
+						       HERMES_RID_CNF_INTERSIL_KEY0 + i,
 						       HERMES_BYTES_TO_RECLEN(keylen),
-						       keybuf);
+						       priv->keys[i].data);
 				if (err)
 					return err;
 			}
 
 			/* Write the index of the key used in transmission */
-			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_TX_KEY,
+			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_INTERSIL_TX_KEY,
 						   priv->tx_key);
 			if (err)
 				return err;
@@ -743,9 +787,10 @@
 		}
 		
 		/* Master WEP setting : on/off */
-		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_WEP_ON, master_wep_flag);
+		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_INTERSIL_WEP_ON, master_wep_flag);
 		if (err)
 			return err;	
+
 		break;
 
 	default:
@@ -756,6 +801,8 @@
 		}
 	}
 
+	TRACE_EXIT(priv->ndev.name);
+
 	return 0;
 }
 
@@ -795,7 +842,7 @@
 		/* My guess is that the OWN_SSID should always be whatever
 		 * we set to the card, whereas CURRENT_SSID is the one that
 		 * may change... - Jean II */
-		uint16_t rid;
+		u16 rid;
 
 		*active = 1;
 
@@ -834,7 +881,7 @@
 	
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	uint16_t channel;
+	u16 channel;
 	long freq = 0;
 
 	dldwd_lock(priv);
@@ -862,7 +909,7 @@
 }
 
 static int dldwd_hw_get_bitratelist(dldwd_priv_t *priv, int *numrates,
-				    int32_t *rates, int max)
+				    s32 *rates, int max)
 {
 	hermes_t *hw = &priv->hw;
 	hermes_id_t list;
@@ -881,7 +928,7 @@
 	
 	num = le16_to_cpu(list.len);
 	*numrates = num;
-	num = MIN(num, max);
+	num = min(num, max);
 
 	for (i = 0; i < num; i++) {
 		rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
@@ -960,7 +1007,7 @@
 	hermes_t *hw = &priv->hw;
 	struct net_device *dev = &priv->ndev;
 	int count = IRQ_LOOP_MAX;
-	uint16_t evstat, events;
+	u16 evstat, events;
 	static int old_time = 0, timecount = 0; /* Eugh, revolting hack for now */
 
 	if (test_and_set_bit(DLDWD_STATE_INIRQ, &priv->state))
@@ -1066,7 +1113,7 @@
 	struct iw_statistics *wstats = &priv->wstats;
 	struct sk_buff *skb = NULL;
 	int l = RX_EIO_RETRY;
-	uint16_t rxfid, status;
+	u16 rxfid, status;
 	int length, data_len, data_off;
 	char *p;
 	struct dldwd_frame_hdr hdr;
@@ -1241,7 +1288,7 @@
 
 static void __dldwd_ev_alloc(dldwd_priv_t *priv, hermes_t *hw)
 {
-	uint16_t allocfid;
+	u16 allocfid;
 
 	allocfid = hermes_read_regn(hw, ALLOCFID);
 	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev.name, allocfid);
@@ -1259,9 +1306,9 @@
 	hermes_t *hw = &priv->hw;
 	int err;
 	struct sta_id {
-		uint16_t id, vendor, major, minor;
-	} __PACKED__ sta_id;
-	uint32_t firmver;
+		u16 id, vendor, major, minor;
+	} __attribute__ ((packed)) sta_id;
+	u32 firmver;
 
 	/* Get the firmware version */
 	err = HERMES_READ_RECORD(hw, USER_BAP,
@@ -1276,7 +1323,7 @@
 	le16_to_cpus(&sta_id.major);
 	le16_to_cpus(&sta_id.minor);
 
-	firmver = ((uint32_t)sta_id.major << 16) | sta_id.minor;
+	firmver = ((u32)sta_id.major << 16) | sta_id.minor;
 
 	printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
 	       dev->name, sta_id.id, sta_id.vendor,
@@ -1286,7 +1333,7 @@
 
 	if (sta_id.vendor == 1) {
 		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
-		   ELSE, Meloc, HP, IBM, Dell 1150 */
+		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
 		printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
 		       "version %d.%02d\n", dev->name,
 		       sta_id.major, sta_id.minor);
@@ -1303,7 +1350,7 @@
 		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);
+		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
 		priv->has_preamble = 0;
 		priv->ibss_port = 1;
 		/* Tested with Lucent firmware :
@@ -1314,27 +1361,55 @@
 		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
 		/* Intel MAC : 00:02:B3:* */
 		/* 3Com MAC : 00:50:DA:* */
+		char tmp[SYMBOL_MAX_VER_LEN+1];
+
+		memset(tmp, 0, sizeof(tmp));
+		/* Get the Symbol firmware version */
+		err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SYMBOL_SECONDARY_VER,
+				      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';
+		}
+
 		printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
-		       "(unknown version)\n", dev->name);
+		       "version [%s] (parsing to %X)\n", dev->name,
+		       tmp, firmver);
 
-		/* FIXME : we need to get Symbol firmware revision.
-		 * I tried to use SYMBOL_***ARY_VER, but it didn't
-		 * returned anything proper... */
 		priv->firmware_type = FIRMWARE_TYPE_SYMBOL;
 		priv->tx_rate_ctrl = 0xF;	/* 11 Mb/s auto */
 		priv->need_card_reset = 1;
 		priv->broken_reset = 0;
 		priv->broken_allocate = 1;
 		priv->has_port3 = 1;
-		priv->has_ibss = 1; /* FIXME */
-		priv->has_wep = 1; /* FIXME */
-		priv->has_big_wep = 1;	/* RID_SYMBOL_KEY_LENGTH */
+		priv->has_ibss = (firmver >= 0x20000);
+		priv->has_wep = (firmver >= 0x15012);
+		priv->has_big_wep = (firmver >= 0x20000);
 		priv->has_mwo = 0;
-		priv->has_pm = 1; /* FIXME */
-		priv->has_preamble = 0; /* FIXME */
+		priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
+		priv->has_preamble = (firmver >= 0x20000);
 		priv->ibss_port = 4;
-		/* Tested with Intel firmware : v15 => Jean II */
+		/* Tested with Intel firmware : 0x20015 => Jean II */
+		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
 	} else {
+		/* 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:* */
 		printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
 		       "version %d.%02d\n", dev->name,
 		       sta_id.major, sta_id.minor);
@@ -1347,7 +1422,7 @@
 		priv->has_port3 = 1;
 		priv->has_ibss = (firmver >= 0x00007); /* FIXME */
 		priv->has_wep = (firmver >= 0x00008);
-		priv->has_big_wep = 0;
+		priv->has_big_wep = priv->has_wep;
 		priv->has_mwo = 0;
 		priv->has_pm = (firmver >= 0x00007);
 		priv->has_preamble = 0;
@@ -1374,11 +1449,11 @@
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	hermes_id_t nickbuf;
-	uint16_t reclen;
+	u16 reclen;
 	int len;
 
 	TRACE_ENTER("dldwd");
-	
+
 	dldwd_lock(priv);
 
 	/* Do standard firmware reset */
@@ -1426,10 +1501,10 @@
 		       dev->name);
 		goto out;
 	}
-	if ( nickbuf.len )
-		len = MIN(IW_ESSID_MAX_SIZE, le16_to_cpu(nickbuf.len));
+	if (nickbuf.len)
+		len = min_t(u16, IW_ESSID_MAX_SIZE, le16_to_cpu(nickbuf.len));
 	else
-		len = MIN(IW_ESSID_MAX_SIZE, 2 * reclen);
+		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
 	memcpy(priv->nick, &nickbuf.val, len);
 	priv->nick[len] = '\0';
 
@@ -1556,20 +1631,12 @@
 		err = HERMES_READ_RECORD(hw, USER_BAP,
 					 HERMES_RID_COMMSQUALITY, &cq);
 		
-		le16_to_cpus(&cq.qual);
-		le16_to_cpus(&cq.signal);
-		le16_to_cpus(&cq.noise);
-		
 		DEBUG(3, "%s: Global stats = %X-%X-%X\n", dev->name,
 		      cq.qual, cq.signal, cq.noise);
 
-		/* Why are we using MIN/MAX ? We don't really care
-		 * if the value goes above max, because we export the
-		 * raw dBm values anyway. The normalisation should be done
-		 * in user space - Jean II */
-		wstats->qual.qual = MAX(MIN(cq.qual, 0x8b-0x2f), 0);
-		wstats->qual.level = MAX(MIN(cq.signal, 0x8a), 0x2f) - 0x95;
-		wstats->qual.noise = MAX(MIN(cq.noise, 0x8a), 0x2f) - 0x95;
+		wstats->qual.qual = (int)le16_to_cpu(cq.qual);
+		wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
+		wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
 		wstats->qual.updated = 7;
 	}
 
@@ -1582,9 +1649,8 @@
 }
 
 #ifdef WIRELESS_SPY
-static inline void dldwd_spy_gather(struct net_device *dev,
-				    u_char *mac,
-				    dldwd_commsqual_t *cq)
+static inline void dldwd_spy_gather(struct net_device *dev, u_char *mac,
+				    int level, int noise)
 {
 	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
 	int i;
@@ -1593,9 +1659,9 @@
 	 * source address with out list, and if match, get the stats... */
 	for (i = 0; i < priv->spy_number; i++)
 		if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
-			priv->spy_stat[i].qual = MAX(MIN(cq->qual, 0x8b-0x2f), 0);
-			priv->spy_stat[i].level = MAX(MIN(cq->signal, 0x8a), 0x2f) - 0x95;
-			priv->spy_stat[i].noise = MAX(MIN(cq->noise, 0x8a), 0x2f) - 0x95;
+			priv->spy_stat[i].level = level - 0x95;
+			priv->spy_stat[i].noise = noise - 0x95;
+			priv->spy_stat[i].qual = level - noise;
 			priv->spy_stat[i].updated = 7;
 		}
 }
@@ -1607,7 +1673,6 @@
 		   struct dldwd_frame_hdr *hdr)
 {
 	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
-	dldwd_commsqual_t cq;
 
 	/* Using spy support with lots of Rx packets, like in an
 	 * infrastructure (AP), will really slow down everything, because
@@ -1617,31 +1682,18 @@
 	 * Note that to get here, you need both WIRELESS_SPY
 	 * compiled in AND some addresses in the list !!!
 	 */
-#ifdef WIRELESS_EXT
+#ifdef WIRELESS_SPY
 	/* Note : gcc will optimise the whole section away if
 	 * WIRELESS_SPY is not defined... - Jean II */
-	if (
-#ifdef WIRELESS_SPY
-		(priv->spy_number > 0) ||
-#endif
-		0 )
-	{
-		u_char *stats = (u_char *) &(hdr->desc.q_info);
+	if (priv->spy_number > 0) {
+		u8 *stats = (u8 *) &(hdr->desc.q_info);
 		/* This code may look strange. Everywhere we are using 16 bit
 		 * ints except here. I've verified that these are are the
 		 * correct values. Please check on PPC - Jean II */
-		cq.signal = stats[1];	/* High order byte */
-		cq.noise = stats[0];	/* Low order byte */
-		cq.qual = stats[0] - stats[1];	/* Better than nothing */
-
-		DEBUG(3, "%s: Packet stats = %X-%X-%X\n", dev->name,
-		      cq.qual, cq.signal, cq.noise);
 
-#ifdef WIRELESS_SPY
-		dldwd_spy_gather(dev, skb->mac.raw + ETH_ALEN, &cq);  
-#endif
+		dldwd_spy_gather(dev, skb->mac.raw + ETH_ALEN, (int)stats[1], (int)stats[0]);
 	}
-#endif /* WIRELESS_EXT */
+#endif /* WIRELESS_SPY */
 }
 
 int
@@ -1651,7 +1703,7 @@
 	struct net_device_stats *stats = &priv->stats;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	uint16_t txfid = priv->txfid;
+	u16 txfid = priv->txfid;
 	char *p;
 	struct ethhdr *eh;
 	int len, data_len, data_off;
@@ -1674,7 +1726,7 @@
 	dldwd_lock(priv);
 
 	/* Length of the packet body */
-	len = MAX(skb->len - ETH_HLEN, ETH_ZLEN);
+	len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN);
 
 	eh = (struct ethhdr *)skb->data;
 
@@ -1699,12 +1751,13 @@
 		hdr.p8023.h_proto = htons(data_len + ENCAPS_OVERHEAD);
 		
 		/* 802.2 header */
-		/* FIXME: ugh, what a hack for the 00:00:00 APs.  Need to find a better way */
-		if (use_alternate_encaps)
-			memcpy(&hdr.p8022, &alternate_encaps_hdr, sizeof(alternate_encaps_hdr));
+		if (! use_old_encaps) 
+			memcpy(&hdr.p8022, &encaps_hdr,
+			       sizeof(encaps_hdr));
 		else
-			memcpy(&hdr.p8022, &encaps_hdr, sizeof(encaps_hdr));
-
+			memcpy(&hdr.p8022, &encaps_hdr,
+			       sizeof(old_encaps_hdr));
+			
 		hdr.ethertype = eh->h_proto;
 		err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
 					 txfid, 0);
@@ -1930,15 +1983,15 @@
 	int setindex = priv->tx_key;
 	int enable = priv->wep_on;
 	int restricted = priv->wep_restrict;
-	uint16_t xlen = 0;
+	u16 xlen = 0;
 	int err = 0;
 	char keybuf[MAX_KEY_SIZE];
-
+	
 	if (erq->pointer) {
 		/* We actually have a key to set */
-		if(erq->length > MAX_KEY_SIZE)
+		if ( (erq->length < SMALL_KEY_SIZE) || (erq->length > MAX_KEY_SIZE) )
 			return -EINVAL;
-
+		
 		if (copy_from_user(keybuf, erq->pointer, erq->length))
 			return -EFAULT;
 	}
@@ -2018,7 +2071,7 @@
 {
 	dldwd_priv_t *priv = dev->priv;
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-	uint16_t xlen = 0;
+	u16 xlen = 0;
 	char keybuf[MAX_KEY_SIZE];
 
 	
@@ -2068,7 +2121,7 @@
 
 	memset(&essidbuf, 0, sizeof(essidbuf));
 
-	if (erq->flags) { 
+	if (erq->flags) {
 		if (erq->length > IW_ESSID_MAX_SIZE)
 			return -E2BIG;
 		
@@ -2080,7 +2133,7 @@
 
 	dldwd_lock(priv);
 
-	memcpy(priv->desired_essid, essidbuf, IW_ESSID_MAX_SIZE+1);
+	memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
 
 	dldwd_unlock(priv);
 
@@ -2194,7 +2247,7 @@
 {
 	dldwd_priv_t *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
-	uint16_t val;
+	u16 val;
 	int err;
 
 	dldwd_lock(priv);
@@ -2280,7 +2333,7 @@
 	dldwd_priv_t *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	uint16_t val;
+	u16 val;
 
 	dldwd_lock(priv);
 	
@@ -2389,7 +2442,7 @@
 	dldwd_priv_t *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	uint16_t val;
+	u16 val;
 	int brate = 0;
 
 	dldwd_lock(priv);
@@ -2503,7 +2556,7 @@
 	dldwd_priv_t *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	uint16_t enable, period, timeout, mcast;
+	u16 enable, period, timeout, mcast;
 
 	dldwd_lock(priv);
 	
@@ -2549,7 +2602,7 @@
 	dldwd_priv_t *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	uint16_t short_limit, long_limit, lifetime;
+	u16 short_limit, long_limit, lifetime;
 
 	dldwd_lock(priv);
 	
@@ -3418,7 +3471,7 @@
 }
 
 struct {
-	uint16_t rid;
+	u16 rid;
 	char *name;
 	int minlen, maxlen;
 	int displaytype;
@@ -3449,12 +3502,12 @@
 	RTCNFENTRY(KEYS, DISPLAY_BYTES),
 	RTCNFENTRY(TX_KEY, DISPLAY_WORDS),
 	RTCNFENTRY(TICKTIME, DISPLAY_WORDS),
-	RTCNFENTRY(PRISM2_TX_KEY, DISPLAY_WORDS),
-	RTCNFENTRY(PRISM2_KEY0, DISPLAY_BYTES),
-	RTCNFENTRY(PRISM2_KEY1, DISPLAY_BYTES),
-	RTCNFENTRY(PRISM2_KEY2, DISPLAY_BYTES),
-	RTCNFENTRY(PRISM2_KEY3, DISPLAY_BYTES),
-	RTCNFENTRY(PRISM2_WEP_ON, DISPLAY_WORDS),
+	RTCNFENTRY(INTERSIL_TX_KEY, DISPLAY_WORDS),
+	RTCNFENTRY(INTERSIL_KEY0, DISPLAY_BYTES),
+	RTCNFENTRY(INTERSIL_KEY1, DISPLAY_BYTES),
+	RTCNFENTRY(INTERSIL_KEY2, DISPLAY_BYTES),
+	RTCNFENTRY(INTERSIL_KEY3, DISPLAY_BYTES),
+	RTCNFENTRY(INTERSIL_WEP_ON, DISPLAY_WORDS),
 #undef RTCNFENTRY
 #define RTINFENTRY(name,type) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, type }
 	RTINFENTRY(CHANNEL_LIST, DISPLAY_WORDS),
@@ -3479,7 +3532,7 @@
 	char *buf;
 	int total = 0, slop = 0;
 	int i;
-	uint16_t length;
+	u16 length;
 	int err;
 
 	/* Hum, in this case hardware register are probably not readable... */
@@ -3490,12 +3543,12 @@
 
 	/* print out all the config RIDs */
 	for (i = 0; i < NUM_RIDS; i++) {
-		uint16_t rid = record_table[i].rid;
+		u16 rid = record_table[i].rid;
 		int minlen = record_table[i].minlen;
 		int maxlen = record_table[i].maxlen;
 		int len;
-		uint8_t *val8;
-		uint16_t *val16;
+		u8 *val8;
+		u16 *val16;
 		int j;
 
 		val8 = kmalloc(maxlen + 2, GFP_KERNEL);
@@ -3508,11 +3561,11 @@
 			DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
 			continue;
 		}
-		val16 = (uint16_t *)val8;
+		val16 = (u16 *)val8;
 
 		buf += sprintf(buf, "%-15s (0x%04x): length=%d (%d bytes)\tvalue=", record_table[i].name,
 			       rid, length, (length-1)*2);
-		len = MIN( MAX(minlen, (length-1)*2), maxlen);
+		len = min( (int)max(minlen, ((int)length-1)*2), maxlen);
 
 		switch (record_table[i].displaytype) {
 		case DISPLAY_WORDS:
@@ -3531,7 +3584,7 @@
 			break;
 
 		case DISPLAY_STRING:
-			len = MIN(len, le16_to_cpu(val16[0])+2);
+			len = min(len, le16_to_cpu(val16[0])+2);
 			val8[len] = '\0';
 			buf += sprintf(buf, "\"%s\"", (char *)&val16[1]);
 			break;
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/orinoco.h linux/drivers/net/wireless/orinoco.h
--- v2.4.10/linux/drivers/net/wireless/orinoco.h	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wireless/orinoco.h	Tue Oct  9 15:13:03 2001
@@ -8,7 +8,7 @@
 #define _ORINOCO_H
 
 /* To enable debug messages */
-//#define ORINOCO_DEBUG		3
+/*  #define ORINOCO_DEBUG		3 */
 
 #if (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10)
 #error "orinoco_cs requires Wireless extensions v10 or later."
@@ -25,7 +25,7 @@
 #define DLDWD_MACPORT		0
 #define IRQ_LOOP_MAX		10
 #define TX_NICBUF_SIZE		2048
-#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Intel firmware */
+#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
 #define MAX_KEYS		4
 #define MAX_KEY_SIZE		14
 #define LARGE_KEY_SIZE		13
@@ -33,7 +33,7 @@
 #define MAX_FRAME_SIZE		2304
 
 typedef struct dldwd_key {
-	uint16_t len;
+	uint16_t len;	/* always store little-endian */
 	char data[MAX_KEY_SIZE];
 } __attribute__ ((packed)) dldwd_key_t;
 
@@ -110,7 +110,7 @@
 
 #ifdef ORINOCO_DEBUG
 extern int dldwd_debug;
-#define DEBUG(n, args...) if (dldwd_debug>(n)) printk(KERN_DEBUG args)
+#define DEBUG(n, args...) do { if (dldwd_debug>(n)) printk(KERN_DEBUG args); } while(0)
 #define DEBUGMORE(n, args...) do { if (dldwd_debug>(n)) printk(args); } while (0)
 #else
 #define DEBUG(n, args...) do { } while (0)
@@ -119,9 +119,6 @@
 
 #define TRACE_ENTER(devname) DEBUG(2, "%s: -> " __FUNCTION__ "()\n", devname);
 #define TRACE_EXIT(devname)  DEBUG(2, "%s: <- " __FUNCTION__ "()\n", devname);
-
-#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
-#define MIN(a, b) ( (a) < (b) ? (a) : (b) )
 
 #define RUP_EVEN(a) ( (a) % 2 ? (a) + 1 : (a) )
 
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/orinoco_cs.c linux/drivers/net/wireless/orinoco_cs.c
--- v2.4.10/linux/drivers/net/wireless/orinoco_cs.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/wireless/orinoco_cs.c	Tue Oct  9 15:13:03 2001
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.07	- (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.08a	- (formerly known as dldwd_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -10,6 +10,8 @@
  * Copyright notice & release notes in file orinoco.c
  */
 
+#include <linux/config.h>
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -42,7 +44,7 @@
 
 /*====================================================================*/
 
-static char version[] __initdata = "orinoco_cs.c 0.07 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco_cs.c 0.08a (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
@@ -198,7 +200,7 @@
 	CardServices(AccessConfigurationRegister, link->handle, &reg);
 	default_cor = reg.Value;
 
-	DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%lX\n", default_cor);
+	DEBUG(2, "dldwd : dldwd_cs_cor_reset() : cor=0x%X\n", default_cor);
 
 	/* Soft-Reset card */
 	reg.Action = CS_WRITE;
diff -u --recursive --new-file v2.4.10/linux/drivers/net/wireless/orinoco_plx.c linux/drivers/net/wireless/orinoco_plx.c
--- v2.4.10/linux/drivers/net/wireless/orinoco_plx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/wireless/orinoco_plx.c	Tue Oct  9 15:13:03 2001
@@ -0,0 +1,306 @@
+/* orinoco_plx.c 0.01
+ * 
+ * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a PLX9052. 
+ *
+ * Specifically here we're talking about the SMC2602W (EZConnect
+ * Wireless PCI Adaptor)
+ *
+ * The actual driving is done by orinoco.c, this is just resource
+ * allocation stuff.  The explanation below is courtesy of Ryan Niemi
+ * on the linux-wlan-ng list at
+ * http://archives.neohapsis.com/archives/dev/linux-wlan/2001-q1/0026.html
+ *
+ * Copyright (C) 2001 Daniel Barlow <dan@telent.net>
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+
+The PLX9052-based cards (WL11000 and several others) are a different
+beast than the usual PCMCIA-based PRISM2 configuration expected by
+wlan-ng. Here's the general details on how the WL11000 PCI adapter
+works:
+
+ - Two PCI I/O address spaces, one 0x80 long which contains the PLX9052
+   registers, and one that's 0x40 long mapped to the PCMCIA slot I/O
+   address space.
+
+ - One PCI memory address space, mapped to the PCMCIA memory space
+   (containing the CIS).
+
+After identifying the I/O and memory space, you can read through the
+memory space to confirm the CIS's device ID or manufacturer ID to make
+sure it's the expected card. Keep in mind that the PCMCIA spec specifies
+the CIS as the lower 8 bits of each word read from the CIS, so to read the
+bytes of the CIS, read every other byte (0,2,4,...). Passing that test,
+you need to enable the I/O address space on the PCMCIA card via the PCMCIA
+COR register. This is the first byte following the CIS. In my case
+(which may not have any relation to what's on the PRISM2 cards), COR was
+at offset 0x800 within the PCI memory space. Write 0x41 to the COR
+register to enable I/O mode and to select level triggered interrupts. To
+confirm you actually succeeded, read the COR register back and make sure
+it actually got set to 0x41, incase you have an unexpected card inserted.
+
+Following that, you can treat the second PCI I/O address space (the one
+that's not 0x80 in length) as the PCMCIA I/O space.
+
+Note that in the Eumitcom's source for their drivers, they register the
+interrupt as edge triggered when registering it with the Windows kernel. I
+don't recall how to register edge triggered on Linux (if it can be done at
+all). But in some experimentation, I don't see much operational
+difference between using either interrupt mode. Don't mess with the
+interrupt mode in the COR register though, as the PLX9052 wants level
+triggers with the way the serial EEPROM configures it on the WL11000.
+
+There's some other little quirks related to timing that I bumped into, but
+I don't recall right now. Also, there's two variants of the WL11000 I've
+seen, revision A1 and T2. These seem to differ slightly in the timings
+configured in the wait-state generator in the PLX9052. There have also
+been some comments from Eumitcom that cards shouldn't be hot swapped,
+apparently due to risk of cooking the PLX9052. I'm unsure why they
+believe this, as I can't see anything in the design that would really
+cause a problem, except for crashing drivers not written to expect it. And
+having developed drivers for the WL11000, I'd say it's quite tricky to
+write code that will successfully deal with a hot unplug. Very odd things
+happen on the I/O side of things. But anyway, be warned. Despite that,
+I've hot-swapped a number of times during debugging and driver development
+for various reasons (stuck WAIT# line after the radio card's firmware
+locks up).
+
+Hope this is enough info for someone to add PLX9052 support to the wlan-ng
+card. In the case of the WL11000, the PCI ID's are 0x1639/0x0200, with
+matching subsystem ID's. Other PLX9052-based manufacturers other than
+Eumitcom (or on cards other than the WL11000) may have different PCI ID's.
+
+If anyone needs any more specific info, let me know. I haven't had time
+to implement support myself yet, and with the way things are going, might
+not have time for a while..
+
+---end of mail---
+
+  Bus  0, device   4, function  0:
+    Network controller: Unknown vendor Unknown device (rev 2).
+      Vendor id=1638. Device id=1100.
+      Medium devsel.  Fast back-to-back capable.  IRQ 10.  
+      I/O at 0x1000 [0x1001].
+      Non-prefetchable 32 bit memory at 0x40000000 [0x40000000].
+      I/O at 0x10c0 [0x10c1].
+*/
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <linux/proc_fs.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/wireless.h>
+#include <linux/fcntl.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/bus_ops.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static dev_info_t dev_info = "orinoco_plx";
+
+#define COR_OFFSET    0x3e0	/* COR attribute offset of Prism2 PC card */
+#define COR_VALUE     0x41	/* Enable PC card with interrupt in level trigger */
+
+static int orinoco_plx_open(struct net_device *dev)
+{
+	dldwd_priv_t *priv = (dldwd_priv_t *) dev->priv;
+	int err;
+
+	netif_device_attach(dev);
+
+	err = dldwd_reset(priv);
+	if (err)
+		printk(KERN_ERR "%s: dldwd_reset failed in orinoco_plx_open()",
+		       dev->name);
+	else
+		netif_start_queue(dev);
+
+	return err;
+}
+
+static int orinoco_plx_stop(struct net_device *dev)
+{
+	dldwd_priv_t *priv = (dldwd_priv_t *) dev->priv;
+	netif_stop_queue(dev);
+	dldwd_shutdown(priv);
+	return 0;
+}
+
+static void
+orinoco_plx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	dldwd_interrupt(irq, ((struct net_device *) dev_id)->priv, regs);
+}
+
+static int orinoco_plx_init_one(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	struct net_device *dev;
+	unsigned long pccard_ioaddr;
+	int i;
+	int reg;
+	unsigned char *attr_mem;
+	dldwd_priv_t *priv;
+
+	if ((i = pci_enable_device(pdev)))
+		return -EIO;
+
+	/* Resource 2 is mapped to the PCMCIA space */
+	attr_mem = ioremap(pci_resource_start(pdev, 2), 0x1000);
+	/* and 3 to the PCMCIA slot I/O address space */
+	pccard_ioaddr = pci_resource_start(pdev, 3);
+
+	/* Verify whether PC card is present */
+	if (attr_mem[0] != 0x01 || attr_mem[2] != 0x03 ||
+	    attr_mem[4] != 0x00 || attr_mem[6] != 0x00 ||
+	    attr_mem[8] != 0xFF || attr_mem[10] != 0x17 ||
+	    attr_mem[12] != 0x04 || attr_mem[14] != 0x67) {
+		printk(KERN_ERR "orinoco_plx: The CIS value of Prism2 PC card is invalid.\n");
+		return -EIO;
+	}
+	/* PCMCIA COR is the first byte following CIS: this write should
+	 * enable I/O mode and select level-triggered interrupts */
+	attr_mem[COR_OFFSET] = COR_VALUE;
+	reg = attr_mem[COR_OFFSET];
+	/* assert(reg==COR_VALUE); doesn't work */
+	iounmap(attr_mem);	/* done with this now, it seems */
+	if (!request_region(pccard_ioaddr,
+			    pci_resource_len(pdev, 3), dev_info)) {
+		printk(KERN_ERR "orinoco_plx: I/O resource 0x%lx @ 0x%lx busy\n",
+		       pci_resource_len(pdev, 3), pccard_ioaddr);
+		return -EBUSY;
+	}
+	if (!(priv = kmalloc(sizeof(*priv), GFP_KERNEL)))
+		return -ENOMEM;
+	memset(priv, 0, sizeof(*priv));
+	dev = &priv->ndev;
+
+	dldwd_setup(priv);	/* XXX clean up if <0 */
+	dev->irq = pdev->irq;
+	dev->base_addr = pccard_ioaddr;
+	dev->open = orinoco_plx_open;
+	dev->stop = orinoco_plx_stop;
+	priv->card_reset_handler = NULL; /* We have no reset handler */
+
+	printk(KERN_DEBUG
+	       "Detected Orinoco/Prism2 PCI device at %s, mem:0x%lx, irq:%d, io addr:0x%lx\n",
+	       pdev->slot_name, (long) attr_mem, pdev->irq, pccard_ioaddr);
+
+	hermes_struct_init(&(priv->hw), dev->base_addr);	/* XXX */
+	dev->name[0] = '\0';	/* name defaults to ethX */
+	register_netdev(dev);
+	request_irq(pdev->irq, orinoco_plx_interrupt, SA_SHIRQ, dev->name,
+		    dev);
+	if (dldwd_proc_dev_init(priv) != 0) {
+		printk(KERN_ERR "%s: Failed to create /proc node\n", dev->name);
+		return -EIO;
+	}
+
+	SET_MODULE_OWNER(dev);
+	priv->hw_ready = 1;
+
+	/* if(reset_cor) dldwd_cs_cor_reset(priv); */
+	return 0;		/* succeeded */
+}
+
+static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	dldwd_priv_t *priv = dev->priv;
+
+	if (!dev)
+		BUG();
+
+	dldwd_proc_dev_cleanup(priv);
+	free_irq(dev->irq, dev);
+	unregister_netdev(dev);
+	release_region(dev->base_addr, 0x40);
+	kfree(dev->priv);
+	pci_set_drvdata(pdev, NULL);
+}
+
+
+static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
+	{0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},
+	{0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table);
+
+static struct pci_driver orinoco_plx_driver = {
+	name:"orinoco_plx",
+	id_table:orinoco_plx_pci_id_table,
+	probe:orinoco_plx_init_one,
+	remove:orinoco_plx_remove_one,
+	suspend:0,
+	resume:0
+};
+
+static int __init orinoco_plx_init(void)
+{
+	return pci_module_init(&orinoco_plx_driver);
+}
+
+extern void __exit orinoco_plx_exit(void)
+{
+	pci_unregister_driver(&orinoco_plx_driver);
+}
+
+module_init(orinoco_plx_init);
+module_exit(orinoco_plx_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -u --recursive --new-file v2.4.10/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
--- v2.4.10/linux/drivers/net/yellowfin.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/net/yellowfin.c	Sun Sep 30 12:26:07 2001
@@ -150,6 +150,8 @@
 #endif /* !USE_IO_OPS */
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- v2.4.10/linux/drivers/parport/ChangeLog	Sun Sep 23 11:40:59 2001
+++ linux/drivers/parport/ChangeLog	Mon Oct  8 11:54:10 2001
@@ -1,3 +1,23 @@
+2001-10-08  David C. Hansen  <haveblue@us.ibm.com>
+
+	* share.c: Make driverlist_lock and parportlist_lock static.
+
+2001-10-08  Philip Blundell  <philb@gnu.org>
+
+	* parport_pc.c: New modular parameter verbose_logging.
+	Make port->modes indicate the modes that we are prepared to use,
+	rather than the modes that are available.
+
+2001-10-07  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_pc.c (parport_pc_probe_port): Fix memory leak spotted by
+	Kipp Cannon.
+
+2001-10-07  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_serial.c: Remove NetMos support, since it causes problems
+	for some people.
+
 2001-08-30  Tim Waugh  <twaugh@redhat.com>
 
 	* parport_serial.c (parport_serial_pci_probe): Clean-up on partial
diff -u --recursive --new-file v2.4.10/linux/drivers/parport/parport_cs.c linux/drivers/parport/parport_cs.c
--- v2.4.10/linux/drivers/parport/parport_cs.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/parport/parport_cs.c	Sun Sep 30 12:26:08 2001
@@ -480,3 +480,4 @@
 
 module_init(init_parport_cs);
 module_exit(exit_parport_cs);
+MODULE_LICENSE("Dual MPL/GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.4.10/linux/drivers/parport/parport_pc.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/parport/parport_pc.c	Mon Oct  8 11:54:10 2001
@@ -91,6 +91,7 @@
 } superios[NR_SUPERIOS] __devinitdata = { {0,},};
 
 static int user_specified __devinitdata = 0;
+static int verbose_probing;
 static int registered_parport;
 
 /* frob_control, but for ECR */
@@ -1244,10 +1245,10 @@
 static void __devinit show_parconfig_smsc37c669(int io, int key)
 {
 	int cr1,cr4,cra,cr23,cr26,cr27,i=0;
-	char *modes[]={ "SPP and Bidirectional (PS/2)",	
-			"EPP and SPP",
-			"ECP",
-			"ECP and EPP"};
+	static const char *modes[]={ "SPP and Bidirectional (PS/2)",	
+				     "EPP and SPP",
+				     "ECP",
+				     "ECP and EPP" };
 
 	outb(key,io);
 	outb(key,io);
@@ -1265,23 +1266,25 @@
 	cr27=inb(io+1);
 	outb(0xaa,io);
 
-	printk (KERN_INFO "SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, "
-		"A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n",
-		cr1,cr4,cra,cr23,cr26,cr27);
-
-	/* The documentation calls DMA and IRQ-Lines by letters, so
-	   the board maker can/will wire them
-	   appropriately/randomly...  G=reserved H=IDE-irq, */
-	printk (KERN_INFO "SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, "
-		"fifo threshold=%d\n", cr23*4,
-		(cr27 &0x0f) ? 'A'-1+(cr27 &0x0f): '-',
-		(cr26 &0x0f) ? 'A'-1+(cr26 &0x0f): '-', cra & 0x0f);
-	printk(KERN_INFO "SMSC LPT Config: enabled=%s power=%s\n",
-	       (cr23*4 >=0x100) ?"yes":"no", (cr1 & 4) ? "yes" : "no");
-	printk(KERN_INFO "SMSC LPT Config: Port mode=%s, EPP version =%s\n",
-	       (cr1 & 0x08 ) ? "Standard mode only (SPP)" : modes[cr4 & 0x03], 
-	       (cr4 & 0x40) ? "1.7" : "1.9");
-
+	if (verbose_probing) {
+		printk (KERN_INFO "SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, "
+			"A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n",
+			cr1,cr4,cra,cr23,cr26,cr27);
+		
+		/* The documentation calls DMA and IRQ-Lines by letters, so
+		   the board maker can/will wire them
+		   appropriately/randomly...  G=reserved H=IDE-irq, */
+		printk (KERN_INFO "SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, "
+			"fifo threshold=%d\n", cr23*4,
+			(cr27 &0x0f) ? 'A'-1+(cr27 &0x0f): '-',
+			(cr26 &0x0f) ? 'A'-1+(cr26 &0x0f): '-', cra & 0x0f);
+		printk(KERN_INFO "SMSC LPT Config: enabled=%s power=%s\n",
+		       (cr23*4 >=0x100) ?"yes":"no", (cr1 & 4) ? "yes" : "no");
+		printk(KERN_INFO "SMSC LPT Config: Port mode=%s, EPP version =%s\n",
+		       (cr1 & 0x08 ) ? "Standard mode only (SPP)" : modes[cr4 & 0x03], 
+		       (cr4 & 0x40) ? "1.7" : "1.9");
+	}
+		
 	/* Heuristics !  BIOS setup for this mainboard device limits
 	   the choices to standard settings, i.e. io-address and IRQ
 	   are related, however DMA can be 1 or 3, assume DMA_A=DMA1,
@@ -1319,15 +1322,16 @@
 static void __devinit show_parconfig_winbond(int io, int key)
 {
 	int cr30,cr60,cr61,cr70,cr74,crf0,i=0;
-	char *modes[]={ "Standard (SPP) and Bidirectional(PS/2)", /* 0 */
-			"EPP-1.9 and SPP",
-			"ECP",
-			"ECP and EPP-1.9",
-			"Standard (SPP)",
-			"EPP-1.7 and SPP",		/* 5 */
-			"undefined!",
-			"ECP and EPP-1.7"};
-	char *irqtypes[]={"pulsed low, high-Z", "follows nACK"};
+	static const char *modes[] = {
+		"Standard (SPP) and Bidirectional(PS/2)", /* 0 */
+		"EPP-1.9 and SPP",
+		"ECP",
+		"ECP and EPP-1.9",
+		"Standard (SPP)",
+		"EPP-1.7 and SPP",		/* 5 */
+		"undefined!",
+		"ECP and EPP-1.7" };
+	static char *irqtypes[] = { "pulsed low, high-Z", "follows nACK" };
 		
 	/* The registers are called compatible-PnP because the
            register layout is modelled after ISA-PnP, the access
@@ -1350,17 +1354,19 @@
 	crf0=inb(io+1);
 	outb(0xaa,io);
 
-	printk(KERN_INFO "Winbond LPT Config: cr_30=%02x 60,61=%02x%02x "
-	       "70=%02x 74=%02x, f0=%02x\n", cr30,cr60,cr61,cr70,cr74,crf0);
-	printk(KERN_INFO "Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ", 
-	       (cr30 & 0x01) ? "yes":"no", cr60,cr61,cr70&0x0f );
-	if ((cr74 & 0x07) > 3)
-		printk("dma=none\n");
-	else
-		printk("dma=%d\n",cr74 & 0x07);
-	printk(KERN_INFO "Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n",
-	       irqtypes[crf0>>7], (crf0>>3)&0x0f);
-	printk(KERN_INFO "Winbond LPT Config: Port mode=%s\n", modes[crf0 & 0x07]);
+	if (verbose_probing) {
+		printk(KERN_INFO "Winbond LPT Config: cr_30=%02x 60,61=%02x%02x "
+		       "70=%02x 74=%02x, f0=%02x\n", cr30,cr60,cr61,cr70,cr74,crf0);
+		printk(KERN_INFO "Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ", 
+		       (cr30 & 0x01) ? "yes":"no", cr60,cr61,cr70&0x0f );
+		if ((cr74 & 0x07) > 3)
+			printk("dma=none\n");
+		else
+			printk("dma=%d\n",cr74 & 0x07);
+		printk(KERN_INFO "Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n",
+		       irqtypes[crf0>>7], (crf0>>3)&0x0f);
+		printk(KERN_INFO "Winbond LPT Config: Port mode=%s\n", modes[crf0 & 0x07]);
+	}
 
 	if(cr30 & 0x01) { /* the settings can be interrogated later ... */
 		while((superios[i].io!= 0) && (i<NR_SUPERIOS))
@@ -1378,7 +1384,7 @@
 
 static void __devinit decode_winbond(int efer, int key, int devid, int devrev, int oldid)
 {
-	char *type=NULL;
+	const char *type = "unknown";
 	int id,progif=2;
 
 	if (devid == devrev)
@@ -1386,8 +1392,6 @@
                    non-winbond register */
 		return;
 
-	printk(KERN_INFO "Winbond chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x "
-	       "oldid=%02x\n", efer,key,devid,devrev,oldid);
 	id=(devid<<8) | devrev;
 
 	/* Values are from public data sheets pdf files, I can just
@@ -1405,19 +1409,18 @@
 	else if ((oldid &0x0f ) == 0x0d) { type="83877ATF"; progif=1;}
 	else progif=0;
 
-	if(type==NULL) 
-		printk(KERN_INFO "Winbond unknown chip type\n");
-	else	
-	 	printk(KERN_INFO "Winbond chip type %s\n",type);
+	if (verbose_probing)
+		printk(KERN_INFO "Winbond chip at EFER=0x%x key=0x%02x "
+		       "devid=%02x devrev=%02x oldid=%02x type=%s\n", 
+		       efer, key, devid, devrev, oldid, type);
 
-	if(progif==2)
+	if (progif == 2)
 		show_parconfig_winbond(efer,key);
-	return;
 }
 
 static void __devinit decode_smsc(int efer, int key, int devid, int devrev)
 {
-        char *type=NULL;
+        const char *type = "unknown";
 	void (*func)(int io, int key);
         int id;
 
@@ -1427,8 +1430,6 @@
 		return;
 
 	func=NULL;
-        printk(KERN_INFO "SMSC chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x\n",
-	       efer,key,devid,devrev);
         id=(devid<<8) | devrev;
 
 	if	(id==0x0302) {type="37c669"; func=show_parconfig_smsc37c669;}
@@ -1436,13 +1437,13 @@
 	else if	(devid==0x65) type="37c665GT";
 	else if	(devid==0x66) type="37c666GT";
 
-	if(type==NULL)
-                printk(KERN_INFO "SMSC unknown chip type\n");
-        else
-                printk(KERN_INFO "SMSC chip type %s\n",type);
+	if (verbose_probing)
+		printk(KERN_INFO "SMSC chip at EFER=0x%x "
+		       "key=0x%02x devid=%02x devrev=%02x type=%s\n",
+		       efer, key, devid, devrev, type);
 
-	if(func) (func)(efer,key);
-	return;
+	if (func)
+		func(efer,key);
 }
 
 
@@ -1540,8 +1541,8 @@
 
 static void __devinit detect_and_report_winbond (void)
 { 
-	printk(KERN_DEBUG "Winbond Super-IO detection, now testing ports 3F0,370,250,4E,2E ...\n");
-
+	if (verbose_probing)
+		printk(KERN_DEBUG "Winbond Super-IO detection, now testing ports 3F0,370,250,4E,2E ...\n");
 	winbond_check(0x3f0,0x87);
 	winbond_check(0x370,0x87);
 	winbond_check(0x2e ,0x87);
@@ -1553,7 +1554,8 @@
 
 static void __devinit detect_and_report_smsc (void)
 {
-	printk(KERN_DEBUG "SMSC Super-IO detection, now testing Ports 2F0, 370 ...\n");
+	if (verbose_probing)
+		printk(KERN_DEBUG "SMSC Super-IO detection, now testing Ports 2F0, 370 ...\n");
 	smsc_check(0x3f0,0x55);
 	smsc_check(0x370,0x55);
 	smsc_check(0x3f0,0x44);
@@ -1627,7 +1629,7 @@
 	if (user_specified)
 		/* That didn't work, but the user thinks there's a
 		 * port here. */
-		printk (KERN_DEBUG "parport 0x%lx (WARNING): CTR: "
+		printk (KERN_INFO "parport 0x%lx (WARNING): CTR: "
 			"wrote 0x%02x, read 0x%02x\n", pb->base, w, r);
 
 	/* Try the data register.  The data lines aren't tri-stated at
@@ -1646,9 +1648,9 @@
 	if (user_specified) {
 		/* Didn't work, but the user is convinced this is the
 		 * place. */
-		printk (KERN_DEBUG "parport 0x%lx (WARNING): DATA: "
+		printk (KERN_INFO "parport 0x%lx (WARNING): DATA: "
 			"wrote 0x%02x, read 0x%02x\n", pb->base, w, r);
-		printk (KERN_DEBUG "parport 0x%lx: You gave this address, "
+		printk (KERN_INFO "parport 0x%lx: You gave this address, "
 			"but there is probably no parallel port there!\n",
 			pb->base);
 	}
@@ -1760,9 +1762,8 @@
 	int config, configb;
 	int pword;
 	struct parport_pc_private *priv = pb->private_data;
-	int intrline[]={0,7,9,10,11,14,15,5}; /* Translate ECP
-                                                 intrLine to ISA irq
-                                                 value */
+	/* Translate ECP intrLine to ISA irq value */	
+	static const int intrline[]= { 0, 7, 9, 10, 11, 14, 15, 5 }; 
 
 	/* If there is no ECR, we have no hope of supporting ECP. */
 	if (!priv->ecr)
@@ -1784,7 +1785,8 @@
 	}
 
 	priv->fifo_depth = i;
-	printk (KERN_INFO "0x%lx: FIFO is %d bytes\n", pb->base, i);
+	if (verbose_probing)
+		printk (KERN_DEBUG "0x%lx: FIFO is %d bytes\n", pb->base, i);
 
 	/* Find out writeIntrThreshold */
 	frob_econtrol (pb, 1<<2, 1<<2);
@@ -1796,10 +1798,11 @@
 			break;
 	}
 
-	if (i <= priv->fifo_depth)
-		printk (KERN_INFO "0x%lx: writeIntrThreshold is %d\n",
-			pb->base, i);
-	else
+	if (i <= priv->fifo_depth) {
+		if (verbose_probing)
+			printk (KERN_DEBUG "0x%lx: writeIntrThreshold is %d\n",
+				pb->base, i);
+	} else
 		/* Number of bytes we know we can write if we get an
                    interrupt. */
 		i = 0;
@@ -1818,10 +1821,11 @@
 			break;
 	}
 
-	if (i <= priv->fifo_depth)
-		printk (KERN_INFO "0x%lx: readIntrThreshold is %d\n",
-			pb->base, i);
-	else
+	if (i <= priv->fifo_depth) {
+		if (verbose_probing)
+			printk (KERN_INFO "0x%lx: readIntrThreshold is %d\n",
+				pb->base, i);
+	} else
 		/* Number of bytes we can read if we get an interrupt. */
 		i = 0;
 
@@ -1850,28 +1854,30 @@
 		pword = 1;
 	}
 	priv->pword = pword;
-	printk (KERN_DEBUG "0x%lx: PWord is %d bits\n", pb->base, 8 * pword);
 
-	printk (KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base,
-		config & 0x80 ? "Level" : "Pulses");
+	if (verbose_probing) {
+		printk (KERN_DEBUG "0x%lx: PWord is %d bits\n", pb->base, 8 * pword);
+		
+		printk (KERN_DEBUG "0x%lx: Interrupts are ISA-%s\n", pb->base,
+			config & 0x80 ? "Level" : "Pulses");
 
-	configb = inb (CONFIGB (pb));
-	printk (KERN_DEBUG "0x%lx: ECP port cfgA=0x%02x cfgB=0x%02x\n",
-		pb->base, config, configb);
-        printk (KERN_DEBUG "0x%lx: ECP settings irq=", pb->base);
-	if ((configb >>3) & 0x07)
-		printk("%d",intrline[(configb >>3) & 0x07]);
-	else
-		printk("<none or set by other means>");
-	printk (" dma=");
-	if( (configb & 0x03 ) == 0x00)
-		printk("<none or set by other means>\n");
-	else
-		printk("%d\n",configb & 0x07);
+		configb = inb (CONFIGB (pb));
+		printk (KERN_DEBUG "0x%lx: ECP port cfgA=0x%02x cfgB=0x%02x\n",
+			pb->base, config, configb);
+		printk (KERN_DEBUG "0x%lx: ECP settings irq=", pb->base);
+		if ((configb >>3) & 0x07)
+			printk("%d",intrline[(configb >>3) & 0x07]);
+		else
+			printk("<none or set by other means>");
+		printk (" dma=");
+		if( (configb & 0x03 ) == 0x00)
+			printk("<none or set by other means>\n");
+		else
+			printk("%d\n",configb & 0x07);
+	}
 
 	/* Go back to mode 000 */
 	frob_econtrol (pb, 0xe0, ECR_SPP << 5);
-	pb->modes |= PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
 
 	return 1;
 }
@@ -2191,10 +2197,10 @@
 	p->ops = ops;
 	p->private_data = priv;
 	p->physport = p;
-	if (base_hi && !check_region(base_hi,3)) {
+
+	if (base_hi && !check_region(base_hi,3))
 		parport_ECR_present(p);
-		parport_ECP_supported(p);
-	}
+
 	if (base != 0x3bc) {
 		if (!check_region(base+0x3, 5)) {
 			if (!parport_EPP_supported(p))
@@ -2204,6 +2210,7 @@
 	if (!parport_SPP_supported (p)) {
 		/* No port. */
 		kfree (priv);
+		kfree (ops);
 		return NULL;
 	}
 	if (priv->ecr)
@@ -2250,8 +2257,10 @@
 		p->dma = PARPORT_DMA_NONE;
 
 #ifdef CONFIG_PARPORT_PC_FIFO
-	if (p->dma != PARPORT_DMA_NOFIFO &&
+	if (parport_ECP_supported(p) &&
+	    p->dma != PARPORT_DMA_NOFIFO &&
 	    priv->fifo_depth > 0 && p->irq != PARPORT_IRQ_NONE) {
+		p->modes |= PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
 		p->ops->compat_write_data = parport_pc_compat_write_block_pio;
 #ifdef CONFIG_PARPORT_1284
 		p->ops->ecp_write_data = parport_pc_ecp_write_block_pio;
@@ -2870,6 +2879,8 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s");
 MODULE_PARM_DESC(dma, "DMA channel");
 MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s");
+MODULE_PARM(verbose_probing, "i");
+MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation");
 
 int init_module(void)
 {	
diff -u --recursive --new-file v2.4.10/linux/drivers/parport/parport_serial.c linux/drivers/parport/parport_serial.c
--- v2.4.10/linux/drivers/parport/parport_serial.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/parport/parport_serial.c	Mon Oct  8 11:54:10 2001
@@ -32,8 +32,6 @@
 enum parport_pc_pci_cards {
 	titan_110l = 0,
 	titan_210l,
-	netmos_9735,
-	netmos_9835,
 	avlab_1s1p,
 	avlab_1s1p_650,
 	avlab_1s1p_850,
@@ -58,8 +56,6 @@
 } cards[] __devinitdata = {
 	/* titan_110l */		{ 1, { { 3, -1 }, } },
 	/* titan_210l */		{ 1, { { 3, -1 }, } },
-	/* netmos_9735 (not tested) */	{ 1, { { 2, 3 }, } },
-	/* netmos_9835 (not tested) */	{ 1, { { 2, 3 }, } },
 	/* avlab_1s1p     */		{ 1, { { 1, 2}, } },
 	/* avlab_1s1p_650 */		{ 1, { { 1, 2}, } },
 	/* avlab_1s1p_850 */		{ 1, { { 1, 2}, } },
@@ -77,10 +73,6 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l },
 	{ PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l },
-	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9735 },
-	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9835 },
 	/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
 	{ 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p},
 	{ 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650},
@@ -119,8 +111,6 @@
 
 /* titan_110l */	{ SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 },
 /* titan_210l */	{ SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
-/* netmos_9735 (n/t)*/	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
-/* netmos_9835 (n/t)*/	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
 /* avlab_1s1p (n/t) */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
 /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
 /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
@@ -357,6 +347,7 @@
 
 MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>");
 MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");
+MODULE_LICENSE("GPL");
 
 module_init(parport_serial_init);
 module_exit(parport_serial_exit);
diff -u --recursive --new-file v2.4.10/linux/drivers/parport/share.c linux/drivers/parport/share.c
--- v2.4.10/linux/drivers/parport/share.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/parport/share.c	Mon Oct  8 11:54:10 2001
@@ -18,6 +18,7 @@
 #undef PARPORT_DEBUG_SHARING		/* undef for production */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/string.h>
 #include <linux/threads.h>
 #include <linux/parport.h>
@@ -41,10 +42,10 @@
 int parport_default_spintime =  DEFAULT_SPIN_TIME;
 
 static struct parport *portlist = NULL, *portlist_tail = NULL;
-spinlock_t parportlist_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t parportlist_lock = SPIN_LOCK_UNLOCKED;
 
 static struct parport_driver *driver_chain = NULL;
-spinlock_t driverlist_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t driverlist_lock = SPIN_LOCK_UNLOCKED;
 
 /* What you can do to a port that's gone away.. */
 static void dead_write_lines (struct parport *p, unsigned char b){}
@@ -1140,3 +1141,4 @@
 	return parport_parse_params (nports, dmastr, dmaval, PARPORT_DMA_AUTO,
 				     PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO);
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.4.10/linux/drivers/pci/pci.ids	Sun Sep 23 11:40:59 2001
+++ linux/drivers/pci/pci.ids	Tue Oct  2 12:58:47 2001
@@ -27,6 +27,8 @@
 0e11  Compaq Computer Corporation
 	0001  PCI to EISA Bridge
 	0002  PCI to ISA Bridge
+	0049  NC7132 Gigabit Upgrade Module
+	004a  NC6136 Gigabit Server Adapter
 	0508  Netelligent 4/16 Token Ring
 	1000  Triflex/Pentium Bridge, Model 1000
 	2000  Triflex/Pentium Bridge, Model 2000
@@ -40,6 +42,8 @@
 	a0f0  Advanced System Management Controller
 	a0f3  Triflex PCI to ISA Bridge
 	a0f7  PCI Hotplug Controller
+		8086 002a  PCI Hotplug Controller A
+		8086 002b  PCI Hotplug Controller B
 	a0f8  USB Open Host Controller
 	ae10  Smart-2/P RAID Controller
 		0e11 4030  Smart-2/P Array Controller
@@ -61,13 +65,29 @@
 	ae6d  NorthStar CPU to PCI Bridge
 	b011  Integrated Netelligent 10/100
 	b012  Netelligent 10 T/2
+	b01e  NC3120 Fast Ethernet NIC
+	b01f  NC3122 Fast Ethernet NIC
+	b02f  NC1120 Ethernet NIC
 	b030  Netelligent WS 5100
-	b04a  10/100TX WOL UTP Controller
-	b0c6  10/100TX Embedded WOL UTP Controller
-	b0d7  NC3121 (Rev A & B)
+	b04a  10/100 TX PCI Intel WOL UTP Controller
+	b0c6  NC3161 Fast Ethernet NIC
+	b0c7  NC3160 Fast Ethernet NIC
+	b0d7  NC3121 Fast Ethernet NIC
+	b0dd  NC3131 Fast Ethernet NIC
+	b0de  NC3132 Fast Ethernet Module
+	b0df  NC6132 Gigabit Module
+	b0e0  NC6133 Gigabit Module
+	b0e1  NC3133 Fast Ethernet Module
+	b123  NC6134 Gigabit NIC
+	b134  NC3163 Fast Ethernet NIC
+	b13c  NC3162 Fast Ethernet NIC
+	b144  NC3123 Fast Ethernet NIC
+	b163  NC3134 Fast Ethernet NIC
+	b164  NC3135 Fast Ethernet Upgrade Module
+	b1a4  NC7131 Gigabit Server Adapter
 	f130  NetFlex-3/P ThunderLAN 1.0
 	f150  NetFlex-3/P ThunderLAN 2.3
-1000  Symbios Logic Inc. (formerly NCR)
+1000  LSI Logic / Symbios Logic (formerly NCR)
 	0001  53c810
 		1000 1000  8100S
 	0002  53c820
@@ -141,16 +161,19 @@
 		0e11 b10e  3D Rage LT Pro (Compaq Armada 1750)
 		1028 0085  Rage 3D LT Pro
 	4c44  3D Rage LT Pro AGP-66
-	4c46  Mobility M3 AGP 2x
+	4c45  Rage Mobility M3 AGP
+	4c46  Rage Mobility M3 AGP 2x
 	4c47  3D Rage LT-G 215LG
 	4c49  3D Rage LT Pro
-	4c4d  3D Rage P/M Mobility AGP 2x
-	4c4e  3D Rage L Mobility AGP 2x
+	4c4d  Rage Mobility P/M AGP 2x
+	4c4e  Rage Mobility L AGP 2x
 	4c50  3D Rage LT Pro
 	4c51  3D Rage LT Pro
-	4c52  3D Rage P/M Mobility
-	4c53  3D Rage L Mobility
+	4c52  Rage Mobility P/M
+	4c53  Rage Mobility L
 	4c54  264LT [Mach64 LT]
+	4d46  Rage Mobility M4 AGP
+	4d4c  Rage Mobility M4 AGP
 	5041  Rage 128 PA
 	5042  Rage 128 PB
 	5043  Rage 128 PC
@@ -244,7 +267,7 @@
 	000f  OHCI Compliant FireWire Controller
 	0011  National PCI System I/O
 	0012  USB Controller
-	0020  DP83815 (MacPhyter) Ethernet Controller
+	0020  DP83815
 	d001  87410 IDE
 100c  Tseng Labs Inc
 	3202  ET4000/W32p rev A
@@ -276,6 +299,8 @@
 		1113 1207  EN-1207-TX Fast Ethernet
 		1186 1100  DFE-500TX Fast Ethernet
 		1186 1112  DFE-570TX Fast Ethernet
+		1186 1140  DFE-660 Cardbus Ethernet 10/100
+		1186 1142  DFE-660 Cardbus Ethernet 10/100
 		1282 9100  AEF-380TXD Fast Ethernet
 		1385 1100  FA310TX Fast Ethernet
 		2646 0001  KNE100TX Fast Ethernet
@@ -374,7 +399,7 @@
 	0020  MCA
 	0022  IBM27-82351
 	002d  Python
-	002e  ServeRAID controller
+	002e  ServeRAID-3x
 	0036  Miami
 	003a  CPU to PCI Bridge
 	003e  16/4 Token ring UTP/STP controller
@@ -415,6 +440,10 @@
 	0144  Yotta Video Compositor Output
 		1014 0145 Yotta Output Controller (ytout)
 	0156  405GP PLB to PCI Bridge
+	01bd  Netfinity ServeRAID controller
+	01be  ServeRAID-4M
+	01bf  ServeRAID-4L
+	022e  ServeRAID-4H
 	ffff  MPIC-2 interrupt controller
 1015  LSI Logic Corp of Canada
 1016  ICL Personal Systems
@@ -438,6 +467,9 @@
 	9712  Pipeline 9712
 	c24a  90C
 101e  American Megatrends Inc.
+	1960  MegaRAID
+		1028 0471 PowerEdge RAID Controller 3/QC
+		1028 0493 PowerEdge RAID Controller 3/DC
 	9010  MegaRAID
 	9030  EIDE Controller
 	9031  EIDE Controller
@@ -589,6 +621,7 @@
 	0005  PowerEdge Expandable RAID Controller 3/Di
 	0006  PowerEdge Expandable RAID Controller 3/Di
 	0008  PowerEdge Expandable RAID Controller 3/Di
+	000a  PowerEdge Expandable RAID Controller 3/Di
 1029  Siemens Nixdorf IS
 102a  LSI Logic
 	0000  HYDRA
@@ -642,6 +675,8 @@
 		0e11 b16f  Matrox MGA-G400 AGP
 		102b 0328  Millennium G400 16Mb SDRAM
 		102b 0338  Millennium G400 16Mb SDRAM
+		102b 0378  Millennium G400 32Mb SDRAM
+		102b 0641  Millennium G450 32Mb SDRAM
 		102b 19d8  Millennium G400 16Mb SGRAM
 		102b 19f8  Millennium G400 32Mb SGRAM
 		102b 2159  Millennium G400 Dual Head 16Mb
@@ -664,6 +699,8 @@
 		102b ff05  MGA-G100 Productiva AGP Multi-Monitor
 		110a 001e  MGA-G100 AGP
 	2007  MGA Mistral
+	2527  MGA G550 AGP
+		102b 0f84  Millennium G550 Dual Head DDR 32Mb
 	4536  VIA Framegrabber
 	6573  Shark 10/100 Multiport SwitchNIC
 102c  Chips and Technologies
@@ -984,6 +1021,7 @@
 	4802  Falcon
 	4803  Hawk
 	4806  CPX8216
+	4d68  20268
 	5600  SM56 PCI Modem
 		1057 0300  SM56 PCI Speakerphone Modem
 		1057 0301  SM56 PCI Voice Modem
@@ -1129,19 +1167,26 @@
 	0012  YMF-754 [DS-1E Audio Controller]
 		1073 0012  DS-XG PCI Audio Codec
 	0020  DS-1 Audio
+	2000  DS2416 Digital Mixing Card
+		1073 2000  DS2416 Digital Mixing Card
 1074  NexGen Microsystems
 	4e78  82c500/1
 1075  Advanced Integrations Research
 1076  Chaintech Computer Co. Ltd
-1077  Q Logic
+1077  QLogic Corp.
+	1016  QLA10160
 	1020  ISP1020
 	1022  ISP1022
-	1080  ISP1080
-	1240  ISP1240
-	1280  ISP1280
+	1080  QLA1080
+	1216  QLA12160
+		101e 8471 QLA12160 on AMI MegaRAID
+		101e 8493 QLA12160 on AMI MegaRAID
+	1240  QLA1240
+	1280  QLA1280
 	2020  ISP2020A
-	2100  ISP2100
-	2200  ISP2200
+	2100  QLA2100
+	2200  QLA2200
+	2300  QLA2300
 1078  Cyrix Corporation
 	0000  5510 [Grappa]
 	0001  PCI Master
@@ -1291,7 +1336,7 @@
 109e  Brooktree Corporation
 	0350  Bt848 TV with DMA push
 	0351  Bt849A Video capture
-	036c  Bt879(?) Video Capture
+	036c  Bt879(??) Video Capture
 		13e9 0070  Win/TV (Video Section)
 	036e  Bt878
 		0070 13eb  WinTV/GO
@@ -1476,6 +1521,8 @@
 	906e  9060ES
 	9080  9080
 		10b5 9080  9080 [real subsystem ID not set]
+	a001  GTEK Jetport II 2 port serial adaptor
+	c001  GTEK Cyclone 16/32 port serial adaptor
 10b6  Madge Networks
 	0001  Smart 16/4 PCI Ringnode
 	0002  Smart 16/4 PCI Ringnode Mk2
@@ -1505,13 +1552,13 @@
 		10b7 3590  TokenLink Velocity XL Adapter
 	4500  3c450 Cyclone/unknown
 	5055  3c555 Laptop Hurricane
-	6055  3c556 Laptop Tornado
+	6055  3c556 Laptop Hurricane
 	6056  3c556B Laptop Hurricane
 	5057  3c575 [Megahertz] 10/100 LAN CardBus
 		10b7 5a57  3C575 Megahertz 10/100 LAN Cardbus PC Card
-	5157  3CCFE575BT Cyclone CardBus
+	5157  3c575 [Megahertz] 10/100 LAN CardBus
 		10b7 5b57  3C575 Megahertz 10/100 LAN Cardbus PC Card
-	5257  3CCFE575CT Tornado CardBus
+	5257  3CCFE575CT Cyclone CardBus
 	5900  3c590 10BaseT [Vortex]
 	5920  3c592 EISA 10mbps Demon/Vortex
 	5950  3c595 100BaseTX [Vortex]
@@ -1521,8 +1568,8 @@
 	5b57  3c595 [Megahertz] 10/100 LAN CardBus
 		10b7 5b57  3C575 Megahertz 10/100 LAN Cardbus PC Card
 	6560  3CCFE656 Cyclone CardBus
-	6562  3CCFEM656B Cyclone CardBus
-	6564  3CXFEM656C Tornado CardBus
+	6562  3CCFEM656 [id 6562] Cyclone CardBus
+	6564  3CCFEM656 [id 6564] Cyclone CardBus
 	7646  3cSOHO100-TX Hurricane
 	8811  Token ring
 	9000  3c900 10BaseT [Boomerang]
@@ -1564,8 +1611,8 @@
 		10b7 1000  3C905C-TX Fast Etherlink for PC Management NIC
 	9800  3c980-TX [Fast Etherlink XL Server Adapter]
 		10b7 9800  3c980-TX Fast Etherlink XL Server Adapter
-	9805  3c982 Dual Port Server Cyclone
-		10b7 9805  3c982 Dual Port Server Cyclone
+	9805  3c980-TX 10/100baseTX NIC [Python-T]
+		10b7 9805  3c980 10/100baseTX NIC [Python-T]
 10b8  Standard Microsystems Corp [SMC]
 	0005  83C170QF
 		1055 e000  LANEPIC
@@ -1674,6 +1721,8 @@
 		10f7 8312  MagicGraph 128XD
 	0005  [MagicMedia 256AV]
 	0006  NM2360 [MagicMedia 256ZX]
+	0016  NM2380 [MagicMedia 256XL+]
+		10c8 0016  MagicMedia 256XL+
 	0083  [MagicGraph 128ZV Plus]
 	8005  [MagicMedia 256AV Audio]
 		0e11 b0d1  MagicMedia 256AV Audio Device on Discovery
@@ -1730,7 +1779,7 @@
 	0008  EDGE 3D [NV1]
 	0009  EDGE 3D [NV1]
 	0010  Mutara V08 [NV2]
-	0020  Riva TnT 128 [NV04]
+	0020  Riva TnT [NV04]
 		1043 0200  V3400 TNT
 		1048 0c18  Erazor II SGRAM
 		1092 0550  Viper V550
@@ -1803,14 +1852,16 @@
 		1102 102e  CT6971 GeForce 256 DDR
 		14af 5021  3D Prophet DDR-DVI
 	0103  Quadro (GeForce 256 GL)
-	0110  NV11
-	0111  NV11 DDR
-	0113  NV11 GL
-	0150  NV15 (Geforce2 GTS)
+	0110  NV11 (GeForce2 MX)
+	0111  NV11 (GeForce2 MX DDR)
+	0112  GeForce2 Go
+	0113  NV11 (GeForce2 MXR)
+	0150  NV15 (Geforce2 Pro)
 		107d 2840  WinFast GeForce2 GTS with TV output
 	0151  NV15 DDR (Geforce2 GTS)
-	0152  NV15 Bladerunner (Geforce2 GTS)
-	0153  NV15 GL (Quadro2)
+	0152  NV15 Bladerunner (Geforce2 Ultra)
+	0153  NV15 GL (Quadro2 Pro)
+	0203  Quadro DCC
 10df  Emulex Corporation
 	10df  Light Pulse Fibre Channel Adapter
 	1ae5  LP6000 Fibre Channel Host Adapter
@@ -1824,6 +1875,7 @@
 	9128  IMS9129 [Twin turbo 128]
 10e1  Tekram Technology Co.,Ltd.
 	0391  TRM-S1040
+		10e1 0391  DC-315U SCSI-3 Host Adapter
 	690c  DC-690c
 	dc29  DC-290
 10e2  Aptix Corporation
@@ -1877,6 +1929,7 @@
 		1025 8921  ALN-325
 		10bd 0320  EP-320X-R
 		10ec 8139  RT8139
+		1186 1300  DFE-538TX
 		1186 1320  SN5200
 		1259 2500  AT-2500TX
 		1429 d010  ND010
@@ -1926,7 +1979,7 @@
 	9401  INI-950
 	9500  360P
 1102  Creative Labs
-	0002  SB Live! EMU10000
+	0002  SB Live! EMU10k1
 		1102 0020  CT4850 SBLive! Value
 		1102 0021  CT4620 SBLive!
 		1102 002f  SBLive! mainboard implementation 
@@ -1942,9 +1995,10 @@
 		1102 8051  CT4850 SBLive! Value
 	7002  SB Live!
 		1102 0020  Gameport Joystick
-1103  HighPoint Technologies, Inc.
-	0003  HPT343 UltraDMA 33 IDE Controller
-	0004  HPT366/370 UltraDMA 66/100 IDE Controller
+1103  Triones Technologies, Inc.
+	0003  HPT343
+	0004  HPT366 / HPT370
+		1103 0005  HPT370 UDMA100
 1104  RasterOps Corp.
 1105  Sigma Designs, Inc.
 	8300  REALmagic Hollywood Plus DVD Decoder
@@ -1955,7 +2009,7 @@
 	0505  VT82C505
 	0561  VT82C561
 	0571  Bus Master IDE
-	0576  VT82C576 [Apollo Master]
+	0576  VT82C576 3V [Apollo Master]
 	0585  VT82C585VP [Apollo VP1/VPX]
 	0586  VT82C586/A/B PCI-to-ISA [Apollo VP]
 		1106 0000  MVP3 ISA Bridge
@@ -1973,12 +2027,12 @@
 		1106 0686  VT82C686/A PCI to ISA Bridge
 	0691  VT82C693A/694x [Apollo PRO133x]
 		1458 0691  VT82C691 Apollo Pro System Controller
-	0698  VT82C693A [Apollo Pro133 AGP]
 	0693  VT82C693 [Apollo Pro Plus]
+	0698  VT82C693A [Apollo Pro133 AGP]
 	0926  VT82C926 [Amazon]
 	1000  VT82C570MV
 	1106  VT82C570MV
-	1571  VT82C576 IDE [Apollo Master]
+	1571  VT82C416MV
 	1595  VT82C595/97 [Apollo VP2/97]
 	3038  UHCI USB
 		1234 0925  MVP3 USB Controller
@@ -2012,8 +2066,8 @@
 	8598  VT82C598/694x [Apollo MVP3/Pro133x AGP]
 	8601  VT8601 [Apollo ProMedia AGP]
 	8605  VT8605 [PM133 AGP]
-	B091  VT8633 [Apollo Pro266 AGP]
-	B099  VT8367 [KT266 AGP]
+	b091  VT8633 [Apollo Pro266 AGP]
+	b099  VT8367 [KT266 AGP]
 	8691  VT82C691 [Apollo Pro]
 1107  Stratus Computers
 	0576  VIA VT82C570MV [Apollo] (Wrong vendor ID!)
@@ -2073,7 +2127,7 @@
 1118  Berg Electronics
 1119  ICP Vortex Computersysteme GmbH
 	0000  GDT 6000/6020/6050
-	0001  GDT 6000b/6010
+	0001  GDT 6000B/6010
 	0002  GDT 6110/6510
 	0003  GDT 6120/6520
 	0004  GDT 6530
@@ -2081,9 +2135,9 @@
 	0006  GDT 6x17
 	0007  GDT 6x27
 	0008  GDT 6537
-	0009  GDT 5557
-	000a  GDT 6x15
-	000b  GDT 6x25
+	0009  GDT 6557
+	000a  GDT 6115/6515
+	000b  GDT 6125/6525
 	000c  GDT 6535
 	000d  GDT 6555
 	0100  GDT 6117RP/6517RP
@@ -2092,30 +2146,34 @@
 	0103  GDT 6557RP
 	0104  GDT 6111RP/6511RP
 	0105  GDT 6121RP/6521RP
-	0110  GDT 6117RP1/6517RP1
-	0111  GDT 6127RP1/6527RP1
-	0112  GDT 6537RP1
-	0113  GDT 6557RP1
-	0114  GDT 6111RP1/6511RP1
-	0115  GDT 6121RP1/6521RP1
-	0118  GDT 6x18RD
-	0119  GDT 6x28RD
-	011a  GDT 6x38RD
-	011b  GDT 6x58RD
-	0120  GDT 6117RP2/6517RP2
-	0121  GDT 6127RP2/6527RP2
-	0122  GDT 6537RP2
-	0123  GDT 6557RP2
-	0124  GDT 6111RP2/6511RP2
-	0125  GDT 6121RP2/6521RP2
-	0168  GDT 7x18RN
-	0169  GDT 7x28RN
-	016a  GDT 7x38RN
-	016b  GDT 7x58RN
-	0210  GDT 6x19RD
-	0211  GDT 6x29RD
-	0260  GDT 7x19RN
-	0261  GDT 7x29RN
+	0110  GDT 6117RD/6517RD
+	0111  GDT 6127RD/6527RD
+	0112  GDT 6537RD
+	0113  GDT 6557RD
+	0114  GDT 6111RD/6511RD
+	0115  GDT 6121RD/6521RD
+	0118  GDT 6118RD/6518RD/6618RD
+	0119  GDT 6128RD/6528RD/6628RD
+	011a  GDT 6538RD/6638RD
+	011b  GDT 6558RD/6658RD
+	0138  GDT 6118RS/6518RS/6618RS
+	0139  GDT 6128RS/6528RS/6628RS
+	013a  GDT 6538RS/6638RS
+	013b  GDT 6558RS/6658RS
+	0166  GDT 7113RN/7513RN/7613RN
+	0167  GDT 7123RN/7523RN/7623RN
+	0168  GDT 7118RN/7518RN/7518RN
+	0169  GDT 7128RN/7528RN/7628RN
+	016a  GDT 7538RN/7638RN
+	016b  GDT 7558RN/7658RN
+	016c  GDT 7533RN/7633RN
+	016d  GDT 7543RN/7643RN
+	016e  GDT 7553RN/7653RN
+	016f  GDT 7563RN/7663RN
+	0210  GDT 6519RD/6619RD
+	0211  GDT 6529RD/6629RD
+	0260  GDT 7519RN/7619RN
+	0261  GDT 7529RN/7629RN
 111a  Efficient Networks, Inc
 	0000  155P-MF1 (FPGA)
 	0002  155P-MF1 (ASIC)
@@ -2235,7 +2293,7 @@
 1145  Workbit Corporation
 1146  Force Computers
 1147  Interface Corp
-1148  SysKonnect GmbH
+1148  Syskonnect (Schneider & Koch)
 	4000  FDDI Adapter
 		0e11 b03b  Netelligent 100 FDDI DAS Fibre SC
 		0e11 b03c  Netelligent 100 FDDI SAS Fibre SC
@@ -2252,7 +2310,7 @@
 		1148 5841  FDDI SK-5841 (SK-NET FDDI-FP64)
 		1148 5843  FDDI SK-5843 (SK-NET FDDI-LP64)
 		1148 5844  FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
-	4200  Token Ring adapter
+	4200  Token ring adaptor
 	4300  Gigabit Ethernet
 		1148 9821  SK-9821 (1000Base-T single link)
 		1148 9822  SK-9822 (1000Base-T dual link)
@@ -2429,6 +2487,7 @@
 118b  Hypertec Pty Limited
 118c  Corollary, Inc
 	0014  PCIB [C-bus II to PCI bus host bridge chip]
+	1117  Intel 8-way XEON Profusion Chipset [Cache Coherency Filter]
 118d  BitFlow Inc
 	0001  Raptor-PCI framegrabber
 	0012  Model 12 Road Runner Frame Grabber
@@ -2478,7 +2537,7 @@
 	1221  82C092G
 119c  Information Technology Inst.
 119d  Bug, Inc. Sapporo Japan
-119e  Fujitsu Microelectronics Europe GMBH
+119e  Fujitsu Microelectronics Ltd.
 	0001 FireStream 155
 	0003 FireStream 50
 119f  Bull HN Information Systems
@@ -2692,6 +2751,7 @@
 11f5  Computing Devices International
 11f6  Compex
 	0112  ENet100VG4
+	0113  FreedomLine 100
 	1401  ReadyLink 2000
 	2011  RL100-ATX 10/100
 	2201  ReadyLink 100TX (Winbond W89C840)
@@ -2803,7 +2863,8 @@
 		121a 0060  Voodoo3 3500 TV (NTSC)
 		121a 0061  Voodoo3 3500 TV (PAL)
 		121a 0062  Voodoo3 3500 TV (SECAM)
-	0009  Voodoo 4
+	0009  Voodoo 4 / Voodoo 5
+		121a 0009  Voodoo5 AGP 5500/6000
 121b  Advanced Telecommunications Modules
 121c  Nippon Texaco., Ltd
 121d  Lippert Automationstechnik GmbH
@@ -3029,13 +3090,13 @@
 		8086 5753  ES1371, ES1373 AudioPCI On Motherboard WS440BX
 	5000  ES1370 [AudioPCI]
 		4942 4c4c  Creative Sound Blaster AudioPCI128
-	5880  CT5880 [AudioPCI]
+	5880  5880 AudioPCI
 		1274 2000  Creative Sound Blaster AudioPCI128
 		1274 5880  Creative Sound Blaster AudioPCI128
-		1462 6880  CT5880 AudioPCI On Motherboard MS-6188 1.00
-		270f 2001  CT5880 AudioPCI On Motherboard 6CTR
-		270f 2200  CT5880 AudioPCI On Motherboard 6WTX
-		270f 7040  CT5880 AudioPCI On Motherboard 6ATA4
+		1462 6880  5880 AudioPCI On Motherboard MS-6188 1.00
+		270f 2001  5880 AudioPCI On Motherboard 6CTR
+		270f 2200  5880 AudioPCI On Motherboard 6WTX
+		270f 7040  5880 AudioPCI On Motherboard 6ATA4
 1275  Network Appliance Corporation
 1276  Switched Network Technologies, Inc.
 1277  Comstream
@@ -3146,8 +3207,9 @@
 12ac  Measurex Corporation
 12ad  Multidata GmbH
 12ae  Alteon Networks Inc.
-	0001  AceNIC Gigabit Ethernet
+	0001  AceNIC Gigabit Ethernet (Fibre)
 		1410 0104  Gigabit Ethernet-SX PCI Adapter (14100401)
+	0002  AceNIC Gigabit Ethernet (Copper)
 12af  TDK USA Corp
 12b0  Jorge Scientific Corp
 12b1  GammaLink
@@ -3368,7 +3430,8 @@
 1312  Acuity Imaging, Inc
 1313  Yaskawa Electric Co.
 1316  Teradyne Inc
-1317  Bridgecom, Inc
+1317  Linksys
+	0985  Network Everywhere Fast Ethernet 10/100 model NC100
 1318  Packet Engines Inc.
 	0911  PCI Ethernet Adapter
 1319  Fortemedia, Inc
@@ -3528,6 +3591,7 @@
 1384  Reality Simulation Systems Inc
 1385  Netgear
 	620a  GA620
+	f311  FA311
 1386  Video Domain Technologies
 1387  Systran Corp
 1388  Hitachi Information Technology Co Ltd
@@ -3920,7 +3984,31 @@
 14e2  INFOLIBRIA
 14e3  AMTELCO
 14e4  BROADCOM Corporation
-	1644  Tigon3
+	1644  NetXtreme BCM5700 Gigabit Ethernet
+		10b7 1000  3C996-T 1000BaseTX
+		10b7 1001  3C996B-T 1000BaseTX
+		10b7 1002  3C996C-T 1000BaseTX
+		10b7 1003  3C997-T 1000BaseTX
+		10b7 1004  3C996-SX 1000BaseSX
+		10b7 1005  3C997-SX 1000BaseSX
+		14e4 0002  NetXtreme 1000BaseSX
+		14e4 0003  NetXtreme 1000BaseSX
+		14e4 0004  NetXtreme 1000BaseTX
+		14e4 1644  NetXtreme BCM5700 1000BaseTX
+	1645  NetXtreme BCM5701 Gigabit Ethernet
+		0e11 007d  NC6770 1000BaseSX
+		0e11 007c  NC7770 1000BaseTX
+		0e11 0085  NC7780 1000BaseTX
+		10b7 1004  3C996-SX 1000BaseSX
+		10b7 1006  3C996B-T 1000BaseTX
+		10b7 1007  3C1000-T 1000BaseTX
+		10b7 1008  3C940-BR01 1000BaseTX
+		14e4 0001  NetXtreme BCM5701 1000BaseTX
+		14e4 0005  NetXtreme BCM5701 1000BaseTX
+		14e4 0006  NetXtreme BCM5701 1000BaseTX
+		14e4 0007  NetXtreme BCM5701 1000BaseSX
+		14e4 0008  NetXtreme BCM5701 1000BaseTX
+		14e4 8008  NetXtreme BCM5701 1000BaseTX
 14e5  Pixelfusion Ltd
 14e6  SHINING Technology Inc
 14e7  3CX
@@ -3955,6 +4043,8 @@
 		14f1 2015  SoftK56 Speakerphone Winmodem
 	2016  SoftK56 Speakerphone Winmodem
 		14f1 2016  SoftK56 Speakerphone Winmodem
+	2443  SoftK56 Speakerphone Winmodem
+		14f1 2443  SoftK56 Speakerphone Winmodem
 14f2  MOBILITY Electronics
 14f3  BROADLOGIC
 14f4  TOKYO Electronic Industry CO Ltd
@@ -3979,7 +4069,7 @@
 # 1507  HTEC Ltd
 # Commented out because there are no known HTEC chips and 1507 is already
 # used by mistake by Motorola (see vendor ID 1057)
-1507  Motorola ? / HTEC
+1507  Motorola ?? / HTEC
 	0001  MPC105 [Eagle]
 	0002  MPC106 [Grackle]
 	0003  MPC8240 [Kahlua]
@@ -4300,7 +4390,7 @@
 270b  Xantel Corporation
 270f  Chaintech Computer Co. Ltd
 2711  AVID Technology Inc.
-2a15  3D Vision(?)
+2a15  3D Vision(???)
 3000  Hansol Electronics Inc.
 3142  Post Impression Systems.
 3388  Hint Corp
@@ -4332,6 +4422,7 @@
 		3d3d 0125  Oxygen VX1
 		3d3d 0127  Permedia3 Create!
 	000a  GLINT R3
+		3d3d 0121  Oxygen VX1
 	0100  Permedia II 2D+3D
 	1004  Permedia
 	3d04  Permedia
@@ -4476,12 +4567,16 @@
 		5333 9125  86C394-397 Savage4 SGRAM 125
 		5333 9143  86C394-397 Savage4 SGRAM 143
 	8a23  Savage 4
+	8a25  ProSavage PM133
+	8a26  ProSavage KM133
 	8c00  ViRGE/M3
 	8c01  ViRGE/MX
 	8c02  ViRGE/MX+
 	8c03  ViRGE/MX+MV
-	8c10  86C270-294 Savage/MX-/IX
-	8c12  86C270-294 Savage/MX-/IX
+	8c10  86C270-294 Savage/MX-MV
+	8c11  82C270-294 Savage/MX
+	8c12  86C270-294 Savage/IX-MV
+	8c13  86C270-294 Savage/IX
 	9102  86C410 Savage 2000
 		1092 5932  Viper II Z200
 		1092 5934  Viper II Z200
@@ -4496,6 +4591,8 @@
 5455  Technische University Berlin
 	4458  S5933
 5519  Cnet Technologies, Inc.
+5544  Dunord Technologies
+	0001  I-30xx Scanner Interface
 5555  Genroco, Inc
 	0003  TURBOstor HFP-832 [HiPPI NIC]
 5700  Netpower
@@ -4523,22 +4620,37 @@
 	04a3  82434LX [Mercury/Neptune]
 	04d0  82437FX [Triton FX]
 	0960  80960RP [i960 RP Microprocessor/Bridge]
-	1000  82542 Gigabit Ethernet Adapter
+	0964  80960RP [i960 RP Microprocessor/Bridge]
+	1000  82542 Gigabit Ethernet Controller
 		0e11 b0df  NC1632 Gigabit Ethernet Adapter
 		0e11 b0e0  NC1633 Gigabit Ethernet Adapter
 		0e11 b123  NC1634 Gigabit Ethernet Adapter
 		1014 0119  Netfinity Gigabit Ethernet SX Adapter
-		8086 1000  EtherExpress PRO/1000 Gigabit Server Adapter
+	1001  82543GC Gigabit Ethernet Controller
+	1004  82543GC Gigabit Ethernet Controller
+	1008  82544EI Gigabit Ethernet Controller
+	100c  82544GC Gigabit Ethernet Controller
+	100d  82544GC Gigabit Ethernet Controller
 	1030  82559 InBusiness 10/100
+	1031  82801CAM (ICH3) Chipset Ethernet Controller
+	1032  82801CAM (ICH3) Chipset Ethernet Controller
+	1033  82801CAM (ICH3) Chipset Ethernet Controller
+	1034  82801CAM (ICH3) Chipset Ethernet Controller
+	1035  82801CAM (ICH3) Chipset Ethernet Controller
+	1036  82801CAM (ICH3) Chipset Ethernet Controller
+	1037  82801CAM (ICH3) Chipset Ethernet Controller
+	1038  82801CAM (ICH3) Chipset Ethernet Controller
+	1130  82815 815 Chipset Host Bridge and Memory Controller Hub
+	1132  82815 CGC [Chipset Graphics Controller] 
 	1161  82806AA PCI64 Hub Advanced Programmable Interrupt Controller
 	1209  82559ER
 	1221  82092AA_0
 	1222  82092AA_1
 	1223  SAA7116
 	1225  82452KX/GX [Orion]
-	1226  82596
-	1227  82865 [Ether Express Pro 100]
-	1228  82556 [Ether Express Pro 100 Smart]
+	1226  82596 PRO/10 PCI
+	1227  82865 EtherExpress PRO/100A
+	1228  82556 EtherExpress PRO/100 Smart
 	1229  82557 [Ethernet Pro 100]
 		0e11 b01e  NC3120
 		0e11 b01f  NC3122
@@ -4550,6 +4662,7 @@
 		0e11 b0dd  NC3131
 		0e11 b0de  NC3132
 		0e11 b0e1  NC3133
+		0e11 b144  NC3123 (82559)
 		1014 005c  82558B Ethernet Pro 10/100
 		1014 105c  Netfinity 10/100
 		1033 8000  PC-9821X-B06
@@ -4604,6 +4717,9 @@
 	1960  80960RP [i960RP Microprocessor]
 		101e 0438  MegaRaid 438
 		101e 0466  MegaRaid 466
+		101e 0467  MegaRaid 467
+		1028 0467  PowerEdge Expandable RAID Controller 2/DC
+		1028 1111  PowerEdge Expandable RAID Controller 2/SC
 		103c 10c6  MegaRaid 438
 		103c 10c7  MegaRaid T5
 		1111 1111  MegaRaid 466
@@ -4630,18 +4746,18 @@
 		11d4 0048  SoundMAX Integrated Digital Audio
 	2426  82801AB AC'97 Modem
 	2428  82801AB PCI Bridge
-	2440  82801BA ISA Bridge (ICH2)
-	2442  82801BA(M) USB (Hub A)
-	2443  82801BA(M) SMBus
-	2444  82801BA(M) USB (Hub B)
-	2445  82801BA(M) AC'97 Audio
-	2446  82801BA(M) AC'97 Modem
-	2448  82801BA PCI
-	2449  82801BA(M) Ethernet
-	244a  82801BAM IDE U100
-	244b  82801BA IDE U100
-	244c  82801BAM ISA Bridge (ICH2)
-	244e  82801BAM PCI
+	2440  82820 820 (Camino 2) Chipset ISA Bridge (ICH2)
+	2442  82820 820 (Camino 2) Chipset USB (Hub A)
+	2443  82820 820 (Camino 2) Chipset SMBus
+	2444  82820 820 (Camino 2) Chipset USB (Hub B)
+	2445  82820 820 (Camino 2) Chipset AC'97 Audio Controller
+	2446  82820 820 (Camino 2) Chipset AC'97 Modem Controller
+	2448  82820 820 (Camino 2) Chipset PCI (-M)
+	2449  82820 (ICH2) Chipset Ethernet Controller
+	244a  82820 820 (Camino 2) Chipset IDE U100 (-M)
+	244b  82820 820 (Camino 2) Chipset IDE U100
+	244c  82820 820 (Camino 2) Chipset ISA Bridge (ICH2-M)
+	244e  82820 820 (Camino 2) Chipset PCI
 	2500  82820 820 (Camino) Chipset Host Bridge (MCH)
 		1043 801c  P3C-2000 system chipset
 	2501  82820 820 (Camino) Chipset Host Bridge (MCH)
@@ -4651,10 +4767,13 @@
 	2520  82805AA MTH Memory Translator Hub
 	2521  82804AA MRH-S Memory Repeater Hub for SDRAM
 	2530  82850 850 (Tehama) Chipset Host Bridge (MCH)
+	2531  82850 860 (Wombat) Chipset Host Bridge (MCH)
 	2532  82850 850 (Tehama) Chipset AGP Bridge
-	5200  EtherExpress PRO/100
-	5201  EtherExpress PRO/100
+	2533  82860 860 (Wombat) Chipset AGP Bridge
+	5200  EtherExpress PRO/100 Intelligent Server
+	5201  EtherExpress PRO/100 Intelligent Server
 		8086 0001  EtherExpress PRO/100 Server Ethernet Adapter
+	530d  80310 IOP [IO Processor]
 	7000  82371SB PIIX3 ISA [Natoma/Triton II]
 	7010  82371SB PIIX3 IDE [Natoma/Triton II]
 	7020  82371SB PIIX3 USB [Natoma/Triton II]
@@ -4717,7 +4836,7 @@
 9004  Adaptec
 # FIXME: [dj] In one document I have, lot of these AIC's are actually AHA's
 	1078  AIC-7810
-	1160  AIC-1160 [Family Fiber Channel Adapter]
+	1160  AIC-1160 [Family Fibre Channel Adapter]
 	2178  AIC-7821
 	3860  AHA-2930CU
 	3b78  AHA-4844W/4844UW
@@ -4834,6 +4953,7 @@
 	00c0  7899A
 	00c1  7899B
 	00c3  7899D
+	00c5  RAID subsystem HBA
 	00cf  7899P
 907f  Atronics
 	2015  IDE-2015PL
@@ -5017,7 +5137,7 @@
 		10  OHCI
 		80  Unspecified
 		Fe  USB Device
-	04  Fiber Channel
+	04  Fibre Channel
 	05  SMBus
 	06  InfiniBand
 C 0d  Wireless controller
diff -u --recursive --new-file v2.4.10/linux/drivers/pci/setup-bus.c linux/drivers/pci/setup-bus.c
--- v2.4.10/linux/drivers/pci/setup-bus.c	Sat May 19 17:43:06 2001
+++ linux/drivers/pci/setup-bus.c	Thu Oct  4 18:47:08 2001
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 
 
-#define DEBUG_CONFIG 1
+#define DEBUG_CONFIG 0
 #if DEBUG_CONFIG
 # define DBGC(args)     printk args
 #else
diff -u --recursive --new-file v2.4.10/linux/drivers/pci/setup-res.c linux/drivers/pci/setup-res.c
--- v2.4.10/linux/drivers/pci/setup-res.c	Sat May 19 17:43:06 2001
+++ linux/drivers/pci/setup-res.c	Thu Oct  4 18:47:08 2001
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 
 
-#define DEBUG_CONFIG 1
+#define DEBUG_CONFIG 0
 #if DEBUG_CONFIG
 # define DBGC(args)     printk args
 #else
diff -u --recursive --new-file v2.4.10/linux/drivers/pcmcia/cb_enabler.c linux/drivers/pcmcia/cb_enabler.c
--- v2.4.10/linux/drivers/pcmcia/cb_enabler.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/pcmcia/cb_enabler.c	Sun Sep 30 12:26:07 2001
@@ -65,6 +65,7 @@
 
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("CardBus stub enabler module");
+MODULE_LICENSE("Dual MPL/GPL");
 
 /*====================================================================*/
 
diff -u --recursive --new-file v2.4.10/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- v2.4.10/linux/drivers/pcmcia/cs.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/pcmcia/cs.c	Sun Sep 30 12:26:07 2001
@@ -96,6 +96,7 @@
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Linux Kernel Card Services " CS_RELEASE
 		   "\n  options:" OPTIONS);
+MODULE_LICENSE("Dual MPL/GPL");	  
 
 /*====================================================================*/
 
diff -u --recursive --new-file v2.4.10/linux/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
--- v2.4.10/linux/drivers/pcmcia/ds.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/pcmcia/ds.c	Sun Sep 30 12:26:07 2001
@@ -68,6 +68,8 @@
 
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("PCMCIA Driver Services " CS_RELEASE);
+MODULE_LICENSE("Dual MPL/GPL");
+
 
 /*====================================================================*/
 
@@ -415,7 +417,10 @@
     driver->use_count++;
     b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
     if (!b) 
-      return -ENOMEM;
+    {
+    	driver->use_count--;
+	return -ENOMEM;    
+    }
     b->driver = driver;
     b->function = bind_info->function;
     b->instance = NULL;
diff -u --recursive --new-file v2.4.10/linux/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c
--- v2.4.10/linux/drivers/pcmcia/i82365.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/pcmcia/i82365.c	Sun Sep 30 12:26:07 2001
@@ -1660,5 +1660,5 @@
 
 module_init(init_i82365);
 module_exit(exit_i82365);
-
+MODULE_LICENSE("Dual MPL/GPL");
 /*====================================================================*/
diff -u --recursive --new-file v2.4.10/linux/drivers/pcmcia/tcic.c linux/drivers/pcmcia/tcic.c
--- v2.4.10/linux/drivers/pcmcia/tcic.c	Tue Mar  6 19:28:32 2001
+++ linux/drivers/pcmcia/tcic.c	Sun Sep 30 12:26:07 2001
@@ -69,6 +69,7 @@
 
 MODULE_AUTHOR("David Hinds <dhinds@pcmcia.sourceforge.org>");
 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
+MODULE_LICENSE("Dual MPL/GPL");
 
 /*====================================================================*/
 
diff -u --recursive --new-file v2.4.10/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- v2.4.10/linux/drivers/pcmcia/yenta.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/pcmcia/yenta.c	Sun Sep 30 12:26:07 2001
@@ -895,3 +895,4 @@
 	yenta_proc_setup
 };
 EXPORT_SYMBOL(yenta_operations);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- v2.4.10/linux/drivers/s390/block/dasd.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/block/dasd.c	Sun Sep 30 12:26:07 2001
@@ -135,7 +135,9 @@
 static void dasd_enable_single_device ( unsigned long);
 static inline int dasd_state_init_to_ready(dasd_device_t*);
 static inline void dasd_setup_partitions ( dasd_device_t *);
+static inline void dasd_destroy_partitions ( dasd_device_t *);
 static inline int dasd_setup_blkdev(dasd_device_t*);
+static void dasd_deactivate_queue (dasd_device_t *);
 static inline int dasd_disable_blkdev(dasd_device_t*);
 static void dasd_flush_chanq ( dasd_device_t * device, int destroy ); 
 static void dasd_flush_request_queues ( dasd_device_t * device, int destroy );
@@ -205,12 +207,20 @@
         int i;
 
 	if ( from > to ) {
-                printk (KERN_WARNING PRINTK_HEADER "Adding device range %04X-%04X: range invalid, ignoring.\n",from,to);
+                printk (KERN_WARNING PRINTK_HEADER 
+                        "Adding device range %04x-%04x: range invalid, ignoring.\n",
+                        from,
+                        to);
+
 		return NULL;
 	}
 	for (i=from;i<=to;i++) {
                 if (dasd_device_from_devno(i)) {
-                        printk (KERN_WARNING PRINTK_HEADER "device range %04X-%04X: device %04X is already in a range.\n",from,to,i);
+                        printk (KERN_WARNING PRINTK_HEADER 
+                                "device range %04x-%04x: device %04x is already in a range.\n",
+                                from,
+                                to,
+                                i);
                 }
         }
 	range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL);
@@ -501,8 +511,15 @@
         }
 
         /* copy device no to buffer and convert to decimal */
-        for (i=0;isxdigit(temp[i]);i++)
-                buffer[i]=temp[i];
+        for (i=0; temp[i]!='\0' && temp[i]!='(' && 
+                  temp[i]!='-'  && temp[i]!=' '; i++){
+                if (isxdigit(temp[i])) {
+                        buffer[i]=temp[i];
+                } else {
+                        return -EINVAL;
+                }
+        }
+
         buffer[i]='\0';
 
         val = simple_strtoul (buffer, &buffer, 16);
@@ -524,10 +541,12 @@
                                         break;
                                 }
                                 printk (KERN_WARNING PRINTK_HEADER 
-                                        "unsupported feature: %s, ignoring setting",buffer);
+                                        "unsupported feature: %s, ignoring setting",
+                                        buffer);
                         }
                 }
         }
+
         *stra = temp+i;
         return val;
 }
@@ -537,12 +556,13 @@
  * examines the strings given in the string array str and
  * creates and adds the ranges to the apropriate lists
  */
-static inline void
+static int
 dasd_parse (char **str)
 {
 	char *temp;
 	int from, to;
         int features = 0;
+        int rc = 0;
 
 	if (*str) {
 		/* turn off probeonly mode, if any dasd parameter is present */
@@ -570,10 +590,18 @@
 				temp++;
 				to = dasd_strtoul (temp, &temp, &features);
 			}
-			dasd_add_range (from, to ,features);
-		}
+                        if (from == -EINVAL ||
+                            to   == -EINVAL    ) {
+                                rc = -EINVAL;
+                                break;
+                        } else {
+                                dasd_add_range (from, to ,features);
+                        }
+                }
 		str++;
 	}
+
+        return rc;
 }
 
 /* SECTION: Dealing with devices registered to multiple major numbers */
@@ -648,7 +676,9 @@
 	rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);
 	if (rc < 0) {
 		printk (KERN_WARNING PRINTK_HEADER
-			"Cannot register to major no %d, rc = %d\n", major, rc);
+			"Cannot register to major no %d, rc = %d\n",
+                        major, 
+                        rc);
 		goto out_reg_blkdev; 
 	} else {
 		major_info->flags |= DASD_MAJOR_INFO_REGISTERED;
@@ -751,7 +781,8 @@
 	rc = devfs_unregister_blkdev (major, DASD_NAME);
 	if (rc < 0) {
 		printk (KERN_WARNING PRINTK_HEADER
-			"Unable to unregister from major no %d, rc = %d\n", major,
+			"Unable to unregister from major no %d, rc = %d\n", 
+                        major,
 			rc);
 	} else {
 		major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;
@@ -800,7 +831,8 @@
 	rc = devfs_unregister_blkdev (major, DASD_NAME);
 	if (rc < 0) {
 		printk (KERN_WARNING PRINTK_HEADER
-			"Cannot unregister from major no %d, rc = %d\n", major,
+			"Cannot unregister from major no %d, rc = %d\n",
+                        major,
 			rc);
 		return rc;
 	} else {
@@ -1051,8 +1083,6 @@
 dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* device)
 {
 	ccw_req_t *rv = NULL;
-	int i;
-	unsigned long flags;
 
 	if ((rv = ccw_alloc_request (magic, cplength, datasize)) != NULL) {
 		return rv;
@@ -1062,7 +1092,9 @@
 		BUG ();
 		}
         if (device->lowmem_cqr==NULL) {
-                DASD_MESSAGE (KERN_WARNING, device, "Low memory! Using emergency request %p",device->lowmem_ccws);
+                DASD_MESSAGE (KERN_WARNING, device, 
+                              "Low memory! Using emergency request %p",
+                              device->lowmem_ccws);
                 device->lowmem_cqr=device->lowmem_ccws;
                 rv = device->lowmem_ccws;
 		memset (rv, 0, PAGE_SIZE);
@@ -1073,7 +1105,10 @@
 		rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
 		rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
         } else {
-                DASD_MESSAGE (KERN_WARNING, device,"Refusing emergency mem for request NULL, already in use at %p.",device->lowmem_ccws);
+                DASD_MESSAGE (KERN_WARNING, device,
+                              "Refusing emergency mem for request "
+                              "NULL, already in use at %p.",
+                              device->lowmem_ccws);
 	}
 	return rv;
 }
@@ -1086,47 +1121,61 @@
 dasd_free_request (ccw_req_t * request, dasd_device_t* device)
 {
 #ifdef CONFIG_ARCH_S390X
-    ccw1_t* ccw;
-    /* clear any idals used for chain */
-    ccw=request->cpaddr-1;
-    do {
-            ccw++;
-            if ((ccw->cda < (unsigned long) device->lowmem_idals) || (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE))
-                    clear_normalized_cda (ccw);
-            else {
-                    if (device->lowmem_idal_ptr != device->lowmem_idals)
-                            DASD_MESSAGE (KERN_WARNING, device, "Freeing emergency idals from request at %p.",request);
-                    device->lowmem_idal_ptr = device->lowmem_idals;
-                    device->lowmem_cqr=NULL;
-            }
-    } while ((ccw->flags & CCW_FLAG_CC) || (ccw->flags & CCW_FLAG_DC));
+        ccw1_t* ccw;
+        /* clear any idals used for chain */
+        ccw=request->cpaddr-1;
+        do {
+                ccw++;
+                if ((ccw->cda < (unsigned long) device->lowmem_idals           ) || 
+                    (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE)   )
+                        clear_normalized_cda (ccw);
+                else {
+                        if (device->lowmem_idal_ptr != device->lowmem_idals)
+                                DASD_MESSAGE (KERN_WARNING, device,
+                                              "Freeing emergency idals from request at %p.",
+                                              request);
+                        device->lowmem_idal_ptr = device->lowmem_idals;
+                        device->lowmem_cqr=NULL;
+                }
+        } while ((ccw->flags & CCW_FLAG_CC) || 
+                 (ccw->flags & CCW_FLAG_DC)   );
 #endif
-    if (request != device->lowmem_ccws) { /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */
+        if (request != device->lowmem_ccws) { 
+                /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */
 		ccw_free_request (request);
-    } else {
-            DASD_MESSAGE (KERN_WARNING, device,  "Freeing emergency request at %p",request);
-            device->lowmem_cqr=NULL;
+        } else {
+                DASD_MESSAGE (KERN_WARNING, device,
+                              "Freeing emergency request at %p",
+                              request);
+                device->lowmem_cqr=NULL;
 	}
 }
 
 int
-dasd_set_normalized_cda ( ccw1_t * cp, unsigned long address, ccw_req_t* request, dasd_device_t* device )
+dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, 
+                         ccw_req_t* request, dasd_device_t* device )
 {
 #ifdef CONFIG_ARCH_S390X
 	int nridaws;
         int count = cp->count;
         
         if (set_normalized_cda (cp, address)!=-ENOMEM) {
-            return 0;
+                return 0;
         }
 
         if ((device->lowmem_cqr!=NULL) && (device->lowmem_cqr!=request)) {
-            DASD_MESSAGE (KERN_WARNING, device, "Refusing emergency idals for request %p, memory is already in use for request %p",request,device->lowmem_cqr);
-            return -ENOMEM;
+                DASD_MESSAGE (KERN_WARNING, device, 
+                              "Refusing emergency idals for request %p, memory"
+                              " is already in use for request %p",
+                              request,
+                              device->lowmem_cqr);
+                return -ENOMEM;
         }
         device->lowmem_cqr=request;
         if (device->lowmem_idal_ptr == device->lowmem_idals) {
-            DASD_MESSAGE (KERN_WARNING,device, "Low memory! Using emergency IDALs for request %p.\n",request);
+            DASD_MESSAGE (KERN_WARNING,device, 
+                          "Low memory! Using emergency IDALs for request %p.\n",
+                          request);
         }
         nridaws = ((address & (IDA_BLOCK_SIZE-1)) + count + 
 		   (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
@@ -1165,7 +1214,27 @@
 		q->head = cqr;
 	cqr->next = NULL;
 	q->tail = cqr;
-	check_then_set (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
+	check_then_set (&cqr->status, 
+                        CQR_STATUS_FILLED, 
+                        CQR_STATUS_QUEUED);
+
+       
+        /* save profile information for non erp cqr */
+        if (cqr->refers == NULL) {
+                unsigned int  counter = 0;
+                ccw_req_t     *ptr;
+                dasd_device_t *device = cqr->device;
+
+                /* count the length of the chanq for statistics */
+                for (ptr = q->head; 
+                     ptr->next != NULL && counter <=31; 
+                     ptr = ptr->next) {
+                        counter++;
+                }                
+                
+                dasd_global_profile.dasd_io_nr_req[counter]++;
+                device->profile.dasd_io_nr_req[counter]++;
+        }
 }
 
 /*
@@ -1217,8 +1286,11 @@
 /* SECTION: Managing the device queues etc. */
 
 /*
- * function dasd_start_IO
- * attempts to start the IO and returns an appropriate return code
+ * DASD_TERM_IO
+ *
+ * attempts to terminate the the current IO and set it to failed if termination
+ * was successful.
+ * returns an appropriate return code
  */
 int
 dasd_term_IO (ccw_req_t * cqr)
@@ -1234,49 +1306,54 @@
 	irq = device->devinfo.irq;
 	if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
 		DASD_MESSAGE (KERN_WARNING, device,
-			      " ccw_req_t 0x%08X magic doesn't match"
-			      " discipline 0x%08X\n",
+			      " ccw_req_t 0x%08x magic doesn't match"
+			      " discipline 0x%08x\n",
 			      cqr->magic,
 			      *(unsigned int *) device->discipline->name);
 		return -EINVAL;
 	}
+        
+        while ((retries < 5                    ) &&
+               (cqr->status == CQR_STATUS_IN_IO)   ) {
 
-        while ( retries < 5 ) {
-            if ( retries < 2 )
-                rc = halt_IO(irq, (long)cqr, 
-                             cqr->options | DOIO_WAIT_FOR_INTERRUPT);
-            else
-                rc = clear_IO(irq, (long)cqr, 
-                              cqr->options | DOIO_WAIT_FOR_INTERRUPT);
-            switch (rc) {
-            case 0:
-		break;
-            case -ENODEV:
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "device gone, retry\n");
-		break;
-            case -EIO:
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "I/O error, retry\n");
-		break;
-            case -EBUSY:
-		DASD_MESSAGE (KERN_WARNING, device, "%s",
-			      "device busy, retry later\n");
-		break;
-            default:
-		DASD_MESSAGE (KERN_ERR, device,
-			      "line %d unknown RC=%d, please report"
-			      " to linux390@de.ibm.com\n", __LINE__, rc);
-		BUG ();
-		break;
-            }
-            if (rc == 0) {
-		check_then_set (&cqr->status,
-				CQR_STATUS_IN_IO, CQR_STATUS_FAILED);
-                asm volatile ("STCK %0":"=m" (cqr->stopclk));
-                break;
-            }
-            retries ++;
+                if ( retries < 2 )
+                        rc = halt_IO(irq, (long)cqr, 
+                                     cqr->options | DOIO_WAIT_FOR_INTERRUPT);
+                else
+                        rc = clear_IO(irq, (long)cqr, 
+                                      cqr->options | DOIO_WAIT_FOR_INTERRUPT);
+
+                switch (rc) {
+                case 0:         /* termination successful */
+                        check_then_set (&cqr->status,
+                                        CQR_STATUS_IN_IO, 
+                                        CQR_STATUS_FAILED);
+                        
+                        asm volatile ("STCK %0":"=m" (cqr->stopclk));
+                        break;
+                case -ENODEV:
+                        DASD_MESSAGE (KERN_WARNING, device, "%s",
+                                      "device gone, retry\n");
+                        break;
+                case -EIO:
+                        DASD_MESSAGE (KERN_WARNING, device, "%s",
+                                      "I/O error, retry\n");
+                        break;
+                case -EBUSY:
+                        DASD_MESSAGE (KERN_WARNING, device, "%s",
+                                      "device busy, retry later\n");
+                        break;
+                default:
+                        DASD_MESSAGE (KERN_ERR, device,
+                                      "line %d unknown RC=%d, please report"
+                                      " to linux390@de.ibm.com\n", 
+                                      __LINE__, 
+                                      rc);
+                        BUG ();
+                        break;
+                }
+
+                retries ++;
         }
 	return rc;
 }
@@ -1299,30 +1376,54 @@
 	irq = device->devinfo.irq;
 	if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
 		DASD_MESSAGE (KERN_WARNING, device,
-			      " ccw_req_t 0x%08X magic doesn't match"
-			      " discipline 0x%08X\n",
+			      " ccw_req_t 0x%08x magic doesn't match"
+			      " discipline 0x%08x\n",
 			      cqr->magic,
 			      *(unsigned int *) device->discipline->name);
 		return -EINVAL;
 	}
 
 	asm volatile ("STCK %0":"=m" (now));
+        cqr->startclk = now;
+
 	rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options);
+
 	switch (rc) {
 	case 0:
-		break;
-	case -ENODEV:
-		check_then_set (&cqr->status,
-				CQR_STATUS_QUEUED, CQR_STATUS_FAILED);
-		break;
-	case -EIO:
-		check_then_set (&cqr->status,
-				CQR_STATUS_QUEUED, CQR_STATUS_FAILED);
+                if (cqr->options & DOIO_WAIT_FOR_INTERRUPT) {
+                        /* request already finished (synchronous IO) */
+                        DASD_MESSAGE (KERN_ERR, device, "%s",
+                                      " do_IO finished request... "
+                                      "DOIO_WAIT_FOR_INTERRUPT was set");
+                        check_then_set (&cqr->status,
+                                        CQR_STATUS_QUEUED, 
+                                        CQR_STATUS_DONE);
+
+                        cqr->stopclk = now;
+                        dasd_schedule_bh (device);
+                        
+                } else {
+                        check_then_set (&cqr->status,
+                                        CQR_STATUS_QUEUED, 
+                                        CQR_STATUS_IN_IO);
+                }
 		break;
 	case -EBUSY:
 		DASD_MESSAGE (KERN_WARNING, device, "%s",
 			      "device busy, retry later\n");
 		break;
+	case -ETIMEDOUT: 
+		DASD_MESSAGE (KERN_WARNING, device, "%s",
+			      "request timeout - terminated\n");
+	case -ENODEV:
+	case -EIO:
+		check_then_set (&cqr->status,
+				CQR_STATUS_QUEUED, 
+                                CQR_STATUS_FAILED);
+
+                cqr->stopclk = now;
+                dasd_schedule_bh (device);
+		break;
 	default:
 		DASD_MESSAGE (KERN_ERR, device,
 			      "line %d unknown RC=%d, please report"
@@ -1330,11 +1431,7 @@
 		BUG ();
 		break;
 	}
-	if (rc == 0) {
-		check_then_set (&cqr->status,
-				CQR_STATUS_QUEUED, CQR_STATUS_IN_IO);
-		cqr->startclk = now;
-	}
+
 	return rc;
 }
 
@@ -1410,7 +1507,7 @@
 /*
  * function dasd_check_expire_time
  * check the request given as argument for expiration
- * and returns 0 if not yet expired, nonzero else
+ * and returns 0 if not yet expired, EIO else
  */
 static inline int
 dasd_check_expire_time (ccw_req_t * cqr)
@@ -1425,6 +1522,7 @@
 			      (long) (cqr->expires >> 44),
 			      (long) (cqr->expires >> 12), cqr);
 		cqr->expires <<= 1;
+                rc = -EIO;
 	}
 	return rc;
 }
@@ -1502,6 +1600,8 @@
                                                 CQR_STATUS_ERROR,
                                                 CQR_STATUS_FAILED);
 
+                                asm volatile ("STCK %0":"=m" (qp->head->stopclk));
+
                         } else if ((device->discipline->erp_action == NULL                          ) ||
                                    ((erp_action = device->discipline->erp_action (qp->head)) == NULL)   ) {
                                 
@@ -1628,7 +1728,8 @@
 		}
 	}
 	s390irq_spin_unlock_irqrestore (irq, flags);
-}
+
+} /* end dasd_process_queues */
 
 /*
  * function dasd_run_bh
@@ -1703,28 +1804,30 @@
 
 		printk (KERN_DEBUG PRINTK_HEADER
 			"unable to find device for state change pending "
-			"interrupt: devno%04X\n", stat->devno);
-	} else {
-		/* re-activate first request in queue */
-		cqr = (*device_addr)->queue.head;
-
-		if (cqr->status == CQR_STATUS_PENDING) {
-
-			DASD_MESSAGE (KERN_DEBUG, (*device_addr),
-				      "%s",
-				      "device request queue restarted by "
-				      "state change pending interrupt\n");
-
-			del_timer (&(*device_addr)->timer);
-
-			check_then_set (&cqr->status,
-					CQR_STATUS_PENDING, CQR_STATUS_QUEUED);
+			"interrupt: devno%04x\n", 
+                        stat->devno);
+                return;
+	} 
 
-			dasd_schedule_bh (*device_addr);
+        /* re-activate first request in queue */
+        cqr = (*device_addr)->queue.head;
+        
+        if (cqr->status == CQR_STATUS_PENDING) {
+                
+                DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s",
+                              "device request queue restarted by "
+                              "state change pending interrupt\n");
+                
+                del_timer (&(*device_addr)->timer);
+                
+                check_then_set (&cqr->status,
+                                CQR_STATUS_PENDING, CQR_STATUS_QUEUED);
+                
+                dasd_schedule_bh (*device_addr);
+                
+        }
 
-		}
-	}
-}				/* end dasd_handle_state_change_pending */
+} /* end dasd_handle_state_change_pending */
 
 /*
  * function dasd_int_handler
@@ -1740,44 +1843,66 @@
 	dasd_era_t era = dasd_era_none; /* default is everything is okay */
 	devstat_t *stat = (devstat_t *)ds;
 
-        DASD_DRIVER_DEBUG_EVENT (4, dasd_int_handler,
-                                 "Interrupt: IRQ 0x%x",irq);
+        DASD_DRIVER_DEBUG_EVENT (6, dasd_int_handler,
+                                 "Interrupt: IRQ %02x, stat %02x, devno %04x",
+                                 irq,
+                                 stat->dstat,
+                                 stat->devno);
         asm volatile ("STCK %0":"=m" (now));
         if (stat == NULL) {
                 BUG();
 	}
 
         /* first of all check for state change pending interrupt */
-        if (stat->dstat & (DEV_STAT_ATTENTION | 
-                           DEV_STAT_DEV_END   |
-                           DEV_STAT_UNIT_EXCEP )) {
+        if ((stat->dstat & DEV_STAT_ATTENTION ) && 
+            (stat->dstat & DEV_STAT_DEV_END   ) &&
+            (stat->dstat & DEV_STAT_UNIT_EXCEP)   ) {
                 DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
-                                         "State change Interrupt: %04X",
+                                         "State change Interrupt: %04x",
                                          stat->devno);
                 dasd_handle_state_change_pending (stat);
-                //return; /* TBD */
+                return;
         }
 
 	ip = stat->intparm;
 	if (!ip) {		/* no intparm: unsolicited interrupt */
                 DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
-                                         "Unsolicited Interrupt: %04X",
+                                         "Unsolicited Interrupt: %04x",
                                          stat->devno);
 		printk (KERN_DEBUG PRINTK_HEADER
-                        "unsolicited interrupt: irq0x%x devno%04X\n",
-                        irq,stat->devno);
+                        "unsolicited interrupt: irq 0x%x devno %04x\n",
+                        irq,
+                        stat->devno);
 		return;
 	}
 	if (ip & 0x80000001) {
                 DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
-                                         "spurious Interrupt: %04X",
+                                         "spurious Interrupt: %04x",
                                          stat->devno);
 		printk (KERN_DEBUG PRINTK_HEADER
-                        "spurious interrupt: irq0x%x devno%04X, parm %08x\n",
-                        irq,stat->devno,ip);
+                        "spurious interrupt: irq 0x%x devno %04x, parm %08x\n",
+                        irq,
+                        stat->devno,ip);
 		return;
 	}
+
 	cqr = (ccw_req_t *)(long)ip;
+
+        /* check status - the request might have been killed because of dyn dettach */
+	if (cqr->status != CQR_STATUS_IN_IO) {
+                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
+                                         "invalid status %02x on device %04x",
+                                         cqr->status,
+                                         stat->devno);
+
+		printk (KERN_DEBUG PRINTK_HEADER
+                        "invalid status: irq 0x%x devno %04x, status %02x\n",
+                        irq,
+                        stat->devno,
+                        cqr->status);
+		return;
+	}
+
 	device = (dasd_device_t *) cqr->device;
 	if (device == NULL || 
             device != ds-offsetof(dasd_device_t,dev_status)) {
@@ -1789,46 +1914,11 @@
 	if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) {
                 BUG();
 	}
-#ifdef ERP_FAKE
-        {
-                static int counter    = 0;
-                static int fake_count = 0;
-
-                if ((++counter % 937 >=   0) &&
-                    (  counter % 937 <=  10) && 
-                    (  counter       < 5000) && 
-                    (  counter       > 2000)   ) {
 
-                        char *sense = stat->ii.sense.data;
-                        
-                        printk (KERN_INFO PRINTK_HEADER
-                                "***********************************************\n");
-                        printk (KERN_INFO PRINTK_HEADER
-                                "Faking I/O error to recover from; cntr=%i / %02X\n",
-                                counter, ++fake_count);
-                        printk (KERN_INFO PRINTK_HEADER
-                                "***********************************************\n");
-
-                        era = dasd_era_recover;
-                        stat->flag  |= DEVSTAT_FLAG_SENSE_AVAIL;
-                        stat->dstat |= 0x02;
-                        memset(sense,0,32);
-
-                        /* 32 byte sense (byte 27 bit 1 = 0)*/
-                        sense[25] = 0x1D;
-//                        sense [25] = (fake_count % 256); //0x1B;
-
-                        /* 24 byte sense (byte 27 bit 1 = 1)*/
-//                        sense [0] = (counter % 0xFF); //0x1B;
-//                        sense [1] = ((counter * 7) % 0xFF); //0x1B;
-//                        sense [2] = (fake_count % 0xFF); //0x1B;
-//                        sense [27] = 0x80;
-                }
-        }
-#endif /* ERP_FAKE */
         /* first of all lets try to find out the appropriate era_action */
-        DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04X",
+        DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04x",
                                  ((stat->cstat<<8)|stat->dstat));
+
 	/* first of all lets try to find out the appropriate era_action */
 	if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL ||
 	    stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
@@ -1844,7 +1934,9 @@
 	}
         if ( era == dasd_era_none ) {
                 check_then_set(&cqr->status, 
-                               CQR_STATUS_IN_IO, CQR_STATUS_DONE);
+                               CQR_STATUS_IN_IO, 
+                               CQR_STATUS_DONE);
+
                 cqr->stopclk=now;
 		/* start the next queued request if possible -> fast_io */
                 if (cqr->next &&
@@ -1875,11 +1967,15 @@
 
 		switch (era) {
 		case dasd_era_fatal:
-			check_then_set (&cqr->status, CQR_STATUS_IN_IO,
+			check_then_set (&cqr->status, 
+                                        CQR_STATUS_IN_IO,
 					CQR_STATUS_FAILED);
+
+                        cqr->stopclk = now;
 			break;
 		case dasd_era_recover:
-			check_then_set (&cqr->status, CQR_STATUS_IN_IO,
+			check_then_set (&cqr->status, 
+                                        CQR_STATUS_IN_IO,
 					CQR_STATUS_ERROR);
 			break;
 		default:
@@ -1894,7 +1990,8 @@
                         wake_up (&dasd_init_waitq);
         }
 	dasd_schedule_bh (device);
-}
+
+} /* end dasd_int_handler */
 
 /* SECTION: Some stuff related to error recovery */
 
@@ -1929,13 +2026,15 @@
                                 CQR_STATUS_ERROR,
                                 CQR_STATUS_FAILED);
 
+                asm volatile ("STCK %0":"=m" (cqr->stopclk));
+
                 return cqr;
 	}
 
 	erp->cpaddr->cmd_code = CCW_CMD_TIC;
 	erp->cpaddr->cda = (__u32) (void *) cqr->cpaddr;
 	erp->function = dasd_default_erp_action;
-	erp->refers = (unsigned int) (unsigned long) cqr;
+	erp->refers = cqr;
 	erp->device = cqr->device;
 	erp->magic = cqr->magic;
 	erp->retries = 16;
@@ -1946,7 +2045,8 @@
                              erp);
 
 	return erp;
-}
+
+} /* end dasd_default_erp_action */
 
 /*
  * DEFAULT_ERP_POSTACTION
@@ -2012,6 +2112,8 @@
 		check_then_set (&cqr->status,
 				CQR_STATUS_ERROR, 
                                 CQR_STATUS_FAILED);
+
+                asm volatile ("STCK %0":"=m" (cqr->stopclk));
 	}
 
 	return cqr;
@@ -2040,8 +2142,10 @@
 	}
 	DASD_MESSAGE (KERN_INFO, device,
 		      "formatting units %d to %d (%d B blocks) flags %d",
-		      fdata->start_unit, fdata->stop_unit,
-		      fdata->blksize, fdata->intensity);
+		      fdata->start_unit, 
+                      fdata->stop_unit,
+		      fdata->blksize, 
+                      fdata->intensity);
 	while ((!rc) && (fdata->start_unit <= fdata->stop_unit)) {
                 ccw_req_t *req;
                 dasd_format_fn_t ffn = device->discipline->format_device;
@@ -2060,8 +2164,10 @@
 			break;
 		} 
 		dasd_free_request (req, device);	/* request is no longer used */
-	        if ( signal_pending(current) )
+	        if ( signal_pending(current) ) {
+			rc = -ERESTARTSYS;
 			break;		
+                }
 		fdata->start_unit++;
 	}
 	return rc;
@@ -2126,7 +2232,13 @@
 	}
 	for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) {
                 int major = device->major_info->gendisk.major;
-		invalidate_device(MKDEV (major, start+i), 1);
+		int minor = start + i;
+		kdev_t devi = MKDEV (major, minor);
+		struct super_block *sb = get_super (devi);
+		//sync_dev (devi);
+		if (sb)
+			invalidate_inodes (sb);
+		invalidate_buffers (devi);
 	}
         dasd_destroy_partitions(device);
         dasd_setup_partitions(device);
@@ -2143,7 +2255,8 @@
 	if (!device) {
 		printk (KERN_WARNING PRINTK_HEADER
 			"No device registered as device (%d:%d)\n",
-			MAJOR (inp->i_rdev), MINOR (inp->i_rdev));
+			MAJOR (inp->i_rdev), 
+                        MINOR (inp->i_rdev));
 		return -EINVAL;
 	}
 	if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) {
@@ -2154,15 +2267,21 @@
 #if 0
 	printk (KERN_DEBUG PRINTK_HEADER
 		"ioctl 0x%08x %s'0x%x'%d(%d) on /dev/%s (%d:%d,"
-		" devno 0x%04X on irq %d) with data %8lx\n",
+		" devno 0x%04x on irq %d) with data %8lx\n",
 		no,
 		_IOC_DIR (no) == _IOC_NONE ? "0" :
 		_IOC_DIR (no) == _IOC_READ ? "r" :
 		_IOC_DIR (no) == _IOC_WRITE ? "w" :
 		_IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
-		_IOC_TYPE (no), _IOC_NR (no), _IOC_SIZE (no),
-		device->name, MAJOR (inp->i_rdev), MINOR (inp->i_rdev),
-		device->devinfo.devno, device->devinfo.irq, data);
+		_IOC_TYPE (no),
+                _IOC_NR (no),
+                _IOC_SIZE (no),
+		device->name, 
+                MAJOR (inp->i_rdev), 
+                MINOR (inp->i_rdev),
+		device->devinfo.devno, 
+                device->devinfo.irq, 
+                data);
 #endif
 	switch (no) {
         case DASDAPIVER: {
@@ -2175,13 +2294,11 @@
 	case BLKGETSIZE:{	/* Return device size */
 			long blocks = major_info->gendisk.sizes 
                                       [MINOR (inp->i_rdev)] << 1;
-			rc = put_user(blocks, (long *)arg);
-			break;
-		}
-	case BLKGETSIZE64:{
-			u64 blocks = major_info->gendisk.sizes 
-                                      [MINOR (inp->i_rdev)];
-			rc = put_user(blocks << 10, (u64 *)arg);
+			rc =
+			    copy_to_user ((long *) data, &blocks,
+					  sizeof (long));
+			if (rc)
+				rc = -EFAULT;
 			break;
 		}
 	case BLKRRPART:{
@@ -2210,6 +2327,7 @@
 				break;
 			}
                         if ( device->level > DASD_STATE_ACCEPT) {
+                                dasd_deactivate_queue(device);
                                 if ( device->request_queue)
                                         dasd_flush_request_queues(device,0);
                                 dasd_flush_chanq(device,0);
@@ -2264,7 +2382,7 @@
 			rc = dasd_format (device, &fdata);
 			break;
 		}
-	case BIODASDPRRST:{
+	case BIODASDPRRST:{     /* reset device profile information */
 			if (!capable (CAP_SYS_ADMIN)) {
 				rc = -EACCES;
 				break;
@@ -2273,7 +2391,7 @@
 				sizeof (dasd_profile_info_t));
 			break;
 		}
-	case BIODASDPRRD:{
+	case BIODASDPRRD:{      /* retrun device profile information */
 			rc = copy_to_user((long *)data,
 					  (long *)&device->profile,
 					  sizeof(dasd_profile_info_t));
@@ -2281,7 +2399,7 @@
 				rc = -EFAULT;
 			break;
 		}
-	case BIODASDRSRV:{
+	case BIODASDRSRV:{      /* reserve */
 			ccw_req_t *req;
 			if (!capable (CAP_SYS_ADMIN)) {
 				rc = -EACCES;
@@ -2292,7 +2410,7 @@
 			dasd_free_request (req, device);
 			break;
 		}
-	case BIODASDRLSE:{
+	case BIODASDRLSE:{      /* release */
 			ccw_req_t *req;
 			if (!capable (CAP_SYS_ADMIN)) {
 				rc = -EACCES;
@@ -2303,9 +2421,15 @@
 			dasd_free_request (req, device);
 			break;
 		}
-	case BIODASDSLCK:{
-			printk (KERN_WARNING PRINTK_HEADER
-				"Unsupported ioctl BIODASDSLCK\n");
+	case BIODASDSLCK:{      /* steal lock - unconditional reserve */
+			ccw_req_t *req;
+			if (!capable (CAP_SYS_ADMIN)) {
+				rc = -EACCES;
+				break;
+			}
+			req = device->discipline->steal_lock (device);
+			rc = dasd_sleep_on_req (req);
+			dasd_free_request (req, device);
 			break;
 		}
 	case BIODASDINFO:{
@@ -2398,11 +2522,12 @@
 					      no,
 					      _IOC_DIR (no) == _IOC_NONE ? "0" :
 					      _IOC_DIR (no) == _IOC_READ ? "r" :
-					      _IOC_DIR (no) ==
-					      _IOC_WRITE ? "w" : _IOC_DIR (no)
-					      == (_IOC_READ | _IOC_WRITE) ? "rw"
-					      : "u", _IOC_TYPE (no),
-					      _IOC_NR (no), _IOC_SIZE (no),
+					      _IOC_DIR (no) == _IOC_WRITE ? "w" : 
+                                              _IOC_DIR (no) == 
+                                              (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
+                                              _IOC_TYPE (no),
+					      _IOC_NR (no), 
+                                              _IOC_SIZE (no),
 					      data);
 				rc = -ENOTTY;
 			}
@@ -2441,7 +2566,8 @@
 	if (dasd_probeonly) {
 		printk ("\n" KERN_INFO PRINTK_HEADER
 			"No access to device (%d:%d) due to probeonly mode\n",
-			MAJOR (inp->i_rdev), MINOR (inp->i_rdev));
+			MAJOR (inp->i_rdev), 
+                        MINOR (inp->i_rdev));
 		rc = -EPERM;
                 goto fail;
 	}
@@ -2450,13 +2576,14 @@
 	if (device == NULL ) {
 		printk (KERN_WARNING PRINTK_HEADER
 			"No device registered as (%d:%d)\n",
-			MAJOR (inp->i_rdev), MINOR (inp->i_rdev));
+			MAJOR (inp->i_rdev), 
+                        MINOR (inp->i_rdev));
 		rc = -ENODEV;
                 goto unlock;
 	}
-	if (device->level < DASD_STATE_ACCEPT ) {
-		DASD_MESSAGE (KERN_WARNING, device,
-			      " %s", " Cannot open unrecognized device\n");
+	if (device->level <= DASD_STATE_ACCEPT ) {
+		DASD_MESSAGE (KERN_WARNING, device, " %s", 
+                              " Cannot open unrecognized device\n");
 		rc = -ENODEV;
                 goto unlock;
 	}
@@ -2473,6 +2600,11 @@
 	return rc;
 }
 
+/*
+ * DASD_RELEASE
+ *
+ * DESCRIPTION
+ */
 static int
 dasd_release (struct inode *inp, struct file *filp)
 {
@@ -2488,17 +2620,19 @@
 	if (device == NULL) {
 		printk (KERN_WARNING PRINTK_HEADER
 			"No device registered as %d:%d\n",
-			MAJOR (inp->i_rdev), MINOR (inp->i_rdev));
+			MAJOR (inp->i_rdev), 
+                        MINOR (inp->i_rdev));
 		rc = -EINVAL;
                 goto out;
 	}
 
 	if (device->level < DASD_STATE_ACCEPT ) {
-		DASD_MESSAGE (KERN_WARNING, device,
-			      " %s", " Cannot release unrecognized device\n");
+		DASD_MESSAGE (KERN_WARNING, device, " %s",
+                              " Cannot release unrecognized device\n");
 		rc = -ENODEV;
                 goto out;
 	}
+	// fsync_dev (inp->i_rdev);	/* sync the device */
         count = atomic_dec_return (&device->open_count);
         if ( count == 0) {
                 invalidate_buffers (inp->i_rdev);
@@ -2604,11 +2738,14 @@
                 s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
                 cqr = device->queue.head;
                 while ( cqr != NULL ) {
-                        if ( cqr -> status == CQR_STATUS_IN_IO )
+                        if ( cqr->status == CQR_STATUS_IN_IO )
                                 device->discipline->term_IO (cqr);
                         if ( cqr->status != CQR_STATUS_DONE ||
                              cqr->status != CQR_STATUS_FAILED ) {
+
                                 cqr->status = CQR_STATUS_FAILED;
+                                asm volatile ("STCK %0":"=m" (cqr->stopclk));
+
                         }
                         dasd_schedule_bh(device);
                         cqr = cqr->next;
@@ -2638,29 +2775,26 @@
         int rc = 0;
         int target  = DASD_STATE_KNOWN;
         int count = atomic_read (&device->open_count);
-        int part;
         
 	if ( count ) {
 		DASD_MESSAGE (KERN_EMERG, device, "%s",
 			      "device has vanished although it was open!");
         }
         if ( force ) {
+                dasd_deactivate_queue(device);
                 dasd_flush_chanq(device,force);
                 dasd_flush_request_queues(device,force);
                 dasd_disable_blkdev(device);
                 target = DASD_STATE_DEL;
         }
 
-#if 0
-        /* unregister devfs entries */
-        for (part = 0; part < (1 << DASD_PARTN_BITS); part++) {
-                devfs_unregister(device->major_info->gendisk.part[MINOR(device->kdev)+part].de);
-                device->major_info->gendisk.part[MINOR(device->kdev)+part].de = NULL;
-        }                        
-#endif
+        /* unregister partitions ('ungrok_partitions') */
+        devfs_register_partitions(&device->major_info->gendisk,
+                                  MINOR(device->kdev),1);
         
         DASD_MESSAGE (KERN_WARNING, device, 
-                      "disabling device, target state:%d",target);
+                      "disabling device, target state: %d",target);
+
         dasd_set_device_level (device->devinfo.devno, 
                                device->discipline, 
                                target);
@@ -2777,9 +2911,14 @@
                              device->level >= DASD_STATE_READY &&
                              device->request_queue == NULL ) {
                                 if (dasd_features_from_devno(j)&DASD_FEATURE_READONLY) {
-                                    for (tempdev=device->kdev;tempdev<(device->kdev +(1 << DASD_PARTN_BITS));tempdev++)
-                                        set_device_ro (tempdev, 1);
-                                     printk (KERN_WARNING PRINTK_HEADER "setting read-only mode for device /dev/%s\n",device->name);
+                                        for (tempdev=device->kdev;
+                                             tempdev<(device->kdev +(1 << DASD_PARTN_BITS));
+                                             tempdev++)
+                                                set_device_ro (tempdev, 1);
+
+                                        printk (KERN_WARNING PRINTK_HEADER 
+                                                "setting read-only mode for device /dev/%s\n",
+                                                device->name);
                                 }
                                 dasd_setup_blkdev(device);
                                 dasd_setup_partitions(device);
@@ -2790,6 +2929,12 @@
 }
 
 #ifdef CONFIG_DASD_DYNAMIC
+/*
+ * DASD_NOT_OPER_HANDLER
+ *
+ * DESCRIPTION
+ *   handles leaving devices
+ */
 static void
 dasd_not_oper_handler (int irq, int status)
 {
@@ -2811,14 +2956,26 @@
 		if (devno != -ENODEV)
 			break;
 	}
+
+	DASD_DRIVER_DEBUG_EVENT (5, dasd_not_oper_handler, 
+                                 "called for devno %04x", 
+                                 devno);
+
 	if (devno < 0) {
 		printk (KERN_WARNING PRINTK_HEADER
-			"not_oper_handler called on irq %d no devno!\n", irq);
+			"not_oper_handler called on irq 0x%04x no devno!\n", 
+                        irq);
 		return;
 	}
-        dasd_disable_volume(device, 0);
+        dasd_disable_volume(device, 1);
 }
 
+/*
+ * DASD_OPER_HANDLER
+ *
+ * DESCRIPTION
+ *   called by the machine check handler to make an device operational
+ */
 int
 dasd_oper_handler (int irq, devreg_t * devreg)
 {
@@ -2835,7 +2992,12 @@
 		rc = -ENODEV;
                 goto out;
 	}
-	/* find out devno of leaving device: CIO has already deleted this information ! */
+
+	DASD_DRIVER_DEBUG_EVENT (5, dasd_oper_handler, 
+                                 "called for devno %04x", 
+                                 devno);
+
+	/* find out devno of device */
 	list_for_each (l, &dasd_major_info[0].list) {
 		major_info = list_entry (l, major_info_t, list);
 		for (i = 0; i < DASD_PER_MAJOR; i++) {
@@ -2881,10 +3043,11 @@
         dasd_device_t **device_addr;
 
 	DASD_DRIVER_DEBUG_EVENT (1, dasd_find_device_addr, 
-                                 "devno %04X", devno);
+                                 "devno %04x", 
+                                 devno);
 	if ( dasd_devindex_from_devno (devno) < 0 ) {
                 DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr, 
-                                             "no dasd: devno %04X",
+                                             "no dasd: devno %04x",
                                              devno);
 		return NULL;
 	}
@@ -2996,6 +3159,13 @@
         if ( rc ) {
                 goto out;
         }
+
+	DASD_DRIVER_DEBUG_EVENT (5, dasd_state_new_to_known, 
+                                 "got devinfo CU-type %04x and dev-type %04x", 
+                                 device->devinfo.sid_data.cu_type,
+                                 device->devinfo.sid_data.dev_type);
+
+
         if ( devno != device->devinfo.devno )
                 BUG();
         device->discipline = dasd_find_disc (device, disc);
@@ -3003,7 +3173,8 @@
                 rc = -ENODEV;
                 goto out;
         }
-        sprintf (buffer, "%04x", device->devinfo.devno);
+        sprintf (buffer, "%04x", 
+                 device->devinfo.devno);
         dir = devfs_mk_dir (dasd_devfs_handle, buffer, device);
         device->major_info->gendisk.de_arr[MINOR(device->kdev)
                                           >> DASD_PARTN_BITS] = dir;
@@ -3039,7 +3210,8 @@
                                              3 * sizeof (long));
         debug_register_view (device->debug_area, &debug_sprintf_view);
         debug_register_view (device->debug_area, &debug_hex_ascii_view);
-        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area created",device);
+        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area created",
+                                 device);
         
         if (device->discipline->int_handler) {
                 rc = s390_request_irq_special (device->devinfo.irq,
@@ -3065,7 +3237,8 @@
         if (device->discipline->int_handler) {
                 free_irq (device->devinfo.irq, &device->dev_status);
         }
-        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area deleted",device);
+        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area deleted",
+                                 device);
         if ( device->debug_area != NULL )
                 debug_unregister (device->debug_area);
         device->discipline = NULL;
@@ -3080,6 +3253,10 @@
         int rc = 0;
         unsigned long flags;
 
+        printk (KERN_ERR PRINTK_HEADER
+                "called dasd_state_accept_to_init for device %02x\n",
+                device->devinfo.devno);
+
         if ( device->discipline->init_analysis ) {
                 device->init_cqr=device->discipline->init_analysis (device);
                 if ( device->init_cqr != NULL ) {
@@ -3197,6 +3374,18 @@
         return rc;
 }
 
+static void
+dasd_deactivate_queue (dasd_device_t *device)
+{
+        int i;
+        int major = MAJOR(device->kdev);
+        int minor = MINOR(device->kdev);
+
+        for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
+                device->major_info->gendisk.sizes[minor + i] = 0;
+        }
+}
+
 static inline int
 dasd_disable_blkdev (dasd_device_t *device ) 
 {
@@ -3238,7 +3427,6 @@
 dasd_destroy_partitions ( dasd_device_t * device ) 
 {
         int i;
-        int major = MAJOR(device->kdev);
         int minor = MINOR(device->kdev);
         
         for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
@@ -3285,6 +3473,12 @@
                 from_state = device->level;
         }
 
+        DASD_DRIVER_DEBUG_EVENT (3, dasd_set_device_level,
+                                 "devno %04x; from %i to %i",
+                                 devno,
+                                 from_state,
+                                 to_state);
+
         if ( from_state == to_state )
                 goto out;
 
@@ -3340,8 +3534,12 @@
  bringup_fail:   /* revert changes */
 #if 0
         printk (KERN_DEBUG PRINTK_HEADER
-                "failed to set device from state %d to %d at level %d rc %d. Reverting...\n",
-                from_state,to_state,device->level,rc);
+                "failed to set device from state %d to %d at "
+                "level %d rc %d. Reverting...\n",
+                from_state,
+                to_state,
+                device->level,
+                rc);
 #endif
         to_state = from_state;
         from_state = device->level;
@@ -3352,18 +3550,22 @@
              to_state <= DASD_STATE_READY ) 
                 if (dasd_state_online_to_ready(device))
                         BUG();
+
         if ( from_state >= DASD_STATE_READY &&
-                      to_state <= DASD_STATE_ACCEPT ) 
+             to_state <= DASD_STATE_ACCEPT ) 
                 if ( dasd_state_ready_to_accept(device))
                         BUG();
+
         if ( from_state >= DASD_STATE_ACCEPT &&
              to_state <= DASD_STATE_KNOWN ) 
                 if ( dasd_state_accept_to_known(device))
                         BUG();
+
         if ( from_state >= DASD_STATE_KNOWN &&
              to_state <= DASD_STATE_NEW ) 
                 if ( dasd_state_known_to_new(device))
                         BUG();
+
         if ( from_state >= DASD_STATE_NEW &&
              to_state <= DASD_STATE_DEL) 
                 if (dasd_state_new_to_del(device_addr))
@@ -3420,7 +3622,8 @@
 	}
 	info->data = (char *) vmalloc (size);	
 	DASD_DRIVER_DEBUG_EVENT (1, dasd_devices_open, "area: %p, size 0x%x",
-				 info->data, size);
+				 info->data, 
+                                 size);
 	if (size && info->data == NULL) {
 		printk (KERN_WARNING "No memory available for data\n");
 		vfree (info);
@@ -3437,7 +3640,7 @@
                         device = temp->dasd_device[i];
 			if (device) {
 				len += sprintf (info->data + len,
-						"%04X(%s) at (%3d:%3d) is %7s:",
+						"%04x(%s) at (%3d:%3d) is %7s:",
 						device->devinfo.devno,
 						device->discipline ?
 						device->
@@ -3506,7 +3709,7 @@
                                                         "none");
                                 } else {
                                         len += sprintf (info->data + len,
-                                                        "%04X",devno);
+                                                        "%04x",devno);
                                 }
                                 len += sprintf (info->data + len,
                                                 "(none) at (%3d:%3d) is %7s: unknown",
@@ -3591,22 +3794,31 @@
 		range.to = dasd_strtoul (temp, &temp, &features);
 	}
 
-	off = (long) temp - (long) buffer;
-	if (!strncmp (buffer, "add", strlen ("add"))) {
-		dasd_add_range (range.from, range.to, features);
-                dasd_enable_ranges (&range, NULL, 0);
-	} else { 
-		while (buffer[off] && !isalnum (buffer[off]))
-			off++;
-		if (!strncmp (buffer + off, "on", strlen ("on"))) {
-        	        dasd_enable_ranges (&range, NULL, 0);
-		} else if (!strncmp (buffer + off, "off", strlen ("off"))) {
-        	        dasd_disable_ranges (&range, NULL, 0, 1);
-		} else {
-			printk (KERN_WARNING PRINTK_HEADER
-			"/proc/dasd/devices: parse error in '%s'", buffer);
-		}
-	}
+        if (range.from == -EINVAL ||
+            range.to   == -EINVAL   ) {
+                
+                printk (KERN_WARNING PRINTK_HEADER
+                        "/proc/dasd/devices: parse error in '%s'", 
+                        buffer);
+        } else {
+                off = (long) temp - (long) buffer;
+                if (!strncmp (buffer, "add", strlen ("add"))) {
+                        dasd_add_range (range.from, range.to, features);
+                        dasd_enable_ranges (&range, NULL, 0);
+                } else { 
+                        while (buffer[off] && !isalnum (buffer[off]))
+                                off++;
+                        if (!strncmp (buffer + off, "on", strlen ("on"))) {
+                                dasd_enable_ranges (&range, NULL, 0);
+                        } else if (!strncmp (buffer + off, "off", strlen ("off"))) {
+                                dasd_disable_ranges (&range, NULL, 0, 1);
+                        } else {
+                                printk (KERN_WARNING PRINTK_HEADER
+                                        "/proc/dasd/devices: parse error in '%s'", buffer);
+                        }
+                }
+        }
+
 	vfree (buffer);
 	return user_len;
 }
@@ -3660,112 +3872,124 @@
                 MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
+        
+        /* prevent couter 'ouverflow' on output */
 	for (shift = 0, help = dasd_global_profile.dasd_io_reqs;
-	     help > 8192; help = help >> 1, shift++) ;
-	len =
-	    sprintf (info->data, "%d dasd I/O requests\n",
-		     dasd_global_profile.dasd_io_reqs);
-	len +=
-	    sprintf (info->data + len, "with %d sectors(512B each)\n",
-		     dasd_global_profile.dasd_io_sects);
-	len +=
-	    sprintf (info->data + len,
-		     "__<4 ___8 __16 __32 __64 _128 _256 _512 __1k __2k __4k __8k _16k _32k _64k 128k\n");
-	len +=
-	    sprintf (info->data + len,
-		     "_256 _512 __1M __2M __4M __8M _16M _32M _64M 128M 256M 512M __1G __2G __4G _>4G\n");
+	     help > 9999999; help = help >> 1, shift++) ;
+
+	len = sprintf (info->data, "%d dasd I/O requests\n",
+                       dasd_global_profile.dasd_io_reqs);
+	len += sprintf (info->data + len, "with %d sectors(512B each)\n",
+                        dasd_global_profile.dasd_io_sects);
+
+	len += sprintf (info->data + len,
+                        "   __<4    ___8    __16    __32    __64 "
+                        "   _128    _256    _512    __1k    __2k "
+                        "   __4k    __8k    _16k    _32k    _64k "
+                        "   128k\n");
+
+	len += sprintf (info->data + len,
+                        "   _256    _512    __1M    __2M    __4M "
+                        "   __8M    _16M    _32M    _64M    128M "
+                        "   256M    512M    __1G    __2G    __4G "
+                        "   _>4G\n");
+
 	len += sprintf (info->data + len, "Histogram of sizes (512B secs)\n");
 	for (i = 0; i < 16; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_secs[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_secs[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
+
 	len += sprintf (info->data + len, "Histogram of I/O times\n");
 	for (i = 0; i < 16; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_times[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_times[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
 	for (; i < 32; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_times[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_times[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
-	len +=
-	    sprintf (info->data + len, "Histogram of I/O times per sector\n");
+
+	len += sprintf (info->data + len, "Histogram of I/O times per sector\n");
 	for (i = 0; i < 16; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_timps[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_timps[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
 	for (; i < 32; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_timps[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_timps[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
+
 	len += sprintf (info->data + len, "Histogram of I/O time till ssch\n");
 	for (i = 0; i < 16; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_time1[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_time1[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
 	for (; i < 32; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_time1[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_time1[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
-	len +=
-	    sprintf (info->data + len,
-		     "Histogram of I/O time between ssch and irq\n");
+
+	len += sprintf (info->data + len,
+                        "Histogram of I/O time between ssch and irq\n");
 	for (i = 0; i < 16; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_time2[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_time2[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
 	for (; i < 32; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_time2[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_time2[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
-	len +=
-	    sprintf (info->data + len,
-		     "Histogram of I/O time between ssch and irq per sector\n");
+
+	len += sprintf (info->data + len,
+                        "Histogram of I/O time between ssch and irq per sector\n");
 	for (i = 0; i < 16; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_time2ps[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_time2ps[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
 	for (; i < 32; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_time2ps[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_time2ps[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
-	len +=
-	    sprintf (info->data + len,
-		     "Histogram of I/O time between irq and end\n");
+
+	len += sprintf (info->data + len,
+                        "Histogram of I/O time between irq and end\n");
 	for (i = 0; i < 16; i++) {
 		len +=
-		    sprintf (info->data + len, "%4d ",
+		    sprintf (info->data + len, "%7d ",
 			     dasd_global_profile.dasd_io_time3[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
 	for (; i < 32; i++) {
-		len +=
-		    sprintf (info->data + len, "%4d ",
-			     dasd_global_profile.dasd_io_time3[i] >> shift);
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_time3[i] >> shift);
+	}
+	len += sprintf (info->data + len, "\n");
+
+	len += sprintf (info->data + len,
+                        "# of req in chanq at enqueuing (1..32) \n");
+	for (i = 0; i < 16; i++) {
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_nr_req[i] >> shift);
 	}
 	len += sprintf (info->data + len, "\n");
+	for (; i < 32; i++) {
+		len += sprintf (info->data + len, "%7d ",
+                                dasd_global_profile.dasd_io_nr_req[i] >> shift);
+	}
+	len += sprintf (info->data + len, "\n");
+
 	info->len = len;
 	return rc;
 }
@@ -3838,7 +4062,9 @@
 	} 
 	while ( (rc=request_module(name)) != 0 ) {
         	DECLARE_WAIT_QUEUE_HEAD(wait);
-		printk ( KERN_INFO "request_module returned %d for %s\n",rc,(char*)name);
+		printk ( KERN_INFO "request_module returned %d for %s\n",
+                         rc,
+                         (char*)name);
         	sleep_on_timeout(&wait,5* HZ); /* wait in steps of 5 seconds */
     	}
     	return rc;
@@ -3855,7 +4081,7 @@
 	struct list_head *l;
 
 	printk (KERN_INFO PRINTK_HEADER "initializing...\n");
-	dasd_debug_area = debug_register (DASD_NAME, 0, 2, 4 * sizeof (long));
+	dasd_debug_area = debug_register (DASD_NAME, 0, 2, 5 * sizeof (long));
 	debug_register_view (dasd_debug_area, &debug_sprintf_view);
 	debug_register_view (dasd_debug_area, &debug_hex_ascii_view);
 
@@ -3864,10 +4090,12 @@
 	if (dasd_debug_area == NULL) {
 		goto failed;
 	}
-	DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", "ENTRY");
+	DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", 
+                                 "ENTRY");
 	dasd_devfs_handle = devfs_mk_dir (NULL, DASD_NAME, NULL);
 	if (dasd_devfs_handle < 0) {
-		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", "no devfs");
+		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", 
+                                         "no devfs");
 		goto failed;
 	}
 	list_for_each (l, &dasd_major_info[0].list) {
@@ -3893,7 +4121,12 @@
 #ifndef MODULE
 	dasd_split_parm_string (dasd_parm_string);
 #endif				/* ! MODULE */
-	dasd_parse (dasd);
+	rc = dasd_parse (dasd);
+	if (rc) {
+		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s",
+                                         "invalid range found");
+		goto failed;
+	}
 
 	rc = dasd_proc_init ();
 	if (rc) {
@@ -3909,7 +4142,7 @@
 			int index = dasd_devindex_from_devno (devno);
 			if (index == -ENODEV) {	/* not included in ranges */
 				DASD_DRIVER_DEBUG_EVENT (2, dasd_init,
-							 "add %04X to range",
+							 "add %04x to range",
 							 devno);
 				dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES);
 			}
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/block/dasd_3990_erp.c linux/drivers/s390/block/dasd_3990_erp.c
--- v2.4.10/linux/drivers/s390/block/dasd_3990_erp.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/block/dasd_3990_erp.c	Sun Sep 30 12:26:07 2001
@@ -1724,8 +1724,16 @@
         dasd_3990_handle_env_data (erp,
                                    sense);
 
-	erp = dasd_3990_erp_action_4 (erp,
-				      sense);
+        /* don't retry on disabled interface */
+        if (sense[7] != 0x0F) {
+
+                erp = dasd_3990_erp_action_4 (erp,
+                                              sense);
+        } else {
+
+                erp = dasd_3990_erp_cleanup (erp,
+                                             CQR_STATUS_IN_IO);
+        }
 
 	return erp;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/block/dasd_diag.c linux/drivers/s390/block/dasd_diag.c
--- v2.4.10/linux/drivers/s390/block/dasd_diag.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/block/dasd_diag.c	Sun Sep 30 12:26:07 2001
@@ -158,9 +158,6 @@
 				CQR_STATUS_QUEUED, CQR_STATUS_DONE);
 		dasd_schedule_bh (device);
 	} else {
-		if (cqr->expires) {
-			cqr->expires += cqr->startclk;
-		}
 		check_then_set (&cqr->status,
 				CQR_STATUS_QUEUED, CQR_STATUS_IN_IO);
 		rc = 0;
@@ -178,6 +175,8 @@
 	dasd_device_t *device;
 	int done_fast_io = 0;
 	int devno;
+        unsigned long flags;
+
 
 	irq_enter(cpu, -1);
 
@@ -195,6 +194,7 @@
 	}
 	cqr = (ccw_req_t *) ip;
 	device = (dasd_device_t *) cqr->device;
+
 	devno = device->devinfo.devno;
 	if (device == NULL) {
 		printk (KERN_WARNING PRINTK_HEADER
@@ -214,7 +214,13 @@
 		irq_exit(cpu, -1);
 		return;
 	}
+
+        /* get irq lock to modify request queue */
+        s390irq_spin_lock_irqsave (device->devinfo.irq, 
+                                   flags);
+
 	asm volatile ("STCK %0":"=m" (cqr->stopclk));
+
 	switch (status) {
 	case 0x00:
 		check_then_set (&cqr->status,
@@ -233,9 +239,14 @@
 				CQR_STATUS_IN_IO, CQR_STATUS_FAILED);
 		break;
 	}
+
+        s390irq_spin_unlock_irqrestore (device->devinfo.irq, 
+                                        flags);
+
 	wake_up (&device->wait_q);
 	dasd_schedule_bh (device);
 	irq_exit(cpu, -1);
+
 }
 
 static int
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/block/dasd_eckd.c linux/drivers/s390/block/dasd_eckd.c
--- v2.4.10/linux/drivers/s390/block/dasd_eckd.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/block/dasd_eckd.c	Sun Sep 30 12:26:07 2001
@@ -209,7 +209,7 @@
 	memset (de_ccw, 0, sizeof (ccw1_t));
 	de_ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
 	de_ccw->count = 16;
-	if (rc=dasd_set_normalized_cda (de_ccw, __pa (data), cqr, device)) 
+	if ((rc=dasd_set_normalized_cda (de_ccw, __pa (data), cqr, device))) 
                 return rc;
 
 	memset (data, 0, sizeof (DE_eckd_data_t));
@@ -283,7 +283,7 @@
 	memset (lo_ccw, 0, sizeof (ccw1_t));
 	lo_ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
 	lo_ccw->count = 16;
-	if (rc=dasd_set_normalized_cda (lo_ccw, __pa (data), cqr, device))
+	if ((rc=dasd_set_normalized_cda (lo_ccw, __pa (data), cqr, device)))
                 return rc;
 
 	memset (data, 0, sizeof (LO_eckd_data_t));
@@ -1157,6 +1157,16 @@
 	return ret;
 }
 #endif
+
+/*
+ * DASD_ECKD_RESERVE
+ *
+ * DESCRIPTION
+ *    Buils a channel programm to reserve a device.
+ *    Options are set to 'synchronous wait for interrupt' and
+ *    'timeout the request'. This leads to an terminate IO if 
+ *    the interrupt is outstanding for a certain time. 
+ */
 ccw_req_t *
 dasd_eckd_reserve (struct dasd_device_t * device)
 {
@@ -1168,12 +1178,21 @@
 		return NULL;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
-	cqr->device = device;
+	cqr->device  = device;
 	cqr->retries = 0;
-	cqr->status = CQR_STATUS_FILLED;
-	return cqr;
+	cqr->expires = 10 * TOD_SEC;
+        cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */
+	cqr->status  = CQR_STATUS_FILLED;
+	return cqr; 
 }
 
+/*
+ * DASD_ECKD_RELEASE
+ *
+ * DESCRIPTION
+ *    Buils a channel programm to releases a prior reserved 
+ *    (see dasd_eckd_reserve) device.
+ */
 ccw_req_t *
 dasd_eckd_release (struct dasd_device_t * device)
 {
@@ -1185,13 +1204,41 @@
 		return NULL;
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
-	cqr->device = device;
+	cqr->device  = device;
 	cqr->retries = 0;
-	cqr->status = CQR_STATUS_FILLED;
+	cqr->expires = 10 * TOD_SEC;
+        cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */
+	cqr->status  = CQR_STATUS_FILLED;
 	return cqr;
 
 }
 
+/*
+ * DASD_ECKD_STEAL_LOCK
+ *
+ * DESCRIPTION
+ *    Buils a channel programm to break a device's reservation. 
+ *    (unconditional reserve)
+ */
+ccw_req_t *
+dasd_eckd_steal_lock (struct dasd_device_t * device)
+{
+	ccw_req_t *cqr =
+	    dasd_alloc_request (dasd_eckd_discipline.name, 1 + 1, 0, device);
+	if (cqr == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"No memory to allocate initialization request\n");
+		return NULL;
+	}
+	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
+	cqr->device  = device;
+	cqr->retries = 0;
+	cqr->expires = 10 * TOD_SEC;
+        cqr->options = (DOIO_WAIT_FOR_INTERRUPT | DOIO_TIMEOUT); /* timeout reqest */
+	cqr->status  = CQR_STATUS_FILLED;
+	return cqr;
+}
+
 static inline ccw1_t *
 dasd_eckd_find_cmd (ccw_req_t * cqr, int cmd)
 {
@@ -1335,6 +1382,7 @@
 	int_handler:dasd_int_handler,
 	reserve:dasd_eckd_reserve,
 	release:dasd_eckd_release,
+        steal_lock:dasd_eckd_steal_lock,
 	merge_cp:dasd_eckd_merge_cp,
 	fill_info:dasd_eckd_fill_info,
 };
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/block/dasd_eckd.h linux/drivers/s390/block/dasd_eckd.h
--- v2.4.10/linux/drivers/s390/block/dasd_eckd.h	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/block/dasd_eckd.h	Sun Sep 30 12:26:07 2001
@@ -26,6 +26,7 @@
 #define DASD_ECKD_CCW_READ_CKD_MT 0x9e
 #define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
 #define DASD_ECKD_CCW_RESERVE 0xB4
+#define DASD_ECKD_CCW_SLCK 0x14	/* steal lock - unconditional reserve */
 
 typedef
     struct eckd_count_t {
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/block/dasd_fba.c linux/drivers/s390/block/dasd_fba.c
--- v2.4.10/linux/drivers/s390/block/dasd_fba.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/block/dasd_fba.c	Sun Sep 30 12:26:07 2001
@@ -71,7 +71,7 @@
 	memset (DE_data, 0, sizeof (DE_fba_data_t));
 	ccw->cmd_code = DASD_FBA_CCW_DEFINE_EXTENT;
 	ccw->count = 16;
-	if (rc=dasd_set_normalized_cda (ccw, __pa (DE_data), cqr, device))
+	if ((rc=dasd_set_normalized_cda (ccw, __pa (DE_data), cqr, device)))
                 return rc;
 	if (rw == WRITE)
 		(DE_data->mask).perm = 0x0;
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/block/dasd_int.h linux/drivers/s390/block/dasd_int.h
--- v2.4.10/linux/drivers/s390/block/dasd_int.h	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/block/dasd_int.h	Sun Sep 30 12:26:07 2001
@@ -254,6 +254,7 @@
 typedef char *(*dasd_dump_sense_fn_t)(struct dasd_device_t *,ccw_req_t *);
 typedef ccw_req_t *(*dasd_reserve_fn_t)(struct dasd_device_t *);
 typedef ccw_req_t *(*dasd_release_fn_t)(struct dasd_device_t *);
+typedef ccw_req_t *(*dasd_steal_lock_fn_t)(struct dasd_device_t *);
 typedef ccw_req_t *(*dasd_merge_cp_fn_t)(struct dasd_device_t *);
 typedef int (*dasd_info_fn_t) (struct dasd_device_t *, dasd_information_t *);
 typedef int (*dasd_use_count_fn_t) (int);
@@ -286,6 +287,7 @@
         dasd_int_handler_fn_t int_handler;
         dasd_reserve_fn_t reserve;
         dasd_release_fn_t release;
+        dasd_steal_lock_fn_t steal_lock;
         dasd_merge_cp_fn_t merge_cp;
         dasd_info_fn_t fill_info;
 	struct list_head list;	/* used for list of disciplines */
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/char/ctrlchar.c linux/drivers/s390/char/ctrlchar.c
--- v2.4.10/linux/drivers/s390/char/ctrlchar.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/ctrlchar.c	Sun Sep 30 12:26:07 2001
@@ -38,7 +38,7 @@
 		return;
 	INIT_LIST_HEAD(&ctrlchar_tq.list);
 	ctrlchar_tq.sync = 0;
-	ctrlchar_tq.routine = ctrlchar_handle_sysrq;
+	ctrlchar_tq.routine = (void (*)(void *)) ctrlchar_handle_sysrq;
 #endif
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/char/hwc_cpi.c linux/drivers/s390/char/hwc_cpi.c
--- v2.4.10/linux/drivers/s390/char/hwc_cpi.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/hwc_cpi.c	Sun Sep 30 12:26:07 2001
@@ -16,6 +16,9 @@
 #include "hwc_rw.h"
 #include "hwc.h"
 
+#define CPI_RETRIES		3
+#define CPI_SLEEP_TICKS		50
+
 #define CPI_LENGTH_SYSTEM_TYPE	8
 #define CPI_LENGTH_SYSTEM_NAME	8
 #define CPI_LENGTH_SYSPLEX_NAME	8
@@ -84,6 +87,7 @@
 	int system_type_length;
 	int system_name_length;
 	int sysplex_name_length = 0;
+	int retries;
 
 	if (!MACHINE_HAS_HWC) {
 		printk ("cpi: bug: hardware console not present\n");
@@ -163,21 +167,29 @@
 	cpi_request.word = HWC_CMDW_WRITEDATA;
 	cpi_request.callback = cpi_callback;
 
-	retval = hwc_send (&cpi_request);
-	if (retval) {
-		printk ("cpi: failed (%i)\n", retval);
-		goto free;
-	}
-	down (&sem);
-
-	switch (cpi_hwcb->response_code) {
-	case 0x0020:
-		printk ("cpi: succeeded\n");
-		break;
-	default:
-		printk ("cpi: failed with response code 0x%x\n",
-			cpi_hwcb->response_code);
+	for (retries = CPI_RETRIES; retries; retries--) {
+		retval = hwc_send (&cpi_request);
+		if (retval) {
+
+			set_current_state (TASK_INTERRUPTIBLE);
+			schedule_timeout (CPI_SLEEP_TICKS);
+		} else {
+
+			down (&sem);
+
+			switch (cpi_hwcb->response_code) {
+			case 0x0020:
+				printk ("cpi: succeeded\n");
+				break;
+			default:
+				printk ("cpi: failed with response code 0x%x\n",
+					cpi_hwcb->response_code);
+			}
+			goto free;
+		}
 	}
+
+	printk ("cpi: failed (%i)\n", retval);
 
       free:
 	kfree (cpi_hwcb);
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/char/hwc_rw.c linux/drivers/s390/char/hwc_rw.c
--- v2.4.10/linux/drivers/s390/char/hwc_rw.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/char/hwc_rw.c	Sun Sep 30 12:26:07 2001
@@ -238,17 +238,18 @@
 				unsigned int,
 				unsigned char);
 
+unsigned char hwc_ip_buf[512];
+
 static asmlinkage int 
 internal_print (char write_time, char *fmt,...)
 {
 	va_list args;
 	int i;
-	unsigned char buf[512];
 
 	va_start (args, fmt);
-	i = vsprintf (buf, fmt, args);
+	i = vsprintf (hwc_ip_buf, fmt, args);
 	va_end (args);
-	return do_hwc_write (0, buf, i, write_time);
+	return do_hwc_write (0, hwc_ip_buf, i, write_time);
 }
 
 int 
@@ -256,15 +257,14 @@
 {
 	va_list args;
 	int i;
-	unsigned char buf[512];
 	unsigned long flags;
 	int retval;
 
 	spin_lock_irqsave (&hwc_data.lock, flags);
 
-	i = vsprintf (buf, fmt, args);
+	i = vsprintf (hwc_ip_buf, fmt, args);
 	va_end (args);
-	retval = do_hwc_write (0, buf, i, IMMEDIATE_WRITE);
+	retval = do_hwc_write (0, hwc_ip_buf, i, IMMEDIATE_WRITE);
 
 	spin_unlock_irqrestore (&hwc_data.lock, flags);
 
@@ -2098,10 +2098,10 @@
 		retval = -ENOTSUPP;
 		goto unlock;
 	}
-	hwc_data.request = req;
 	cc = service_call (req->word, req->block);
 	switch (cc) {
 	case 0:
+		hwc_data.request = req;
 		hwc_data.current_servc = req->word;
 		hwc_data.current_hwcb = req->block;
 		retval = 0;
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/misc/chandev.c linux/drivers/s390/misc/chandev.c
--- v2.4.10/linux/drivers/s390/misc/chandev.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/misc/chandev.c	Sun Sep 30 12:26:07 2001
@@ -599,9 +599,6 @@
 	
 	chandev_unlock();
  Fail2:
-	/* We don't really need to report /sbin/hotplug not existing */
-	if(retval!=-ENOENT)
-	   printk("chandev_exec_start_script failed retval=%d\n",retval);
 	return(retval);
 }
 
@@ -1140,6 +1137,7 @@
 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
 	chandev_use_devno_names=FALSE;
 #endif
+	chandev_persistent=0;
 	chandev_unlock();
 }
 
@@ -2225,7 +2223,7 @@
 	"unregister_probe_by_chan_type",
 	"read_conf",
 	"dont_read_conf",
-	"persistent"
+	"persist"
 };
 
 typedef enum
@@ -2262,7 +2260,7 @@
 	unregister_probe_by_chan_type_stridx,
 	read_conf_stridx,
 	dont_read_conf_stridx,
-	persistent_stridx,
+	persist_stridx,
 	last_stridx,
 } chandev_str_enum;
 
@@ -2388,7 +2386,7 @@
 
 
 
-static int chandev_setup(char *instr,char *errstr,int lineno)
+static int chandev_setup(int in_read_conf,char *instr,char *errstr,int lineno)
 {
 	chandev_strval   val=isnull;
 	chandev_str_enum stridx;
@@ -2676,12 +2674,17 @@
 				chandev_unregister_probe_by_chan_type((chandev_type)ints[1]);
 				break;
 			case read_conf_stridx*stridx_mult:
+				if(in_read_conf)
+				{
+					printk("attempt to recursively call read_conf\n");
+					goto BadArgs;
+				}
 				chandev_read_conf();
 				break;
 			case dont_read_conf_stridx*stridx_mult:
 				atomic_set(&chandev_conf_read,TRUE);
 				break;
-			case (persistent_stridx*stridx_mult)|iscomma:
+			case (persist_stridx*stridx_mult)|iscomma:
 				if(ints[0]==1)
 					chandev_persistent=ints[1];
 				else
@@ -2729,7 +2732,7 @@
 	copystr=alloca(len+1);
 	strncpy(copystr,str,len);
 	copystr[len]=0;
-	if(chandev_setup(copystr,"at "CHANDEV_KEYWORD" bootparam no",paramno)==0)
+	if(chandev_setup(FALSE,copystr,"at "CHANDEV_KEYWORD" bootparam no",paramno)==0)
 		return(0);
 	return(len);
 
@@ -2758,7 +2761,7 @@
 	}
 }
 
-int chandev_do_setup(char *buff,int size)
+int chandev_do_setup(int in_read_conf,char *buff,int size)
 {
 	int curr,comment=FALSE,newline=FALSE,oldnewline=TRUE;
 	char *startline=NULL,*endbuff=&buff[size];
@@ -2787,7 +2790,7 @@
 			startline=buff;
 		if(startline&&(buff>startline)&&(oldnewline==FALSE)&&(newline==TRUE))
 		{
-			if((chandev_setup(startline," on line no",lineno))==0)
+			if((chandev_setup(in_read_conf,startline," on line no",lineno))==0)
 				return(-EINVAL);
 			startline=NULL;
 		}
@@ -2835,7 +2838,7 @@
 				close(fd);
 			}
 			set_fs(USER_DS);
-			chandev_do_setup(buff,statbuf.st_size);
+			chandev_do_setup(TRUE,buff,statbuf.st_size);
 			vfree(buff);
 		}
 	}
@@ -2898,7 +2901,7 @@
 	chandev_printf(chan_exit,"\n%s\n"
 		       "*'s for cu/dev type/models indicate don't cares\n",chandev_keydescript);
 	chandev_printf(chan_exit,"\ncautious_auto_detect: %s\n",chandev_cautious_auto_detect ? "on":"off");
-	chandev_printf(chan_exit,"\nchandev_persistent = 0x%02x\n",chandev_persistent);
+	chandev_printf(chan_exit,"\npersist = 0x%02x\n",chandev_persistent);
 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,3,0)
 	chandev_printf(chan_exit,"\nuse_devno_names: %s\n\n",chandev_use_devno_names ? "on":"off");
 #endif
@@ -3151,7 +3154,7 @@
 		rc = copy_from_user(buff,buffer,count);
 		if (rc)
 			goto chandev_write_exit;
-		chandev_do_setup(buff,count);
+		chandev_do_setup(FALSE,buff,count);
 		rc=count;
 	chandev_write_exit:
 		vfree(buff);
@@ -3212,13 +3215,25 @@
 			       chandev_msck_notification_func msck_notfunc,
 			       chandev_type chan_type)
 {
-	chandev_probelist *new_probe;
+	chandev_probelist *new_probe,*curr_probe;
 	/* Avoid chicked & egg situations where we may be called before we */
 	/* are initialised. */
 
 	chandev_interrupt_check();
 	if(!atomic_compare_and_swap(FALSE,TRUE,&chandev_initialised))
 		chandev_init();
+	chandev_lock();
+	for_each(curr_probe,chandev_probelist_head)
+	{
+		if(curr_probe->probefunc==probefunc)
+		{
+			chandev_unlock();
+			printk("chandev_register_and_probe detected duplicate probefunc %p"
+			       " for chan_type  0x%02x \n",probefunc,chan_type);
+			return (-EPERM);
+		}
+	}
+	chandev_unlock();
 	if((new_probe=chandev_alloc(sizeof(chandev_probelist))))
 	{
 		new_probe->probefunc=probefunc;
@@ -3229,12 +3244,12 @@
 		chandev_add_to_list((list **)&chandev_probelist_head,new_probe);
 		chandev_probe();
 	}
-	return(new_probe ? new_probe->devices_found:0);
+	return(new_probe ? new_probe->devices_found:-ENOMEM);
 }
 
 void chandev_unregister(chandev_probefunc probefunc,int call_shutdown)
 {
-	chandev_probelist *curr_probe=NULL;
+	chandev_probelist *curr_probe;
 	chandev_activelist *curr_device,*next_device;
 	
 	chandev_interrupt_check();
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/net/ctcmain.c linux/drivers/s390/net/ctcmain.c
--- v2.4.10/linux/drivers/s390/net/ctcmain.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/net/ctcmain.c	Sun Sep 30 12:26:07 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.46 2001/07/05 17:36:41 felfert Exp $
+ * $Id: ctcmain.c,v 1.49 2001/08/31 14:50:05 felfert Exp $
  *
  * CTC / ESCON network driver
  *
@@ -35,7 +35,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.46 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.49 $
  *
  */
 
@@ -43,7 +43,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
@@ -80,7 +80,7 @@
 #if LINUX_VERSION_CODE >= 0x020213
 #  include <asm/idals.h>
 #else
-#  define set_normalized_cda(ccw, addr) ((ccw)->cda = (addr))
+#  define set_normalized_cda(ccw, addr) ((ccw)->cda = (addr),0)
 #  define clear_normalized_cda(ccw)
 #endif
 #if LINUX_VERSION_CODE < 0x020400
@@ -382,7 +382,7 @@
  */
 static void print_banner(void) {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.46 $";
+	char vbuf[] = "$Revision: 1.49 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -925,6 +925,7 @@
 	    (ch->flags & CHANNEL_FLAGS_BUFSIZE_CHANGED)) {
 		if (ch->trans_skb != NULL)
 			dev_kfree_skb(ch->trans_skb);
+		clear_normalized_cda(&ch->ccw[1]);
 		ch->trans_skb = dev_alloc_skb(ch->max_bufsize);
 		if (ch->trans_skb == NULL) {
 			if (warn)
@@ -935,9 +936,9 @@
 				       "RX" : "TX");
 			return -ENOMEM;
 		}
-		set_normalized_cda(&ch->ccw[1],
-				   virt_to_phys(ch->trans_skb->data));
-		if (ch->ccw[1].cda == 0) {
+		ch->ccw[1].count = ch->max_bufsize;
+		if (set_normalized_cda(&ch->ccw[1],
+				       virt_to_phys(ch->trans_skb->data))) {
 			dev_kfree_skb(ch->trans_skb);
 			ch->trans_skb = NULL;
 			if (warn)
@@ -949,6 +950,7 @@
 				       "RX" : "TX");
 			return -ENOMEM;
 		}
+		ch->ccw[1].count = 0;
 		ch->flags &= ~CHANNEL_FLAGS_BUFSIZE_CHANGED;
 	}
 	return 0;
@@ -1330,6 +1332,15 @@
 		dev_kfree_skb(ch->trans_skb);
 		ch->trans_skb = NULL;
 	}
+	if (CHANNEL_DIRECTION(ch->flags) == READ) {
+		ch->ccw[1].cmd_code = CCW_CMD_READ;
+		ch->ccw[1].flags    = CCW_FLAG_SLI;
+		ch->ccw[1].count    = 0;
+	} else {
+		ch->ccw[1].cmd_code = CCW_CMD_WRITE;
+		ch->ccw[1].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;
+		ch->ccw[1].count    = 0;
+	}
 	if (ctc_checkalloc_buffer(ch, 0))
 		printk(KERN_NOTICE
 		       "%s: Could not allocate %s trans_skb, delaying "
@@ -1350,21 +1361,13 @@
 	ch->ccw[0].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;
 	ch->ccw[0].count    = 0;
 	ch->ccw[0].cda	    = 0;
-	if (CHANNEL_DIRECTION(ch->flags) == READ) {
-		ch->ccw[1].cmd_code = CCW_CMD_READ;
-		ch->ccw[1].flags    = CCW_FLAG_SLI;
-		ch->ccw[1].count    = 0;
-	} else {
-		ch->ccw[1].cmd_code = CCW_CMD_WRITE;
-		ch->ccw[1].flags    = CCW_FLAG_SLI | CCW_FLAG_CC;
-		ch->ccw[1].count    = 0;
-	}
 	ch->ccw[2].cmd_code = CCW_CMD_NOOP;	 /* jointed CE + DE */
 	ch->ccw[2].flags    = CCW_FLAG_SLI;
 	ch->ccw[2].count    = 0;
 	ch->ccw[2].cda	    = 0;
 	memcpy(&ch->ccw[3], &ch->ccw[0], sizeof(ccw1_t) * 3);
 	ch->ccw[4].cda	    = 0;
+	ch->ccw[4].flags    &= ~CCW_FLAG_IDA;
 
 	fsm_newstate(fi, CH_STATE_STARTWAIT);
 	fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch);
@@ -1696,9 +1699,10 @@
 		if ((skb = skb_peek(&ch->io_queue))) {
 			int rc = 0;
 
-			set_normalized_cda(&ch->ccw[4],
-					   virt_to_phys(skb->data));
-			if (ch->ccw[4].cda == 0) {
+			clear_normalized_cda(&ch->ccw[4]);
+			ch->ccw[4].count = skb->len;
+			if (set_normalized_cda(&ch->ccw[4],
+					       virt_to_phys(skb->data))) {
 				printk(KERN_DEBUG "%s: IDAL alloc failed, "
 				       "restarting channel\n", dev->name);
 				fsm_event(((ctc_priv *)dev->priv)->fsm,
@@ -1709,7 +1713,6 @@
 			fsm_addtimer(&ch->timer, 1000, CH_EVENT_TIMER, ch);
 			if (event == CH_EVENT_TIMER)
 				s390irq_spin_lock_irqsave(ch->irq, saveflags);
-			ch->ccw[4].count = skb->len;
 #ifdef DEBUG
 	printk(KERN_DEBUG "ccw[4].cda = %08x\n", ch->ccw[4].cda);
 #endif
@@ -2488,8 +2491,8 @@
 		       LL_HEADER_LENGTH);
 		block_len = skb->len + 2;
 		*((__u16 *)skb_push(skb, 2)) = block_len;
-		set_normalized_cda(&ch->ccw[4], virt_to_phys(skb->data));
-		if (ch->ccw[4].cda == 0) {
+		ch->ccw[4].count = block_len;
+		if (set_normalized_cda(&ch->ccw[4], virt_to_phys(skb->data))) {
 			/**
 			 * idal allocation failed, try via copying to
 			 * trans_skb. trans_skb usually has a pre-allocated
@@ -2513,7 +2516,6 @@
 			dev_kfree_skb_irq(skb);
 			ccw_idx = 0;
 		} else {
-			ch->ccw[4].count = block_len;
 			skb_queue_tail(&ch->io_queue, skb);
 			ccw_idx = 3;
 		}
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/net/iucv.c linux/drivers/s390/net/iucv.c
--- v2.4.10/linux/drivers/s390/net/iucv.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/net/iucv.c	Sun Sep 30 12:26:07 2001
@@ -1,30 +1,41 @@
-/*                                                                                             
- *   drivers/s390/net/iucv.c
- *    Support for VM IUCV functions for use by other part of the
- *    kernel or loadable modules.
- *
- *  S390 version
- *    Copyright (C) 2000 IBM Corporation
- *    Author(s): Alan Altmark (Alan_Altmark@us.ibm.com)
- *               Xenia Tkatschow (xenia@us.ibm.com)
- * Functionality:                                                    
- * To explore any of the IUCV functions, one must first register     
- * their program using iucv_register(). Once your program has        
- * successfully completed a register, it can use the other functions.
- * For furthur reference on all IUCV functionality, refer to the     
- * CP Programming Services book, also available on the web            
- * thru www.ibm.com/s390/vm/pubs , manual # SC24-5760.               
- *                                                                    
- *      Definition of Return Codes                                    
- *      -All positive return codes including zero are reflected back 
- *       from CP and the definition can be found in CP Programming    
- *       Services book.                  
- *      - (-ENOMEM) Out of memory
- *      - (-EINVAL) Invalid value                             
-*/
-/* #define DEBUG 1 */
+/*
+ * $Id$
+ *
+ * IUCV network driver
+ *
+ * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s):
+ *    Original source:
+ *      Alan Altmark (Alan_Altmark@us.ibm.com)  Sept. 2000
+ *      Xenia Tkatschow (xenia@us.ibm.com)
+ *    2Gb awareness and general cleanup:
+ *      Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
+ *
+ * Documentation used:
+ *    The original source
+ *    CP Programming Service, IBM document # SC24-5760
+ *
+ * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * RELEASE-TAG: IUCV lowlevel driver $Revision$
+ *
+ */
+
 #include <linux/module.h>
 #include <linux/config.h>
+
 #include <linux/version.h>
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
@@ -32,6 +43,7 @@
 #include <linux/init.h>
 #include <linux/tqueue.h>
 #include <linux/interrupt.h>
+#include <linux/list.h>
 #include <asm/atomic.h>
 #include "iucv.h"
 #include <asm/io.h>
@@ -39,20 +51,11 @@
 #include <asm/s390_ext.h>
 #include <asm/ebcdic.h>
 
-#ifdef DEBUG
-#undef KERN_INFO
-#undef KERN_DEBUG
-#define KERN_INFO KERN_EMERG
-#define KERN_DEBUG KERN_EMERG
-#endif
+#undef DEBUG
 
-#undef NULL
-#define NULL 0
-
-#define PRRTY_PRMTD    0x01	/* priority permitted */
-#define RPY_RQRD       0x01	/* reply required */
-#define ADDED_STOR  64		/* ADDITIONAL STORAGE FOR PATHID @'S */
-#define BUFFER_SIZE 40		/* Size of 31-bit iparml */
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
 
 /* FLAGS:
  * All flags are defined in the field IPFLAGS1 of each function
@@ -74,55 +77,43 @@
 #define IPANSLST        0x08
 #define IPBUFLST        0x40
 
-static uchar iucv_external_int_buffer[40];
-
-/* Spin Lock declaration */
-struct tq_struct short_task;	/* automatically initialized to zero */
-static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED;
-
 /* General IUCV interrupt structure */
 typedef struct {
-	u16 ippathid;
-	uchar res1;
-	uchar iptype;
-	u32 res2;
-	uchar ipvmid[8];
-	uchar res3[24];
+	__u16 ippathid;
+	__u8  res1;
+	__u8  iptype;
+	__u32 res2;
+	__u8  ipvmid[8];
+	__u8  res3[24];
 } iucv_GeneralInterrupt;
 
-/***************INTERRUPT HANDLING DEFINITIONS***************/
-typedef struct _iucv_packet {
-	struct _iucv_packet *next;
-	uchar data[40];
-} iucv_packet;
-struct tq_struct short_task;
-
-static spinlock_t iucv_packets_lock = SPIN_LOCK_UNLOCKED;
+static iucv_GeneralInterrupt *iucv_external_int_buffer;
 
-iucv_packet *iucv_packets_head, *iucv_packets_tail;
-
-static atomic_t bh_scheduled = ATOMIC_INIT (0);
-
-/* 
- *Internal function prototypes 
- */
+/* Spin Lock declaration */
 
-static ulong iucv_vmsize (void);
+static spinlock_t iucv_lock = SPIN_LOCK_UNLOCKED;
 
-int iucv_declare_buffer (void);
+/***************INTERRUPT HANDLING ***************/
 
-int iucv_retrieve_buffer (void);
+typedef struct {
+	struct list_head queue;
+	iucv_GeneralInterrupt data;
+} iucv_irqdata;
 
-static int iucv_add_pathid (u16 pathid, iucv_handle_t handle, void *pgm_data);
+struct list_head  iucv_irq_queue;
+static spinlock_t iucv_irq_queue_lock = SPIN_LOCK_UNLOCKED;
 
-static void iucv_remove_pathid (u16 pathid);
+struct tq_struct  iucv_tq;
 
-void bottom_half_interrupt (void);
+static atomic_t   iucv_bh_scheduled = ATOMIC_INIT (0);
 
-static void do_int (iucv_GeneralInterrupt *);
+/*
+ *Internal function prototypes
+ */
+static void iucv_bh_handler(void);
+static void iucv_irq_handler(struct pt_regs *, __u16);
 
-inline void top_half_interrupt (struct pt_regs *regs, __u16 code);
-/************FUNCTION ID'S****************************/
+/************ FUNCTION ID'S ****************************/
 
 #define ACCEPT          10
 #define CONNECT         11
@@ -139,1180 +130,1066 @@
 #define SETMASK         16
 #define SEVER           15
 
-/*                                                               
- * Structure: handler                                            
- * members: next - is a pointer to next handler on chain         
- *          prev - is a pointer to prev handler on chain         
- *          structure: id                                        
- *             vmid - 8 char array of machine identification     
- *             user_data - 16 char array for user identification 
- *             mask - 24 char array used to compare the 2 previous  
- *          interrupt_table - vector of interrupt functions.     
- *          pathid_head - pointer to start of user_pathid_table  
- *          pathid_tail - pointer to end of user_pathid_table    
- *          entries -  ulong, size of user_pathid_table          
- *          pgm_data -  ulong, application data that is passed   
- *                      to the interrupt handlers                
+/**
+ * Structure: handler
+ * members: list - list management.
+ *          structure: id
+ *             userid - 8 char array of machine identification
+ *             user_data - 16 char array for user identification
+ *             mask - 24 char array used to compare the 2 previous
+ *          interrupt_table - vector of interrupt functions.
+ *          pgm_data -  ulong, application data that is passed
+ *                      to the interrupt handlers
 */
-typedef struct {
-	ulong *next;
-	ulong *prev;
+typedef struct handler_t {
+	struct list_head list;
 	struct {
-		uchar userid[8];
-		uchar user_data[16];
-		uchar mask[24];
-	} id;
+		__u8 userid[8];
+		__u8 user_data[16];
+		__u8 mask[24];
+	}                    id;
 	iucv_interrupt_ops_t *interrupt_table;
-	ulong *pathid_head;
-	ulong *pathid_tail;
-	ulong entries;
-	void *pgm_data;
+	void                 *pgm_data;
 } handler;
 
-/*                                                         
- * Structure: handler_table_entry                          
- * members: addrs - pointer to a handler                   
- *          pathid - ushort containing path identification 
- *          pgm_data - ulong, application data that is     
- *                     passed to the interrupt handlers    
- *          ops - pointer to iucv interrupt vector         
+/**
+ * iucv_handler_table: List of registered handlers.
  */
+static struct list_head iucv_handler_table;
 
-typedef struct {
-	handler *addrs;
-	u16 pathid;
-	void *pgm_data;
-	iucv_interrupt_ops_t *ops;
-} handler_table_entry;
-
-/* 
- * Internal function prototypes 
+/**
+ * iucv_pathid_table: an array of *handler pointing into
+ *                    iucv_handler_table for fast indexing by pathid;
  */
+static handler **iucv_pathid_table;
 
-static int iucv_add_handler (handler * new_handler);
-
-static void iucv_remove_handler (handler * users_handler);
-
-/* handler_anchor: points to first handler on chain */
-/* handler_tail: points to last handler on chain */
-/* handler_table_anchor: points to beginning of handler_table_entries*/
+static unsigned long max_connections;
 
-static handler *handler_anchor = NULL;
-
-static handler *handler_tail = NULL;
-
-static handler_table_entry *handler_table_anchor = NULL;
-
-/* declare_flag: is 0 when iucv_declare_buffer has not been called */
-
-static ulong declare_flag = 0;
+/**
+ * declare_flag: is 0 when iucv_declare_buffer has not been called
+ */
+static int declare_flag;
 
 /****************FIVE 40-BYTE PARAMETER STRUCTURES******************/
-/* Data struct 1: iparml_control                                      
- * Used for iucv_accept                                               
- *          iucv_connect                                              
- *          iucv_quiesce                                              
- *          iucv_resume                                               
- *          iucv_sever                                                
- *          iucv_retrieve_buffer                                      
- * Data struct 2: iparml_dpl     (data in parameter list)             
- * Used for iucv_send_prmmsg                                          
- *          iucv_send2way_prmmsg                                      
- *          iucv_send2way_prmmsg_array                                
- *          iucv_reply_prmmsg                                         
- * Data struct 3: iparml_db       (data in a buffer)                  
- * Used for iucv_receive                                              
- *          iucv_receive_array                                        
- *          iucv_reject                                               
- *          iucv_reply                                                
- *          iucv_reply_array                
- *          iucv_send                       
- *          iucv_send_array                 
- *          iucv_send2way                   
- *          iucv_send2way_array             
- *          iucv_declare_buffer             
- * Data struct 4: iparml_purge              
- * Used for iucv_purge                      
- *          iucv_query                      
- * Data struct 5: iparml_set_mask           
- * Used for iucv_set_mask                   
-*/
+/* Data struct 1: iparml_control
+ * Used for iucv_accept
+ *          iucv_connect
+ *          iucv_quiesce
+ *          iucv_resume
+ *          iucv_sever
+ *          iucv_retrieve_buffer
+ * Data struct 2: iparml_dpl     (data in parameter list)
+ * Used for iucv_send_prmmsg
+ *          iucv_send2way_prmmsg
+ *          iucv_send2way_prmmsg_array
+ *          iucv_reply_prmmsg
+ * Data struct 3: iparml_db       (data in a buffer)
+ * Used for iucv_receive
+ *          iucv_receive_array
+ *          iucv_reject
+ *          iucv_reply
+ *          iucv_reply_array
+ *          iucv_send
+ *          iucv_send_array
+ *          iucv_send2way
+ *          iucv_send2way_array
+ *          iucv_declare_buffer
+ * Data struct 4: iparml_purge
+ * Used for iucv_purge
+ *          iucv_query
+ * Data struct 5: iparml_set_mask
+ * Used for iucv_set_mask
+ */
 
 typedef struct {
-	u16 ippathid;
-	uchar ipflags1;
-	uchar iprcode;
-	u16 ipmsglim;
-	u16 res1;
-	uchar ipvmid[8];
-	uchar ipuser[16];
-	uchar iptarget[8];
+	__u16 ippathid;
+	__u8  ipflags1;
+	__u8  iprcode;
+	__u16 ipmsglim;
+	__u16 res1;
+	__u8  ipvmid[8];
+	__u8  ipuser[16];
+	__u8  iptarget[8];
 } iparml_control;
 
 typedef struct {
-	u16 ippathid;
-	uchar ipflags1;
-	uchar iprcode;
-	u32 ipmsgid;
-	u32 iptrgcls;
-	uchar iprmmsg[8];
-	u32 ipsrccls;
-	u32 ipmsgtag;
-	u32 ipbfadr2;
-	u32 ipbfln2f;
-	u32 res;
+	__u16 ippathid;
+	__u8  ipflags1;
+	__u8  iprcode;
+	__u32 ipmsgid;
+	__u32 iptrgcls;
+	__u8  iprmmsg[8];
+	__u32 ipsrccls;
+	__u32 ipmsgtag;
+	__u32 ipbfadr2;
+	__u32 ipbfln2f;
+	__u32 res;
 } iparml_dpl;
 
 typedef struct {
-	u16 ippathid;
-	uchar ipflags1;
-	uchar iprcode;
-	u32 ipmsgid;
-	u32 iptrgcls;
-	u32 ipbfadr1;
-	u32 ipbfln1f;
-	u32 ipsrccls;
-	u32 ipmsgtag;
-	u32 ipbfadr2;
-	u32 ipbfln2f;
-	u32 res;
+	__u16 ippathid;
+	__u8  ipflags1;
+	__u8  iprcode;
+	__u32 ipmsgid;
+	__u32 iptrgcls;
+	__u32 ipbfadr1;
+	__u32 ipbfln1f;
+	__u32 ipsrccls;
+	__u32 ipmsgtag;
+	__u32 ipbfadr2;
+	__u32 ipbfln2f;
+	__u32 res;
 } iparml_db;
 
 typedef struct {
-	u16 ippathid;
-	uchar ipflags1;
-	uchar iprcode;
-	u32 ipmsgid;
-	uchar ipaudit[3];
-	uchar res1[5];
-	u32 res2;
-	u32 ipsrccls;
-	u32 ipmsgtag;
-	u32 res3[3];
+	__u16 ippathid;
+	__u8  ipflags1;
+	__u8  iprcode;
+	__u32 ipmsgid;
+	__u8  ipaudit[3];
+	__u8  res1[5];
+	__u32 res2;
+	__u32 ipsrccls;
+	__u32 ipmsgtag;
+	__u32 res3[3];
 } iparml_purge;
 
 typedef struct {
-	uchar ipmask;
-	uchar res1[2];
-	uchar iprcode;
-	u32 res2[9];
+	__u8  ipmask;
+	__u8  res1[2];
+	__u8  iprcode;
+	__u32 res2[9];
 } iparml_set_mask;
 
-/*********************INTERNAL FUNCTIONS*****************************/
-
-static ulong
-iucv_vmsize (void)
-{
-	extern unsigned long memory_size;
-	return memory_size;
-}
-
-/*
- * Name: dumpit                                                     
- * Purpose: print to the console buffers of a given length          
- * Input: buf - (* uchar) - pointer to buffer to be printed         
- *        len - int - length of buffer being printed                
- * Output: void                                                     
- */
-
+typedef struct {
+	union {
+		iparml_control  p_ctrl;
+		iparml_dpl      p_dpl;
+		iparml_db       p_db;
+		iparml_purge    p_purge;
+		iparml_set_mask p_set_mask;
+	} param;
+	atomic_t in_use;
+}  __attribute__ ((aligned(8))) iucv_param;
+#define PARAM_POOL_SIZE (PAGE_SIZE / sizeof(iucv_param))
+
+static iucv_param * iucv_param_pool;
+
+/*
+ * Debugging stuff
+ *******************************************************************************/
+
 #ifdef DEBUG
 
 static void
-iucv_dumpit (uchar * buf, int len)
+iucv_dumpit(void *buf, int len)
 {
 	int i;
+	__u8 *p = (__u8 *)buf;
+
+	printk(KERN_DEBUG "  ");
 	for (i = 0; i < len; i++) {
 		if (!(i % 16) && i != 0)
-			printk ("\n");
+			printk ("\n  ");
 		else if (!(i % 4) && i != 0)
 			printk (" ");
-		printk ("%02X", buf[i]);
+		printk ("%02X", *p++);
 	}
 	if (len % 16)
 		printk ("\n");
 	return;
 }
+#define iucv_debug(fmt, args...) \
+printk(KERN_DEBUG __FUNCTION__ ": " fmt "\n" , ## args);
 
 #else
-static void
-iucv_dumpit (uchar * buf, int len)
-{
-}
+
+#define iucv_debug(fmt, args...)
+#define iucv_dumpit(buf, len)
 
 #endif
 
 /*
- * Name iucv_add_handler
- * Purpose: Place new handle on handler_anchor chain, if identical handler is not
- *	    found. Handlers are ordered with largest mask integer value first.
- * Input: new_handler - handle that is being entered into chain
- * Return: int
- *	   0 - handler added
- *	   1 - identical handler found, handler not added to chain
-*/
-int
-iucv_add_handler (handler * new_handler)
+ * Internal functions
+ *******************************************************************************/
+
+/**
+ * iucv_init - Initialization
+ *
+ * Allocates and initializes various data structures.
+ */
+static int
+iucv_init(void)
+{
+	if (iucv_external_int_buffer)
+		return 0;
+
+	/* Note: GFP_DMA used used to get memory below 2G */
+	iucv_external_int_buffer = kmalloc(sizeof(iucv_GeneralInterrupt),
+					   GFP_KERNEL|GFP_DMA);
+	if (!iucv_external_int_buffer) {
+		printk(KERN_WARNING
+		       "%s: Could not allocate external interrupt buffer\n",
+		       __FUNCTION__);
+		return -ENOMEM;
+	}
+	memset(iucv_external_int_buffer, 0, sizeof(iucv_GeneralInterrupt));
+
+	/* Initialize parameter pool */
+	iucv_param_pool = kmalloc(sizeof(iucv_param) * PARAM_POOL_SIZE,
+				  GFP_KERNEL|GFP_DMA);
+	if (!iucv_param_pool) {
+		printk(KERN_WARNING "%s: Could not allocate param pool\n",
+		       __FUNCTION__);
+		kfree(iucv_external_int_buffer);
+		iucv_external_int_buffer = NULL;
+		return -ENOMEM;
+	}
+	memset(iucv_param_pool, 0, sizeof(iucv_param) * PARAM_POOL_SIZE);
+
+	/* Initialize task queue */
+	INIT_LIST_HEAD(&iucv_tq.list);
+	iucv_tq.sync = 0;
+	iucv_tq.routine = (void *)iucv_bh_handler;
+
+	/* Initialize irq queue */
+	INIT_LIST_HEAD(&iucv_irq_queue);
+
+	/* Initialize handler table */
+	INIT_LIST_HEAD(&iucv_handler_table);
+
+	return 0;
+}
+
+/**
+ * grab_param: - Get a parameter buffer from the pre-allocated pool.
+ *
+ * This function searches for an unused element in the the pre-allocated pool
+ * of parameter buffers. If one is found, it marks it "in use" and returns
+ * a pointer to it. The calling function is responsible for releasing it
+ * when it has finished its usage.
+ *
+ * Returns: A pointer to iucv_param.
+ */
+static __inline__ iucv_param *
+grab_param(void)
+{
+	iucv_param *ret;
+	static int i = 0;
+
+	while (atomic_compare_and_swap(0, 1, &iucv_param_pool[i].in_use)) {
+		i++;
+		if (i >= PARAM_POOL_SIZE)
+			i = 0;
+	}
+	ret = &iucv_param_pool[i];
+	memset(&ret->param, 0, sizeof(ret->param));
+	return ret;
+}
+
+/**
+ * release_param - Release a parameter buffer.
+ * @p: A pointer to a struct iucv_param, previously obtained by calling
+ *     grab_param().
+ *
+ * This function marks the specified parameter buffer "unused".
+ */
+static __inline__ void
+release_param(void *p)
+{
+	atomic_set(&((iucv_param *)p)->in_use, 0);
+}
+
+/**
+ * iucv_add_handler: - Add a new handler
+ * @new_handler: handle that is being entered into chain.
+ *
+ * Places new handle on iucv_handler_table, if identical handler is not
+ * found.
+ *
+ * Returns: 0 on success, !0 on failure (handler already in chain).
+ */
+static int
+iucv_add_handler (handler *new)
 {
-	handler *R = new_handler;
-	int rc = 1, comp = 0;	/* return code (rc = 1 not added) or (rc = 0 added) */
 	ulong flags;
-	pr_debug ("iucv_add_handler: entering\n");
-	iucv_dumpit ((uchar *) new_handler, sizeof (handler));
+
+	iucv_debug("entering");
+	iucv_dumpit(new, sizeof(handler));
+
 	spin_lock_irqsave (&iucv_lock, flags);
-	if (handler_anchor == NULL) {
-		/* add to beginning of chain */
-		handler_anchor = handler_tail = new_handler;
-		rc = 0;
-	} else
-		for (R = handler_anchor; R != NULL; R = (handler *) R->next) {
-			comp = memcmp ((void *) &(new_handler->id),
-				       (void *) &(R->id), sizeof (R->id));
-			pr_debug ("comp = %d\n", comp);
-			if (comp == 0)	/* identicle handler found */
-				break;	/* break out of for loop */
-			else if (comp > 0) {	/* new_handler > R */
-				pr_debug
-				    ("iucv_add_handler: Found a place to add,"
-				     "R is\n");
-				iucv_dumpit ((uchar *) R, sizeof (handler));
-				if ((R->prev != NULL)) {
-					/* add to middle of chain */
-					pr_debug
-					    ("iucv_add_handler: added to middle\n");
-					new_handler->prev = R->prev;
-					new_handler->next = (ulong *) R;
-					((handler *) (R->prev))->next =
-					    (ulong *) new_handler;
-					R->prev = (ulong *) new_handler;
-					rc = 0;
-					break;	/* break out of FOR loop */
-				} else {	/* R->prev == NULL */
-					/* add to start of chain;  */
-					pr_debug ("iucv_add_handler:"
-						  "added to beginning\n");
-					R->prev = (ulong *) new_handler;
-					new_handler->next = (ulong *) R;
-					handler_anchor = new_handler;
-					rc = 0;
-					break;	/* break out of FOR loop */
-				}
-			}	/* end of else if */
-		}		/* end of for loop */
-	if (R == NULL) {
-		/* add to end of chain */
-		pr_debug ("iucv_add_handler: added to end\n");
-		handler_tail->next = (ulong *) new_handler;
-		new_handler->prev = (ulong *) handler_tail;
-		handler_tail = new_handler;
-		rc = 0;
+	if (!list_empty(&iucv_handler_table)) {
+		struct list_head *lh;
+
+		/**
+		 * Search list for handler with identical id. If one
+		 * is found, the new handler is _not_ added.
+		 */
+		list_for_each(lh, &iucv_handler_table) {
+			handler *h = list_entry(lh, handler, list);
+			if (memcmp(&new->id, &h->id, sizeof(h->id)) == 0) {
+				iucv_debug("ret 1");
+				spin_unlock_irqrestore (&iucv_lock, flags);
+				return 1;
+			}
+		}
 	}
+	/**
+	 * If we get here, no handler was found.
+	 */
+	INIT_LIST_HEAD(&new->list);
+	list_add(&new->list, &iucv_handler_table);
 	spin_unlock_irqrestore (&iucv_lock, flags);
 
-	pr_debug ("Current Chain of handlers is\n");
-	for (R = handler_anchor; R != NULL; R = (handler *) R->next)
-		iucv_dumpit ((uchar *) R, (int) sizeof (handler));
-
-	pr_debug ("iucv_add_handler: exiting\n");
-	return rc;
+	iucv_debug("exiting");
+	return 0;
 }
 
-/* 
- * Name: iucv_remove_handler
- * Purpose: Remove handler when application unregisters.
- * Input: users_handler - handler to be removed
- * Output: void
-*/
-void
-iucv_remove_handler (handler * users_handler)
+/**
+ * iucv_remove_handler:
+ * @users_handler: handler to be removed
+ *
+ * Remove handler when application unregisters.
+ */
+static void
+iucv_remove_handler(handler *handler)
 {
-	handler *R;		/* used for Debugging */
-	pr_debug ("iucv_remove_handler: entering\n");
-	if ((users_handler->next != NULL) & (users_handler->prev != NULL)) {
-		/* remove from middle of chain */
-		((handler *) (users_handler->next))->prev =
-		    (ulong *) users_handler->prev;
-		((handler *) (users_handler->prev))->next =
-		    (ulong *) users_handler->next;
-	} else if ((users_handler->next != NULL) &
-		   (users_handler->prev == NULL)) {
-		/* remove from start of chain */
-		((handler *) (users_handler->next))->prev = NULL;
-		handler_anchor = (handler *) users_handler->next;
-	} else if ((users_handler->next == NULL) &
-		   (users_handler->prev != NULL)) {
-		/* remove from end of chain */
-		((handler *) (users_handler->prev))->next = NULL;
-		handler_tail = (handler *) users_handler->prev;
-	} else {
-		handler_anchor = NULL;
-		handler_tail = NULL;
-	}
+	unsigned long flags;
 
-	pr_debug ("Current Chain of handlers is\n");
-	for (R = handler_anchor; R != NULL; R = (handler *) R->next)
-		iucv_dumpit ((uchar *) R, (int) sizeof (handler));
+	if ((!iucv_pathid_table) || (!handler))
+		return;
 
-	pr_debug ("iucv_remove_handler: exiting\n");
+	iucv_debug("entering");
+
+	spin_lock_irqsave (&iucv_lock, flags);
+	list_del(&handler->list);
+	spin_unlock_irqrestore (&iucv_lock, flags);
+
+	iucv_debug("exiting");
 	return;
 }
 
-/*
- * Name: b2f0
- * Purpose: This function calls CP to execute IUCV commands.
- * Input: code -  identifier of IUCV call to CP.
- *        parm -  pointer to 40 byte iparml area
- *               passed to CP
- * Output: iprcode- return code from CP's IUCV call
- * NOTE: Assembler code performing IUCV call
-*/
-inline ulong
-b2f0 (u32 code, void *parm)
+/**
+ * b2f0:
+ * @code: identifier of IUCV call to CP.
+ * @parm: pointer to 40 byte iparml area passed to CP
+ *
+ * Calls CP to execute IUCV commands.
+ *
+ * Returns: return code from CP's IUCV call
+ */
+static __inline__ ulong
+b2f0(__u32 code, void *parm)
 {
-	uchar *iprcode;
-	pr_debug ("iparml before b2f0 call\n");
-	iucv_dumpit ((uchar *) parm, (int) BUFFER_SIZE);
-	asm volatile ("LRA   1,0(%1)\n\t"
-		      "LR    0,%0\n\t"
-		      ".long 0xb2f01000"::"d" (code), "a" (parm):"0", "1");
-	pr_debug ("iparml after b2f0 call\n");
-	iucv_dumpit ((uchar *) parm, (int) BUFFER_SIZE);
-	iprcode = (uchar *) (parm + 3);
-	return (ulong) (*iprcode);
+	iucv_debug("iparml before b2f0 call:");
+	iucv_dumpit(parm, sizeof(iucv_param.param));
+
+	asm volatile (
+		"LRA   1,0(%1)\n\t"
+		"LR    0,%0\n\t"
+		".long 0xb2f01000"
+		:
+		: "d" (code), "a" (parm)
+		: "0", "1"
+		);
+
+	iucv_debug("iparml after b2f0 call:");
+	iucv_dumpit(parm, sizeof(iucv_param.param));
+
+	return (unsigned long)*((__u8 *)(parm + 3));
 }
 
 /*
- * Name: iucv_add_pathid                                            
- * Purpose: Adds a path id to the system.                       
- * Input: pathid -  pathid that is going to be entered into system              
+ * Name: iucv_add_pathid
+ * Purpose: Adds a path id to the system.
+ * Input: pathid -  pathid that is going to be entered into system
  *        handle -  address of handler that the pathid will be associated
  *		   with.
- *        pgm_data - token passed in by application.                
+ *        pgm_data - token passed in by application.
  * Output: 0: successful addition of pathid
  *	   - EINVAL - pathid entry is being used by another application
- *	   - ENOMEM - storage allocation for a new pathid table failed      
+ *	   - ENOMEM - storage allocation for a new pathid table failed
 */
-int
-iucv_add_pathid (u16 pathid, iucv_handle_t handle, void *pgm_data)
+static int
+iucv_add_pathid(__u16 pathid, handler *handler)
 {
-	ulong add_flag = 0;
-	ulong old_size = 0, new_size = 0;
 	ulong flags;
-	uchar *to, *from;	/* pointer for copying the table */
-	handler_table_entry *P = 0;	/*P is a pointer to the users H_T_E */
-	handler *users_handler = 0;
-	ulong *X = 0;		/* Points to array of pointers to H-T_E */
 
-	pr_debug ("iucv_add_pathid: entering\n");
+	iucv_debug("entering");
 
-	users_handler = (handler *) handle;
+	iucv_debug("handler is pointing to %p", handler);
 
-	pr_debug ("iucv_add_pathid: users_handler is pointing to %p ",
-		  users_handler);
+	if (pathid > (max_connections - 1))
+		return -EINVAL;
 
 	spin_lock_irqsave (&iucv_lock, flags);
-
-	/*
-	 * P points to the users handler table entry (H_T_E) in which all entries in
-	 * that structure should be NULL. If they're not NULL, then there
-	 * is a bad pointer and it will return(-EINVAL) immediately, otherwise users
-	 * data will be entered into H_T_E.
-	 */
-
-	P = handler_table_anchor + pathid;	/* index into users handler table */
-
-	pr_debug ("handler_table_anchor is %p\n", handler_table_anchor);
-	pr_debug ("P=handler_table_anchor+pathid = %p\n", P);
-
-	if (P->addrs) {
-		pr_debug ("iucv_add_pathid: P = %p \n", P);
-		pr_debug ("iucv_add_pathid: P->addrs is %p \n", P->addrs);
+	if (iucv_pathid_table[pathid]) {
 		spin_unlock_irqrestore (&iucv_lock, flags);
-		/* This message should be sent to syslog */
-		printk (KERN_WARNING "iucv_add_pathid: Pathid being used,"
-			"error.\n");
-		return (-EINVAL);
+		iucv_debug("pathid entry is %p", iucv_pathid_table[pathid]);
+		printk(KERN_WARNING
+		       "%s: Pathid being used, error.\n", __FUNCTION__);
+		return -EINVAL;
 	}
+	iucv_pathid_table[pathid] = handler;
+	spin_unlock_irqrestore (&iucv_lock, flags);
 
-	P->addrs = handle;
-	P->pathid = pathid;
-
-	/*
-	 * pgm_data provided in iucv_register may be overwritten on a connect, accept. 
-	 */
-
-	if (pgm_data)
-		P->pgm_data = pgm_data;
-	else
-		P->pgm_data = users_handler->pgm_data;
-
-	/*
-	 * Address of pathid's iucv_interrupt_ops is taken from the associated handler
-	 * and added here for quicker access to the interrupt tables during interrupt
-	 * handling.
-	 */
-
-	P->ops = (P->addrs)->interrupt_table;
-
-	pr_debug ("Complete users H_T_E is\n");
-	iucv_dumpit ((uchar *) P, sizeof (handler_table_entry));
-
-	/*
-	 * Step thru the table of addresses of pathid's to find the first
-	 * available entry (NULL). If an entry is found, add the pathid,
-	 * unlock and exit. If an available entry is not found, allocate a
-	 * new, larger table, copy over the old table to the new table. De-allocate the
-	 * old table and enter the new pathid.
-	 */
-
-	pr_debug ("iucv_add_pathid: address of handle is %p\n", handle);
-	pr_debug ("iucv_add_pathid: &(users_handler->pathid_head) is %p\n",
-		  &(users_handler->pathid_head));
-	pr_debug ("iucv_add_pathid: &(users_handler->pathid_tail) is %p\n",
-		  &(users_handler->pathid_tail));
-	pr_debug ("iucv_add_pathid: start of pathid table is %p\n",
-		  (users_handler->pathid_head));
-	pr_debug ("iucv_add_pathid: end of pathid table is %p\n",
-		  (users_handler->pathid_tail));
-	iucv_dumpit ((uchar *) users_handler->pathid_head,
-		     (int) (users_handler->pathid_tail -
-			    users_handler->pathid_head));
-
-	for (X = (users_handler->pathid_head);
-	     X <
-	     (users_handler->pathid_head +
-	      users_handler->entries * sizeof (ulong)); X++)
-		if (*X == NULL) {
-			pr_debug ("adding pathid, %p = P\n", P);
-			*X = (ulong) P;
-			add_flag = 1;
-			break;	/* breaks out of for loop */
-		}
-
-	pr_debug ("Addresses of HTE's are\n");
-	iucv_dumpit ((uchar *) users_handler->pathid_head,
-		     users_handler->entries * sizeof (ulong));
-
-	if (add_flag == 0) {	/* element not added to list: must get a new table */
-		X = users_handler->pathid_head;
-		old_size = users_handler->entries;
-		new_size = old_size + ADDED_STOR;	/*number of entries of new table */
-		from = (uchar *) (users_handler->pathid_head);	/*address of old table */
-		users_handler->pathid_head =
-		    kmalloc (new_size * sizeof (ulong), GFP_ATOMIC);
+	iucv_debug("exiting");
+	return 0;
+}				/* end of add_pathid function */
 
-		if (users_handler->pathid_head == NULL) {
-			users_handler->pathid_head = X;	/*setting old condition */
-			spin_unlock_irqrestore (&iucv_lock, flags);
-			printk (KERN_WARNING
-				"iucv_add_pathid: storage allocation"
-				"failed for new pathid table \n ");
-			memset (P, 0, sizeof (handler_table_entry));
-			return -ENOMEM;
-		}
+static void
+iucv_remove_pathid(__u16 pathid)
+{
+	ulong flags;
 
-		memset (users_handler->pathid_head, 0,
-			new_size * sizeof (ulong));
-		to = (uchar *) (users_handler->pathid_head);	/* address of new table */
-		/* copy old table to new  */
-		memcpy (to, from, old_size * (sizeof (ulong)));
-
-		pr_debug ("iucv: add_pathid: Getting a new pathid table\n");
-		pr_debug ("iucv: add_pathid: to is %p \n", to);
-		pr_debug ("iucv: add_pathid: from is %p \n", from);
-
-		users_handler->entries = new_size;	/* storing new size of table */
-		users_handler->pathid_tail =
-		    (users_handler->pathid_head) + (users_handler->entries);
-		X = users_handler->pathid_head + old_size;
-		*X = (ulong) P;	/* adding element to new table */
-
-		pr_debug ("iucv: add_pathid: users_handler->entries is %u \n",
-			  (int) (users_handler->entries));
-		pr_debug
-		    ("iucv: add_pathid: users_handler->pathid_tail is %p\n",
-		     users_handler->pathid_tail);
-		pr_debug ("users_handler->pathid_head is %p \n",
-			  users_handler->pathid_head);
-		pr_debug ("iucv: add_pathid: X is %p \n", X);
-		pr_debug ("iucv: add_pathid: *X is %u \n", (int) (*X));
-		pr_debug ("Addresses of HTE's after getting new table is\n");
-		iucv_dumpit ((uchar *) users_handler->pathid_head,
-			     users_handler->entries * sizeof (ulong));
-		pr_debug ("New handler is\n");
-		iucv_dumpit ((uchar *) users_handler, sizeof (handler));
+	if (pathid > (max_connections - 1))
+		return;
 
-		kfree (from);	/* free old table */
-	}
+	spin_lock_irqsave (&iucv_lock, flags);
+	iucv_pathid_table[pathid] = NULL;
 	spin_unlock_irqrestore (&iucv_lock, flags);
-	pr_debug ("iucv_dd_pathid: exiting\n");
-	return (0);
-}				/* end of add_pathid function */
+}
 
 /*
- * Name: iucv_declare_buffer                                    
- * Purpose: Specifies the guests real address of an external  
- *          interrupt.                                        
- * Input: void                             
- * Output: iprcode - return code from b2f0 call               
+ * Name: iucv_declare_buffer
+ * Purpose: Specifies the guests real address of an external
+ *          interrupt.
+ * Input: void
+ * Output: iprcode - return code from b2f0 call
 */
 int
 iucv_declare_buffer (void)
 {
-	iparml_db parm;
 	ulong b2f0_result;
-	pr_debug ("iucv_declare_buffer: entering\n");
-	memset (&parm, 0, sizeof (parm));
-	parm.ipbfadr1 = virt_to_phys ((uchar *) iucv_external_int_buffer);
-	b2f0_result = b2f0 (DECLARE_BUFFER, &parm);
-	pr_debug ("iucv_declare_buffer: Address of EIB = %p\n",
-		  iucv_external_int_buffer);
-	pr_debug ("iucv_declare_buffer: exiting\n");
+	iparml_db *parm = (iparml_db *)grab_param();
+
+	parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer);
+	b2f0_result = b2f0(DECLARE_BUFFER, parm);
+	release_param(parm);
+	iucv_debug("Address of EIB = %p", iucv_external_int_buffer);
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_retrieve_buffer
- * Purpose: Terminates all use of IUCV.
- * Input: void
- * Output:
- *      b2f0_result: return code from CP
-*/
+/**
+ * iucv_retrieve_buffer:
+ *
+ * Terminates all use of IUCV.
+ * Returns: return code from CP
+ */
 int
 iucv_retrieve_buffer (void)
 {
-	iparml_control parm;
 	ulong b2f0_result = 0;
-	pr_debug ("iucv_retrieve_buffer: entering\n");
-	memset (&parm, 0, sizeof (parm));
-	b2f0_result = b2f0 (RETRIEVE_BUFFER, &parm);
-	if (b2f0_result == NULL) {
-		kfree (handler_table_anchor);
-		handler_table_anchor = NULL;
+	iparml_control *parm = (iparml_control *)grab_param();
+
+	iucv_debug("entering");
+
+	b2f0_result = b2f0(RETRIEVE_BUFFER, parm);
+	release_param(parm);
+	if (b2f0_result == 0) {
+		kfree(iucv_pathid_table);
+		iucv_pathid_table = NULL;
 		declare_flag = 0;
 	}
-	pr_debug ("iucv_retrieve_buffer: exiting\n");
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_register_program
- * Purpose: Registers an application with IUCV.   
- * Input: prmname - user identification
- *        userid  - machine identification
- *        pgmmask - indicates which bits in the prmname and userid combined will be used
- *	   to determine who is given control
- *        ops - address of vector of interrupt handlers
- *        pgm_data- application data passed to interrupt handlers
- * Output: NA
- * Return: type: iucv_handle_t
- *          address of handler
- *         (0) - registration failed
- *	       - Machine size > 2GB
- *	       - new_handler kmalloc failed
- * 	       - pgmname was not provided
- *	       - pathid_table kmalloc failed
- *             - application with identical pgmname, userid, and pgmmask is registered
- * 	       - iucv_declare_buffer failed
- * NOTE: pgmmask
- *	When pgmname, userid, pgmmask is provided, mask is entered into the handler
- *	as is.
- *	When pgmname, userid is provided, pgmmask is all 0xff's
- *	When pgmname, pgmmask is provided, the first 8 bytes = 0x00 and the last 16
- *      bytes are as provided by pgmmask. 
- *	When pgmname is provided is provided, the first 8 bytes = 0x00 and the last
- *	16 bytes are 0xff.   
-*/
+/**
+ * iucv_register_program:
+ * @pgmname:  user identification
+ * @userid:   machine identification
+ * @pgmmask:  Indicates which bits in the pgmname and userid combined will be
+ *            used to determine who is given control.
+ * @ops:      Address of interrupt handler table.
+ * @pgm_data: Application data to be passed to interrupt handlers.
+ *
+ * Registers an application with IUCV.
+ * Returns:
+ *           The address of handler, or NULL on failure.
+ * NOTE on pgmmask:
+ *   If pgmname, userid and pgmmask are provided, pgmmask is entered into the
+ *   handler as is.
+ *   If pgmmask is NULL, the internal mask is set to all 0xff's
+ *   When userid is NULL, the first 8 bytes of the internal mask are forced
+ *   to 0x00.
+ *   If pgmmask and userid are NULL, the first 8 bytes of the internal mask
+ *   are forced to 0x00 and the last 16 bytes to 0xff.
+ */
 
 iucv_handle_t
-iucv_register_program (uchar pgmname[16],
-		       uchar userid[8],
-		       uchar pgmmask[24],
+iucv_register_program (__u8 pgmname[16],
+		       __u8 userid[8],
+		       __u8 pgmmask[24],
 		       iucv_interrupt_ops_t * ops, void *pgm_data)
 {
 	ulong rc = 0;		/* return code from function calls */
-	ulong machine_size = 0;	/* size of virtual machine */
-	static u32 maxconn1;
-	handler *new_handler = NULL;
+	handler *new_handler;
 
-	pr_debug ("iucv_register_program:entering\n");
+	iucv_debug("entering");
 
 	if (ops == NULL) {
 		/* interrupt table is not defined */
-		printk (KERN_WARNING "iucv_register_program:"
-			"Interrupt table is not defined, exiting\n");
+		printk(KERN_WARNING "%s: Interrupt table is not defined, "
+		       "exiting\n", __FUNCTION__);
+		return NULL;
+	}
+	if (!pgmname) {
+		printk(KERN_WARNING "%s: pgmname not provided\n", __FUNCTION__);
 		return NULL;
 	}
 
-	if (declare_flag == 0) {
-		/* check size of virtual machine */
-		if ((machine_size = iucv_vmsize ()) > 0x100000000) {	/* 2GB */
-			printk (KERN_WARNING "iucv_register_progam: Virtual"
-				"storage = %lx hex," "exiting\n", machine_size);
+	/* Allocate handler entry */
+	new_handler = (handler *)kmalloc(sizeof(handler), GFP_KERNEL);
+	if (new_handler == NULL) {
+		printk(KERN_WARNING "%s: storage allocation for new handler "
+		       "failed.\n", __FUNCTION__);
+		return NULL;
+	}
+
+	if (!iucv_pathid_table) {
+		if (iucv_init()) {
+			kfree(new_handler);
 			return NULL;
 		}
 
-		pr_debug ("machine_size is %lx\n", machine_size);
-
-		maxconn1 = iucv_query_maxconn ();
-		handler_table_anchor = kmalloc (maxconn1 * sizeof
-						(handler_table_entry),
-						GFP_KERNEL);
-
-		if (handler_table_anchor == NULL) {
-			printk (KERN_WARNING "iucv_register_program:"
-				"handler_table_anchor"
-				"storage allocation failed\n");
+		max_connections = iucv_query_maxconn();
+		iucv_pathid_table = kmalloc(max_connections * sizeof(handler *),
+				       GFP_KERNEL);
+		if (iucv_pathid_table == NULL) {
+			printk(KERN_WARNING "%s: iucv_pathid_table storage "
+			       "allocation failed\n", __FUNCTION__);
 			return NULL;
 		}
-
-		memset (handler_table_anchor, 0,
-			maxconn1 * sizeof (handler_table_entry));
-
+		memset (iucv_pathid_table, 0, max_connections * sizeof(handler *));
 	}
-	/* Allocate handler table */
-	new_handler = (handler *) kmalloc (sizeof (handler), GFP_KERNEL);
-	if (new_handler == NULL) {
-		printk (KERN_WARNING "iucv_register_program: storage allocation"
-			"for new handler failed. \n ");
-		return NULL;
-	}
-	memset (new_handler, 0, sizeof (handler));
-	if (pgmname) {
-		memcpy (new_handler->id.user_data, pgmname,
-			sizeof (new_handler->id.user_data));
-		if (userid) {
-			memcpy (new_handler->id.userid, userid,
-				sizeof (new_handler->id.userid));
-			ASCEBC (new_handler->id.userid,
-				sizeof (new_handler->id.userid));
-			EBC_TOUPPER (new_handler->id.userid,
-				     sizeof (new_handler->id.userid));
-
-			if (pgmmask) {
-				memcpy (new_handler->id.mask, pgmmask,
-					sizeof (new_handler->id.mask));
-			} else {
-				memset (new_handler->id.mask, 0xFF,
-					sizeof (new_handler->id.mask));
-			}
+	memset(new_handler, 0, sizeof (handler));
+	memcpy(new_handler->id.user_data, pgmname,
+		sizeof (new_handler->id.user_data));
+	if (userid) {
+		memcpy (new_handler->id.userid, userid,
+			sizeof (new_handler->id.userid));
+		ASCEBC (new_handler->id.userid,
+			sizeof (new_handler->id.userid));
+		EBC_TOUPPER (new_handler->id.userid,
+			     sizeof (new_handler->id.userid));
+		
+		if (pgmmask) {
+			memcpy (new_handler->id.mask, pgmmask,
+				sizeof (new_handler->id.mask));
 		} else {
-			if (pgmmask) {
-				memcpy (new_handler->id.mask, pgmmask,
-					sizeof (new_handler->id.mask));
-			} else {
-				memset (new_handler->id.mask, 0xFF,
-					sizeof (new_handler->id.mask));
-			}
-			memset (new_handler->id.mask, 0x00,
-				sizeof (new_handler->id.userid));
+			memset (new_handler->id.mask, 0xFF,
+				sizeof (new_handler->id.mask));
 		}
 	} else {
-		kfree (new_handler);
-		printk (KERN_WARNING "iucv_register_program: pgmname not"
-			"provided\n");
-		return NULL;
+		if (pgmmask) {
+			memcpy (new_handler->id.mask, pgmmask,
+				sizeof (new_handler->id.mask));
+		} else {
+			memset (new_handler->id.mask, 0xFF,
+				sizeof (new_handler->id.mask));
+		}
+		memset (new_handler->id.mask, 0x00,
+			sizeof (new_handler->id.userid));
 	}
 	/* fill in the rest of handler */
 	new_handler->pgm_data = pgm_data;
 	new_handler->interrupt_table = ops;
-	new_handler->entries = ADDED_STOR;
-	/* Allocate storage for pathid table */
-	new_handler->pathid_head =
-	    kmalloc (new_handler->entries * sizeof (ulong), GFP_KERNEL);
-	if (new_handler->pathid_head == NULL) {
-		printk (KERN_WARNING "iucv_register_program: storage allocation"
-			"failed\n");
-		kfree (new_handler);
-		return NULL;
-	}
 
-	memset (new_handler->pathid_head, 0,
-		new_handler->entries * sizeof (ulong));
-	new_handler->pathid_tail =
-	    new_handler->pathid_head + new_handler->entries;
-	/* 
-	 * Check if someone else is registered with same pgmname, userid, and mask. 
-	 * If someone is already registered with same pgmname, userid, and mask 
-	 * registration will fail and NULL will be returned to the application. 
+	/*
+	 * Check if someone else is registered with same pgmname, userid
+	 * and mask. If someone is already registered with same pgmname,
+	 * userid and mask, registration will fail and NULL will be returned
+	 * to the application.
 	 * If identical handler not found, then handler is added to list.
 	 */
-	rc = iucv_add_handler (new_handler);
+	rc = iucv_add_handler(new_handler);
 	if (rc) {
-		printk (KERN_WARNING "iucv_register_program: Someone already"
-			"registered with same pgmname, userid, pgmmask\n");
-		kfree (new_handler->pathid_head);
+		printk(KERN_WARNING "%s: Someone already registered with same "
+		       "pgmname, userid, pgmmask\n", __FUNCTION__);
 		kfree (new_handler);
 		return NULL;
 	}
 
 	if (declare_flag == 0) {
-		rc = iucv_declare_buffer ();
+		rc = iucv_declare_buffer();
 		if (rc) {
-			kfree (handler_table_anchor);
-			kfree (new_handler->pathid_head);
-			kfree (new_handler);
-			handler_table_anchor = NULL;
-			printk (KERN_WARNING "iucv_register_program: rc from"
-				"iucv_declare_buffer is:% ld \n ", rc);
+			iucv_remove_handler(new_handler);
+			kfree(new_handler);
+			printk(KERN_WARNING "%s: iucv_declare_buffer "
+			       "returned %ld\n", __FUNCTION__, rc);
 			return NULL;
 		}
 		/* request the 0x4000 external interrupt */
-		rc = register_external_interrupt (0x4000, top_half_interrupt);
+		rc = register_external_interrupt (0x4000, iucv_irq_handler);
 		if (rc) {
-			iucv_retrieve_buffer ();
-			kfree (new_handler->pathid_head);
+			iucv_remove_handler(new_handler);
+			iucv_retrieve_buffer();
 			kfree (new_handler);
-			printk (KERN_WARNING "iucv_register_program: rc from"
-				"register_external_interrupt is:% ld \n ", rc);
+			printk(KERN_WARNING "%s: "
+			       "register_external_interrupt returned %ld\n",
+			       __FUNCTION__, rc);
 			return NULL;
 
 		}
 		declare_flag = 1;
 	}
-	pr_debug ("iucv_register_program: exiting\n");
+	iucv_debug("exiting");
 	return new_handler;
 }				/* end of register function */
 
-/*
- * Name: iucv_unregister_program
- * Purpose: Unregister application with IUCV.
- * Input: handle address of handler
- * Output: NA
- * Return: (0) - Normal return
- *         (-EINVAL)- Matching handler was not found
-*/
+/**
+ * iucv_unregister_program:
+ * @handle: address of handler
+ *
+ * Unregister application with IUCV.
+ * Returns:
+ *   Always 0
+ */
 
 int
 iucv_unregister_program (iucv_handle_t handle)
 {
-	handler *users_handler = 0, *R;
-	handler_table_entry *H_T_E = 0;
-	ulong *S = 0;		/*points to the beginning of block of h_t_e's */
+	handler *h = (handler *)handle;
+	int i;
 	ulong flags;
-	u16 pathid_sever = 0;
-	pr_debug ("iucv_unregister_program: entering\n");
-	pr_debug ("iucv_unregister_program: address of handle is %p\n", handle);
-	spin_lock_irqsave (&iucv_lock, flags);
-	users_handler = (handler *) handle;
-	/* 
-	 * Checking if handle is still registered: if yes, continue
-	 *  if not registered, return.
+
+	iucv_debug("entering");
+	iucv_debug("address of handler is %p", h);
+
+	/**
+	 * First, walk thru iucv_pathid_table and sever any pathid which is
+	 * still pointing to the handler to be removed.
 	 */
-	for (R = handler_anchor; R != NULL; R = (handler *) R->next)
-		if (users_handler == R) {
-			pr_debug ("iucv_unregister_program: found a matching"
-				  "handler\n");
-			break;
-		}
-	if (!R) {
-		pr_debug ("You are not registered\n");
-		spin_unlock_irqrestore (&iucv_lock, flags);
-		return (0);
-	}
-	S = users_handler->pathid_head;
-	while (S < (users_handler->pathid_tail)) {	/* index thru table */
-		if (*S) {
-			H_T_E = (handler_table_entry *) (*S);
-
-			pr_debug ("iucv_unregister_program: pointer to H_T_E is"
-				  "%p\n", H_T_E);
-			pr_debug
-			    ("iucv_unregister_program: address of handle in"
-			     "H_T_E is %p", (H_T_E->addrs));
-			pathid_sever = H_T_E->pathid;
+	spin_lock_irqsave (&iucv_lock, flags);
+	for (i = 0; i < max_connections; i++)
+		if (iucv_pathid_table[i] == h) {
 			spin_unlock_irqrestore (&iucv_lock, flags);
-			iucv_sever (pathid_sever, users_handler->id.user_data);
-			spin_lock_irqsave (&iucv_lock, flags);
+			iucv_sever(i, h->id.user_data);
+			spin_lock_irqsave(&iucv_lock, flags);
 		}
+	spin_unlock_irqrestore (&iucv_lock, flags);
 
-		S++;		/* index by address */
-	}
+	iucv_remove_handler(h);
+	kfree(h);
 
-	kfree (users_handler->pathid_head);
-	iucv_remove_handler (users_handler);
-	spin_unlock_irqrestore (&iucv_lock, flags);
-	kfree (handle);
-	pr_debug ("iucv_unregister_program: exiting\n");
+	iucv_debug("exiting");
 	return 0;
 }
 
-/*
- * Name: iucv_accept
- * Purpose: This function is issued after the user receives a Connection Pending external
- *          interrupt and now wishes to complete the IUCV communication path.
- * Input:  pathid - u16 , path identification number   
- *         msglim_reqstd - u16, The number of outstanding messages requested.
- *         user_data - uchar[16], Data specified by the iucv_connect function.
- *	   flags1 - int, Contains options for this path.
- *           -IPPRTY - 0x20- Specifies if you want to send priority message.
- *           -IPRMDATA - 0x80, Specifies whether your program can handle a message
- *            	in  the parameter list.
- *           -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being
- *		established.
- *         handle - iucv_handle_t, Address of handler.
- *         pgm_data - ulong, Application data passed to interrupt handlers.
- *	   flags1_out - int *, Options for path.
- *           IPPRTY - 0x20 - Indicates you may send a priority message.
- *         priority_permitted -uchar *, Indicates you may send priority messages.
- *         msglim - *u16, Number of outstanding messages.
- * Output: b2f0_result - return code from CP
-*/
+/**
+ * iucv_accept:
+ * @pathid:             Path identification number
+ * @msglim_reqstd:      The number of outstanding messages requested.
+ * @user_data:          Data specified by the iucv_connect function.
+ * @flags1:             Contains options for this path.
+ *     - IPPRTY (0x20)   Specifies if you want to send priority message.
+ *     - IPRMDATA (0x80) Specifies whether your program can handle a message
+ *                       in the parameter list.
+ *     - IPQUSCE (0x40)  Specifies whether you want to quiesce the path being
+ *		         established.
+ * @handle:             Address of handler.
+ * @pgm_data:           Application data passed to interrupt handlers.
+ * @flags1_out:         Pointer to an int. If not NULL, on return the options for
+ *                      the path are stored at the given location:
+ *     - IPPRTY (0x20)  Indicates you may send a priority message.
+ * @msglim:             Pointer to an __u16. If not NULL, on return the maximum
+ *                      number of outstanding messages is stored at the given
+ *                      location.
+ *
+ * This function is issued after the user receives a Connection Pending external
+ * interrupt and now wishes to complete the IUCV communication path.
+ * Returns:
+ *   return code from CP
+ */
 int
-iucv_accept (u16 pathid, u16 msglim_reqstd,
-	     uchar user_data[16], int flags1,
+iucv_accept(__u16 pathid, __u16 msglim_reqstd,
+	     __u8 user_data[16], int flags1,
 	     iucv_handle_t handle, void *pgm_data,
-	     int *flags1_out, u16 * msglim)
+	     int *flags1_out, __u16 * msglim)
 {
-	iparml_control parm;
 	ulong b2f0_result = 0;
 	ulong flags;
-	handler *R = NULL;
-	pr_debug ("iucv_accept: entering \n");
-	pr_debug ("iucv_accept: pathid = %d\n", pathid);
+	struct list_head *lh;
+	handler *h = NULL;
+	iparml_control *parm;
+
+	iucv_debug("entering");
+	iucv_debug("pathid = %d", pathid);
 
 	/* Checking if handle is valid  */
 	spin_lock_irqsave (&iucv_lock, flags);
-
-	for (R = handler_anchor; R != NULL; R = (handler *) R->next)
-		if (R == handle)
+	list_for_each(lh, &iucv_handler_table) {
+		if ((handler *)handle == list_entry(lh, handler, list)) {
+			h = (handler *)handle;
 			break;
-
+		}
+	}
 	spin_unlock_irqrestore (&iucv_lock, flags);
-	if (R == NULL) {
-		printk (KERN_WARNING "iucv_connect: NULL handle passed by"
-			"application\n");
+
+	if (!h) {
+		printk(KERN_WARNING "%s: NULL handle passed by application "
+		       "or handler not found in iucv_handler_table\n",
+		       __FUNCTION__);
 		return -EINVAL;
 	}
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.ipmsglim = msglim_reqstd;
+	parm = (iparml_control *)grab_param();
+
+	parm->ippathid = pathid;
+	parm->ipmsglim = msglim_reqstd;
 	if (user_data)
-		memcpy (parm.ipuser, user_data, sizeof (parm.ipuser));
-	parm.ipflags1 = (uchar) flags1;
-	b2f0_result = b2f0 (ACCEPT, &parm);
+		memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));
+
+	parm->ipflags1 = (__u8)flags1;
+	b2f0_result = b2f0(ACCEPT, parm);
 
 	if (b2f0_result == 0) {
 		if (pgm_data)
-			(handler_table_anchor + pathid)->pgm_data = pgm_data;
-		if (parm.ipflags1 & IPPRTY)
-			if (flags1_out) {
-				pr_debug ("*flags1_out = %d\n", *flags1_out);
-				*flags1_out = 0;
-				*flags1_out |= IPPRTY;
-				pr_debug (" *flags1_out = %d\n", *flags1_out);
-			}
-	}
-
-	pr_debug ("iucv_accept: exiting\n");
+			h->pgm_data = pgm_data;
+		if (flags1_out)
+			*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;
+	}
+	release_param(parm);
+
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_connect                                         
- * Purpose: This function establishes an IUCV path. Although the connect may complete
- *	    successfully, you are not able to use the path until you receive an IUCV 
- *          Connection Complete external interrupt.            
- * Input: pathid - u16 *, path identification number          
- *        msglim_reqstd - u16, number of outstanding messages requested       
- *        user_data - uchar[16], 16-byte user data                    
- *        userid - uchar[8], 8-byte of user identification                        
- *        system_name - uchar[8], 8-byte identifying the system name 
- *        flags1 - int, Contains options for this path.
- *          -IPPRTY - 0x20- Specifies if you want to send priority message.
- *          -IPRMDATA - 0x80, Specifies whether your program can handle a message
- *               in  the parameter list.
- *          -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being
- *              established.
- *          -IPLOCAL - 0X01, allows an application to force the partner to be on the
- *              local system. If local is specified then target class cannot be
- *              specified.  
- *         flags1_out - int *, Options for path. 
- *           IPPRTY - 0x20 - Indicates you may send a priority message.
- *        msglim - * u16, number of outstanding messages
- *        handle - iucv_handle_t, address of handler                         
- *        pgm_data - *void, application data passed to interrupt handlers                  
- * Output: b2f0_result - return code from CP
- *         -ENOMEM
- *         rc - return code from iucv_declare_buffer
- *         -EINVAL - invalid handle passed by application 
- *         -EINVAL - pathid address is NULL 
- *	   -ENOMEM - pathid table storage allocation failed
- *         add_pathid_result - return code from internal function add_pathid             
-*/
-int
-iucv_connect (u16 * pathid, u16 msglim_reqstd,
-	      uchar user_data[16], uchar userid[8],
-	      uchar system_name[8], int flags1,
-	      int *flags1_out, u16 * msglim,
+/**
+ * iucv_connect:
+ * @pathid:        Path identification number
+ * @msglim_reqstd: Number of outstanding messages requested
+ * @user_data:     16-byte user data
+ * @userid:        8-byte of user identification
+ * @system_name:   8-byte identifying the system name
+ * @flags1:        Specifies options for this path:
+ *     - IPPRTY (0x20)   Specifies if you want to send priority message.
+ *     - IPRMDATA (0x80) Specifies whether your program can handle a message
+ *                       in  the parameter list.
+ *     - IPQUSCE (0x40)  Specifies whether you want to quiesce the path being
+ *                       established.
+ *     - IPLOCAL (0x01)  Allows an application to force the partner to be on the
+ *                       local system. If local is specified then target class
+ *                       cannot be specified.
+ * @flags1_out:    Pointer to an int. If not NULL, on return the options for
+ *                 the path are stored at the given location:
+ *     - IPPRTY (0x20)   Indicates you may send a priority message.
+ * @msglim:        Pointer to an __u16. If not NULL, on return the maximum
+ *                 number of outstanding messages is stored at the given
+ *                 location.
+ * @handle:        Address of handler.
+ * @pgm_data:      Application data to be passed to interrupt handlers.
+ *
+ * This function establishes an IUCV path. Although the connect may complete
+ * successfully, you are not able to use the path until you receive an IUCV
+ * Connection Complete external interrupt.
+ * Returns: return code from CP, or one of the following
+ *     - ENOMEM
+ *     - return code from iucv_declare_buffer
+ *     - EINVAL - invalid handle passed by application
+ *     - EINVAL - pathid address is NULL
+ *     - ENOMEM - pathid table storage allocation failed
+ *     - return code from internal function add_pathid
+ */
+int
+iucv_connect (__u16 *pathid, __u16 msglim_reqstd,
+	      __u8 user_data[16], __u8 userid[8],
+	      __u8 system_name[8], int flags1,
+	      int *flags1_out, __u16 * msglim,
 	      iucv_handle_t handle, void *pgm_data)
 {
-	iparml_control parm;
+	iparml_control *parm;
+	struct list_head *lh;
 	ulong b2f0_result = 0;
 	ulong flags;
 	int add_pathid_result = 0;
-	handler *R = NULL;
-	uchar no_memory[16] = "NO MEMORY";
+	handler *h = NULL;
+	__u8 no_memory[16] = "NO MEMORY";
 
-	pr_debug ("iucv_connect: entering \n");
+	iucv_debug("entering");
 
 	/* Checking if handle is valid  */
 	spin_lock_irqsave (&iucv_lock, flags);
-
-	for (R = handler_anchor; R != NULL; R = (handler *) R->next)
-		if (R == handle)
+	list_for_each(lh, &iucv_handler_table) {
+		if ((handler *)handle == list_entry(lh, handler, list)) {
+			h = (handler *)handle;
 			break;
-
+		}
+	}
 	spin_unlock_irqrestore (&iucv_lock, flags);
 
-	if (R == NULL) {
-		printk (KERN_WARNING "iucv_connect: NULL handle passed by"
-			"application\n");
+	if (!h) {
+		printk(KERN_WARNING "%s: NULL handle passed by application "
+		       "or handler not found in iucv_handler_table\n",
+		       __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if (pathid == NULL) {
-		printk (KERN_WARNING "iucv_connect: NULL pathid pointer\n");
+		printk(KERN_WARNING "%s: NULL pathid pointer\n",
+		       __FUNCTION__);
 		return -EINVAL;
 	}
-	memset (&parm, 0, sizeof (iparml_control));
-	parm.ipmsglim = msglim_reqstd;
+
+	parm = (iparml_control *)grab_param();
+
+	parm->ipmsglim = msglim_reqstd;
 
 	if (user_data)
-		memcpy (parm.ipuser, user_data, sizeof (parm.ipuser));
+		memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));
 
 	if (userid) {
-		memcpy (parm.ipvmid, userid, sizeof (parm.ipvmid));
-		ASCEBC (parm.ipvmid, sizeof (parm.ipvmid));
-		EBC_TOUPPER (parm.ipvmid, sizeof (parm.ipvmid));
+		memcpy(parm->ipvmid, userid, sizeof(parm->ipvmid));
+		ASCEBC(parm->ipvmid, sizeof(parm->ipvmid));
+		EBC_TOUPPER(parm->ipvmid, sizeof(parm->ipvmid));
 	}
 
 	if (system_name) {
-		memcpy (parm.iptarget, system_name, sizeof (parm.iptarget));
-		ASCEBC (parm.iptarget, sizeof (parm.iptarget));
-		EBC_TOUPPER (parm.iptarget, sizeof (parm.iptarget));
+		memcpy(parm->iptarget, system_name, sizeof(parm->iptarget));
+		ASCEBC(parm->iptarget, sizeof(parm->iptarget));
+		EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget));
 	}
 
-	parm.ipflags1 = (uchar) flags1;
-	b2f0_result = b2f0 (CONNECT, &parm);
-	if (b2f0_result)
-		return b2f0_result;
-
-	add_pathid_result = iucv_add_pathid (parm.ippathid, handle, pgm_data);
-	if (add_pathid_result) {
+	parm->ipflags1 = (__u8)flags1;
+	b2f0_result = b2f0(CONNECT, parm);
 
-		iucv_sever (parm.ippathid, no_memory);
-		printk (KERN_WARNING "iucv_connect: add_pathid failed with rc ="
-			"%d\n", add_pathid_result);
-		return (add_pathid_result);
+	if (b2f0_result) {
+		release_param(parm);
+		return b2f0_result;
 	}
 
-	*pathid = parm.ippathid;
+	add_pathid_result = iucv_add_pathid(parm->ippathid, h);
+	*pathid = parm->ippathid;
 
 	if (msglim)
-		*msglim = parm.ipmsglim;
+		*msglim = parm->ipmsglim;
+	if (flags1_out)
+		*flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0;
 
-	if (parm.ipflags1 & IPPRTY)
-		if (flags1_out) {
-			*flags1_out = 0;
-			*flags1_out |= IPPRTY;
-		}
+	if (add_pathid_result) {
+		iucv_sever(parm->ippathid, no_memory);
+		printk(KERN_WARNING "%s: add_pathid failed with rc ="
+			" %d\n", __FUNCTION__, add_pathid_result);
+		return(add_pathid_result);
+	}
 
-	pr_debug ("iucv_connect: exiting\n");
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_purge                                           
- * Purpose: Cancels a message you have sent.                   
- * Input: pathid -   address of pathid                                  
- *        msgid  -   address of message identification             
- *        srccls -   address of source message class                     
- *        audit  -  contains information about                              
- *                 asynchronous error that may have affected                           
- *                 the normal completion of this message.                  
- * Output:b2f0_result - return code from CP                   
-*/
+/**
+ * iucv_purge:
+ * @pathid: Path identification number
+ * @msgid:  Message ID of message to purge.
+ * @srccls: Message class of the message to purge.
+ * @audit:  Pointer to an __u32. If not NULL, on return, information about
+ *          asynchronous errors that may have affected the normal completion
+ *          of this message ist stored at the given location.
+ *
+ * Cancels a message you have sent.
+ * Returns: return code from CP
+ */
 int
-iucv_purge (u16 pathid, u32 msgid, u32 srccls, uchar audit[3])
+iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
 {
-	iparml_purge parm;
+	iparml_purge *parm;
 	ulong b2f0_result = 0;
-	pr_debug ("iucv_purge: entering\n");
-	pr_debug ("iucv_purge: pathid = %d \n", pathid);
-	memset (&parm, 0, sizeof (parm));
-	parm.ipmsgid = msgid;
-	parm.ippathid = pathid;
-	parm.ipsrccls = srccls;
-	parm.ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID);
-	b2f0_result = b2f0 (PURGE, &parm);
 
-	if ((b2f0_result == 0) && (audit))
-		memcpy (audit, parm.ipaudit, sizeof (parm.ipaudit));
+	iucv_debug("entering");
+	iucv_debug("pathid = %d", pathid);
 
-	pr_debug ("iucv_purge: b2f0_result = %ld \n", b2f0_result);
-	pr_debug ("iucv_purge: exiting\n");
-	return b2f0_result;
-}
+	parm = (iparml_purge *)grab_param();
 
-/*
- * Name: iucv_query_maxconn                                            
- * Purpose: Determines the maximum number of connections thay may be established.
- * Output: maxconn - ulong: Maximum number of connections that can be.     
-*/
-ulong
-iucv_query_maxconn (void)
-{
-	iparml_purge parm;	/* DOESN'T MATTER WHICH IPARML IS USED    */
-	static u32 maxconn1, bufsize1;
-
-	pr_debug ("iucv_query_maxconn: entering\n");
+	parm->ipmsgid = msgid;
+	parm->ippathid = pathid;
+	parm->ipsrccls = srccls;
+	parm->ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID);
+	b2f0_result = b2f0(PURGE, parm);
 
-	memset (&parm, 0, sizeof (parm));
+	if ((b2f0_result == 0) && audit) {
+		memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit));
+		/* parm->ipaudit has only 3 bytes */
+		*audit >>= 8;
+	}
+	
+	release_param(parm);
 
-	/* Assembler instruction calling b2f0  and storing R0 and R1 */
-	asm volatile ("LRA   1,0(%3)\n\t"
-		      "LR    0,%2\n\t"
-		      ".long 0xb2f01000\n\t"
-		      "ST    0,%0\n\t"
-		      "ST    1,%1\n\t":"=m" (bufsize1),
-		      "=m" (maxconn1):"d" (QUERY), "a" (&parm):"0", "1");
+	iucv_debug("b2f0_result = %ld", b2f0_result);
+	iucv_debug("exiting");
+	return b2f0_result;
+}
 
-	pr_debug (" bufsize1 = %d and maxconn1 = %d \n", bufsize1, maxconn1);
-	pr_debug ("iucv_query_maxconn: exiting\n");
+/**
+ * iucv_query_generic:
+ * @want_maxconn: Flag, describing which value is to be returned.
+ *
+ * Helper function for iucv_query_maxconn() and iucv_query_bufsize().
+ *
+ * Returns: The buffersize, if want_maxconn is 0; the maximum number of
+ *           connections, if want_maxconn is 1 or an error-code < 0 on failure.
+ */
+static int
+iucv_query_generic(int want_maxconn)
+{
+	iparml_purge *parm = (iparml_purge *)grab_param();
+	int bufsize, maxconn;
+	int ccode;
+
+	/**
+	 * Call b2f0 and store R0 (max buffer size),
+	 * R1 (max connections) and CC.
+	 */
+	asm volatile (
+		"LRA   1,0(%4)\n\t"
+		"LR    0,%3\n\t"
+		".long 0xb2f01000\n\t"
+		"IPM   %0\n\t"
+		"SRL   %0,28\n\t"
+		"ST    0,%1\n\t"
+		"ST    1,%2\n\t"
+		: "=d" (ccode), "=m" (bufsize), "=m" (maxconn)
+		: "d" (QUERY), "a" (parm)
+		: "0", "1", "cc"
+		);
+	release_param(parm);
+
+	if (ccode)
+		return -EPERM;
+	if (want_maxconn)
+		return maxconn;
+	return bufsize;
+}
 
-	return maxconn1;
+/**
+ * iucv_query_maxconn:
+ *
+ * Determines the maximum number of connections thay may be established.
+ *
+ * Returns: Maximum number of connections that can be.
+ */
+ulong
+iucv_query_maxconn(void)
+{
+	return iucv_query_generic(1);
 }
 
-/*
- * Name: iucv_query_bufsize
- * Purpose: Determines the size of the external interrupt buffer.
- * Output: bufsize - ulong: Size of external interrupt buffer.
+/**
+ * iucv_query_bufsize:
+ *
+ * Determines the size of the external interrupt buffer.
+ *
+ * Returns: Size of external interrupt buffer.
  */
 ulong
 iucv_query_bufsize (void)
 {
-	iparml_purge parm;	/* DOESN'T MATTER WHICH IPARML IS USED    */
-	static u32 maxconn1, bufsize1;
-
-	pr_debug ("iucv_query_bufsize: entering\n");
-	pr_debug ("iucv_query_maxconn: entering\n");
-
-	memset (&parm, 0, sizeof (parm));
-
-	/* Assembler instruction calling b2f0  and storing R0 and R1 */
-	asm volatile ("LRA   1,0(%3)\n\t"
-		      "LR    0,%2\n\t"
-		      ".long 0xb2f01000\n\t"
-		      "ST    0,%0\n\t"
-		      "ST    1,%1\n\t":"=m" (bufsize1),
-		      "=m" (maxconn1):"d" (QUERY), "a" (&parm):"0", "1");
-
-	pr_debug (" bufsize1 = %d and maxconn1 = %d \n", bufsize1, maxconn1);
-	pr_debug ("iucv_query_bufsize: exiting\n");
-
-	return bufsize1;
+	return iucv_query_generic(0);
 }
 
-/*
- * Name: iucv_quiesce                                         
- * Purpose: temporarily suspends incoming messages on an IUCV path.
- *          You can later reactivate the path by invoking the iucv_resume function        
- * Input: pathid - u16, path identification number                             
- *        user_data - uchar[16], 16-byte user data                      
- * Output: b2f0_result - return code from CP               
+/**
+ * iucv_quiesce:
+ * @pathid:    Path identification number
+ * @user_data: 16-byte user data
+ *
+ * Temporarily suspends incoming messages on an IUCV path.
+ * You can later reactivate the path by invoking the iucv_resume function.
+ * Returns: return code from CP
  */
 int
-iucv_quiesce (u16 pathid, uchar user_data[16])
+iucv_quiesce (__u16 pathid, __u8 user_data[16])
 {
-	iparml_control parm;
+	iparml_control *parm;
 	ulong b2f0_result = 0;
 
-	pr_debug ("iucv_quiesce: entering \n");
-	pr_debug ("iucv_quiesce: pathid = %d\n", pathid);
+	iucv_debug("entering");
+	iucv_debug("pathid = %d", pathid);
 
-	memset (&parm, 0, sizeof (parm));
-	memcpy (parm.ipuser, user_data, sizeof (parm.ipuser));
-	parm.ippathid = pathid;
+	parm = (iparml_control *)grab_param();
 
-	b2f0_result = b2f0 (QUIESCE, &parm);
+	memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));
+	parm->ippathid = pathid;
 
-	pr_debug ("iucv_quiesce: b2f0_result = %ld\n", b2f0_result);
-	pr_debug ("iucv_quiesce: exiting\n");
+	b2f0_result = b2f0(QUIESCE, parm);
+	release_param(parm);
+
+	iucv_debug("b2f0_result = %ld", b2f0_result);
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_receive
- * Purpose: This function receives messages that are being sent to you
- *          over established paths. 
- * Input:
- *        pathid - path identification number
- *        buffer - address of buffer to receive
- *        buflen - length of buffer to receive
- *        msgid - specifies the message ID.
- *        trgcls - specifies target class
- * Output:
- *	 flags1_out: Options for path.
- *         IPNORPY - 0x10 specifies whether a reply is required
- *         IPPRTY - 0x20 specifies if you want to send priority message
- *         IPRMDATA - 0x80 specifies the data is contained in the parameter list
- *       residual_buffer - address of buffer updated by the number
- *                         of bytes you have received.
- *       residual_length - 
- *		Contains one of the following values, if the receive buffer is:
- *		 The same length as the message, this field is zero.
- *		 Longer than the message, this field contains the number of
- *		  bytes remaining in the buffer.
- *		 Shorter than the message, this field contains the residual
- *		  count (that is, the number of bytes remaining in the
- *		  message that does not fit into the buffer. In this
- *		  case b2f0_result = 5. 
- * Return: b2f0_result - return code from CP IUCV call.
- *         (-EINVAL) - buffer address is pointing to NULL
+/**
+ * iucv_receive:
+ * @pathid: Path identification number.
+ * @buffer: Address of buffer to receive. Must be below 2G.
+ * @buflen: Length of buffer to receive.
+ * @msgid:  Specifies the message ID.
+ * @trgcls: Specifies target class.
+ * @flags1_out: Receives options for path on return.
+ *    - IPNORPY (0x10)  Specifies whether a reply is required
+ *    - IPPRTY (0x20)   Specifies if you want to send priority message
+ *    - IPRMDATA (0x80) Specifies the data is contained in the parameter list
+ * @residual_buffer: Receives the address of buffer updated by the number
+ *                   of bytes you have received on return.
+ * @residual_length: On return, receives one of the following values:
+ *    - 0                          If the receive buffer is the same length as
+ *                                 the message.
+ *    - Remaining bytes in buffer  If the receive buffer is longer than the
+ *                                 message.
+ *    - Remaining bytes in message If the receive buffer is shorter than the
+ *                                 message.
+ *
+ * This function receives messages that are being sent to you over established
+ * paths.
+ * Returns: return code from CP IUCV call; If the receive buffer is shorter
+ *   than the message, always 5
+ *   -EINVAL - buffer address is pointing to NULL
  */
 int
-iucv_receive (u16 pathid, u32 msgid, u32 trgcls,
+iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls,
 	      void *buffer, ulong buflen,
 	      int *flags1_out, ulong * residual_buffer, ulong * residual_length)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
-	int moved = 0;		/* number of bytes moved from parmlist to buffer */
-	pr_debug ("iucv_receive: entering\n");
+	int moved = 0;	/* number of bytes moved from parmlist to buffer */
+
+	iucv_debug("entering");
 
 	if (!buffer)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ipbfadr1 = (u32) buffer;
-	parm.ipbfln1f = (u32) ((ulong) buflen);
-	parm.ipmsgid = msgid;
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipflags1 = (IPFGPID | IPFGMID | IPFGMCL);
+	parm = (iparml_db *)grab_param();
 
-	b2f0_result = b2f0 (RECEIVE, &parm);
+	parm->ipbfadr1 = (__u32) buffer;
+	parm->ipbfln1f = (__u32) ((ulong) buflen);
+	parm->ipmsgid = msgid;
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipflags1 = (IPFGPID | IPFGMID | IPFGMCL);
+
+	b2f0_result = b2f0(RECEIVE, parm);
 
 	if (b2f0_result == 0 || b2f0_result == 5) {
 		if (flags1_out) {
-			pr_debug ("*flags1_out = %d\n", *flags1_out);
-			*flags1_out = (parm.ipflags1 & (~0x07));
-			pr_debug ("*flags1_out = %d\n", *flags1_out);
+			iucv_debug("*flags1_out = %d", *flags1_out);
+			*flags1_out = (parm->ipflags1 & (~0x07));
+			iucv_debug("*flags1_out = %d", *flags1_out);
 		}
 
-		if (!(parm.ipflags1 & IPRMDATA)) {	/*msg not in parmlist */
+		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */
 			if (residual_length)
-				*residual_length = parm.ipbfln1f;
+				*residual_length = parm->ipbfln1f;
 
 			if (residual_buffer)
-				*residual_buffer = parm.ipbfadr1;
+				*residual_buffer = parm->ipbfadr1;
 		} else {
-			moved = min_t(unsigned int, buflen, 8);
+			moved = min (buflen, 8);
 
 			memcpy ((char *) buffer,
-				(char *) &parm.ipbfadr1, moved);
+				(char *) &parm->ipbfadr1, moved);
 
 			if (buflen < 8)
 				b2f0_result = 5;
@@ -1324,14 +1201,16 @@
 				*residual_buffer = (ulong) (buffer + moved);
 		}
 	}
-	pr_debug ("iucv_receive: exiting \n");
+	release_param(parm);
+
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
 /*
  * Name: iucv_receive_array
  * Purpose: This function receives messages that are being sent to you
- *          over established paths. 
+ *          over established paths.
  * Input: pathid - path identification number
  *        buffer - address of array of buffers
  *        buflen - total length of buffers
@@ -1357,64 +1236,65 @@
  *         (-EINVAL) - buffer address is NULL
  */
 int
-iucv_receive_array (u16 pathid,
-		    u32 msgid, u32 trgcls,
+iucv_receive_array (__u16 pathid,
+		    __u32 msgid, __u32 trgcls,
 		    iucv_array_t * buffer, ulong buflen,
 		    int *flags1_out,
 		    ulong * residual_buffer, ulong * residual_length)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
 	int i = 0, moved = 0, need_to_move = 8, dyn_len;
-	pr_debug ("iucv_receive_array: entering\n");
+
+	iucv_debug("entering");
 
 	if (!buffer)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ipbfadr1 = (u32) ((ulong) buffer);
-	parm.ipbfln1f = (u32) buflen;
-	parm.ipmsgid = msgid;
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL);
+	parm = (iparml_db *)grab_param();
+
+	parm->ipbfadr1 = (__u32) ((ulong) buffer);
+	parm->ipbfln1f = (__u32) buflen;
+	parm->ipmsgid = msgid;
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL);
 
-	b2f0_result = b2f0 (RECEIVE, &parm);
+	b2f0_result = b2f0(RECEIVE, parm);
 
 	if (b2f0_result == 0 || b2f0_result == 5) {
 
 		if (flags1_out) {
-			pr_debug ("*flags1_out = %d\n", *flags1_out);
-			*flags1_out = (parm.ipflags1 & (~0x07));
-			pr_debug ("*flags1_out = %d\n", *flags1_out);
+			iucv_debug("*flags1_out = %d", *flags1_out);
+			*flags1_out = (parm->ipflags1 & (~0x07));
+			iucv_debug("*flags1_out = %d", *flags1_out);
 		}
 
-		if (!(parm.ipflags1 & IPRMDATA)) {	/*msg not in parmlist */
+		if (!(parm->ipflags1 & IPRMDATA)) {	/*msg not in parmlist */
 
 			if (residual_length)
-				*residual_length = parm.ipbfln1f;
+				*residual_length = parm->ipbfln1f;
 
 			if (residual_buffer)
-				*residual_buffer = parm.ipbfadr1;
+				*residual_buffer = parm->ipbfadr1;
 
 		} else {
 			/* copy msg from parmlist to users array. */
 
 			while ((moved < 8) && (moved < buflen)) {
 				dyn_len =
-				    min_t(unsigned int,
-					(buffer + i)->length, need_to_move);
+				    min ((buffer + i)->length, need_to_move);
 
 				memcpy ((char *)((ulong)((buffer + i)->address)),
-					((char *) &parm.ipbfadr1) + moved,
+					((char *) &parm->ipbfadr1) + moved,
 					dyn_len);
 
 				moved += dyn_len;
 				need_to_move -= dyn_len;
 
 				(buffer + i)->address =
-				    	(u32)  
-				((ulong)(uchar *) ((ulong)(buffer + i)->address) 
+				    	(__u32)
+				((ulong)(__u8 *) ((ulong)(buffer + i)->address)
 						+ dyn_len);
 
 				(buffer + i)->length -= dyn_len;
@@ -1437,52 +1317,55 @@
 
 		}
 	}
+	release_param(parm);
 
-	pr_debug ("iucv_receive_array: exiting\n");
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_reject                                          
- * Purpose: Refuses a specified message. Between the time you are notified of a 
- *          message and the time that you complete the message, the message may
- *          be rejected.                                 
- * Input: pathid - u16, path identification number.                            
- *        msgid  - u32, specifies the message ID.
- *        trgcls - u32, specifies target class.                
- * Output: b2f0_result - return code from CP
- * NOTE: see b2f0 output list                                 
-*/
+/**
+ * iucv_reject:
+ * @pathid: Path identification number.
+ * @msgid:  Message ID of the message to reject.
+ * @trgcls: Target class of the message to reject.
+ * Returns: return code from CP
+ *
+ * Refuses a specified message. Between the time you are notified of a
+ * message and the time that you complete the message, the message may
+ * be rejected.
+ */
 int
-iucv_reject (u16 pathid, u32 msgid, u32 trgcls)
+iucv_reject (__u16 pathid, __u32 msgid, __u32 trgcls)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result = 0;
 
-	pr_debug ("iucv_reject: entering \n");
-	pr_debug ("iucv_reject: pathid = %d\n", pathid);
+	iucv_debug("entering");
+	iucv_debug("pathid = %d", pathid);
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.ipmsgid = msgid;
-	parm.iptrgcls = trgcls;
-	parm.ipflags1 = (IPFGMCL | IPFGMID | IPFGPID);
+	parm = (iparml_db *)grab_param();
 
-	b2f0_result = b2f0 (REJECT, &parm);
+	parm->ippathid = pathid;
+	parm->ipmsgid = msgid;
+	parm->iptrgcls = trgcls;
+	parm->ipflags1 = (IPFGMCL | IPFGMID | IPFGPID);
 
-	pr_debug ("iucv_reject: b2f0_result = %ld\n", b2f0_result);
-	pr_debug ("iucv_reject: exiting\n");
+	b2f0_result = b2f0(REJECT, parm);
+	release_param(parm);
+
+	iucv_debug("b2f0_result = %ld", b2f0_result);
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
 
-/* 
+/*
  * Name: iucv_reply
  * Purpose: This function responds to the two-way messages that you
  *          receive. You must identify completely the message to
  *          which you wish to reply. ie, pathid, msgid, and trgcls.
  * Input: pathid - path identification number
- *        msgid - specifies the message ID. 
+ *        msgid - specifies the message ID.
  *        trgcls - specifies target class
  *        flags1 - option for path
  *                 IPPRTY- 0x20 - specifies if you want to send priority message
@@ -1503,37 +1386,39 @@
  *         (-EINVAL) - buffer address is NULL
  */
 int
-iucv_reply (u16 pathid,
-	    u32 msgid, u32 trgcls,
+iucv_reply (__u16 pathid,
+	    __u32 msgid, __u32 trgcls,
 	    int flags1,
 	    void *buffer, ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_reply: entering\n");
+	iucv_debug("entering");
 
 	if (!buffer)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ipbfadr2 = (u32) ((ulong) buffer);
-	parm.ipbfln2f = (u32) buflen;	/* length of message */
-	parm.ippathid = pathid;
-	parm.ipmsgid = msgid;
-	parm.iptrgcls = trgcls;
-	parm.ipflags1 = (uchar) flags1;	/* priority message */
+	parm = (iparml_db *)grab_param();
 
-	b2f0_result = b2f0 (REPLY, &parm);
+	parm->ipbfadr2 = (__u32) ((ulong) buffer);
+	parm->ipbfln2f = (__u32) buflen;	/* length of message */
+	parm->ippathid = pathid;
+	parm->ipmsgid = msgid;
+	parm->iptrgcls = trgcls;
+	parm->ipflags1 = (__u8) flags1;	/* priority message */
+
+	b2f0_result = b2f0(REPLY, parm);
 
 	if ((b2f0_result == 0) || (b2f0_result == 5)) {
 		if (ipbfadr2)
-			*ipbfadr2 = parm.ipbfadr2;
+			*ipbfadr2 = parm->ipbfadr2;
 		if (ipbfln2f)
-			*ipbfln2f = parm.ipbfln2f;
+			*ipbfln2f = parm->ipbfln2f;
 	}
+	release_param(parm);
 
-	pr_debug ("iucv_reply: exiting\n");
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
@@ -1541,13 +1426,13 @@
 /*
  * Name: iucv_reply_array
  * Purpose: This function responds to the two-way messages that you
- *          receive. You must identify completely the message to   
+ *          receive. You must identify completely the message to
  *          which you wish to reply. ie, pathid, msgid, and trgcls.
  *          The array identifies a list of addresses and lengths of
  *          discontiguous buffers that contains the reply data.
  * Input: pathid - path identification number
- *        msgid - specifies the message ID. 
- *        trgcls - specifies target class 
+ *        msgid - specifies the message ID.
+ *        trgcls - specifies target class
  *        flags1 - option for path
  *                 IPPRTY- specifies if you want to send priority message
  *        buffer - address of array of reply buffers
@@ -1566,39 +1451,41 @@
  *             (-EINVAL) - buffer address is NULL
 */
 int
-iucv_reply_array (u16 pathid,
-		  u32 msgid, u32 trgcls,
+iucv_reply_array (__u16 pathid,
+		  __u32 msgid, __u32 trgcls,
 		  int flags1,
 		  iucv_array_t * buffer,
 		  ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_reply_array: entering\n");
+	iucv_debug("entering");
 
 	if (!buffer)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ipbfadr2 = (u32) ((ulong) buffer);
-	parm.ipbfln2f = buflen;	/* length of message */
-	parm.ippathid = pathid;
-	parm.ipmsgid = msgid;
-	parm.iptrgcls = trgcls;
-	parm.ipflags1 = (IPANSLST | flags1);
+	parm = (iparml_db *)grab_param();
 
-	b2f0_result = b2f0 (REPLY, &parm);
+	parm->ipbfadr2 = (__u32) ((ulong) buffer);
+	parm->ipbfln2f = buflen;	/* length of message */
+	parm->ippathid = pathid;
+	parm->ipmsgid = msgid;
+	parm->iptrgcls = trgcls;
+	parm->ipflags1 = (IPANSLST | flags1);
+
+	b2f0_result = b2f0(REPLY, parm);
 
 	if ((b2f0_result == 0) || (b2f0_result == 5)) {
 
 		if (ipbfadr2)
-			*ipbfadr2 = parm.ipbfadr2;
+			*ipbfadr2 = parm->ipbfadr2;
 		if (ipbfln2f)
-			*ipbfln2f = parm.ipbfln2f;
+			*ipbfln2f = parm->ipbfln2f;
 	}
+	release_param(parm);
 
-	pr_debug ("iucv_reply_array: exiting\n");
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
@@ -1611,7 +1498,7 @@
  *          Prmmsg signifies the data is moved into the
  *          parameter list.
  * Input: pathid - path identification number
- *        msgid - specifies the message ID. 
+ *        msgid - specifies the message ID.
  *        trgcls - specifies target class
  *        flags1 - option for path
  *                 IPPRTY- specifies if you want to send priority message
@@ -1621,98 +1508,105 @@
  * Return: b2f0_result - return code from CP
 */
 int
-iucv_reply_prmmsg (u16 pathid,
-		   u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8])
+iucv_reply_prmmsg (__u16 pathid,
+		   __u32 msgid, __u32 trgcls, int flags1, __u8 prmmsg[8])
 {
-	iparml_dpl parm;
+	iparml_dpl *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_reply_prmmsg: entering\n");
+	iucv_debug("entering");
+
+	parm = (iparml_dpl *)grab_param();
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.ipmsgid = msgid;
-	parm.iptrgcls = trgcls;
-	memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg));
-	parm.ipflags1 = (IPRMDATA | flags1);
+	parm->ippathid = pathid;
+	parm->ipmsgid = msgid;
+	parm->iptrgcls = trgcls;
+	memcpy(parm->iprmmsg, prmmsg, sizeof (parm->iprmmsg));
+	parm->ipflags1 = (IPRMDATA | flags1);
 
-	b2f0_result = b2f0 (REPLY, &parm);
+	b2f0_result = b2f0(REPLY, parm);
+	release_param(parm);
 
-	pr_debug ("iucv_reply_prmmsg: exiting\n");
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_resume                                          
- * Purpose: This function restores communication over a quiesced path.       
- * Input: pathid - u16, path identification number                             
- *        user_data - uchar[16], 16-byte of user data                     
- * Output: b2f0_result - return code from CP               
+/**
+ * iucv_resume:
+ * @pathid:    Path identification number
+ * @user_data: 16-byte of user data
+ *
+ * This function restores communication over a quiesced path.
+ * Returns: return code from CP
  */
 int
-iucv_resume (u16 pathid, uchar user_data[16])
+iucv_resume (__u16 pathid, __u8 user_data[16])
 {
-	iparml_control parm;
+	iparml_control *parm;
 	ulong b2f0_result = 0;
 
-	pr_debug ("iucv_resume: entering\n");
-	pr_debug ("iucv_resume: pathid = %d\n", pathid);
+	iucv_debug("entering");
+	iucv_debug("pathid = %d", pathid);
+
+	parm = (iparml_control *)grab_param();
 
-	memset (&parm, 0, sizeof (parm));
-	memcpy (parm.ipuser, user_data, sizeof (*user_data));
-	parm.ippathid = pathid;
+	memcpy (parm->ipuser, user_data, sizeof (*user_data));
+	parm->ippathid = pathid;
 
-	b2f0_result = b2f0 (RESUME, &parm);
+	b2f0_result = b2f0(RESUME, parm);
+	release_param(parm);
 
-	pr_debug ("iucv_resume: exiting \n");
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
 
 /*
- * Name: iucv_send                                             
- * Purpose: sends messages                                    
- * Input: pathid - ushort, pathid                            
- *        msgid  - ulong *, id of message returned to caller   
- *        trgcls - ulong, target message class              
- *        srccls - ulong, source message class              
- *        msgtag - ulong, message tag                    
+ * Name: iucv_send
+ * Purpose: sends messages
+ * Input: pathid - ushort, pathid
+ *        msgid  - ulong *, id of message returned to caller
+ *        trgcls - ulong, target message class
+ *        srccls - ulong, source message class
+ *        msgtag - ulong, message tag
  *	  flags1  - Contains options for this path.
  *		IPPRTY - Ox20 - specifies if you want to send a priority message.
- *        buffer - pointer to buffer                           
- *        buflen - ulong, length of buffer                     
- * Output: b2f0_result - return code from b2f0 call               
- *         msgid - returns message id                         
+ *        buffer - pointer to buffer
+ *        buflen - ulong, length of buffer
+ * Output: b2f0_result - return code from b2f0 call
+ *         msgid - returns message id
  */
 int
-iucv_send (u16 pathid, u32 * msgid,
-	   u32 trgcls, u32 srccls,
-	   u32 msgtag, int flags1, void *buffer, ulong buflen)
+iucv_send (__u16 pathid, __u32 * msgid,
+	   __u32 trgcls, __u32 srccls,
+	   __u32 msgtag, int flags1, void *buffer, ulong buflen)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_send: entering\n");
+	iucv_debug("entering");
 
 	if (!buffer)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ipbfadr1 = (u32) ((ulong) buffer);
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipbfln1f = (u32) buflen;	/* length of message */
-	parm.ipsrccls = srccls;
-	parm.ipmsgtag = msgtag;
-	parm.ipflags1 = (IPNORPY | flags1);	/* one way priority message */
+	parm = (iparml_db *)grab_param();
 
-	b2f0_result = b2f0 (SEND, &parm);
+	parm->ipbfadr1 = (__u32) ((ulong) buffer);
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipbfln1f = (__u32) buflen;	/* length of message */
+	parm->ipsrccls = srccls;
+	parm->ipmsgtag = msgtag;
+	parm->ipflags1 = (IPNORPY | flags1);	/* one way priority message */
+
+	b2f0_result = b2f0(SEND, parm);
 
 	if ((b2f0_result == 0) && (msgid))
-		*msgid = parm.ipmsgid;
+		*msgid = parm->ipmsgid;
+	release_param(parm);
 
-	pr_debug ("iucv_send: exiting\n");
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
@@ -1733,43 +1627,46 @@
  *        buffer - address of array of send buffers
  *        buflen - total length of send buffers
  * Output: msgid - specifies the message ID.
- * Return: b2f0_result - return code from CP 
+ * Return: b2f0_result - return code from CP
  *         (-EINVAL) - buffer address is NULL
  */
 int
-iucv_send_array (u16 pathid,
-		 u32 * msgid,
-		 u32 trgcls,
-		 u32 srccls,
-		 u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen)
+iucv_send_array (__u16 pathid,
+		 __u32 * msgid,
+		 __u32 trgcls,
+		 __u32 srccls,
+		 __u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_send_array: entering\n");
+	iucv_debug("entering");
 
 	if (!buffer)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipbfadr1 = (u32) ((ulong) buffer);
-	parm.ipbfln1f = (u32) buflen;	/* length of message */
-	parm.ipsrccls = srccls;
-	parm.ipmsgtag = msgtag;
-	parm.ipflags1 = (IPNORPY | IPBUFLST | flags1);
-	b2f0_result = b2f0 (SEND, &parm);
+	parm = (iparml_db *)grab_param();
+
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipbfadr1 = (__u32) ((ulong) buffer);
+	parm->ipbfln1f = (__u32) buflen;	/* length of message */
+	parm->ipsrccls = srccls;
+	parm->ipmsgtag = msgtag;
+	parm->ipflags1 = (IPNORPY | IPBUFLST | flags1);
+	b2f0_result = b2f0(SEND, parm);
 
 	if ((b2f0_result == 0) && (msgid))
-		*msgid = parm.ipmsgid;
-	pr_debug ("iucv_send_array: exiting\n");
+		*msgid = parm->ipmsgid;
+	release_param(parm);
+
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
 /*
  * Name: iucv_send_prmmsg
- * Purpose: This function transmits data to another application. 
+ * Purpose: This function transmits data to another application.
  *          Prmmsg specifies that the 8-bytes of data are to be moved
  *          into the parameter list. This is a one-way message and the
  *          receiver will not reply to the message.
@@ -1780,34 +1677,37 @@
  *        flags1 - option for path
  *                 IPPRTY- specifies if you want to send priority message
  *        prmmsg - 8-bytes of data to be placed into parameter list
- * Output: msgid - specifies the message ID.   
+ * Output: msgid - specifies the message ID.
  * Return: b2f0_result - return code from CP
 */
 int
-iucv_send_prmmsg (u16 pathid,
-		  u32 * msgid,
-		  u32 trgcls,
-		  u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8])
+iucv_send_prmmsg (__u16 pathid,
+		  __u32 * msgid,
+		  __u32 trgcls,
+		  __u32 srccls, __u32 msgtag, int flags1, __u8 prmmsg[8])
 {
-	iparml_dpl parm;
+	iparml_dpl *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_send_prmmsg: entering\n");
+	iucv_debug("entering");
+
+	parm = (iparml_dpl *)grab_param();
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipsrccls = srccls;
-	parm.ipmsgtag = msgtag;
-	parm.ipflags1 = (IPRMDATA | IPNORPY | flags1);
-	memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg));
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipsrccls = srccls;
+	parm->ipmsgtag = msgtag;
+	parm->ipflags1 = (IPRMDATA | IPNORPY | flags1);
+	memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg));
 
-	b2f0_result = b2f0 (SEND, &parm);
+	b2f0_result = b2f0(SEND, parm);
 
 	if ((b2f0_result == 0) && (msgid))
-		*msgid = parm.ipmsgid;
+		*msgid = parm->ipmsgid;
+	release_param(parm);
+
+	iucv_debug("exiting");
 
-	pr_debug ("iucv_send_prmmsg: exiting\n");
 	return b2f0_result;
 }
 
@@ -1816,7 +1716,7 @@
  * Purpose: This function transmits data to another application.
  *          Data to be transmitted is in a buffer. The receiver
  *          of the send is expected to reply to the message and
- *          a buffer is provided into which IUCV moves the reply 
+ *          a buffer is provided into which IUCV moves the reply
  *          to this message.
  * Input: pathid - path identification number
  *        trgcls - specifies target class
@@ -1833,38 +1733,41 @@
  *         (-EINVAL) - buffer or ansbuf address is NULL
  */
 int
-iucv_send2way (u16 pathid,
-	       u32 * msgid,
-	       u32 trgcls,
-	       u32 srccls,
-	       u32 msgtag,
+iucv_send2way (__u16 pathid,
+	       __u32 * msgid,
+	       __u32 trgcls,
+	       __u32 srccls,
+	       __u32 msgtag,
 	       int flags1,
 	       void *buffer, ulong buflen, void *ansbuf, ulong anslen)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
-	pr_debug ("iucv_send2way: entering\n");
+
+	iucv_debug("entering");
 
 	if (!buffer || !ansbuf)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipbfadr1 = (u32) ((ulong) buffer);
-	parm.ipbfln1f = (u32) buflen;	/* length of message */
-	parm.ipbfadr2 = (u32) ((ulong) ansbuf);
-	parm.ipbfln2f = (u32) anslen;
-	parm.ipsrccls = srccls;
-	parm.ipmsgtag = msgtag;
-	parm.ipflags1 = flags1;	/* priority message */
+	parm = (iparml_db *)grab_param();
+
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipbfadr1 = (__u32) ((ulong) buffer);
+	parm->ipbfln1f = (__u32) buflen;	/* length of message */
+	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
+	parm->ipbfln2f = (__u32) anslen;
+	parm->ipsrccls = srccls;
+	parm->ipmsgtag = msgtag;
+	parm->ipflags1 = flags1;	/* priority message */
 
-	b2f0_result = b2f0 (SEND, &parm);
+	b2f0_result = b2f0(SEND, parm);
 
 	if ((b2f0_result == 0) && (msgid))
-		*msgid = parm.ipmsgid;
+		*msgid = parm->ipmsgid;
+	release_param(parm);
 
-	pr_debug ("iucv_send2way: exiting\n");
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
@@ -1885,44 +1788,47 @@
  *                 IPPRTY- specifies if you want to send priority message
  *        buffer - address of array of send buffers
  *        buflen - total length of send buffers
- *        ansbuf - address of buffer to reply with                       
- *        anslen - length of buffer to reply with     
+ *        ansbuf - address of buffer to reply with
+ *        anslen - length of buffer to reply with
  * Output: msgid - specifies the message ID.
  * Return: b2f0_result - return code from CP
  *         (-EINVAL) - buffer address is NULL
  */
 int
-iucv_send2way_array (u16 pathid,
-		     u32 * msgid,
-		     u32 trgcls,
-		     u32 srccls,
-		     u32 msgtag,
+iucv_send2way_array (__u16 pathid,
+		     __u32 * msgid,
+		     __u32 trgcls,
+		     __u32 srccls,
+		     __u32 msgtag,
 		     int flags1,
 		     iucv_array_t * buffer,
 		     ulong buflen, iucv_array_t * ansbuf, ulong anslen)
 {
-	iparml_db parm;
+	iparml_db *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_send2way_array: entering\n");
+	iucv_debug("entering");
 
 	if (!buffer || !ansbuf)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipbfadr1 = (u32) ((ulong) buffer);
-	parm.ipbfln1f = (u32) buflen;	/* length of message */
-	parm.ipbfadr2 = (u32) ((ulong) ansbuf);
-	parm.ipbfln2f = (u32) anslen;
-	parm.ipsrccls = srccls;
-	parm.ipmsgtag = msgtag;
-	parm.ipflags1 = (IPBUFLST | IPANSLST | flags1);
-	b2f0_result = b2f0 (SEND, &parm);
+	parm = (iparml_db *)grab_param();
+
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipbfadr1 = (__u32) ((ulong) buffer);
+	parm->ipbfln1f = (__u32) buflen;	/* length of message */
+	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
+	parm->ipbfln2f = (__u32) anslen;
+	parm->ipsrccls = srccls;
+	parm->ipmsgtag = msgtag;
+	parm->ipflags1 = (IPBUFLST | IPANSLST | flags1);
+	b2f0_result = b2f0(SEND, parm);
 	if ((b2f0_result == 0) && (msgid))
-		*msgid = parm.ipmsgid;
-	pr_debug ("iucv_send2way_array: exiting\n");
+		*msgid = parm->ipmsgid;
+	release_param(parm);
+
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
@@ -1934,50 +1840,53 @@
  *          receiver of the message is expected to reply. A buffer
  *          is provided into which IUCV moves the reply to this
  *          message.
- * Input: pathid - path identification number  
+ * Input: pathid - path identification number
  *        trgcls - specifies target class
  *        srccls - specifies the source message class
  *        msgtag - specifies a tag to be associated with the message
  *        flags1 - option for path
  *                 IPPRTY- specifies if you want to send priority message
  *        prmmsg - 8-bytes of data to be placed in parameter list
- *        ansbuf - address of buffer to reply with                       
- *        anslen - length of buffer to reply with     
+ *        ansbuf - address of buffer to reply with
+ *        anslen - length of buffer to reply with
  * Output: msgid - specifies the message ID.
  * Return: b2f0_result - return code from CP
  *         (-EINVAL) - buffer address is NULL
 */
 int
-iucv_send2way_prmmsg (u16 pathid,
-		      u32 * msgid,
-		      u32 trgcls,
-		      u32 srccls,
-		      u32 msgtag,
-		      ulong flags1, uchar prmmsg[8], void *ansbuf, ulong anslen)
+iucv_send2way_prmmsg (__u16 pathid,
+		      __u32 * msgid,
+		      __u32 trgcls,
+		      __u32 srccls,
+		      __u32 msgtag,
+		      ulong flags1, __u8 prmmsg[8], void *ansbuf, ulong anslen)
 {
-	iparml_dpl parm;
+	iparml_dpl *parm;
 	ulong b2f0_result;
-	pr_debug ("iucv_send2way_prmmsg: entering\n");
+
+	iucv_debug("entering");
 
 	if (!ansbuf)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipsrccls = srccls;
-	parm.ipmsgtag = msgtag;
-	parm.ipbfadr2 = (u32) ((ulong) ansbuf);
-	parm.ipbfln2f = (u32) anslen;
-	parm.ipflags1 = (IPRMDATA | flags1);	/* message in prmlist */
-	memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg));
+	parm = (iparml_dpl *)grab_param();
 
-	b2f0_result = b2f0 (SEND, &parm);
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipsrccls = srccls;
+	parm->ipmsgtag = msgtag;
+	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
+	parm->ipbfln2f = (__u32) anslen;
+	parm->ipflags1 = (IPRMDATA | flags1);	/* message in prmlist */
+	memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg));
+
+	b2f0_result = b2f0(SEND, parm);
 
 	if ((b2f0_result == 0) && (msgid))
-		*msgid = parm.ipmsgid;
+		*msgid = parm->ipmsgid;
+	release_param(parm);
 
-	pr_debug ("iucv_send2way_prmmsg: exiting\n");
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
@@ -1994,54 +1903,57 @@
  *          that contain the reply.
  * Input: pathid - path identification number
  *        trgcls - specifies target class
- *        srccls - specifies the source message class   
+ *        srccls - specifies the source message class
  *        msgtag - specifies a tag to be associated with the message
  *        flags1 - option for path
  *                 IPPRTY- specifies if you want to send priority message
  *        prmmsg - 8-bytes of data to be placed into the parameter list
- *        ansbuf - address of buffer to reply with                       
- *        anslen - length of buffer to reply with     
+ *        ansbuf - address of buffer to reply with
+ *        anslen - length of buffer to reply with
  * Output: msgid - specifies the message ID.
  * Return: b2f0_result - return code from CP
  *         (-EINVAL) - ansbuf address is NULL
  */
 int
-iucv_send2way_prmmsg_array (u16 pathid,
-			    u32 * msgid,
-			    u32 trgcls,
-			    u32 srccls,
-			    u32 msgtag,
+iucv_send2way_prmmsg_array (__u16 pathid,
+			    __u32 * msgid,
+			    __u32 trgcls,
+			    __u32 srccls,
+			    __u32 msgtag,
 			    int flags1,
-			    uchar prmmsg[8],
+			    __u8 prmmsg[8],
 			    iucv_array_t * ansbuf, ulong anslen)
 {
-	iparml_dpl parm;
+	iparml_dpl *parm;
 	ulong b2f0_result;
 
-	pr_debug ("iucv_send2way_prmmsg_array: entering\n");
+	iucv_debug("entering");
 
 	if (!ansbuf)
 		return -EINVAL;
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ippathid = pathid;
-	parm.iptrgcls = trgcls;
-	parm.ipsrccls = srccls;
-	parm.ipmsgtag = msgtag;
-	parm.ipbfadr2 = (u32) ((ulong) ansbuf);
-	parm.ipbfln2f = (u32) anslen;
-	parm.ipflags1 = (IPRMDATA | IPANSLST | flags1);
-	memcpy (parm.iprmmsg, prmmsg, sizeof (parm.iprmmsg));
-	b2f0_result = b2f0 (SEND, &parm);
+	parm = (iparml_dpl *)grab_param();
+
+	parm->ippathid = pathid;
+	parm->iptrgcls = trgcls;
+	parm->ipsrccls = srccls;
+	parm->ipmsgtag = msgtag;
+	parm->ipbfadr2 = (__u32) ((ulong) ansbuf);
+	parm->ipbfln2f = (__u32) anslen;
+	parm->ipflags1 = (IPRMDATA | IPANSLST | flags1);
+	memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg));
+	b2f0_result = b2f0(SEND, parm);
 	if ((b2f0_result == 0) && (msgid))
-		*msgid = parm.ipmsgid;
-	pr_debug ("iucv_send2way_prmmsg_array: exiting\n");
+		*msgid = parm->ipmsgid;
+	release_param(parm);
+
+	iucv_debug("exiting");
 	return b2f0_result;
 }
 
 /*
  * Name: iucv_setmask
- * Purpose: This function enables or disables the following IUCV   
+ * Purpose: This function enables or disables the following IUCV
  *          external interruptions: Nonpriority and priority message
  *          interrupts, nonpriority and priority reply interrupts.
  * Input: SetMaskFlag - options for interrupts
@@ -2055,358 +1967,301 @@
 int
 iucv_setmask (int SetMaskFlag)
 {
-	iparml_set_mask parm;
+	iparml_set_mask *parm;
 	ulong b2f0_result = 0;
-	pr_debug ("iucv_setmask: entering \n");
 
-	memset (&parm, 0, sizeof (parm));
-	parm.ipmask = (uchar) SetMaskFlag;
+	iucv_debug("entering");
+
+	parm = (iparml_set_mask *)grab_param();
 
-	b2f0_result = b2f0 (SETMASK, &parm);
+	parm->ipmask = (__u8)SetMaskFlag;
 
-	pr_debug ("iucv_setmask: b2f0_result = %ld\n", b2f0_result);
-	pr_debug ("iucv_setmask: exiting\n");
+	b2f0_result = b2f0(SETMASK, parm);
+	release_param(parm);
+
+	iucv_debug("b2f0_result = %ld", b2f0_result);
+	iucv_debug("exiting");
 
 	return b2f0_result;
 }
 
-/*
- * Name: iucv_sever                                           
- * Purpose: This function terminates an iucv path         
- * Input: pathid - u16, path identification number                             
- *        user_data - uchar[16], 16-byte of user data                     
- * Output: b2f0_result - return code from CP          
- *         -EINVAL - NULL address found for handler                                 
+/**
+ * iucv_sever:
+ * @pathid:    Path identification number
+ * @user_data: 16-byte of user data
+ *
+ * This function terminates an iucv path.
+ * Returns: return code from CP
  */
 int
-iucv_sever (u16 pathid, uchar user_data[16])
+iucv_sever(__u16 pathid, __u8 user_data[16])
 {
-	iparml_control parm;
+	iparml_control *parm;
 	ulong b2f0_result = 0;
-	pr_debug ("iucv_sever: entering\n");
-	memset (&parm, 0, sizeof (parm));
-	memcpy (parm.ipuser, user_data, sizeof (parm.ipuser));
-	parm.ippathid = pathid;
 
-	b2f0_result = b2f0 (SEVER, &parm);
+	iucv_debug("entering");
+	parm = (iparml_control *)grab_param();
 
-	if (!b2f0_result)
-		iucv_remove_pathid (pathid);
+	memcpy(parm->ipuser, user_data, sizeof(parm->ipuser));
+	parm->ippathid = pathid;
 
-	pr_debug ("iucv_sever: exiting \n");
-	return b2f0_result;
-}
+	b2f0_result = b2f0(SEVER, parm);
 
-static void
-iucv_remove_pathid (u16 pathid)
-{
-	handler_table_entry *users_hte = NULL;	/*users handler_table_entry */
-	handler *users_handler = NULL;
-	ulong *users_pathid = NULL;
-	ulong flags;
-	spin_lock_irqsave (&iucv_lock, flags);
-	users_hte = handler_table_anchor + (int) pathid;
-
-	if ((users_hte->addrs) == NULL) {
-		spin_unlock_irqrestore (&iucv_lock, flags);
-		return;		/* wild pointer has been found */
-	}
-
-	users_handler = users_hte->addrs;
-
-	pr_debug ("iucv_sever: pathid is %d\n", pathid);
-	pr_debug ("iucv_sever: H_T_E is %p\n", users_hte);
-	pr_debug ("iucv_sever: address of handler is %p\n", users_handler);
-	pr_debug ("iucv_sever: below is pathid table\n");
-	iucv_dumpit ((uchar *) users_handler->pathid_head,
-		     (int) users_handler->entries * sizeof (ulong));
-
-/*
- * Searching the pathid address table for matching address, once    
- * found, NULL the handler_table_entry field and then zero the H_T_E fields.               
- */
-
-	for (users_pathid = (users_handler->pathid_head);
-	     users_pathid < (users_handler->pathid_tail); users_pathid++)
-
-		if (*users_pathid == (ulong) users_hte) {
-			pr_debug ("iucv_sever: found a path to remove from"
-				  "table\n");
-			pr_debug ("iucv_sever: removing %d \n",
-				  (int) (*users_pathid)); *users_pathid = NULL;
+	if (!b2f0_result)
+		iucv_remove_pathid(pathid);
+	release_param(parm);
 
-			memset (users_hte, 0, sizeof (handler_table_entry));
-		}
-	spin_unlock_irqrestore (&iucv_lock, flags);
-	return;
+	iucv_debug("exiting");
+	return b2f0_result;
 }
 
 /*
- * Interrupt Handling Functions
- * 	top_half_interrupt
- * 	bottom_half_interrupt
- * 	do_int
- */
+ * Interrupt Handlers
+ *******************************************************************************/
 
-/*
- * Name: top_half_interrupt                                         
- * Purpose: Handles interrupts coming in from CP.  Places the interrupt on a queue and  
- * 	    calls bottom_half_interrupt          
- * Input: external interrupt buffer                                
- * Output: void                                                    
+/**
+ * iucv_irq_handler:
+ * @regs: Current registers
+ * @code: irq code
+ *
+ * Handles external interrupts coming in from CP.
+ * Places the interrupt buffer on a queue and schedules iucv_bh_handler().
  */
-
-inline void
-top_half_interrupt (struct pt_regs *regs, __u16 code)
+static void
+iucv_irq_handler(struct pt_regs *regs, __u16 code)
 {
-	iucv_packet *pkt;
-	int cpu = smp_processor_id();
+	iucv_irqdata *irqdata;
+	int          cpu = smp_processor_id();
 
 	irq_enter(cpu, 0x4000);
 
-	pkt = (iucv_packet *) kmalloc (sizeof (iucv_packet), GFP_ATOMIC);
-	if (pkt == NULL) {
-		printk (KERN_WARNING
-			"iucv:top_half_interrupt: out of memory\n");
+	irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC);
+	if (!irqdata) {
+		printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
 		irq_exit(cpu, 0x4000);
 		return;
 	}
 
-	memcpy (pkt->data, iucv_external_int_buffer, BUFFER_SIZE);
-
-	pr_debug ("TH: Got INT: %08x\n", *(int *) (pkt->data + 4));
+	memcpy(&irqdata->data, iucv_external_int_buffer,
+	       sizeof(iucv_GeneralInterrupt));
 
-	/* put new packet on the list */
-	spin_lock (&iucv_packets_lock);
-	pkt->next = NULL;
-
-	if (iucv_packets_tail != NULL)
-		iucv_packets_tail->next = pkt;
-	else
-		iucv_packets_head = pkt;
-
-	iucv_packets_tail = pkt;
-	spin_unlock (&iucv_packets_lock);
-
-	if (atomic_compare_and_swap (0, 1, &bh_scheduled) == 0) {
-		short_task.routine = (void *) bottom_half_interrupt;
-		queue_task (&short_task, &tq_immediate);
-		mark_bh (IMMEDIATE_BH);
+	spin_lock(&iucv_irq_queue_lock);
+	list_add_tail(&irqdata->queue, &iucv_irq_queue);
+	spin_unlock(&iucv_irq_queue_lock);
+
+	if (atomic_compare_and_swap (0, 1, &iucv_bh_scheduled) == 0) {
+		queue_task (&iucv_tq, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
 	}
-	irq_exit(cpu, 0x4000);
-	return;
-}
 
-/*
- * Name: bottom_half_interrupt                                      
- * Purpose: Handle interrupt at a more safer time                  
- * Input: void                                                     
- * Output: void                                                    
- */
-void
-bottom_half_interrupt (void)
-{
-	iucv_packet *iucv_packet_list;
-	iucv_packet *tmp;
-	ulong flags;
-	atomic_set (&bh_scheduled, 0);
-
-	spin_lock_irqsave (&iucv_packets_lock, flags);
-	iucv_packet_list = iucv_packets_head;
-	iucv_packets_head = iucv_packets_tail = NULL;
-	spin_unlock_irqrestore (&iucv_packets_lock, flags);
-
-	/* now process all the request in the iucv_packet_list */
-	pr_debug ("BH: Process all packets\n");
-	while (iucv_packet_list != NULL) {
-		pr_debug ("BH:>  %08x\n",
-			  *(int *) (iucv_packet_list->data + 4));
-
-		do_int ((iucv_GeneralInterrupt *) iucv_packet_list->data);
-
-		pr_debug ("BH:<  %08x\n",
-			  *(int *) (iucv_packet_list->data + 4));
-		tmp = iucv_packet_list;
-		iucv_packet_list = iucv_packet_list->next;
-		kfree (tmp);
-	}
-	pr_debug ("BH: Done\n");
+	irq_exit(cpu, 0x4000);
 	return;
 }
 
-/*
- * Name: do_int                                                     
- * Purpose: Handles the interrupts in a more safe environment             
- * Input: int_buf - pointer to copy of external interrupt buffer  
- * Output: void                                                     
+/**
+ * iucv_do_int:
+ * @int_buf: Pointer to copy of external interrupt buffer
+ *
+ * The workhorse for handling interrupts queued by iucv_irq_handler().
+ * This function is called from the bottom half iucv_bh_handler().
  */
-void
-do_int (iucv_GeneralInterrupt * int_buf)
+static void
+iucv_do_int(iucv_GeneralInterrupt * int_buf)
 {
-	handler_table_entry *P = 0;
+	handler *h = NULL;
+	struct list_head *lh;
 	ulong flags;
-	handler *Q = 0, *R;
-	iucv_interrupt_ops_t *interrupt = 0;	/* interrupt addresses */
-	uchar temp_buff1[24], temp_buff2[24];	/* masked handler id. */
-	int add_pathid_result = 0, j = 0;
-	uchar no_listener[16] = "NO LISTENER";
-
-	pr_debug ("IUCV: BHI: -  Entered do_int "
-		  "pathid %d, type %02X\n", int_buf->ippathid, int_buf->iptype);
-	pr_debug ("BHI:External Interrupt Buffer\n");
-	iucv_dumpit ((uchar *) int_buf, sizeof (iucv_GeneralInterrupt));
+	iucv_interrupt_ops_t *interrupt = NULL;	/* interrupt addresses */
+	__u8 temp_buff1[24], temp_buff2[24];	/* masked handler id. */
+	int rc = 0, j = 0;
+	__u8 no_listener[16] = "NO LISTENER";
+
+	iucv_debug("entering, pathid %d, type %02X",
+		 int_buf->ippathid, int_buf->iptype);
+	iucv_debug("External Interrupt Buffer:");
+	iucv_dumpit(int_buf, sizeof(iucv_GeneralInterrupt));
 
 	ASCEBC (no_listener, 16);
+
 	if (int_buf->iptype != 01) {
-		spin_lock_irqsave (&iucv_lock, flags);
-		P = handler_table_anchor + int_buf->ippathid;
-		Q = P->addrs;
-		interrupt = P->ops;	/* interrupt functions */
+		if ((int_buf->ippathid) > (max_connections - 1)) {
+			printk(KERN_WARNING "%s: Got interrupt with pathid %d"
+			       " > max_connections (%ld)\n", __FUNCTION__,
+			       int_buf->ippathid, max_connections - 1);
+		} else {
+			h = iucv_pathid_table[int_buf->ippathid];
+			interrupt = h->interrupt_table;
 
-		pr_debug ("iucv: do_int: Handler\n");
-		iucv_dumpit ((uchar *) Q, sizeof (handler));
-		spin_unlock_irqrestore (&iucv_lock, flags);
+			iucv_debug("Handler:");
+			iucv_dumpit(h, sizeof(handler));
+		}
 	}
+
 	/* end of if statement */
 	switch (int_buf->iptype) {
-	case 0x01:		/* connection pending */
-		spin_lock_irqsave (&iucv_lock, flags);
-		for (R = handler_anchor; R != NULL; R = (handler *) R->next) {
-			memcpy (temp_buff1, &(int_buf->ipvmid), 24);
-			memcpy (temp_buff2, &(R->id.userid), 24);
-			for (j = 0; j < 24; j++) {
-				temp_buff1[j] =
-				    (temp_buff1[j]) & (R->id.mask)[j];
-				temp_buff2[j] =
-				    (temp_buff2[j]) & (R->id.mask)[j];
-			}
-
-			pr_debug ("iucv:do_int: temp_buff1\n");
-			iucv_dumpit (temp_buff1, sizeof (temp_buff1));
-			pr_debug ("iucv:do_int: temp_buff2\n");
-			iucv_dumpit (temp_buff2, sizeof (temp_buff2));
-
-			if (memcmp ((void *) temp_buff1,
-				    (void *) temp_buff2, 24) == 0) {
-
-				pr_debug
-				    ("iucv:do_int: found a matching handler\n");
-				break;
+		case 0x01:		/* connection pending */
+			spin_lock_irqsave(&iucv_lock, flags);
+			list_for_each(lh, &iucv_handler_table) {
+				h = list_entry(lh, handler, list);
+				memcpy(temp_buff1, &(int_buf->ipvmid), 24);
+				memcpy(temp_buff2, &(h->id.userid), 24);
+				for (j = 0; j < 24; j++) {
+					temp_buff1[j] &= (h->id.mask)[j];
+					temp_buff2[j] &= (h->id.mask)[j];
+				}
+				
+				iucv_debug("temp_buff1:");
+				iucv_dumpit(temp_buff1, sizeof(temp_buff1));
+				iucv_debug("temp_buff2");
+				iucv_dumpit(temp_buff2, sizeof(temp_buff2));
+				
+				if (memcmp (temp_buff1, temp_buff2, 24) == 0) {
+					
+					iucv_debug("found a matching handler");
+					break;
+				}
 			}
-		}
-		spin_unlock_irqrestore (&iucv_lock, flags);
-
-		if (R) {
-			/* ADD PATH TO PATHID TABLE */
-			add_pathid_result = iucv_add_pathid (int_buf->ippathid,
-							     R, R->pgm_data);
-			if (add_pathid_result == NULL) {
-				interrupt = R->interrupt_table;
-				if (interrupt->ConnectionPending) {
-
-					EBCASC (int_buf->ipvmid, 8);
-
-					(interrupt->ConnectionPending)
-					    ((iucv_ConnectionPending *) int_buf,
-					     (R->pgm_data));
-				} else {
+			spin_unlock_irqrestore (&iucv_lock, flags);
+			if (h) {
+				/* ADD PATH TO PATHID TABLE */
+				rc = iucv_add_pathid(int_buf->ippathid, h);
+				if (rc) {
 					iucv_sever (int_buf->ippathid,
 						    no_listener);
+					iucv_debug("add_pathid failed, rc = %d",
+						   (int)add_pathid_result);
+				} else {
+					interrupt = h->interrupt_table;
+					if (interrupt->ConnectionPending) {
+						EBCASC (int_buf->ipvmid, 8);
+						interrupt->ConnectionPending(
+							(iucv_ConnectionPending *)int_buf,
+							h->pgm_data);
+					} else
+						iucv_sever(int_buf->ippathid,
+							   no_listener);
 				}
-			} /* end of if(add_p...... */
-			else {
-				iucv_sever (int_buf->ippathid, no_listener);
-				pr_debug ("iucv:do_int:add_pathid failed"
-					  "with rc = %d\n",
-					  (int) add_pathid_result);
+			} else
+				iucv_sever(int_buf->ippathid, no_listener);
+			break;
+			
+		case 0x02:		/*connection complete */
+			if (h) {
+				if (interrupt->ConnectionComplete)
+					interrupt->ConnectionComplete(
+						(iucv_ConnectionComplete *)int_buf,
+						h->pgm_data);
+				else
+					iucv_debug("ConnectionComplete not called");
 			}
-		} else
-			iucv_sever (int_buf->ippathid, no_listener);
-		break;
-
-	case 0x02:		/*connection complete */
-		if (Q) {
-			if (interrupt->ConnectionComplete)
-				(interrupt->ConnectionComplete)
-				    ((iucv_ConnectionComplete *) int_buf, (P->pgm_data));
-			else
-				pr_debug ("iucv:do_int:"
-					  "ConnectionComplete not called\n");
-		}
-		
-		break;
-
-	case 0x03:		/* connection severed */
-		if (Q) {
-			if (interrupt->ConnectionSevered)
-				(interrupt->ConnectionSevered)
-				    ((iucv_ConnectionSevered *) int_buf,
-				     (P->pgm_data));
-
-			else
-				iucv_sever (int_buf->ippathid, no_listener);
-		} else
-			iucv_sever (int_buf->ippathid, no_listener);
-		break;
-
-	case 0x04:		/* connection quiesced */
-		if (Q) {
-			if (interrupt->ConnectionQuiesced)
-				(interrupt->ConnectionQuiesced)
-				    ((iucv_ConnectionQuiesced *) int_buf,
-				     (P->pgm_data));
-			else
-				pr_debug ("iucv:do_int:"
-					  "ConnectionQuiesced not called\n");
-		}
-		break;
-
-	case 0x05:		/* connection resumed */
-		if (Q) {
-			if (interrupt->ConnectionResumed)
-				(interrupt->ConnectionResumed)
-				    ((iucv_ConnectionResumed *) int_buf, (P->pgm_data));
-			else
-				pr_debug ("iucv:do_int:"
-					  "ConnectionResumed not called\n");
-		}
-		break;
-
-	case 0x06:		/* priority message complete */
-	case 0x07:		/* nonpriority message complete */
-		if (Q) {
-			if (interrupt->MessageComplete)
-				(interrupt->MessageComplete)
-				    ((iucv_MessageComplete *) int_buf, (P->pgm_data));
-			else
-				pr_debug ("iucv:do_int:"
-					  "MessageComplete not called\n");
-		}
-		break;
-
-	case 0x08:		/* priority message pending  */
-	case 0x09:		/* nonpriority message pending  */
-		if (Q) {
-			if (interrupt->MessagePending)
-				(interrupt->MessagePending)
-				    ((iucv_MessagePending *) int_buf, (P->pgm_data));
-			else
-				pr_debug ("iucv:do_int:"
-					  "MessagePending not called\n");
-		}
-		break;
-	default:		/* unknown iucv type */
-		printk (KERN_WARNING "iucv:do_int: unknown iucv interrupt \n");
-		break;
+			
+			break;
+			
+		case 0x03:		/* connection severed */
+			if (h) {
+				if (interrupt->ConnectionSevered)
+					interrupt->ConnectionSevered(
+						(iucv_ConnectionSevered *)int_buf,
+						h->pgm_data);
+				
+				else
+					iucv_sever (int_buf->ippathid, no_listener);
+			} else
+				iucv_sever(int_buf->ippathid, no_listener);
+			break;
+			
+		case 0x04:		/* connection quiesced */
+			if (h) {
+				if (interrupt->ConnectionQuiesced)
+					interrupt->ConnectionQuiesced(
+						(iucv_ConnectionQuiesced *)int_buf,
+						h->pgm_data);
+				else
+					iucv_debug("ConnectionQuiesced not called");
+			}
+			break;
+			
+		case 0x05:		/* connection resumed */
+			if (h) {
+				if (interrupt->ConnectionResumed)
+					interrupt->ConnectionResumed(
+						(iucv_ConnectionResumed *)int_buf,
+						h->pgm_data);
+				else
+					iucv_debug("ConnectionResumed not called");
+			}
+			break;
+			
+		case 0x06:		/* priority message complete */
+		case 0x07:		/* nonpriority message complete */
+			if (h) {
+				if (interrupt->MessageComplete)
+					interrupt->MessageComplete(
+						(iucv_MessageComplete *)int_buf,
+						h->pgm_data);
+				else
+					iucv_debug("MessageComplete not called");
+			}
+			break;
+			
+		case 0x08:		/* priority message pending  */
+		case 0x09:		/* nonpriority message pending  */
+			if (h) {
+				if (interrupt->MessagePending)
+					interrupt->MessagePending(
+						(iucv_MessagePending *) int_buf,
+						h->pgm_data);
+				else
+					iucv_debug("MessagePending not called");
+			}
+			break;
+		default:		/* unknown iucv type */
+			printk(KERN_WARNING "%s: unknown iucv interrupt\n",
+			       __FUNCTION__);
+			break;
 	}			/* end switch */
+	
+	iucv_debug("exiting pathid %d, type %02X",
+		 int_buf->ippathid, int_buf->iptype);
 
-	pr_debug ("BH:-  Exiting do_int "
-		  "pathid %d, type %02X\n", int_buf->ippathid, int_buf->iptype);
+	return;
+}
+
+/**
+ * iucv_bh_handler:
+ *
+ * This function loops over the queue of irq buffers and runs iucv_do_int()
+ * on every queue element.
+ */
+static void
+iucv_bh_handler(void)
+{
+	struct list_head head;
+	struct list_head *next;
+	ulong  flags;
+
+	atomic_set(&iucv_bh_scheduled, 0);
+
+	spin_lock_irqsave(&iucv_irq_queue_lock, flags);
+	list_add(&head, &iucv_irq_queue);
+	list_del_init(&iucv_irq_queue);
+	spin_unlock_irqrestore (&iucv_irq_queue_lock, flags);
+
+	next = head.next;
+	while (next != &head) {
+		iucv_irqdata *p = list_entry(next, iucv_irqdata, queue);
+
+		next = next->next;
+		iucv_do_int(&p->data);
+		kfree(p);
+	}
 
 	return;
 }
-/* end of function call */
 
+/**
+ * Export all public stuff
+ */
 EXPORT_SYMBOL (iucv_accept);
 EXPORT_SYMBOL (iucv_connect);
 EXPORT_SYMBOL (iucv_purge);
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/net/iucv.h linux/drivers/s390/net/iucv.h
--- v2.4.10/linux/drivers/s390/net/iucv.h	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/net/iucv.h	Sun Sep 30 12:26:07 2001
@@ -8,8 +8,6 @@
  *		Xenia Tkatschow (xenia@us.ibm.com)
  *
  *
- * Linux Kernel IUCV will not support a machine with storage > 2 GB. 
- *
  * Functionality:
  * To explore any of the IUCV functions, one must first register
  * their program using iucv_register_program(). Once your program has
@@ -314,7 +312,7 @@
  *                 of this message.                                    
  * Return: Return code from CP IUCV call.                           
 */
-int iucv_purge (u16 pathid, u32 msgid, u32 srccls, uchar audit[3]);
+int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit);
 /*
  * Name: iucv_query_maxconn
  * Purpose: This function determines the maximum number of communication paths you
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/net/netiucv.c linux/drivers/s390/net/netiucv.c
--- v2.4.10/linux/drivers/s390/net/netiucv.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/s390/net/netiucv.c	Sun Sep 30 12:26:07 2001
@@ -1,974 +1,2121 @@
 /*
- *  drivers/s390/net/netiucv.c
- *    Network driver for VM using iucv
+ * $Id: netiucv.c,v 1.11 2001/07/16 17:00:02 felfert Exp $
  *
- *  S/390 version
- *    Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Stefan Hegewald <hegewald@de.ibm.com>
- *               Hartmut Penner <hpenner@de.ibm.com>
- *
- *
- *    2.3 Updates Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- *                Martin Schwidefsky (schwidefsky@de.ibm.com)
- *
- *    Re-write:   Alan Altmark (Alan_Altmark@us.ibm.com)  Sept. 2000
- *                Uses iucv.c kernel module for IUCV services. 
- *
- *    2.4 Updates Alan Altmark (Alan_Altmark@us.ibm.com)  June 2001
- *                Update to use changed IUCV (iucv.c) interface.
- *
- * -------------------------------------------------------------------------- 
- *  An IUCV frame consists of one or more packets preceded by a 16-bit
- *  header.   The header contains the offset to the next packet header,
- *  measured from the beginning of the _frame_.  If zero, there are no more
- *  packets in the frame.  Consider a frame which contains a 10-byte packet
- *  followed by a 20-byte packet:
- *        +-----+----------------+--------------------------------+-----+
- *        |h'12'| 10-byte packet |h'34'|  20-byte packet          |h'00'|
- *        +-----+----------------+-----+--------------------------+-----+
- * Offset: 0     2                12    14                         34  
- *
- *  This means that each header will always have a larger value than the
- *  previous one (except for the final zero header, of course).
- *  
- *  For outbound packets, we send ONE frame per packet.  So, our frame is:
- *       AL2(packet length+2), packet, AL2(0)
- *  The maximum packet size is the MTU, so the maximum IUCV frame we send
- *  is MTU+4 bytes.
- *
- *  For inbound frames, we don't care how long the frame is.  We tear apart
- *  the frame, processing packets up to MTU size in length, until no more
- *  packets remain in the frame.
- *
- * --------------------------------------------------------------------------
- *  The code uses the 2.3.43 network driver interfaces.  If compiled on an
- *  an older level of the kernel, the module provides its own macros.
- *  Doc is in Linux Weekly News (lwn.net) memo from David Miller, 9 Feb 2000.
- *  There are a few other places with 2.3-specific enhancements.
- *
- * --------------------------------------------------------------------------
-*/
-//#define DEBUG 1
-//#define DEBUG2 1
-//#define IPDEBUG 1
-#define LEVEL "1.1"
-
-/* If MAX_DEVICES increased, add initialization data to iucv_netdev[] array */
-/* (See bottom of program.)						    */
-#define MAX_DEVICES 20		/* Allows "iucv0" to "iucv19"   */
-#define MAX_VM_MTU 32764	/* 32K IUCV buffer, minus 4     */
-#define MAX_TX_Q 50		/* Maximum pending TX           */
-
+ * IUCV network driver
+ *
+ * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
+ *
+ * Documentation used:
+ *  the source of the original IUCV driver by:
+ *    Stefan Hegewald <hegewald@de.ibm.com>
+ *    Hartmut Penner <hpenner@de.ibm.com>
+ *    Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ *    Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *    Alan Altmark (Alan_Altmark@us.ibm.com)  Sept. 2000
+ *
+ * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * RELEASE-TAG: IUCV network driver $Revision: 1.11 $
+ *
+ */
+
 #include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+
+#include <linux/ip.h>
+#include <linux/if_arp.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/ctype.h>
+#include <net/dst.h>
+
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+
+#include "iucv.h"
+#include "fsm.h"
+
+#undef DEBUG
 
 #ifdef MODULE
-#include <linux/module.h>
 MODULE_AUTHOR
-    ("(C) 2000 IBM Corporation by Alan Altmark (Alan_Altmark@us.ibm.com)");
-MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver " LEVEL);
-MODULE_PARM (iucv, "1-" __MODULE_STRING (MAX_DEVICES) "s");
+    ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
+MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
+MODULE_PARM (iucv, "1s");
 MODULE_PARM_DESC (iucv,
-		  "Specify the userids associated with iucv0-iucv9:\n"
-		  "iucv=userid1,userid2,...,userid10\n");
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
+		  "Specify the initial remote userids for iucv0 .. iucvn:\n"
+		  "iucv=userid0:userid1:...:useridN\n");
 #endif
 
-#include <linux/sched.h>	/* task queues                  */
-#include <linux/malloc.h>	/* kmalloc()                    */
-#include <linux/errno.h>	/* error codes                  */
-#include <linux/types.h>	/* size_t                       */
-#include <linux/interrupt.h>	/* mark_bh                      */
-#include <linux/netdevice.h>	/* struct net_device, etc.      */
-#include <linux/if_arp.h>	/* ARPHRD_SLIP                  */
-#include <linux/ip.h>		/* IP header                    */
-#include <linux/skbuff.h>	/* skb                          */
-#include <linux/init.h>		/* __setup()                    */
-#include <asm/string.h>		/* memset, memcpy, etc.         */
-#include "iucv.h"
-
-#if defined( DEBUG )
-#undef KERN_INFO
-#undef KERN_DEBUG
-#undef KERN_NOTICE
-#undef KERN_ERR
-#define KERN_INFO    KERN_EMERG
-#define KERN_DEBUG   KERN_EMERG
-#define KERN_NOTICE  KERN_EMERG
-#define KERN_ERR     KERN_EMERG
-#endif
+static char *iucv = "";
 
+/**
+ * compatibility stuff
+ */
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
 typedef struct net_device net_device;
 #else
 typedef struct device net_device;
 #endif
 
-static __inline__ int
-netif_is_busy (net_device * dev)
-{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,45))
-	return (dev->tbusy);
-#else
-	return (test_bit (__LINK_STATE_XOFF, &dev->flags));
+
+/**
+ * Per connection profiling data
+ */
+typedef struct connection_profile_t {
+	unsigned long maxmulti;
+	unsigned long maxcqueue;
+	unsigned long doios_single;
+	unsigned long doios_multi;
+	unsigned long txlen;
+	unsigned long tx_time;
+	struct timeval send_stamp;
+} connection_profile;
+
+/**
+ * Representation of one iucv connection
+ */
+typedef struct iucv_connection_t {
+	struct iucv_connection_t *next;
+	iucv_handle_t            handle;
+	__u16                    pathid;
+	struct sk_buff           *rx_buff;
+	struct sk_buff           *tx_buff;
+	struct sk_buff_head      collect_queue;
+	spinlock_t               collect_lock;
+	int                      collect_len;
+	int                      max_buffsize;
+	int                      flags;
+	fsm_timer                timer;
+	int                      retry;
+	fsm_instance             *fsm;
+	net_device               *netdev;
+	connection_profile       prof;
+	char                     userid[9];
+} iucv_connection;
+
+#define CONN_FLAGS_BUFSIZE_CHANGED 1
+
+/**
+ * Linked list of all connection structs.
+ */
+iucv_connection *connections;
+
+/**
+ * Representation of event-data for the
+ * connection state machine.
+ */
+typedef struct iucv_event_t {
+	iucv_connection *conn;
+	void            *data;
+} iucv_event;
+
+/**
+ * Private part of the network device structure
+ */
+typedef struct netiucv_priv_t {
+	struct net_device_stats stats;
+#if LINUX_VERSION_CODE >= 0x02032D
+	unsigned long           tbusy;
 #endif
+	fsm_instance            *fsm;
+        iucv_connection         *conn;
+	struct proc_dir_entry   *proc_dentry;
+	struct proc_dir_entry   *proc_stat_entry;
+	struct proc_dir_entry   *proc_buffer_entry;
+	struct proc_dir_entry   *proc_user_entry;
+	int                     proc_registered;
+} netiucv_priv;
+
+/**
+ * Link level header for a packet.
+ */
+typedef struct ll_header_t {
+	__u16 next;
+} ll_header;
+
+#define NETIUCV_HDRLEN           (sizeof(ll_header))
+#define NETIUCV_BUFSIZE_MAX      32768
+#define NETIUCV_BUFSIZE_DEFAULT  NETIUCV_BUFSIZE_MAX
+#define NETIUCV_MTU_MAX          (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN)
+#define NETIUCV_MTU_DEFAULT      9216
+#define NETIUCV_QUEUELEN_DEFAULT 50
+#define NETIUCV_TIMEOUT_5SEC     5000
+
+/**
+ * Compatibility macros for busy handling
+ * of network devices.
+ */
+#if LINUX_VERSION_CODE < 0x02032D
+static __inline__ void netiucv_clear_busy(net_device *dev)
+{
+	clear_bit(0 ,(void *)&dev->tbusy);
+	mark_bh(NET_BH);
 }
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,45))
-	/* Provide our own 2.3.45 interfaces */
-#define netif_enter_interrupt(dev) dev->interrupt=1
-#define netif_exit_interrupt(dev) dev->interrupt=0
-#define netif_start(dev) dev->start=1
-#define netif_stop(dev) dev->start=0
-
-static __inline__ void
-netif_stop_queue (net_device * dev)
+static __inline__ int netiucv_test_and_set_busy(net_device *dev)
 {
-	dev->tbusy = 1;
+	return(test_and_set_bit(0, (void *)&dev->tbusy));
 }
 
-static __inline__ void
-netif_start_queue (net_device * dev)
+#define SET_DEVICE_START(device, value) dev->start = value
+#else
+static __inline__ void netiucv_clear_busy(net_device *dev)
 {
-	dev->tbusy = 0;
+	clear_bit(0, &(((netiucv_priv *)dev->priv)->tbusy));
+	netif_start_queue(dev);
 }
 
-static __inline__ void
-netif_wake_queue (net_device * dev)
+static __inline__ int netiucv_test_and_set_busy(net_device *dev)
 {
-	dev->tbusy = 0;
-	mark_bh (NET_BH);
+	netif_stop_queue(dev);
+	return test_and_set_bit(0, &((netiucv_priv *)dev->priv)->tbusy);
 }
 
-#else
-	/* As of 2.3.45, we don't do these things anymore */
-#define netif_enter_interrupt(dev)
-#define netif_exit_interrupt(dev)
-#define netif_start(dev)
-#define netif_stop(dev)
-#endif
-
-static int iucv_start (net_device *);
-static int iucv_stop (net_device *);
-static int iucv_change_mtu (net_device *, int);
-static int iucv_init (net_device *);
-static void iucv_rx (net_device *, u32, uchar *, int);
-static int iucv_tx (struct sk_buff *, net_device *);
-
-static void connection_severed (iucv_ConnectionSevered *, void *);
-static void connection_pending (iucv_ConnectionPending *, void *);
-static void connection_complete (iucv_ConnectionComplete *, void *);
-static void message_pending (iucv_MessagePending *, void *);
-static void send_complete (iucv_MessageComplete *, void *);
+#define SET_DEVICE_START(device, value)
+#endif
 
-void register_iucv_dev (int, char *);
+#if LINUX_VERSION_CODE < 0x020400
+#  define dev_kfree_skb_irq(a) dev_kfree_skb(a)
+#endif
 
-static iucv_interrupt_ops_t netiucv_ops = {
-	&connection_pending,
-	&connection_complete,
-	&connection_severed,
-	NULL,			/* Quiesced             */
-	NULL,			/* Resumed              */
-	&message_pending,	/* Message pending      */
-	&send_complete		/* Message complete     */
+__u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+__u8 iucvMagic[16] = {
+	0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+	0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
 };
 
-static char iucv_userid[MAX_DEVICES][8];
-net_device iucv_netdev[MAX_DEVICES];
-
-/* This structure is private to each device. It contains the    */
-/* information necessary to do IUCV operations.                 */
-struct iucv_priv {
-	struct net_device_stats stats;
-	net_device *dev;
-	iucv_handle_t handle;
-	uchar userid[9];	/* Printable userid */
-	uchar userid2[8];	/* Used for IUCV operations */
-
-	/* Note: atomic_compare_and_swap() return value is backwards */
-	/*       from what you might think: FALSE=0=OK, TRUE=1=FAIL  */
-	atomic_t state;
-#define FREE 0
-#define CONNECTING 1
-#define CONNECTED 2
-	u16 pathid;
+/**
+ * This mask means the 16-byte IUCV "magic" and the origin userid must
+ * match exactly as specified in order to give connection_pending()
+ * control.
+ */
+__u8 mask[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 };
 
-uchar iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-uchar iucvMagic[16] = { 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-	0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
+/**
+ * Convert an iucv userId to its printable
+ * form (strip whitespace at end).
+ *
+ * @param An iucv userId
+ *
+ * @returns The printable string (static data!!)
+ */
+static __inline__ char *
+netiucv_printname(char *name)
+{
+	static char tmp[9];
+	char *p = tmp;
+	memcpy(tmp, name, 8);
+	tmp[8] = '\0';
+	while (*p && (!isspace(*p)))
+		p++;
+	*p = '\0';
+	return tmp;
+}
+
+/**
+ * States of the interface statemachine.
+ */
+enum dev_states {
+	DEV_STATE_STOPPED,
+	DEV_STATE_STARTWAIT,
+	DEV_STATE_STOPWAIT,
+	DEV_STATE_RUNNING,
+	/**
+	 * MUST be always the last element!!
+	 */
+	NR_DEV_STATES
 };
 
-/* This mask means the 16-byte IUCV "magic" and the origin userid must */
-/* match exactly as specified in order to give connection_pending()    */
-/* control. 							       */
-const char mask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+static const char *dev_state_names[] = {
+	"Stopped",
+	"StartWait",
+	"StopWait",
+	"Running",
 };
 
-#if defined( DEBUG2 ) || defined( IPDEBUG )
-/*--------------------------*/
-/* Dump buffer formatted    */
-/*--------------------------*/
-static void
-dumpit (char *buf, int len)
-{
-	int i;
-	printk (KERN_DEBUG);
-	for (i = 0; i < len; i++) {
-		if (!(i % 32) && i != 0)
-			printk ("\n");
-		else if (!(i % 4) && i != 0)
-			printk (" ");
-		printk ("%02X", buf[i]);
-	}
-	if (len % 32)
-		printk ("\n");
-}
-#endif
-
-/*-----------------------------------------------------------------*/
-/* Open a connection to another Linux or VM TCP/IP stack.          */
-/* Called by kernel.						   */
-/*                                                                 */
-/* 1. Register a handler. (Up to now, any attempt by another stack */
-/*    has been rejected by the IUCV handler.)  We give the handler */
-/*    the net_device* so that we can locate the dev associated     */
-/*    with the partner userid if he tries to connect to us or      */
-/*    if the connection is broken.                                 */
-/*                                                                 */
-/* 2. Connect to remote stack.  If we get a connection pending     */
-/*    interrupt while we're in the middle of connecting, don't     */
-/*    worry.  VM will sever its and use ours, because the DEVICE   */
-/*    is defined to be:                                            */
-/*           DEVICE devname IUCV 0 0 linuxvm A                     */
-/*        or DEVICE devname IUCV 0 0 linuxvm B                     */
-/*    In EBCDIC, "0" (0xF0) is greater than "A" (0xC1) or "B", so  */
-/*    win all races.  We will sever any connects that occur while  */
-/*    we are connecting.  The "0 0" is where we get iucvMagic from.*/
-/*								   */
-/*    FIXME: If two Linux machines get into this race condition,   */
-/*           both will sever.  Manual intervention required.       */
-/*           Need a better IUCV "hello"-like function that permits */
-/*           some negotiation.  But can't do that until VM TCP/IP  */
-/*           would support it.                                     */
-/*                                                                 */
-/* 3. Return 0 to indicate device ok.  Anything else is an error.  */
-/*-----------------------------------------------------------------*/
-static int
-iucv_start (net_device * dev)
-{
-	int rc, i;
-	struct iucv_priv *p = (struct iucv_priv *) dev->priv;
-
-	pr_debug ("iucv_start(%s)\n", dev->name);
-
-	if (p == NULL) {
-		/* Allocate priv data */
-		p = (struct iucv_priv *) kmalloc (sizeof (struct iucv_priv),
-						  GFP_ATOMIC);
-		if (p == NULL) {
-			printk (KERN_CRIT "%s: no memory for dev->priv.\n",
-				dev->name);
-			return -ENOMEM;
-		}
-		memset (p, 0, sizeof (struct iucv_priv));
-		dev->priv = p;
-		p->dev = dev;
-
-		memcpy (p->userid, iucv_userid[dev - iucv_netdev], 8);	/* Save userid */
-		memcpy (p->userid2, p->userid, 8);	/* Again, with feeling.  */
-
-		for (i = 0; i < 8; i++) {	/* Change userid to printable form */
-			if (p->userid[i] == ' ') {
-				p->userid[i] = '\0';
-				break;
-			}
+/**
+ * Events of the interface statemachine.
+ */
+enum dev_events {
+	DEV_EVENT_START,
+	DEV_EVENT_STOP,
+	DEV_EVENT_CONUP,
+	DEV_EVENT_CONDOWN,
+	/**
+	 * MUST be always the last element!!
+	 */
+	NR_DEV_EVENTS
+};
+
+static const char *dev_event_names[] = {
+	"Start",
+	"Stop",
+	"Connection up",
+	"Connection down",
+};
+
+/**
+ * Events of the connection statemachine
+ */
+enum conn_events {
+	/**
+	 * Events, representing callbacks from
+	 * lowlevel iucv layer)
+	 */
+	CONN_EVENT_CONN_REQ,
+	CONN_EVENT_CONN_ACK,
+	CONN_EVENT_CONN_REJ,
+	CONN_EVENT_CONN_SUS,
+	CONN_EVENT_CONN_RES,
+	CONN_EVENT_RX,
+	CONN_EVENT_TXDONE,
+
+	/**
+	 * Events, representing errors return codes from
+	 * calls to lowlevel iucv layer
+	 */
+
+	/**
+	 * Event, representing timer expiry.
+	 */
+	CONN_EVENT_TIMER,
+
+	/**
+	 * Events, representing commands from upper levels.
+	 */
+	CONN_EVENT_START,
+	CONN_EVENT_STOP,
+
+	/**
+	 * MUST be always the last element!!
+	 */
+	NR_CONN_EVENTS,
+};
+
+static const char *conn_event_names[] = {
+	"Remote connection request",
+	"Remote connection acknowledge",
+	"Remote connection reject",
+	"Connection suspended",
+	"Connection resumed",
+	"Data received",
+	"Data sent",
+
+	"Timer",
+
+	"Start",
+	"Stop",
+};
+
+/**
+ * States of the connection statemachine.
+ */
+enum conn_states {
+	/**
+	 * Connection not assigned to any device,
+	 * initial state, invalid
+	 */
+	CONN_STATE_INVALID,
+
+	/**
+	 * Userid assigned but not operating
+	 */
+	CONN_STATE_STOPPED,
+
+	/**
+	 * Connection registered,
+	 * no connection request sent yet,
+	 * no connection request received
+	 */
+	CONN_STATE_STARTWAIT,
+
+	/**
+	 * Connection registered and connection request sent,
+	 * no acknowledge and no connection request received yet.
+	 */
+	CONN_STATE_SETUPWAIT,
+
+	/**
+	 * Connection up and running idle
+	 */
+	CONN_STATE_IDLE,
+
+	/**
+	 * Data sent, awaiting CONN_EVENT_TXDONE
+	 */
+	CONN_STATE_TX,
+
+	/**
+	 * Terminating
+	 */
+	CONN_STATE_TERM,
+
+	/**
+	 * Error during registration.
+	 */
+	CONN_STATE_REGERR,
+
+	/**
+	 * Error during registration.
+	 */
+	CONN_STATE_CONNERR,
+
+	/**
+	 * MUST be always the last element!!
+	 */
+	NR_CONN_STATES,
+};
+
+static const char *conn_state_names[] = {
+	"Invalid",
+	"Stopped",
+	"StartWait",
+	"SetupWait",
+	"Idle",
+	"TX",
+	"Terminating",
+	"Registration error",
+	"Connect error",
+};
+
+
+/**
+ * Callback-wrappers, called from lowlevel iucv layer.
+ *****************************************************************************/
+
+static void
+netiucv_callback_rx(iucv_MessagePending *eib, void *pgm_data)
+{
+	iucv_connection *conn = (iucv_connection *)pgm_data;
+	iucv_event ev;
+
+	ev.conn = conn;
+	ev.data = (void *)eib;
+
+	fsm_event(conn->fsm, CONN_EVENT_RX, &ev);
+}
+
+static void
+netiucv_callback_txdone(iucv_MessageComplete *eib, void *pgm_data)
+{
+	iucv_connection *conn = (iucv_connection *)pgm_data;
+	iucv_event ev;
+
+	ev.conn = conn;
+	ev.data = (void *)eib;
+	fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev);
+}
+
+static void
+netiucv_callback_connack(iucv_ConnectionComplete *eib, void *pgm_data)
+{
+	iucv_connection *conn = (iucv_connection *)pgm_data;
+	iucv_event ev;
+
+	ev.conn = conn;
+	ev.data = (void *)eib;
+	fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev);
+}
+
+static void
+netiucv_callback_connreq(iucv_ConnectionPending *eib, void *pgm_data)
+{
+	iucv_connection *conn = (iucv_connection *)pgm_data;
+	iucv_event ev;
+
+	ev.conn = conn;
+	ev.data = (void *)eib;
+	fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev);
+}
+
+static void
+netiucv_callback_connrej(iucv_ConnectionSevered *eib, void *pgm_data)
+{
+	iucv_connection *conn = (iucv_connection *)pgm_data;
+	iucv_event ev;
+
+	ev.conn = conn;
+	ev.data = (void *)eib;
+	fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, &ev);
+}
+
+static void
+netiucv_callback_connsusp(iucv_ConnectionQuiesced *eib, void *pgm_data)
+{
+	iucv_connection *conn = (iucv_connection *)pgm_data;
+	iucv_event ev;
+
+	ev.conn = conn;
+	ev.data = (void *)eib;
+	fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, &ev);
+}
+
+static void
+netiucv_callback_connres(iucv_ConnectionResumed *eib, void *pgm_data)
+{
+	iucv_connection *conn = (iucv_connection *)pgm_data;
+	iucv_event ev;
+
+	ev.conn = conn;
+	ev.data = (void *)eib;
+	fsm_event(conn->fsm, CONN_EVENT_CONN_RES, &ev);
+}
+
+static iucv_interrupt_ops_t netiucv_ops = {
+	ConnectionPending:  netiucv_callback_connreq,
+	ConnectionComplete: netiucv_callback_connack,
+	ConnectionSevered:  netiucv_callback_connrej,
+	ConnectionQuiesced: netiucv_callback_connsusp,
+	ConnectionResumed:  netiucv_callback_connres,
+	MessagePending:     netiucv_callback_rx,
+	MessageComplete:    netiucv_callback_txdone
+};
+
+/**
+ * Dummy NOP action for all statemachines
+ */
+static void
+fsm_action_nop(fsm_instance *fi, int event, void *arg)
+{
+}
+
+/**
+ * Actions of the connection statemachine
+ *****************************************************************************/
+
+/**
+ * Helper function for conn_action_rx()
+ * Unpack a just received skb and hand it over to
+ * upper layers.
+ *
+ * @param conn The connection where this skb has been received.
+ * @param pskb The received skb.
+ */
+//static __inline__ void
+static void
+netiucv_unpack_skb(iucv_connection *conn, struct sk_buff *pskb)
+{
+	net_device     *dev = conn->netdev;
+	netiucv_priv   *privptr = (netiucv_priv *)dev->priv;
+	__u16          offset = 0;
+
+	skb_put(pskb, NETIUCV_HDRLEN);
+	pskb->dev = dev;
+	pskb->ip_summed = CHECKSUM_NONE;
+	pskb->protocol = ntohs(ETH_P_IP);
+
+	while (1) {
+		struct sk_buff *skb;
+		ll_header *header = (ll_header *)pskb->data;
+
+		if (header->next == 0)
+			break;
+
+		skb_pull(pskb, NETIUCV_HDRLEN);
+		header->next -= offset;
+		offset += header->next;
+		header->next -= NETIUCV_HDRLEN;
+		if (skb_tailroom(pskb) < header->next) {
+			printk(KERN_WARNING
+			       "%s: Ilegal next field in iucv header: %d > %d\n",
+			       dev->name, header->next, skb_tailroom(pskb));
+			return;
 		}
-		p->userid[8] = '\0';
-		atomic_set (&p->state, FREE);
-		p->handle =
-		    iucv_register_program (iucvMagic, p->userid2, (char *) mask,
-					   &netiucv_ops, (void *) dev);
-		if (p->handle <= 0) {
-			printk (KERN_ERR
-				"%s: iucv_register_program error, rc=%p\n",
-				dev->name, p->handle);
-			dev->priv = NULL;
-			kfree (p);
-			return -ENODEV;
+		skb_put(pskb, header->next);
+		pskb->mac.raw = pskb->data;
+		skb = dev_alloc_skb(pskb->len);
+		if (!skb) {
+			printk(KERN_WARNING
+			       "%s Out of memory in netiucv_unpack_skb\n",
+			       dev->name);
+			privptr->stats.rx_dropped++;
+			return;
 		}
-		pr_debug ("state@ = %p\n", &p->state);
-		MOD_INC_USE_COUNT;
+		memcpy(skb_put(skb, pskb->len), pskb->data, pskb->len);
+		skb->mac.raw = skb->data;
+		skb->dev = pskb->dev;
+		skb->protocol = pskb->protocol;
+		pskb->ip_summed = CHECKSUM_UNNECESSARY;
+		netif_rx(skb);
+		privptr->stats.rx_packets++;
+		privptr->stats.rx_bytes += skb->len;
+		skb_pull(pskb, header->next);
+		skb_put(pskb, NETIUCV_HDRLEN);
 	}
+}
 
-	if (atomic_compare_and_swap (FREE, CONNECTING, &p->state) != 0) {
-		pr_debug ("Other side connecting during start\n");
-		return 0;
+static void
+conn_action_rx(fsm_instance *fi, int event, void *arg)
+{
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+	iucv_MessagePending *eib = (iucv_MessagePending *)ev->data;
+	netiucv_priv *privptr = (netiucv_priv *)conn->netdev->priv;
+
+	__u16 msglen = eib->ln1msg2.ipbfln1f;
+	int rc;
+
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	if (!conn->netdev) {
+		/* FRITZ: How to tell iucv LL to drop the msg? */
+		printk(KERN_WARNING
+		       "Received data for unlinked connection\n"); 
+		return;
+	}
+	if (msglen > conn->max_buffsize) {
+		/* FRITZ: How to tell iucv LL to drop the msg? */
+		privptr->stats.rx_dropped++;
+		return;
 	}
+	conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head;
+	conn->rx_buff->len = 0;
+	rc = iucv_receive(conn->pathid, eib->ipmsgid, eib->iptrgcls,
+			  conn->rx_buff->data, msglen, NULL, NULL, NULL);
+	if (rc != 0 || msglen < 5) {
+		privptr->stats.rx_errors++;
+		return;
+	}
+	netiucv_unpack_skb(conn, conn->rx_buff);
+}
 
-	rc =
-	    iucv_connect (&(p->pathid), MAX_TX_Q, iucvMagic, p->userid2,
-			  iucv_host, 0, NULL, NULL, p->handle, p);
+static void
+conn_action_txdone(fsm_instance *fi, int event, void *arg)
+{
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+	iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data;
+	netiucv_priv *privptr = NULL;
+	struct sk_buff *skb = (struct sk_buff *)eib->ipmsgtag;
+	__u32 txbytes = 0;
+	__u32 txpackets = 0;
+	__u32 stat_maxcq = 0;
+	unsigned long saveflags;
+	ll_header header;
 
-	/* Some errors are not fatal.  In these cases we will report "OK". */
-	switch (rc) {
-	case 0:		/* Wait for connection to complete */
-		pr_debug ("...waiting for connection to complete...");
-		return 0;
-	case 11:		/* Wait for parter to connect */
-		printk (KERN_NOTICE "%s: "
-			"User %s is not available now.\n",
-			dev->name, p->userid);
-		atomic_set (&p->state, FREE);
-		return 0;
-	case 12:		/* Wait for partner to connect */
-		printk (KERN_NOTICE "%s: "
-			"User %s is not ready to talk now.\n",
-			dev->name, p->userid);
-		atomic_set (&p->state, FREE);
-		return 0;
-	case 13:		/* Fatal */
-		printk (KERN_ERR "%s: "
-			"You have too many IUCV connections."
-			"Check MAXCONN in CP directory.\n", dev->name);
-		break;
-	case 14:		/* Fatal */
-		printk (KERN_ERR "%s: "
-			"User %s has too many IUCV connections."
-			"Check MAXCONN in CP directory.\n",
-			dev->name, p->userid);
-		break;
-	case 15:		/* Fatal */
-		printk (KERN_ERR "%s: "
-			"No IUCV authorization found in CP directory.\n",
-			dev->name);
-		break;
-	default:		/* Really fatal! Should not occur!! */
-		printk (KERN_ERR "%s: "
-			"return code %i from iucv_connect()\n", dev->name, rc);
-	}
-
-	rc = iucv_unregister_program (p->handle);
-	dev->priv = NULL;
-	kfree (p);
-	MOD_DEC_USE_COUNT;
-	return -ENODEV;
-}				/* end iucv_start() */
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	fsm_deltimer(&conn->timer);
+	if (conn && conn->netdev && conn->netdev->priv)
+		privptr = (netiucv_priv *)conn->netdev->priv;
+	if (skb) {
+		if (privptr) {
+			privptr->stats.tx_packets++;
+			privptr->stats.tx_bytes +=
+				(skb->len - NETIUCV_HDRLEN - NETIUCV_HDRLEN);
+		}
+		dev_kfree_skb_any(skb);
+	} else {
+		conn->tx_buff->data = conn->tx_buff->tail = conn->tx_buff->head;
+		conn->tx_buff->len = 0;
+	}
+	spin_lock_irqsave(&conn->collect_lock, saveflags);
+	while ((skb = skb_dequeue(&conn->collect_queue))) {
+		header.next = conn->tx_buff->len + skb->len + NETIUCV_HDRLEN;
+		memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
+		       NETIUCV_HDRLEN);
+		memcpy(skb_put(conn->tx_buff, skb->len), skb->data, skb->len);
+		txbytes += skb->len;
+		txpackets++;
+		stat_maxcq++;
+		atomic_dec(&skb->users);
+		dev_kfree_skb_any(skb);
+	}
+	if (conn->collect_len > conn->prof.maxmulti)
+		conn->prof.maxmulti = conn->collect_len;
+	conn->collect_len = 0;
+	spin_unlock_irqrestore(&conn->collect_lock, saveflags);
+	if (conn->tx_buff->len) {
+		int rc;
+
+		header.next = 0;
+		memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header,
+		       NETIUCV_HDRLEN);
+
+		fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
+			     CONN_EVENT_TIMER, conn);
+		conn->prof.send_stamp = xtime;
+		rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0,
+			       conn->tx_buff->data, conn->tx_buff->len);
+		conn->prof.doios_multi++;
+		conn->prof.txlen += conn->tx_buff->len;
+		if (rc != 0) {
+			fsm_deltimer(&conn->timer);
+			fsm_newstate(fi, CONN_STATE_IDLE);
+			if (privptr)
+				privptr->stats.tx_errors += txpackets;
+		} else {
+			if (privptr) {
+				privptr->stats.tx_packets += txpackets;
+				privptr->stats.tx_bytes += txbytes;
+			}
+			if (stat_maxcq > conn->prof.maxcqueue)
+				conn->prof.maxcqueue = stat_maxcq;
+		}
+	} else
+		fsm_newstate(fi, CONN_STATE_IDLE);
+}
 
-/*********************************************************************/
-/* Our connection TO another stack has been accepted.                */
-/*********************************************************************/
-static void
-connection_complete (iucv_ConnectionComplete * cci, void *pgm_data)
-{
-	struct iucv_priv *p = (struct iucv_priv *) pgm_data;
-	pr_debug ("...%s connection complete... txq=%u\n",
-		  p->dev->name, cci->ipmsglim);
-	atomic_set (&p->state, CONNECTED);
-	p->pathid = cci->ippathid;
-	p->dev->tx_queue_len = cci->ipmsglim;
-	netif_start (p->dev);
-	netif_start_queue (p->dev);
-	printk (KERN_NOTICE "%s: Connection to user %s is up\n",
-		p->dev->name, p->userid);
-}				/* end connection_complete() */
-
-/*********************************************************************/
-/* A connection FROM another stack is pending.  If we are in the     */
-/* middle of connecting, sever the new connection.                   */
-/*								     */
-/* We only get here if we've done an iucv_register(), so we know     */
-/* the remote user is the correct user.                              */
-/*********************************************************************/
-static void
-connection_pending (iucv_ConnectionPending * cpi, void *pgm_data)
-{
-	/* Only get this far if handler is set up, so we know userid is ok. */
-	/* and the device is started.                                       */
-	/* pgm_data is different for this one.  We get dev*, not priv*.     */
-	net_device *dev = (net_device *) pgm_data;
-	struct iucv_priv *p = (struct iucv_priv *) dev->priv;
+static void
+conn_action_connaccept(fsm_instance *fi, int event, void *arg)
+{
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+	iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
+	net_device *netdev = conn->netdev;
+	netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
 	int rc;
-	u16 msglimit;
-	uchar udata[16];
+	__u16 msglimit;
+	__u8 udata[16];
 
-	/* If we're not waiting on a connect, reject the connection */
-	if (atomic_compare_and_swap (FREE, CONNECTING, &p->state) != 0) {
-		iucv_sever (cpi->ippathid, udata);
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	rc = iucv_accept(eib->ippathid, NETIUCV_QUEUELEN_DEFAULT, udata, 0,
+			 conn->handle, conn, NULL, &msglimit);
+	if (rc != 0) {
+		printk(KERN_WARNING
+		       "%s: IUCV accept failed with error %d\n",
+		       netdev->name, rc);
 		return;
 	}
+	fsm_newstate(fi, CONN_STATE_IDLE);
+	conn->pathid = eib->ippathid;
+	netdev->tx_queue_len = msglimit;
+	fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
+}
 
-	rc = iucv_accept (cpi->ippathid,	/* Path id                      */
-			  MAX_TX_Q,	/* desired IUCV msg limit       */
-			  udata,	/* user_Data                    */
-			  0,	/* No flags                     */
-			  p->handle,	/* registration handle          */
-			  p,	/* private data                 */
-			  NULL,	/* don't care about output flags */
-			  &msglimit);	/* Actual IUCV msg limit        */
-	if (rc != 0) {
-		atomic_set (&p->state, FREE);
-		printk (KERN_ERR "%s: iucv accept failed rc=%i\n",
-			p->dev->name, rc);
-	} else {
-		atomic_set (&p->state, CONNECTED);
-		p->pathid = cpi->ippathid;
-		p->dev->tx_queue_len = (u32) msglimit;
-		netif_start (p->dev);
-		netif_start_queue (p->dev);
-		printk (KERN_NOTICE "%s: Connection to user %s is up\n",
-			p->dev->name, p->userid);
-	}
-}				/* end connection_pending() */
-
-/*********************************************************************/
-/* Our connection to another stack has been severed.                 */
-/*********************************************************************/
-static void
-connection_severed (iucv_ConnectionSevered * eib, void *pgm_data)
-{
-	struct iucv_priv *p = (struct iucv_priv *) pgm_data;
-
-	printk (KERN_INFO "%s: Connection to user %s is down\n",
-		p->dev->name, p->userid);
-
-	/* FIXME: We can also get a severed interrupt while in
-	          state CONNECTING!  Fix the state machine ... */
-#if 0
-	if (atomic_compare_and_swap (CONNECTED, FREE, &p->state) != 0)
-		return;		/* In case reconnect in progress already */
-#else
-	atomic_set (&p->state, FREE);
-#endif
+static void
+conn_action_connreject(fsm_instance *fi, int event, void *arg)
+{
+	iucv_event *ev = (iucv_event *)arg;
+	// iucv_connection *conn = ev->conn;
+	iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data;
+	__u8 udata[16];
 
-	netif_stop_queue (p->dev);
-	netif_stop (p->dev);
-}				/* end connection_severed() */
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	iucv_sever(eib->ippathid, udata);
+}
 
-/*-----------------------------------------------------*/
-/* STOP device.                   Called by kernel.    */
-/*-----------------------------------------------------*/
-static int
-iucv_stop (net_device * dev)
+static void
+conn_action_connack(fsm_instance *fi, int event, void *arg)
 {
-	int rc = 0;
-	struct iucv_priv *p;
-	pr_debug ("%s: iucv_stop\n", dev->name);
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+	iucv_ConnectionComplete *eib = (iucv_ConnectionComplete *)ev->data;
+	net_device *netdev = conn->netdev;
+	netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
 
-	netif_stop_queue (dev);
-	netif_stop (dev);
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	fsm_newstate(fi, CONN_STATE_IDLE);
+	conn->pathid = eib->ippathid;
+	netdev->tx_queue_len = eib->ipmsglim;
+	fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev);
+}
 
-	p = (struct iucv_priv *) (dev->priv);
-	if (p == NULL)
-		return 0;
+static void
+conn_action_connsever(fsm_instance *fi, int event, void *arg)
+{
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+	// iucv_ConnectionSevered *eib = (iucv_ConnectionSevered *)ev->data;
+	net_device *netdev = conn->netdev;
+	netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
+	int state = fsm_getstate(fi);
 
-	/* Unregister will sever associated connections */
-	rc = iucv_unregister_program (p->handle);
-	dev->priv = NULL;
-	kfree (p);
-	MOD_DEC_USE_COUNT;
-	return 0;
-}				/* end  iucv_stop() */
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	switch (state) {
+		case CONN_STATE_IDLE:
+		case CONN_STATE_TX:
+			printk(KERN_INFO "%s: Remote dropped connection\n",
+			       netdev->name);
+			iucv_unregister_program(conn->handle);
+			conn->handle = 0;
+			fsm_newstate(fi, CONN_STATE_STOPPED);
+			fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
+			break;
+	}
+}
 
-/*---------------------------------------------------------------------*/
-/* Inbound packets from other host are ready for receipt.  Receive     */
-/* them (they arrive as a single transmission), break them up into     */
-/* separate packets, and send them to the "generic" packet processor.  */
-/*---------------------------------------------------------------------*/
 static void
-message_pending (iucv_MessagePending * mpi, void *pgm_data)
+conn_action_start(fsm_instance *fi, int event, void *arg)
 {
-	struct iucv_priv *p = (struct iucv_priv *) pgm_data;
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+
 	int rc;
-	u32 buffer_length;
-	u16 packet_offset, prev_offset = 0;
-	void *buffer;
-
-	buffer_length = mpi->ln1msg2.ipbfln1f;
-	pr_debug ("%s: MP id=%i Length=%u\n",
-		  p->dev->name, mpi->ipmsgid, buffer_length);
-
-	buffer = kmalloc (buffer_length, GFP_ATOMIC | GFP_DMA);
-	if (buffer == NULL) {
-		p->stats.rx_dropped++;
-		return;
-	}
-	rc = iucv_receive (p->pathid, mpi->ipmsgid, mpi->iptrgcls,
-			   buffer, buffer_length, NULL, NULL, NULL);
 
-	if (rc != 0 || buffer_length < 5) {
-		printk (KERN_INFO
-			"%s: IUCV rcv error. rc=%X ID=%i length=%u\n",
-			p->dev->name, rc, mpi->ipmsgid, buffer_length);
-		p->stats.rx_errors++;
-		kfree (buffer);
-		return;
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	if (conn->handle == 0) {
+		conn->handle =
+			iucv_register_program(iucvMagic, conn->userid, mask,
+					      &netiucv_ops, conn);
+		fsm_newstate(fi, CONN_STATE_STARTWAIT);
+		if (conn->handle <= 0) {
+			fsm_newstate(fi, CONN_STATE_REGERR);
+			conn->handle = 0;
+			return;
+		}
+#ifdef DEBUG
+		printk(KERN_DEBUG "%s('%s'): registered successfully\n",
+		       conn->netdev->name, conn->userid);
+#endif
+	}
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s('%s'): connecting ...\n",
+	       conn->netdev->name, conn->userid);
+#endif
+	rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic,
+			  conn->userid, iucv_host, 0, NULL, NULL, conn->handle,
+			  conn);
+	fsm_newstate(fi, CONN_STATE_SETUPWAIT);
+	switch (rc) {
+		case 0:
+			return;
+		case 11:
+			printk(KERN_NOTICE
+			       "%s: User %s is currently not available.\n",
+			       conn->netdev->name,
+			       netiucv_printname(conn->userid));
+			fsm_newstate(fi, CONN_STATE_STARTWAIT);
+			return;
+		case 12:
+			printk(KERN_NOTICE
+			       "%s: User %s is currently not ready.\n",
+			       conn->netdev->name,
+			       netiucv_printname(conn->userid));
+			fsm_newstate(fi, CONN_STATE_STARTWAIT);
+			return;
+		case 13:
+			printk(KERN_WARNING
+			       "%s: Too many IUCV connections.\n",
+			       conn->netdev->name);
+			fsm_newstate(fi, CONN_STATE_CONNERR);
+			break;
+		case 14:
+			printk(KERN_WARNING
+			       "%s: User %s has too many IUCV connections.\n",
+			       conn->netdev->name,
+			       netiucv_printname(conn->userid));
+			fsm_newstate(fi, CONN_STATE_CONNERR);
+			break;
+		case 15:
+			printk(KERN_WARNING
+			       "%s: No IUCV authorization in CP directory.\n",
+			       conn->netdev->name);
+			fsm_newstate(fi, CONN_STATE_CONNERR);
+			break;
+		default:
+			printk(KERN_WARNING
+			       "%s: iucv_connect returned error %d\n",
+			       conn->netdev->name, rc);
+			fsm_newstate(fi, CONN_STATE_CONNERR);
+			break;
 	}
+	iucv_unregister_program(conn->handle);
+	conn->handle = 0;
+}
 
-	packet_offset = *((u16 *) buffer);
+static void
+netiucv_purge_skb_queue(struct sk_buff_head *q)
+{
+	struct sk_buff *skb;
 
-	while (packet_offset != 0) {
-		if (packet_offset <= prev_offset
-		    || packet_offset > buffer_length - 2) {
-			printk (KERN_INFO "%s: bad inbound packet offset %u, "
-				"prev %u, total %u\n", p->dev->name,
-				packet_offset, prev_offset, buffer_length);
-			p->stats.rx_errors++;
-			break;
-		} else {
-			/* Kick the packet upstairs */
-			iucv_rx (p->dev, mpi->ipmsgid,
-				 buffer + prev_offset + 2,
-				 packet_offset - prev_offset - 2);
-			prev_offset = packet_offset;
-			packet_offset = *((u16 *) (buffer + packet_offset));
-		}
+	while ((skb = skb_dequeue(q))) {
+		atomic_dec(&skb->users);
+		dev_kfree_skb_any(skb);
 	}
+}
 
-	kfree (buffer);
-	return;
-}				/* end message_pending() */
+static void
+conn_action_stop(fsm_instance *fi, int event, void *arg)
+{
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+	net_device *netdev = conn->netdev;
+	netiucv_priv *privptr = (netiucv_priv *)netdev->priv;
+
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	fsm_newstate(fi, CONN_STATE_STOPPED);
+	netiucv_purge_skb_queue(&conn->collect_queue);
+	iucv_unregister_program(conn->handle);
+	conn->handle = 0;
+	fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev);
+}
 
-/*-------------------------------------------------------------*/
-/* Add meta-data to packet and send upstairs.                  */
-/*-------------------------------------------------------------*/
 static void
-iucv_rx (net_device * dev, u32 msgid, uchar * buf, int len)
+conn_action_inval(fsm_instance *fi, int event, void *arg)
 {
-	struct iucv_priv *p = (struct iucv_priv *) dev->priv;
-	struct sk_buff *skb;
+	iucv_event *ev = (iucv_event *)arg;
+	iucv_connection *conn = ev->conn;
+	net_device *netdev = conn->netdev;
+
+	printk(KERN_WARNING
+	       "%s: Cannot connect without username\n",
+	       netdev->name);
+}
+
+static const fsm_node conn_fsm[] = {
+	{ CONN_STATE_INVALID,   CONN_EVENT_START,    conn_action_inval      },
+	{ CONN_STATE_STOPPED,   CONN_EVENT_START,    conn_action_start      },
+	{ CONN_STATE_STARTWAIT, CONN_EVENT_START,    conn_action_start      },
+
+	{ CONN_STATE_STARTWAIT, CONN_EVENT_STOP,     conn_action_stop       },
+	{ CONN_STATE_SETUPWAIT, CONN_EVENT_STOP,     conn_action_stop       },
+	{ CONN_STATE_IDLE,      CONN_EVENT_STOP,     conn_action_stop       },
+	{ CONN_STATE_TX,        CONN_EVENT_STOP,     conn_action_stop       },
+	{ CONN_STATE_REGERR,    CONN_EVENT_STOP,     conn_action_stop       },
+	{ CONN_STATE_CONNERR,   CONN_EVENT_STOP,     conn_action_stop       },
+
+	{ CONN_STATE_STOPPED,   CONN_EVENT_CONN_REQ, conn_action_connreject },
+        { CONN_STATE_STARTWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
+	{ CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REQ, conn_action_connaccept },
+	{ CONN_STATE_IDLE,      CONN_EVENT_CONN_REQ, conn_action_connreject },
+	{ CONN_STATE_TX,        CONN_EVENT_CONN_REQ, conn_action_connreject },
+
+	{ CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_ACK, conn_action_connack    },
+
+	{ CONN_STATE_SETUPWAIT, CONN_EVENT_CONN_REJ, conn_action_connsever  },
+	{ CONN_STATE_IDLE,      CONN_EVENT_CONN_REJ, conn_action_connsever  },
+	{ CONN_STATE_TX,        CONN_EVENT_CONN_REJ, conn_action_connsever  },
+
+	{ CONN_STATE_IDLE,      CONN_EVENT_RX,       conn_action_rx         },
+	{ CONN_STATE_TX,        CONN_EVENT_RX,       conn_action_rx         },
+
+	{ CONN_STATE_TX,        CONN_EVENT_TXDONE,   conn_action_txdone     },
+};
+
+static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
+
+
+/**
+ * Actions for interface - statemachine.
+ *****************************************************************************/
+
+/**
+ * Startup connection by sending CONN_EVENT_START to it.
+ *
+ * @param fi    An instance of an interface statemachine.
+ * @param event The event, just happened.
+ * @param arg   Generic pointer, casted from net_device * upon call.
+ */
+static void
+dev_action_start(fsm_instance *fi, int event, void *arg)
+{
+	net_device   *dev = (net_device *)arg;
+	netiucv_priv *privptr = dev->priv;
+	iucv_event   ev;
 
-#ifdef IPDEBUG
-	printk (KERN_DEBUG "RX id=%i\n", msgid);
-	dumpit (buf, 20);
-	dumpit (buf + 20, 20);
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
 #endif
+	ev.conn = privptr->conn;
+	fsm_newstate(fi, DEV_STATE_STARTWAIT);
+	fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev);
+}
 
-	pr_debug ("%s: RX len=%u\n", p->dev->name, len);
-
-	if (len > p->dev->mtu) {
-		printk (KERN_INFO
-			"%s: inbound packet id# %i length %u exceeds MTU %i\n",
-			p->dev->name, msgid, len, p->dev->mtu);
-		p->stats.rx_errors++;
-		return;
-	}
+/**
+ * Shutdown connection by sending CONN_EVENT_STOP to it.
+ *
+ * @param fi    An instance of an interface statemachine.
+ * @param event The event, just happened.
+ * @param arg   Generic pointer, casted from net_device * upon call.
+ */
+static void
+dev_action_stop(fsm_instance *fi, int event, void *arg)
+{
+	net_device   *dev = (net_device *)arg;
+	netiucv_priv *privptr = dev->priv;
+	iucv_event   ev;
 
-	skb = dev_alloc_skb (len);
-	if (!skb) {
-		p->stats.rx_dropped++;
-		return;
-	}
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	ev.conn = privptr->conn;
 
-	/* If not enough room, skb_put will panic */
-	memcpy (skb_put (skb, len), buf, len);
+	fsm_newstate(fi, DEV_STATE_STOPWAIT);
+	fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev);
+}
 
-	/* Write metadata, and then pass to the receive level.  Since we */
-	/* are not an Ethernet device, we have special fields to set.    */
-	/* This is all boilerplace, not to be messed with.               */
-	skb->dev = p->dev;	/* Set device       */
-	skb->mac.raw = skb->data;	/* Point to packet  */
-	skb->pkt_type = PACKET_HOST;	/* ..for this host. */
-	skb->protocol = htons (ETH_P_IP);	/* IP packet        */
-	skb->ip_summed = CHECKSUM_UNNECESSARY;	/* No checksum      */
-	p->stats.rx_packets++;
-	p->stats.rx_bytes += len;
-	netif_rx (skb);
+/**
+ * Called from connection statemachine
+ * when a connection is up and running.
+ *
+ * @param fi    An instance of an interface statemachine.
+ * @param event The event, just happened.
+ * @param arg   Generic pointer, casted from net_device * upon call.
+ */
+static void
+dev_action_connup(fsm_instance *fi, int event, void *arg)
+{
+	net_device   *dev = (net_device *)arg;
 
-	return;
-}				/* end  iucv_rx() */
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	switch (fsm_getstate(fi)) {
+		case DEV_STATE_STARTWAIT:
+			fsm_newstate(fi, DEV_STATE_RUNNING);
+			printk(KERN_INFO
+			       "%s: connected with remote side\n",
+			       dev->name);
+			break;
+		case DEV_STATE_STOPWAIT:
+			printk(KERN_INFO
+			       "%s: got connection UP event during shutdown!!\n",
+			       dev->name);
+			break;
+	}
+}
 
-/*-------------------------------------------------------------*/
-/* TRANSMIT a packet.            	    Called by kernel.  */
-/* This function deals with hw details of packet transmission. */
-/*-------------------------------------------------------------*/
-static int
-iucv_tx (struct sk_buff *skb, net_device * dev)
+/**
+ * Called from connection statemachine
+ * when a connection has been shutdown.
+ *
+ * @param fi    An instance of an interface statemachine.
+ * @param event The event, just happened.
+ * @param arg   Generic pointer, casted from net_device * upon call.
+ */
+static void
+dev_action_conndown(fsm_instance *fi, int event, void *arg)
 {
-	int rc, pktlen;
-	u32 framelen, msgid;
-	void *frame;
-	struct iucv_priv *p = (struct iucv_priv *) dev->priv;
+	net_device   *dev = (net_device *)arg;
+	netiucv_priv *privptr = dev->priv;
+	iucv_event   ev;
 
-	if (skb == NULL) {	/* Nothing to do */
-		printk (KERN_WARNING "%s: TX Kernel passed null sk_buffer\n",
-			dev->name);
-		p->stats.tx_dropped++;
-		return -EIO;
+#ifdef DEBUG
+	printk(KERN_DEBUG "%s() called\n", __FUNCTION__);
+#endif
+	switch (fsm_getstate(fi)) {
+		case DEV_STATE_RUNNING:
+			fsm_newstate(fi, DEV_STATE_STARTWAIT);
+			ev.conn = privptr->conn;
+			fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev);
+			break;
+		case DEV_STATE_STARTWAIT:
+			break;
+		case DEV_STATE_STOPWAIT:
+			fsm_newstate(fi, DEV_STATE_STOPPED);
+			break;
 	}
+}
 
-	if (netif_is_busy (dev))
-		return -EBUSY;
+static const fsm_node dev_fsm[] = {
+	{ DEV_STATE_STOPPED,   DEV_EVENT_START,   dev_action_start    },
 
-	dev->trans_start = jiffies;	/* save the timestamp */
+	{ DEV_STATE_STOPWAIT,  DEV_EVENT_START,   dev_action_start    },
+	{ DEV_STATE_STOPWAIT,  DEV_EVENT_CONDOWN, dev_action_conndown },
 
-	/* IUCV frame will be released when MessageComplete   */
-	/* interrupt is received.                             */
-	pktlen = skb->len;
-	framelen = pktlen + 4;
-
-	frame = kmalloc (framelen, GFP_ATOMIC | GFP_DMA);
-	if (!frame) {
-		p->stats.tx_dropped++;
-		dev_kfree_skb (skb);
-		return 0;
-	}
+	{ DEV_STATE_STARTWAIT, DEV_EVENT_STOP,    dev_action_stop     },
+	{ DEV_STATE_STARTWAIT, DEV_EVENT_CONUP,   dev_action_connup   },
+	{ DEV_STATE_STARTWAIT, DEV_EVENT_CONDOWN, dev_action_conndown },
+
+	{ DEV_STATE_RUNNING,   DEV_EVENT_STOP,    dev_action_stop     },
+	{ DEV_STATE_RUNNING,   DEV_EVENT_CONDOWN, dev_action_conndown },
+	{ DEV_STATE_RUNNING,   DEV_EVENT_CONUP,   fsm_action_nop      },
+};
 
-	netif_stop_queue (dev);	/* transmission is busy */
+static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
 
-	*(u16 *) frame = pktlen + 2;	/* Set header   */
-	memcpy (frame + 2, skb->data, pktlen);	/* Copy data    */
-	memset (frame + pktlen + 2, 0, 2);	/* Set trailer  */
-
-	/* Ok, now the frame is ready for transmission: send it. */
-	rc = iucv_send (p->pathid, &msgid, 0, 0,
-			(u32) frame,	/* Msg tag      */
-			0,	/* No flags     */
-			frame, framelen);
-	if (rc == 0) {
-#ifdef IPDEBUG
-		printk (KERN_DEBUG "TX id=%i\n", msgid);
-		dumpit (skb->data, 20);
-		dumpit (skb->data + 20, 20);
-#endif
-		pr_debug ("%s: tx START %i.%i @=%p len=%i\n",
-			  p->dev->name, p->pathid, msgid, frame, framelen);
-		p->stats.tx_packets++;
-	} else {
-		if (rc == 3)	/* Exceeded MSGLIMIT */
-			p->stats.tx_dropped++;
+/**
+ * Transmit a packet.
+ * This is a helper function for netiucv_tx().
+ *
+ * @param conn Connection to be used for sending.
+ * @param skb Pointer to struct sk_buff of packet to send.
+ *            The linklevel header has already been set up
+ *            by netiucv_tx().
+ *
+ * @return 0 on success, -ERRNO on failure. (Never fails.)
+ */
+static int
+netiucv_transmit_skb(iucv_connection *conn, struct sk_buff *skb) {
+	unsigned long saveflags;
+	ll_header header;
+	int       rc = 0;
+
+	if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) {
+		int l = skb->len + NETIUCV_HDRLEN;
+
+		spin_lock_irqsave(&conn->collect_lock, saveflags);
+		if (conn->collect_len + l >
+		    (conn->max_buffsize - NETIUCV_HDRLEN))
+			rc = -EBUSY;
 		else {
-			p->stats.tx_errors++;
-			printk (KERN_INFO "%s: tx ERROR id=%i.%i rc=%i\n",
-				p->dev->name, p->pathid, msgid, rc);
+			atomic_inc(&skb->users);
+			skb_queue_tail(&conn->collect_queue, skb);
+			conn->collect_len += l;
+		}
+		spin_unlock_irqrestore(&conn->collect_lock, saveflags);
+	} else {
+		struct sk_buff *nskb = skb;
+		/**
+		 * Copy the skb to a new allocated skb in lowmem only if the
+		 * data is located above 2G in memory or tailroom is < 2.
+		 */
+		unsigned long hi =
+			((unsigned long)(skb->tail + NETIUCV_HDRLEN)) >> 31;
+		int copied = 0;
+		if (hi || (skb_tailroom(skb) < 2)) {
+			nskb = alloc_skb(skb->len + NETIUCV_HDRLEN +
+					 NETIUCV_HDRLEN, GFP_ATOMIC | GFP_DMA);
+			if (!nskb) {
+				printk(KERN_WARNING
+				       "%s: Could not allocate tx_skb\n",
+				       conn->netdev->name);
+				rc = -ENOMEM;
+			} else {
+				skb_reserve(nskb, NETIUCV_HDRLEN);
+				memcpy(skb_put(nskb, skb->len),
+				       skb->data, skb->len);
+			}
+			copied = 1;
+		}
+		/**
+		 * skb now is below 2G and has enough room. Add headers.
+		 */
+		header.next = nskb->len + NETIUCV_HDRLEN;
+		memcpy(skb_push(nskb, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN);
+		header.next = 0;
+		memcpy(skb_put(nskb, NETIUCV_HDRLEN), &header,  NETIUCV_HDRLEN);
+
+		conn->retry = 0;
+		fsm_newstate(conn->fsm, CONN_STATE_TX);
+		fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC,
+			     CONN_EVENT_TIMER, conn);
+		conn->prof.send_stamp = xtime;
+		rc = iucv_send(conn->pathid, NULL, 0, 0, (__u32)nskb, 0,
+			       nskb->data, nskb->len);
+		conn->prof.doios_single++;
+		conn->prof.txlen += skb->len;
+		if (rc != 0) {
+			fsm_deltimer(&conn->timer);
+			if (copied)
+				dev_kfree_skb(nskb);
+			else {
+				/**
+				 * Remove our headers. They get added
+				 * again on retransmit.
+				 */
+				skb_pull(skb, NETIUCV_HDRLEN);
+				skb_trim(skb, skb->len - NETIUCV_HDRLEN);
+			}
+		} else {
+			if (copied)
+				dev_kfree_skb(skb);
 		}
-		/* We won't get interrupt.  Free frame now. */
-		kfree (frame);
 	}
-	dev_kfree_skb (skb);	/* Finished with skb            */
 
-	netif_wake_queue (p->dev);
+	return rc;
+}
+
+/**
+ * Interface API for upper network layers
+ *****************************************************************************/
+
+/**
+ * Open an interface.
+ * Called from generic network layer when ifconfig up is run.
+ *
+ * @param dev Pointer to interface struct.
+ *
+ * @return 0 on success, -ERRNO on failure. (Never fails.)
+ */
+static int
+netiucv_open(net_device *dev) {
+	MOD_INC_USE_COUNT;
+	fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START, dev);
+	return 0;
+}
+
+/**
+ * Close an interface.
+ * Called from generic network layer when ifconfig down is run.
+ *
+ * @param dev Pointer to interface struct.
+ *
+ * @return 0 on success, -ERRNO on failure. (Never fails.)
+ */
+static int
+netiucv_close(net_device *dev) {
+	SET_DEVICE_START(dev, 0);
+	fsm_event(((netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/**
+ * Start transmission of a packet.
+ * Called from generic network device layer.
+ *
+ * @param skb Pointer to buffer containing the packet.
+ * @param dev Pointer to interface struct.
+ *
+ * @return 0 if packet consumed, !0 if packet rejected.
+ *         Note: If we return !0, then the packet is free'd by
+ *               the generic network layer.
+ */
+static int netiucv_tx(struct sk_buff *skb, net_device *dev)
+{
+	int          rc = 0;
+	netiucv_priv *privptr = (netiucv_priv *)dev->priv;
+
+	/**
+	 * Some sanity checks ...
+	 */
+	if (skb == NULL) {
+		printk(KERN_WARNING "%s: NULL sk_buff passed\n", dev->name);
+		privptr->stats.tx_dropped++;
+		return 0;
+	}
+	if (skb_headroom(skb) < (NETIUCV_HDRLEN)) {
+		printk(KERN_WARNING
+		       "%s: Got sk_buff with head room < %ld bytes\n",
+		       dev->name, NETIUCV_HDRLEN);
+		dev_kfree_skb(skb);
+		privptr->stats.tx_dropped++;
+		return 0;
+	}
+
+	/**
+	 * If connection is not running, try to restart it
+	 * notify anybody about a link failure and throw
+	 * away packet. 
+	 */
+	if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
+		fsm_event(privptr->fsm, DEV_EVENT_START, dev);
+		dst_link_failure(skb);
+		dev_kfree_skb(skb);
+		privptr->stats.tx_dropped++;
+		privptr->stats.tx_errors++;
+		privptr->stats.tx_carrier_errors++;
+		return 0;
+	}
+
+	if (netiucv_test_and_set_busy(dev))
+		return -EBUSY;
+
+	dev->trans_start = jiffies;
+	if (netiucv_transmit_skb(privptr->conn, skb) != 0)
+		rc = 1;
+	netiucv_clear_busy(dev);
+	return rc;
+}
+
+/**
+ * Returns interface statistics of a device.
+ *
+ * @param dev Pointer to interface struct.
+ *
+ * @return Pointer to stats struct of this interface.
+ */
+static struct net_device_stats *
+netiucv_stats (net_device * dev)
+{
+	return &((netiucv_priv *)dev->priv)->stats;
+}
+
+/**
+ * Sets MTU of an interface.
+ *
+ * @param dev     Pointer to interface struct.
+ * @param new_mtu The new MTU to use for this interface.
+ *
+ * @return 0 on success, -EINVAL if MTU is out of valid range.
+ *         (valid range is 576 .. NETIUCV_MTU_MAX).
+ */
+static int
+netiucv_change_mtu (net_device * dev, int new_mtu)
+{
+	if ((new_mtu < 576) || (new_mtu > NETIUCV_MTU_MAX))
+		return -EINVAL;
+	dev->mtu = new_mtu;
 	return 0;
-}				/* end iucv_tx() */
+}
+
+
+/**
+ * procfs related structures and routines
+ *****************************************************************************/
+
+static net_device *
+find_netdev_by_ino(unsigned long ino)
+{
+	iucv_connection *conn = connections;
+	net_device *dev = NULL;
+	netiucv_priv *privptr;
+
+	while (conn) {
+		if (conn->netdev != dev) {
+			dev = conn->netdev;
+			privptr = (netiucv_priv *)dev->priv;
+
+			if ((privptr->proc_buffer_entry->low_ino == ino) ||
+			    (privptr->proc_user_entry->low_ino == ino)   ||
+			    (privptr->proc_stat_entry->low_ino == ino)     )
+				return dev;
+		}
+		conn = conn->next;
+	}
+	return NULL;
+}
 
-/*-----------------------------------------------------------*/
-/* SEND COMPLETE                    Called by IUCV handler.  */
-/* Free the IUCV frame that was used for this transmission.  */
-/*-----------------------------------------------------------*/
+#if LINUX_VERSION_CODE < 0x020363
+/**
+ * Lock the module, if someone changes into
+ * our proc directory.
+ */
 static void
-send_complete (iucv_MessageComplete * mci, void *pgm_data)
+netiucv_fill_inode(struct inode *inode, int fill)
 {
-	void *frame;
-#ifdef DEBUG
-	struct iucv_priv *p = (struct iucv_priv *) pgm_data;
+	if (fill) {
+		MOD_INC_USE_COUNT;
+	} else
+		MOD_DEC_USE_COUNT;
+}
 #endif
-	frame = (void *) (ulong) mci->ipmsgtag;
-	kfree (frame);
-	pr_debug ("%s: TX DONE %i.%i @=%p\n",
-		  p->dev->name, mci->ippathid, mci->ipmsgid, frame);
-}				/* end send_complete() */
 
-/*-----------------------------------------------------------*/
-/* STATISTICS reporting.                  Called by kernel.  */
-/*-----------------------------------------------------------*/
-static struct net_device_stats *
-iucv_stats (net_device * dev)
+#define CTRL_BUFSIZE 40
+
+static int
+netiucv_buffer_open(struct inode *inode, struct file *file)
 {
-	struct iucv_priv *p = (struct iucv_priv *) dev->priv;
-	return &p->stats;
-}				/* end iucv_stats() */
-
-/*-----------------------------------------------------------*/
-/* MTU change    .                        Called by kernel.  */
-/* IUCV can handle mtu sizes from 576 (the IP architectural  */
-/* minimum) up to maximum supported by VM.  I don't think IP */
-/* pays attention to new mtu until device is restarted.      */
-/*-----------------------------------------------------------*/
+	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
+	if (file->private_data == NULL)
+		return -ENOMEM;
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
 static int
-iucv_change_mtu (net_device * dev, int new_mtu)
+netiucv_buffer_close(struct inode *inode, struct file *file)
 {
-	if ((new_mtu < 576) || (new_mtu > MAX_VM_MTU))
+	kfree(file->private_data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static ssize_t
+netiucv_buffer_write(struct file *file, const char *buf, size_t count,
+			   loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	net_device   *dev;
+	netiucv_priv *privptr;
+	char         *e;
+	int          bs1;
+	char         tmp[CTRL_BUFSIZE];
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+	privptr = (netiucv_priv *)dev->priv;
+
+	if (count >= 39)
 		return -EINVAL;
-	dev->mtu = new_mtu;
+
+	if (copy_from_user(tmp, buf, count))
+		return -EFAULT;
+	tmp[count+1] = '\0';
+	bs1 = simple_strtoul(tmp, &e, 0);
+
+	if ((bs1 > NETIUCV_BUFSIZE_MAX) ||
+	    (e && (!isspace(*e))))
+		return -EINVAL;
+	if ((dev->flags & IFF_RUNNING) &&
+	    (bs1 < (dev->mtu + NETIUCV_HDRLEN + 2)))
+		return -EINVAL;
+	if (bs1 < (576 + NETIUCV_HDRLEN + NETIUCV_HDRLEN))
+		return -EINVAL;
+
+
+	privptr->conn->max_buffsize = bs1;
+	if (!(dev->flags & IFF_RUNNING))
+		dev->mtu = bs1 - NETIUCV_HDRLEN - NETIUCV_HDRLEN;
+	privptr->conn->flags |= CONN_FLAGS_BUFSIZE_CHANGED;
+
+	return count;
+}
+
+static ssize_t
+netiucv_buffer_read(struct file *file, char *buf, size_t count, loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	char *sbuf = (char *)file->private_data;
+	net_device *dev;
+	netiucv_priv *privptr;
+	ssize_t ret = 0;
+	char *p = sbuf;
+	int l;
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+	privptr = (netiucv_priv *)dev->priv;
+
+	if (file->f_pos == 0)
+		sprintf(sbuf, "%d\n", privptr->conn->max_buffsize);
+
+	l = strlen(sbuf);
+	p = sbuf;
+	if (file->f_pos < l) {
+		p += file->f_pos;
+		l = strlen(p);
+		ret = (count > l) ? l : count;
+		if (copy_to_user(buf, p, ret))
+			return -EFAULT;
+	}
+	file->f_pos += ret;
+	return ret;
+}
+
+static int
+netiucv_user_open(struct inode *inode, struct file *file)
+{
+	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
+	if (file->private_data == NULL)
+		return -ENOMEM;
+	MOD_INC_USE_COUNT;
 	return 0;
-}				/* end iucv_change_mtu() */
+}
+
+static int
+netiucv_user_close(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static ssize_t
+netiucv_user_write(struct file *file, const char *buf, size_t count,
+			   loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	net_device   *dev;
+	netiucv_priv *privptr;
+	int          i;
+	char         *p;
+	char         tmp[CTRL_BUFSIZE];
+	char         user[9];
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+	privptr = (netiucv_priv *)dev->priv;
+
+	if (count >= 39)
+		return -EINVAL;
+
+	if (copy_from_user(tmp, buf, count))
+		return -EFAULT;
+	tmp[count+1] = '\0';
+
+	memset(user, ' ', sizeof(user));
+	user[8] = '\0';
+	for (p = tmp, i = 0; *p && (!isspace(*p)); p++) {
+		if (i > 7)
+			return -EINVAL;
+		user[i++] = *p;
+	}
+
+	if (memcmp(user, privptr->conn->userid, 8) != 0) {
+		/* username changed */
+		if (dev->flags & IFF_RUNNING)
+			return -EBUSY;
+	}
+	memcpy(privptr->conn->userid, user, 9);
+	return count;
+}
 
-/*-----------------------------------------------------------*/
-/* INIT device.                           Called by kernel.  */
-/* Called by register_netdev() in kernel.                    */
-/*-----------------------------------------------------------*/
-static int
-iucv_init (net_device * dev)
-{
-	dev->open = iucv_start;
-	dev->stop = iucv_stop;
-	dev->hard_start_xmit = iucv_tx;
-	dev->get_stats = iucv_stats;
-	dev->change_mtu = iucv_change_mtu;
-	dev->hard_header_len = 0;
-	dev->addr_len = 0;
-	dev->type = ARPHRD_SLIP;
-	dev->tx_queue_len = MAX_TX_Q;	/* Default - updated based on IUCV */
-	/* keep the default flags, just add NOARP and POINTOPOINT */
-	dev->flags |= IFF_NOARP | IFF_POINTOPOINT;
-	dev->mtu = 9216;
+static ssize_t
+netiucv_user_read(struct file *file, char *buf, size_t count, loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	char *sbuf = (char *)file->private_data;
+	net_device *dev;
+	netiucv_priv *privptr;
+	ssize_t ret = 0;
+	char *p = sbuf;
+	int l;
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+	privptr = (netiucv_priv *)dev->priv;
+
+
+	if (file->f_pos == 0)
+		sprintf(sbuf, "%s\n",
+			netiucv_printname(privptr->conn->userid));
+
+	l = strlen(sbuf);
+	p = sbuf;
+	if (file->f_pos < l) {
+		p += file->f_pos;
+		l = strlen(p);
+		ret = (count > l) ? l : count;
+		if (copy_to_user(buf, p, ret))
+			return -EFAULT;
+	}
+	file->f_pos += ret;
+	return ret;
+}
 
-	dev_init_buffers (dev);
-	pr_debug ("%s: iucv_init  dev@=%p\n", dev->name, dev);
+#define STATS_BUFSIZE 2048
+
+static int
+netiucv_stat_open(struct inode *inode, struct file *file)
+{
+	file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL);
+	if (file->private_data == NULL)
+		return -ENOMEM;
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
-#ifndef MODULE
-/*-----------------------------------------------------------------*/
-/* Process iucv=userid1,...,useridn kernel parameter.              */
-/*                                                                 */
-/* Each user id provided will be associated with device 'iucvnn'.  */
-/* iucv_init will be called to initialize each device.             */
-/*-----------------------------------------------------------------*/
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
-#define init_return(a) return a
-static int __init
-iucv_setup (char *iucv)
+static int
+netiucv_stat_close(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static ssize_t
+netiucv_stat_write(struct file *file, const char *buf, size_t count, loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	net_device *dev;
+	netiucv_priv *privptr;
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	privptr = (netiucv_priv *)dev->priv;
+	privptr->conn->prof.maxmulti = 0;
+	privptr->conn->prof.maxcqueue = 0;
+	privptr->conn->prof.doios_single = 0;
+	privptr->conn->prof.doios_multi = 0;
+	privptr->conn->prof.txlen = 0;
+	privptr->conn->prof.tx_time = 0;
+	return count;
+}
+
+static ssize_t
+netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off)
+{
+	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	char *sbuf = (char *)file->private_data;
+	net_device *dev;
+	netiucv_priv *privptr;
+	ssize_t ret = 0;
+	char *p = sbuf;
+	int l;
+
+	if (!(dev = find_netdev_by_ino(ino)))
+		return -ENODEV;
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+	privptr = (netiucv_priv *)dev->priv;
+
+	if (file->f_pos == 0) {
+		p += sprintf(p, "Device FSM state: %s\n",
+			     fsm_getstate_str(privptr->fsm));
+		p += sprintf(p, "RX channel FSM state: %s\n",
+			     fsm_getstate_str(privptr->conn->fsm));
+		p += sprintf(p, "TX channel FSM state: %s\n",
+			     fsm_getstate_str(privptr->conn->fsm));
+		p += sprintf(p, "Max. TX buffer used: %ld\n",
+			     privptr->conn->prof.maxmulti);
+		p += sprintf(p, "Max. chained SKBs: %ld\n",
+			     privptr->conn->prof.maxcqueue);
+		p += sprintf(p, "TX single write ops: %ld\n",
+			     privptr->conn->prof.doios_single);
+		p += sprintf(p, "TX multi write ops: %ld\n",
+			     privptr->conn->prof.doios_multi);
+		p += sprintf(p, "Netto bytes written: %ld\n",
+			     privptr->conn->prof.txlen);
+		p += sprintf(p, "Max. TX IO-time: %ld\n",
+			     privptr->conn->prof.tx_time);
+	}
+	l = strlen(sbuf);
+	p = sbuf;
+	if (file->f_pos < l) {
+		p += file->f_pos;
+		l = strlen(p);
+		ret = (count > l) ? l : count;
+		if (copy_to_user(buf, p, ret))
+			return -EFAULT;
+	}
+	file->f_pos += ret;
+	return ret;
+}
+
+static struct file_operations netiucv_stat_fops = {
+	read:    netiucv_stat_read,
+	write:   netiucv_stat_write,
+	open:    netiucv_stat_open,
+	release: netiucv_stat_close,
+};
+
+static struct file_operations netiucv_buffer_fops = {
+	read:    netiucv_buffer_read,
+	write:   netiucv_buffer_write,
+	open:    netiucv_buffer_open,
+	release: netiucv_buffer_close,
+};
+
+static struct file_operations netiucv_user_fops = {
+	read:    netiucv_user_read,
+	write:   netiucv_user_write,
+	open:    netiucv_user_open,
+	release: netiucv_user_close,
+};
+
+static struct inode_operations netiucv_stat_iops = {
+#if LINUX_VERSION_CODE < 0x020363
+	default_file_ops: &netiucv_stat_fops
+#endif
+};
+static struct inode_operations netiucv_buffer_iops = {
+#if LINUX_VERSION_CODE < 0x020363
+	default_file_ops: &netiucv_buffer_fops
+#endif
+};
+
+static struct inode_operations netiucv_user_iops = {
+#if LINUX_VERSION_CODE < 0x020363
+	default_file_ops: &netiucv_user_fops
+#endif
+};
+
+static struct proc_dir_entry stat_entry = {
+	0,                           /* low_ino */
+	10,                          /* namelen */
+	"statistics",                /* name    */
+	S_IFREG | S_IRUGO | S_IWUSR, /* mode    */
+	1,                           /* nlink   */
+	0,                           /* uid     */
+	0,                           /* gid     */
+	0,                           /* size    */
+	&netiucv_stat_iops           /* ops     */
+};
+
+static struct proc_dir_entry buffer_entry = {
+	0,                           /* low_ino */
+	10,                          /* namelen */
+	"buffersize",                /* name    */
+	S_IFREG | S_IRUSR | S_IWUSR, /* mode    */
+	1,                           /* nlink   */
+	0,                           /* uid     */
+	0,                           /* gid     */
+	0,                           /* size    */
+	&netiucv_buffer_iops         /* ops     */
+};
+
+static struct proc_dir_entry user_entry = {
+	0,                           /* low_ino */
+	8,                           /* namelen */
+	"username",                  /* name    */
+	S_IFREG | S_IRUSR | S_IWUSR, /* mode    */
+	1,                           /* nlink   */
+	0,                           /* uid     */
+	0,                           /* gid     */
+	0,                           /* size    */
+	&netiucv_user_iops           /* ops     */
+};
+
+#if LINUX_VERSION_CODE < 0x020363
+static struct proc_dir_entry netiucv_dir = {
+	0,                           /* low_ino  */
+	4,                           /* namelen  */
+	"iucv",                      /* name     */
+	S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */
+	2,                           /* nlink    */
+	0,                           /* uid      */
+	0,                           /* gid      */
+	0,                           /* size     */
+	0,                           /* ops      */
+	0,                           /* get_info */
+	netiucv_fill_inode           /* fill_ino (for locking) */
+};
+
+static struct proc_dir_entry netiucv_template =
+{
+	0,                           /* low_ino  */
+	0,                           /* namelen  */
+	"",                          /* name     */
+	S_IFDIR | S_IRUGO | S_IXUGO, /* mode     */
+	2,                           /* nlink    */
+	0,                           /* uid      */
+	0,                           /* gid      */
+	0,                           /* size     */
+	0,                           /* ops      */
+	0,                           /* get_info */
+	netiucv_fill_inode           /* fill_ino (for locking) */
+};
+#else
+static struct proc_dir_entry *netiucv_dir = NULL;
+static struct proc_dir_entry *netiucv_template = NULL;
+#endif
+
+/**
+ * Create the driver's main directory /proc/net/iucv
+ */
+static void
+netiucv_proc_create_main(void)
+{
+	/**
+	 * If not registered, register main proc dir-entry now
+	 */
+#if LINUX_VERSION_CODE > 0x020362
+	if (!netiucv_dir)
+		netiucv_dir = proc_mkdir("iucv", proc_net);
 #else
-#define init_return(a) return
-__initfunc (void iucv_setup (char *iucv, int *ints))
+	if (netiucv_dir.low_ino == 0)
+		proc_net_register(&netiucv_dir);
 #endif
+}
+
+#ifdef MODULE
+/**
+ * Destroy /proc/net/iucv
+ */
+static void
+netiucv_proc_destroy_main(void)
 {
-	int i, devnumber;
-	char *s;
-	char temp_userid[9];
+#if LINUX_VERSION_CODE > 0x020362
+	remove_proc_entry("iucv", proc_net);
+#else
+	proc_net_unregister(netiucv_dir.low_ino);
+#endif
+}
+#endif MODULE
 
-	i = devnumber = 0;
-	memset (temp_userid, ' ', 8);
-	temp_userid[8] = '\0';
-	printk (KERN_NOTICE "netiucv: IUCV network driver " LEVEL "\n");
+/**
+ * Create a device specific subdirectory in /proc/net/iucv/ with the
+ * same name like the device. In that directory, create 3 entries
+ * "statistics", "buffersize" and "username".
+ *
+ * @param dev The device for which the subdirectory should be created.
+ *
+ */
+static void
+netiucv_proc_create_sub(net_device *dev) {
+	netiucv_priv *privptr = dev->priv;
 
-	if (!iucv)
-		init_return (0);
+#if LINUX_VERSION_CODE > 0x020362
+	privptr->proc_dentry = proc_mkdir(dev->name, netiucv_dir);
+	privptr->proc_stat_entry =
+		create_proc_entry("statistics",
+				  S_IFREG | S_IRUSR | S_IWUSR,
+				  privptr->proc_dentry);
+	privptr->proc_stat_entry->proc_fops = &netiucv_stat_fops;
+	privptr->proc_stat_entry->proc_iops = &netiucv_stat_iops;
+	privptr->proc_buffer_entry =
+		create_proc_entry("buffersize",
+				  S_IFREG | S_IRUSR | S_IWUSR,
+				  privptr->proc_dentry);
+	privptr->proc_buffer_entry->proc_fops = &netiucv_buffer_fops;
+	privptr->proc_buffer_entry->proc_iops = &netiucv_buffer_iops;
+	privptr->proc_user_entry =
+		create_proc_entry("username",
+				  S_IFREG | S_IRUSR | S_IWUSR,
+				  privptr->proc_dentry);
+	privptr->proc_user_entry->proc_fops = &netiucv_user_fops;
+	privptr->proc_user_entry->proc_iops = &netiucv_user_iops;
+#else
+	privptr->proc_dentry->name = dev->name;
+	privptr->proc_dentry->namelen = strlen(dev->name);
+	proc_register(&netiucv_dir, privptr->proc_dentry);
+	proc_register(privptr->proc_dentry, privptr->proc_stat_entry);
+	proc_register(privptr->proc_dentry, privptr->proc_buffer_entry);
+	proc_register(privptr->proc_dentry, privptr->proc_user_entry);
+#endif
+	privptr->proc_registered = 1;
+}
 
-	for (s = iucv; *s != '\0'; s++) {
-		if (*s == ' ')	/* Compress out blanks */
-			continue;
 
-		if (devnumber >= MAX_DEVICES) {
-			printk (KERN_ERR "More than %i IUCV hosts specified\n",
-				MAX_DEVICES);
-			init_return (-ENODEV);
+/**
+ * Destroy a device specific subdirectory.
+ *
+ * @param privptr Pointer to device private data.
+ */
+static void
+netiucv_proc_destroy_sub(netiucv_priv *privptr) {
+	if (!privptr->proc_registered)
+		return;
+#if LINUX_VERSION_CODE > 0x020362
+	remove_proc_entry("statistics", privptr->proc_dentry);
+	remove_proc_entry("buffersize", privptr->proc_dentry);
+	remove_proc_entry("username", privptr->proc_dentry);
+	remove_proc_entry(privptr->proc_dentry->name, netiucv_dir);
+#else
+	proc_unregister(privptr->proc_dentry,
+			privptr->proc_stat_entry->low_ino);
+	proc_unregister(privptr->proc_dentry,
+			privptr->proc_buffer_entry->low_ino);
+	proc_unregister(privptr->proc_dentry,
+			privptr->proc_user_entry->low_ino);
+	proc_unregister(&netiucv_dir,
+			privptr->proc_dentry->low_ino);
+#endif
+	privptr->proc_registered = 0;
+}
+
+
+/**
+ * Allocate and initialize a new connection structure.
+ * Add it to the list of connections;
+ */
+static iucv_connection *
+netiucv_new_connection(net_device *dev, char *username)
+{
+	iucv_connection **clist = &connections;
+	iucv_connection *conn =
+		(iucv_connection *)kmalloc(sizeof(iucv_connection), GFP_KERNEL);
+	if (conn) {
+		memset(conn, 0, sizeof(iucv_connection));
+		skb_queue_head_init(&conn->collect_queue);
+		conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
+		conn->netdev = dev;
+
+		conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);
+		if (!conn->rx_buff) {
+			kfree(conn);
+			return NULL;
+		}
+		conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, GFP_DMA);
+		if (!conn->tx_buff) {
+			kfree_skb(conn->rx_buff);
+			kfree(conn);
+			return NULL;
 		}
+		conn->fsm = init_fsm("netiucvconn", conn_state_names,
+				     conn_event_names, NR_CONN_STATES,
+				     NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN,
+				     GFP_KERNEL);
+		if (!conn->fsm) {
+			kfree_skb(conn->tx_buff);
+			kfree_skb(conn->rx_buff);
+			kfree(conn);
+			return NULL;
+		}
+		fsm_settimer(conn->fsm, &conn->timer);
+		fsm_newstate(conn->fsm, CONN_STATE_INVALID);
 
-		if (*s != ',') {
-			temp_userid[i++] = *s;
+		if (username) {
+			memcpy(conn->userid, username, 9);
+			fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
+		}
 
-			if (i == 8 || *(s + 1) == ',' || *(s + 1) == '\0') {
-				register_iucv_dev (devnumber, temp_userid);
-				devnumber++;
-				i = 0;
-				memset (temp_userid, ' ', 8);
-				if (*(s + 1) != '\0')
-					*(s + 1) = ' ';
+		conn->next = *clist;
+		*clist = conn;
+	}
+	return conn;
+}
+
+/**
+ * Release a connection structure and remove it from the
+ * list of connections.
+ */
+static void
+netiucv_remove_connection(iucv_connection *conn)
+{
+	iucv_connection **clist = &connections;
+
+	if (conn == NULL)
+		return;
+	while (*clist) {
+		if (*clist == conn) {
+			*clist = conn->next;
+			if (conn->handle != 0) {
+				iucv_unregister_program(conn->handle);
+				conn->handle = 0;
 			}
+			fsm_deltimer(&conn->timer);
+			kfree_fsm(conn->fsm);
+			kfree_skb(conn->rx_buff);
+			kfree_skb(conn->tx_buff);
+			return;
 		}
-	}			/* while */
-
-	init_return (1);
+		clist = &((*clist)->next);
+	}
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
-__setup ("iucv=", iucv_setup);
-#endif
-#else				/* BUILT AS MODULE */
-/*-------------------------------------------------------------------*/
-/* Process iucv=userid1,...,useridn module paramter.                 */
-/*                                                                   */
-/* insmod passes the module an array of string pointers, each of     */
-/* which points to a userid.  The commas are stripped out by insmod. */
-/* MODULE_PARM defines the name of the array.  (See start of module.)*/
-/*                                                                   */
-/* Each user id provided will be associated with device 'iucvnn'.    */
-/* iucv_init will be called to initialize each device.               */
-/*-------------------------------------------------------------------*/
-char *iucv[MAX_DEVICES] = { NULL };
-int
-init_module (void)
-{
-	int i;
-	printk (KERN_NOTICE "netiucv: IUCV network driver " LEVEL "\n");
-	for (i = 0; i < MAX_DEVICES; i++) {
-		if (iucv[i] == NULL)
-			break;
-		register_iucv_dev (i, iucv[i]);
+/**
+ * Allocate and initialize everything of a net device.
+ */
+static net_device *
+netiucv_init_netdevice(int ifno, char *username)
+{
+	netiucv_priv *privptr;
+	int          priv_size;
+
+	net_device *dev = kmalloc(sizeof(net_device)
+#if LINUX_VERSION_CODE < 0x020300
+		      + 11 /* name + zero */
+#endif
+		      , GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(net_device));
+#if LINUX_VERSION_CODE < 0x020300
+	dev->name = (char *)dev + sizeof(net_device);
+#endif
+	sprintf(dev->name, "iucv%d", ifno);
+
+	priv_size = sizeof(netiucv_priv) + sizeof(netiucv_template) +
+		sizeof(stat_entry) + sizeof(buffer_entry) + sizeof(user_entry);
+	dev->priv = kmalloc(priv_size, GFP_KERNEL);
+	if (dev->priv == NULL) {
+		kfree(dev);
+		return NULL;
 	}
-	return 0;
+        memset(dev->priv, 0, priv_size);
+        privptr = (netiucv_priv *)dev->priv;
+        privptr->proc_dentry = (struct proc_dir_entry *)
+		(((char *)privptr) + sizeof(netiucv_priv));
+        privptr->proc_stat_entry = (struct proc_dir_entry *)
+		(((char *)privptr) + sizeof(netiucv_priv) +
+		 sizeof(netiucv_template));
+        privptr->proc_buffer_entry = (struct proc_dir_entry *)
+		(((char *)privptr) + sizeof(netiucv_priv) +
+		 sizeof(netiucv_template) + sizeof(stat_entry));
+        privptr->proc_user_entry = (struct proc_dir_entry *)
+		(((char *)privptr) + sizeof(netiucv_priv) +
+		 sizeof(netiucv_template) + sizeof(stat_entry) +
+		 sizeof(buffer_entry));
+	memcpy(privptr->proc_dentry, &netiucv_template,
+	       sizeof(netiucv_template));
+	memcpy(privptr->proc_stat_entry, &stat_entry, sizeof(stat_entry));
+	memcpy(privptr->proc_buffer_entry, &buffer_entry, sizeof(buffer_entry));
+	memcpy(privptr->proc_user_entry, &user_entry, sizeof(user_entry));
+	privptr->fsm = init_fsm("netiucvdev", dev_state_names,
+				dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,
+				dev_fsm, DEV_FSM_LEN, GFP_KERNEL);
+	if (privptr->fsm == NULL) {
+		kfree(privptr);
+		kfree(dev);
+		return NULL;
+	}
+	privptr->conn = netiucv_new_connection(dev, username);
+	if (!privptr->conn) {
+		kfree_fsm(privptr->fsm);
+		kfree(privptr);
+		kfree(dev);
+		return NULL;
+	}
+
+	fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);
+	dev->mtu	         = NETIUCV_MTU_DEFAULT;
+	dev->hard_start_xmit     = netiucv_tx;
+	dev->open	         = netiucv_open;
+	dev->stop	         = netiucv_close;
+	dev->get_stats	         = netiucv_stats;
+	dev->change_mtu          = netiucv_change_mtu;
+	dev->hard_header_len     = NETIUCV_HDRLEN;
+	dev->addr_len            = 0;
+	dev->type                = ARPHRD_SLIP;
+	dev->tx_queue_len        = NETIUCV_QUEUELEN_DEFAULT;
+	SET_DEVICE_START(dev, 1);
+	dev_init_buffers(dev);
+	dev->flags	         = IFF_POINTOPOINT | IFF_NOARP;
+	return dev;
 }
 
-void
-cleanup_module (void)
+/**
+ * Allocate and initialize everything of a net device.
+ */
+static void
+netiucv_free_netdevice(net_device *dev)
 {
-	int i;
-	for (i = 0; i < MAX_DEVICES; i++) {
-		if (iucv[i])
-			unregister_netdev (&iucv_netdev[i]);
+	netiucv_priv *privptr;
+
+	if (!dev)
+		return;
+
+	privptr = (netiucv_priv *)dev->priv;
+	if (privptr) {
+		if (privptr->conn)
+			netiucv_remove_connection(privptr->conn);
+		if (privptr->fsm)
+			kfree_fsm(privptr->fsm);
+		netiucv_proc_destroy_sub(privptr);
+		kfree(privptr);
 	}
-	return;
+	kfree(dev);
 }
-#endif				/* MODULE */
 
-void
-register_iucv_dev (int devnumber, char *userid)
+static void
+netiucv_banner(void)
 {
-	int rc;
-	net_device *dev;
+	char vbuf[] = "$Revision: 1.11 $";
+	char *version = vbuf;
 
-	memset (iucv_userid[devnumber], ' ', 8);
-	memcpy (iucv_userid[devnumber], userid,
-		min_t(unsigned int, strlen(userid), 8));
-	dev = &iucv_netdev[devnumber];
-	sprintf (dev->name, "iucv%i", devnumber);
-
-	pr_debug ("netiucv: registering %s\n", dev->name);
-
-	if ((rc = register_netdev (dev))) {
-		printk (KERN_ERR
-			"netiucv: register_netdev(%s) error %i\n",
-			dev->name, rc);
+	if ((version = strchr(version, ':'))) {
+		char *p = strchr(version + 1, '$');
+		if (p)
+			*p = '\0';
+	} else
+		version = " ??? ";
+	printk(KERN_INFO "NETIUCV driver Version%s initialized\n", version);
+}
+
+#ifndef MODULE
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
+#  define init_return(a) return a
+static int __init
+iucv_setup(char *param)
+# else
+#  define init_return(a) return
+__initfunc (void iucv_setup(char *param, int *ints))
+# endif
+{
+	/**
+	* We do not parse parameters here because at the time of
+	* calling iucv_setup(), the kernel does not yet have
+	* memory management running. We delay this until probing
+	* is called.
+	*/
+	iucv = param;
+	init_return(1);
+}
+
+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
+__setup ("iucv=", iucv_setup);
+# endif
+#else
+static void
+netiucv_exit(void)
+{
+	while (connections) {
+		net_device *dev = connections->netdev;
+		unregister_netdev(dev);
+		netiucv_free_netdevice(dev);
 	}
+	netiucv_proc_destroy_main();
+
+	printk(KERN_INFO "NETIUCV driver unloaded\n");
 	return;
 }
+#endif
+
+static int
+netiucv_init(void)
+{
+	char *p = iucv;
+	int ifno = 0;
+	int i = 0;
+	char username[10];
+
+	netiucv_proc_create_main();
+	while (p) {
+		if (isalnum(*p)) {
+			username[i++] = *p++;
+			username[i] = '\0';
+			if (i > 8) {
+				printk(KERN_WARNING
+				       "netiucv: Invalid user name '%s'\n",
+				       username);
+				while (*p && (*p != ':') && (*p != ','))
+					p++;
+			}
+		} else {
+			if (*p && (*p != ':') && (*p != ',')) {
+				printk(KERN_WARNING
+				       "netiucv: Invalid delimiter '%c'\n",
+				       *p);
+				while (*p && (*p != ':') && (*p != ','))
+					p++;
+			} else {
+				if (i) {
+					net_device *dev;
+
+					while (i < 9)
+						username[i++] = ' ';
+					username[9] = '\0';
+					dev = netiucv_init_netdevice(ifno,
+								     username);
+					if (!dev)
+						printk(KERN_WARNING
+						       "netiucv: Could not allocate network device structure for user '%s'\n", netiucv_printname(username));
+					else {
+						if (register_netdev(dev)) {
+							printk(KERN_WARNING
+							       "netiucv: Could not register '%s'\n", dev->name);
+							netiucv_free_netdevice(dev);
+						} else {
+							printk(KERN_INFO "%s: '%s'\n", dev->name, netiucv_printname(username));
+							netiucv_proc_create_sub(dev);
+							ifno++;
+						}
+					}						
+				}
+				if (!(*p))
+					break;
+				i = 0;
+				p++;
+			}
+		}
+	}
+	netiucv_banner();
+	return 0;
+}
 
-/* These structures are static because setup() can be called very */
-/* early in kernel init if this module is built into the kernel.  */
-/* Certainly no kmalloc() is available, probably no C runtime.    */
-/* If support changed to be module only, this can all be done     */
-/* dynamically.                                                   */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-static char iucv_names[MAX_DEVICES][8];	/* Allows "iucvXXX" plus null */
-#endif
-net_device iucv_netdev[MAX_DEVICES] = {
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[0][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[1][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[2][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[3][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[4][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[5][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[6][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[7][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[8][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[9][0],  /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[10][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[11][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[12][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[13][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[14][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[15][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[16][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[17][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[18][0], /* Name filled in at load time  */
-#endif
-		init: iucv_init           /* probe function               */
-	},
-	{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-		name: &iucv_names[19][0], /* Name filled in at load time  */
+module_init(netiucv_init);
+#ifdef MODULE
+module_exit(netiucv_exit);
 #endif
-		init: iucv_init           /* probe function               */
-	},
-};
diff -u --recursive --new-file v2.4.10/linux/drivers/s390/s390io.c linux/drivers/s390/s390io.c
--- v2.4.10/linux/drivers/s390/s390io.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/s390/s390io.c	Sun Sep 30 12:26:07 2001
@@ -1,12 +1,13 @@
 /*
- *  arch/s390/kernel/s390io.c
+ *  drivers/s390/s390io.c
  *   S/390 common I/O routines
  *
  *  S390 version
  *    Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH,
  *                             IBM Corporation
  *    Author(s): Ingo Adlung (adlung@de.ibm.com)
- *    ChangeLog: 01/04/2001 Holger Smolinski (smolinsk@de.ibm.com)
+ *    ChangeLog: 01/07/2001 Blacklist cleanup (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ *               01/04/2001 Holger Smolinski (smolinsk@de.ibm.com)
  *                          Fixed lost interrupts and do_adapter_IO
  *               xx/xx/xxxx nnn          multiple changes not reflected
  *               03/12/2001 Ingo Adlung  blacklist= - changed to cio_ignore=  
@@ -20,6 +21,9 @@
  *               05/22/2001 Cornelia Huck added /proc/cio_ignore
  *                                        un-ignore blacklisted devices by piping 
  *                                        to /proc/cio_ignore
+ *               xx/xx/xxxx some bugfixes & cleanups
+ *               08/02/2001 Cornelia Huck not already known devices can be blacklisted
+ *                                        by piping to /proc/cio_ignore
  */
 
 #include <linux/module.h>
@@ -29,7 +33,7 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/string.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
@@ -50,17 +54,26 @@
 #include <asm/lowcore.h>
 #include <asm/idals.h>
 #include <asm/uaccess.h> 
+#include <asm/cpcmd.h>
 
 #include <asm/s390io.h>
 #include <asm/s390dyn.h>
 #include <asm/s390mach.h>
 #include <asm/debug.h>
+#include <asm/queue.h>
 
 #ifndef TRUE
 #define TRUE  1
 #define FALSE 0
 #endif
 
+#define SANITY_CHECK(irq) do { \
+if (irq > highest_subchannel || irq < 0) \
+		return (-ENODEV); \
+	if (ioinfo[irq] == INVALID_STORAGE_AREA) \
+		return (-ENODEV); \
+	} while(0) 
+
 #undef  CONFIG_DEBUG_IO
 #define CONFIG_DEBUG_CRW
 
@@ -129,6 +142,9 @@
 int cio_proc_devinfo = 0; /* switch off the /proc/deviceinfo/ stuff by default
 			     until problems are dealt with */
 
+unsigned long s390_irq_count[NR_CPUS]; /* trace how many irqs have occured per cpu... */
+int cio_count_irqs = 1;       /* toggle use here... */
+
 /* 
  * "Blacklisting" of certain devices:
  * Device numbers given in the commandline as blacklist=... won't be known to Linux
@@ -139,109 +155,39 @@
  */
 
 typedef struct dev_blacklist_range_t {
+     struct dev_blacklist_range_t *next;  /* next range in list */
      unsigned int from;                   /* beginning of range */
      unsigned int to;                     /* end of range */
-     struct dev_blacklist_range_t *next;  /* next range in list */
+     int  kmalloced;	
+    
 } dev_blacklist_range_t;
 
 static dev_blacklist_range_t *dev_blacklist_range_head = NULL; /* Anchor for list of ranges */
+static dev_blacklist_range_t *dev_blacklist_unused_head = NULL;
+
 static spinlock_t blacklist_lock = SPIN_LOCK_UNLOCKED;
 static int nr_blacklisted_ranges = 0;
 
 /* Handling of the blacklist ranges */
 
-/* 
- * Function: blacklist_range_create
- * Creates a range from the given parameters
- */
-static inline dev_blacklist_range_t *blacklist_range_create( int from, int to)
+static inline void blacklist_range_destroy( dev_blacklist_range_t *range,int locked )
 {
-     dev_blacklist_range_t *range = NULL;
-
-     if (to && (from>to)) {
-	     printk("Invalid blacklist range %x to %x, skipping\n", from, to);
-	     return NULL;
-     }
-     if (init_IRQ_complete) {
-	     range = ( dev_blacklist_range_t *) kmalloc( sizeof( dev_blacklist_range_t ), GFP_KERNEL);
-     } else {
-	     range = ( dev_blacklist_range_t *) alloc_bootmem( sizeof( dev_blacklist_range_t ) );
-     }
-     if (range == NULL)
-	  return NULL;
-     memset( range, 0, sizeof( dev_blacklist_range_t ));
-     range->from = from;
-     if (to == 0) {           /* only a single device is given */
-	  range->to = from;
-     } else {
-	  range->to = to;
-     }
-     nr_blacklisted_ranges++;
-     return range;
+	 long flags;
+	 
+	 if(!locked)
+		 spin_lock_irqsave( &blacklist_lock, flags ); 
+	 if(!remove_from_list((list **)&dev_blacklist_range_head,(list *)range))
+		 BUG();
+	 nr_blacklisted_ranges--;
+	 if(range->kmalloced)
+		 kfree(range);
+	 else
+		 add_to_list((list **)&dev_blacklist_unused_head,(list *)range); 
+	 if(!locked)
+		 spin_unlock_irqrestore( &blacklist_lock, flags );
 }
 
-/* 
- * Function: blacklist_range_destroy
- * Free the given range
- */
 
-static inline void blacklist_range_destroy( dev_blacklist_range_t *range )
-{
-	nr_blacklisted_ranges--;
-	/*
-	 * FIXME: the memory was allocated as bootmem, 
-	 * how to get it free again ?! 
-	 */
-	/* kfree( range ); */
-}
-
-/*
- * Function: blacklist_range_append
- * Append a range to the list of blacklisted ranges anchored at dev_blacklist_range_head
- */
-
-static inline void blacklist_range_append( dev_blacklist_range_t *range )
-{
-     dev_blacklist_range_t *temp;
-     long flags;
-
-     spin_lock_irqsave( &blacklist_lock, flags );
-     if (dev_blacklist_range_head == NULL) {
-	  dev_blacklist_range_head = range;
-     } else {
-	  for ( temp = dev_blacklist_range_head;
-		temp && temp->next;
-		temp = temp->next );
-	  temp->next = range;
-     }
-     spin_unlock_irqrestore( &blacklist_lock, flags );
-}
-
-/*
- * Function: blacklist_range_dechain
- * Remove a range from the list of blacklisted ranges
- */
-
-static inline void blacklist_range_dechain( dev_blacklist_range_t *range )
-{
-     dev_blacklist_range_t *temp, *prev = NULL;
-     long flags;
-     
-     spin_lock_irqsave( &blacklist_lock, flags );
-     for ( temp = dev_blacklist_range_head; temp != NULL; temp = temp->next ) {
-	  if ( temp == range )
-	       break;
-	  prev = temp;
-     }
-     if (!temp)
-	  BUG();
-     if (prev) {
-	  prev->next = range->next;
-     } else {
-	  dev_blacklist_range_head = range->next;
-     }
-     spin_unlock_irqrestore( &blacklist_lock, flags );
-}
 
 /* 
  * Function: blacklist_range_add
@@ -249,15 +195,44 @@
  * blacklisted devices
  */
 
-static inline dev_blacklist_range_t *blacklist_range_add( int from, int to )
+static inline dev_blacklist_range_t *blacklist_range_add( int from, int to,int locked)
 {
-     dev_blacklist_range_t *temp;
+ 
+     dev_blacklist_range_t *range = NULL;
+     unsigned long flags;
 
-     temp = blacklist_range_create( from, to );
-     if (!temp) 
-	  return NULL;
-     blacklist_range_append( temp );
-     return temp;
+     if (to && (from>to)) {
+	     printk(KERN_WARNING "Invalid blacklist range %x to %x, skipping\n", from, to);
+	     return NULL;
+     }
+     if(!locked)
+	     spin_lock_irqsave( &blacklist_lock, flags );
+     if(dev_blacklist_unused_head)
+	     range=(dev_blacklist_range_t *)
+		     remove_listhead((list **)&dev_blacklist_unused_head);
+     else if (init_IRQ_complete) {
+	     if((range = ( dev_blacklist_range_t *) 
+		 kmalloc( sizeof( dev_blacklist_range_t ), GFP_KERNEL)))
+		     range->kmalloced=1;
+     } else {
+	     if((range = ( dev_blacklist_range_t *) 
+		 alloc_bootmem( sizeof( dev_blacklist_range_t ) )))
+		     range->kmalloced=0;
+     }
+     if (range)
+     {
+	     add_to_list((list **)&dev_blacklist_range_head,(list *)range);
+	     range->from = from;
+	     if (to == 0) {           /* only a single device is given */
+		     range->to = from;
+	     } else {
+		     range->to = to;
+	     }
+	     nr_blacklisted_ranges++;
+     }
+     if(!locked)
+	     spin_unlock_irqrestore( &blacklist_lock, flags );
+     return range;
 }
 
 /* 
@@ -268,12 +243,14 @@
 static inline void blacklist_range_remove( int from, int to )
 {
      dev_blacklist_range_t *temp;
+     long flags;
 
+     spin_lock_irqsave( &blacklist_lock, flags );
      for ( temp = dev_blacklist_range_head; 
 	   (temp->from != from) && (temp->to != to);
 	   temp = temp->next );
-     blacklist_range_dechain( temp );
-     blacklist_range_destroy( temp );
+     blacklist_range_destroy( temp,1 );
+     spin_unlock_irqrestore( &blacklist_lock, flags );
 }
 
 /* Parsing the commandline for blacklist parameters */
@@ -361,7 +338,7 @@
 	       temp++;
 	       to = blacklist_strtoul( temp, &temp );
 	  }
-	  if (!blacklist_range_add( from, to )) {
+	  if (!blacklist_range_add( from, to,0 )) {
 	       printk( KERN_WARNING "Blacklisting range from %X to %X failed!\n", from, to);
 	  }
 #ifdef CONFIG_DEBUG_IO
@@ -430,20 +407,25 @@
 static inline int is_blacklisted( int devno )
 {
      dev_blacklist_range_t *temp;
+     long flags;
+     int retval=0;
 
      if (dev_blacklist_range_head == NULL) {  
 	  /* no blacklist */
 	  return 0;
      }
 
+     spin_lock_irqsave( &blacklist_lock, flags ); 
      temp = dev_blacklist_range_head;
      while (temp) {
 	  if ((temp->from <= devno) && (temp->to >= devno)) {
-	       return 1;                      /* Deviceno is blacklisted */
+		  retval=1;                      /* Deviceno is blacklisted */
+		  break;
 	  }
 	  temp = temp->next;
      }
-     return 0;
+     spin_unlock_irqrestore( &blacklist_lock, flags );
+     return retval;
 }
 
 /*
@@ -454,12 +436,14 @@
 void blacklist_free_all_ranges(void) 
 {
 	dev_blacklist_range_t *tmp = dev_blacklist_range_head;
+	unsigned long flags;
 
+	spin_lock_irqsave( &blacklist_lock, flags ); 
 	while (tmp) {
-		blacklist_range_dechain(tmp);
-		blacklist_range_destroy(tmp);
+		blacklist_range_destroy(tmp,1);
 		tmp = dev_blacklist_range_head;
 	}
+	spin_unlock_irqrestore( &blacklist_lock, flags );
 }
 
 /*
@@ -477,6 +461,8 @@
 	int to = 0;
 	int changed = 0;
 	dev_blacklist_range_t *range, *temp;
+	long flags;
+	int err = 0;
 
 	tmp = buf;
 	if (strstr(tmp, "free ")) {
@@ -506,39 +492,97 @@
 				} else {
 					to = from;
 				}
+				spin_lock_irqsave( &blacklist_lock, flags ); 
 				range = dev_blacklist_range_head;
 				while (range != NULL) {
 					temp = range->next;
 					if ((from <= range->from) && (to >= range->to)) {
-						blacklist_range_dechain(range);
-						blacklist_range_destroy(range);
+						blacklist_range_destroy(range,1);
 						changed = 1;
 					} else if ((from <= range->from) && (to>=range->from) && (to < range->to)) {
-						blacklist_range_add(to+1, range->to);
-						blacklist_range_dechain(range);
-						blacklist_range_destroy(range);
+						blacklist_range_add(to+1, range->to,1);
+						blacklist_range_destroy(range,1);
 						changed = 1;
 					} else if ((from > range->from) && (from<=range->to) && (to >= range->to)) {
-						blacklist_range_add(range->from, from-1);
-						blacklist_range_dechain(range);
-						blacklist_range_destroy(range);
+						blacklist_range_add(range->from, from-1,1);
+						blacklist_range_destroy(range,1);
 						changed = 1;
 					} else if ((from > range->from) && (to < range->to)) {
-						blacklist_range_add(range->from, from-1);
-						blacklist_range_add(to+1, range->to);
-						blacklist_range_dechain(range);
-						blacklist_range_destroy(range);
+						blacklist_range_add(range->from, from-1,1);
+						blacklist_range_add(to+1, range->to,1);
+						blacklist_range_destroy(range,1);
 						changed = 1;
 					}
 					range = temp;
 				}
+				spin_unlock_irqrestore( &blacklist_lock, flags );
 				kfree(param);
 			}
 			if (changed)
 				s390_redo_validation();
 		}
+	} else if (strstr(tmp, "add ")) {
+		for (i=0;i<4;i++){
+			tmp++;
+		}
+		while (tmp != NULL) {
+			end = strchr(tmp, ',');
+			if (end == NULL) {
+				len = strlen(tmp) + 1;
+			} else {
+				len = (long)end - (long) tmp + 1;
+				*end = '\0';
+				end++;
+			}
+			param =  (char*) kmalloc(len * sizeof(char) + 1, GFP_KERNEL);
+			strncpy(param, (const char *) tmp, len);
+			tmp = end;
+			from = blacklist_strtoul(param, &param);
+			if (*param == '-') {
+				param++;
+				to = blacklist_strtoul(param, &param);
+			} else {
+				to = from;
+			}
+			spin_lock_irqsave( &blacklist_lock, flags ); 
+			
+			/*
+			 * Don't allow for already known devices to be
+			 * blacklisted
+			 * The criterion is a bit dumb, devices which once were
+			 * there but are already gone are also caught...
+			 */
+			
+			err = 0;
+			for (i=0; i<=highest_subchannel; i++) {
+				if (ioinfo[i]!=INVALID_STORAGE_AREA) {
+					if (   (ioinfo[i]->schib.pmcw.dev >= from)
+					    && (ioinfo[i]->schib.pmcw.dev <= to)  ) {
+						printk(KERN_WARNING "cio_ignore: Won't blacklist "
+						       "already known devices, skipping range "
+						       "%x to %x\n", from, to);
+						err = 1;
+						break;
+					}
+				}
+			}
+
+			/*
+			 * Note: We allow for overlapping ranges here, 
+			 * since the user might specify overlapping ranges
+			 * and we walk through all ranges when freeing anyway.
+			 */
+
+			if (!err) 
+				blacklist_range_add(from, to, 1);
+			
+			spin_unlock_irqrestore( &blacklist_lock, flags );
+			kfree(param);
+		}
+
 	} else {
 		printk("cio_ignore: Parse error; try using 'free all|<devno-range>,<devno-range>,...'\n");
+		printk("or 'add <devno-range>,<devno-range>,...'\n");
 	}
 }
 
@@ -571,17 +615,19 @@
 {
 	s32 cnt1, cnt2, maxcnt2;
 	u32 *currptr = (__u32 *)ptr;
+	char buffer[cnt*12];
 
 	debug_sprintf_event(cio_debug_msg_id, level, "%s\n", str);
 
 	for (cnt1 = 0; cnt1<cnt; cnt1+=16) {
-		debug_sprintf_event(cio_debug_msg_id, level, "%08lX ", (unsigned long)currptr);
+		sprintf(buffer, "%08lX ", (unsigned long)currptr);
 		maxcnt2 = cnt - cnt1;
 		if (maxcnt2 > 16)
 			maxcnt2 = 16;
 		for (cnt2 = 0; cnt2 < maxcnt2; cnt2 += 4)
-			debug_sprintf_event(cio_debug_msg_id, level, "%08X ", *currptr++);
+			sprintf(buffer, "%08X ", *currptr++);
 	}
+	debug_sprintf_event(cio_debug_msg_id, level, "%s\n",buffer);
 }
 
 static int __init cio_setup( char *parm )
@@ -704,6 +750,10 @@
 	return;  	
 }
 
+/*
+ * Note : internal use of irqflags SA_PROBE for NOT path grouping 
+ *
+ */
 int s390_request_irq_special( int                      irq,
                               io_handler_func_t        io_handler,
                               not_oper_handler_func_t  not_oper_handler,
@@ -714,6 +764,7 @@
 	int		retval = 0;
 	unsigned long	flags;
 	char            dbf_txt[15];
+	int             retry;
 
 	if (irq >= __MAX_SUBCHANNELS)
 		return -EINVAL;
@@ -738,12 +789,28 @@
 
 	if ( !ioinfo[irq]->ui.flags.ready )
 	{
+		retry = 5;
+		
 		ioinfo[irq]->irq_desc.handler = io_handler;
 		ioinfo[irq]->irq_desc.name    = devname;
 		ioinfo[irq]->irq_desc.dev_id  = dev_id;
 		ioinfo[irq]->ui.flags.ready   = 1;
+		
+		
+		do {
+			retval = enable_subchannel(irq);
+			if (retval) {
+				ioinfo[irq]->ui.flags.ready = 0;
+				break;
+			}
+			
+			stsch(irq,&ioinfo[irq]->schib);
+			if (ioinfo[irq]->schib.pmcw.ena) 
+				retry = 0;
+			else
+				retry--;
 
-		enable_subchannel(irq);
+		} while (retry);
 	}
 	else
 	{
@@ -761,7 +828,8 @@
 
 	if ( retval == 0 )
 	{
-		s390_DevicePathVerification( irq, 0 );
+		if ( !(irqflags & SA_PROBE))
+			s390_DevicePathVerification( irq, 0 );
 
 		ioinfo[irq]->ui.flags.newreq = 1;
 		ioinfo[irq]->nopfunc         = not_oper_handler;  	
@@ -838,6 +906,15 @@
 			/* start deregister */
 			ioinfo[irq]->ui.flags.unready = 1;
 
+			/*
+			 * Try to stop IO first...
+			 * ... it seems disable_subchannel is sometimes
+			 * successfully called with IO still pending.
+			 */
+			halt_IO( irq,
+				 0xC8C1D3E3,
+				 DOIO_WAIT_FOR_INTERRUPT );
+
 			do
 			{
 				ret = disable_subchannel( irq);
@@ -888,23 +965,23 @@
 					} /* endif */
 
 					if ( count == 2 )
-               {
+					{
 						/* give it a very last try ... */
 						disable_subchannel( irq);
 
 						if ( ioinfo[irq]->ui.flags.busy )
-					   {
+					        {
 							printk( KERN_CRIT"free_irq(%04X) "
 							       "- device %04X busy, retry "
 							       "count exceeded\n",
-						   	    irq,
-						      	 ioinfo[irq]->devstat.devno);
+								irq,
+								ioinfo[irq]->devstat.devno);
 							if (cio_debug_initialized)
 								debug_sprintf_event(cio_debug_msg_id, 0,
 										    "free_irq(%04X) - device %04X busy, retry count exceeded\n",
 										    irq, ioinfo[irq]->devstat.devno);
 
-                  } /* endif */
+						} /* endif */
 						
 						break; /* sigh, let's give up ... */
 
@@ -957,8 +1034,7 @@
 	int           ret;
 	char dbf_txt[15];
 
-	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-		return( -ENODEV);
+	SANITY_CHECK(irq);
 
 	if ( !ioinfo[irq]->ui.flags.ready )
 		return -ENODEV;
@@ -984,8 +1060,7 @@
 	int           ret;
 	char dbf_txt[15];
 
-	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-		return( -ENODEV);
+	SANITY_CHECK(irq);
 
 	if ( !ioinfo[irq]->ui.flags.ready )
 		return -ENODEV;
@@ -1008,19 +1083,12 @@
  */
 static int enable_subchannel( unsigned int irq)
 {
-	int   ret;
+	int   ret = 0;
 	int   ccode;
 	int   retry = 5;
 	char dbf_txt[15];
 
-	if ( irq > highest_subchannel || irq < 0 )
-	{
-		return( -ENODEV );
-
-	} /* endif */
-
-	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-		return( -ENODEV);
+	SANITY_CHECK(irq);
 
 	if (cio_debug_initialized) {
 		debug_text_event(cio_debug_trace_id, 2, "ensch");
@@ -1064,19 +1132,12 @@
 				ccode = msch( irq, &(ioinfo[irq]->schib) );
 
 				switch (ccode) {
-				case 0:
+				case 0: /* ok */
 					ret = 0;
+					retry = 0;
 					break;
 
-				case 1:
-					/*
-					 * very bad, requires interrupt alike
-					 *  processing, where "rbh" is a dummy
-					 *  parameter for interface compatibility
-					 *  only. Bottom-half handling cannot be
-					 *  required as this must be an
-					 *  unsolicited interrupt (!busy).
-					 */
+				case 1: /* status pending */
 
 					ioinfo[irq]->ui.flags.s_pend = 1;
 					s390_process_IRQ( irq );
@@ -1084,36 +1145,24 @@
 
 					ret = -EIO;    /* might be overwritten */
 					               /* ... on re-driving    */
-					               /* ... the msch() */
+					               /* ... the msch()       */
 					retry--;
 					break;
 
-				case 2:
+				case 2: /* busy */
 					udelay(100);	/* allow for recovery */
 					ret = -EBUSY;
 					retry--;
 					break;
 
-				case 3:
+				case 3: /* not oper */
 					ioinfo[irq]->ui.flags.oper = 0;
+					retry = 0;
 					ret = -ENODEV;
 					break;
-
-				default:
-					printk( KERN_CRIT"enable_subchannel(%04X) "
-					        " : ccode 2 on msch() for device "
-					        "%04X received !\n",
-					        irq,
-					        ioinfo[irq]->devstat.devno);
-					if (cio_debug_initialized)
-						debug_sprintf_event(cio_debug_msg_id, 0,
-								    "enable_subchannel(%04X) : ccode 2 on msch() for device %04X received !\n",
-								    irq, ioinfo[irq]->devstat.devno);
-
-					ret = -ENODEV; // never reached
 				}
 
-			} while ( (ccode == 1) && retry );
+			} while ( retry );
 
 		} /* endif */
 
@@ -1129,19 +1178,13 @@
 static int disable_subchannel( unsigned int irq)
 {
 	int  cc;          /* condition code */
-	int  ret;         /* function return value */
+	int  ret = 0;     /* function return value */
 	int  retry = 5;
 	char dbf_txt[15];
 
-	if ( irq > highest_subchannel )
-	{
-		ret = -ENODEV;
-	}
-	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-	}
-	else if ( ioinfo[irq]->ui.flags.busy )
+	SANITY_CHECK(irq);
+	
+	if ( ioinfo[irq]->ui.flags.busy )
 	{
 		/*
 		 * the disable function must not be called while there are
@@ -1180,19 +1223,12 @@
 				cc = msch( irq, &(ioinfo[irq]->schib) );
 
 				switch (cc) {
-				case 0 :
-					ret = 0;   /* done */
+				case 0: /* ok */
+					retry = 0;
+					ret = 0;   
 					break;
 
-				case 1 :
-					/*
-					 * very bad, requires interrupt alike
-  					 *  processing, where "rbh" is a dummy
-					 *  parm for interface compatibility
-					 *  only. Bottom-half handling cannot
-					 *  be required as this must be an
-					 *  unsolicited interrupt (!busy).
-					 */
+				case 1: /* status pending */
 					ioinfo[irq]->ui.flags.s_pend = 1;
 					s390_process_IRQ( irq );
 					ioinfo[irq]->ui.flags.s_pend = 0;
@@ -1203,45 +1239,36 @@
 					retry--;
 					break;
 
-				case 2 :
-					/*
-					 * *** must not occur !              ***
-					 * ***                               ***
-					 * *** indicates our internal        ***
-					 * *** interrupt accounting is out   ***
-					 * ***  of sync ===> panic()         ***
-					 */
+				case 2: /* busy; this should not happen! */
 					printk( KERN_CRIT"disable_subchannel(%04X) "
 					        "- unexpected busy condition for "
-							  "device %04X received !\n",
+						"device %04X received !\n",
 					        irq,
 					        ioinfo[irq]->devstat.devno);
 					if (cio_debug_initialized)
 						debug_sprintf_event(cio_debug_msg_id, 0, 
 								    "disable_subchannel(%04X) - unexpected busy condition for device %04X received !\n",
 								    irq, ioinfo[irq]->devstat.devno);
+					retry = 0;
 					ret = -EBUSY;
 					break;
 
-				case 3 :
+				case 3: /* not oper */
 					/*
 					 * should hardly occur ?!
 					 */
 					ioinfo[irq]->ui.flags.oper      = 0;
 					ioinfo[irq]->ui.flags.d_disable = 1;
+					retry = 0;
 
 					ret = 0; /* if the device has gone we */
 					         /* ... don't need to disable */
-					         /* ... it anymore !    */
-					break;
-
-				default :
-					ret = -ENODEV;  // never reached ...
+					         /* ... it anymore !          */
 					break;
 
 				} /* endswitch */
 
-			} while ( (cc == 1) && retry );
+			} while ( retry );
 
 		} /* endif */
 
@@ -1282,6 +1309,12 @@
 
 	s390_process_subchannels();
 
+	if (cio_count_irqs) {
+		int i;
+		for (i=0; i<NR_CPUS; i++) 
+			s390_irq_count[i]=0;
+	}
+
 	/*
 	 * enable default I/O-interrupt sublass 3
 	 */
@@ -1318,6 +1351,8 @@
 	char buffer[80];
 	char dbf_txt[15];
 
+	SANITY_CHECK(irq);
+
 	/*
 	 * The flag usage is mutal exclusive ...
 	 */
@@ -1804,16 +1839,7 @@
 	int ret = 0;
 	char dbf_txt[15];
 
-	if ( irq > highest_subchannel || irq < 0 )
-	{
-		return( -ENODEV );
-
-	} /* endif */
-
-	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-   }
+	SANITY_CHECK(irq);
 
 	/* handler registered ? or free_irq() in process already ? */
 	if ( !ioinfo[irq]->ui.flags.ready || ioinfo[irq]->ui.flags.unready )
@@ -1848,7 +1874,7 @@
 		 *  but its intparm must be returned (see halt_IO() processing)
 		 */
 		if (     ioinfo[irq]->ui.flags.w4final
-           && !ioinfo[irq]->ui.flags.doio_q )
+		      && !ioinfo[irq]->ui.flags.doio_q )
 		{
 			ioinfo[irq]->qflag    = flag;
 			ioinfo[irq]->qcpa     = cpa;
@@ -1879,16 +1905,7 @@
 	int ret = 0;
 	char dbf_txt[15];
 
-	if ( irq > highest_subchannel || irq < 0 )
-	{
-		return( -ENODEV );
-
-	} /* endif */
-
-	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-	}
+	SANITY_CHECK(irq);
 
 	if (cio_debug_initialized) {
 		debug_text_event(cio_debug_trace_id, 4, "resIO");
@@ -1954,20 +1971,12 @@
 	int            ccode;
 	char dbf_txt[15];
 
-	if ( irq > highest_subchannel || irq < 0 )
-	{
-		return -ENODEV;
-	}
-
-	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-	}
+	SANITY_CHECK(irq);
 
 	/*
 	 * we only allow for halt_IO if the device has an I/O handler associated
 	 */
-	else if ( !ioinfo[irq]->ui.flags.ready )
+	if ( !ioinfo[irq]->ui.flags.ready )
 	{
 		ret = -ENODEV;
 	}
@@ -1979,6 +1988,7 @@
 	{
 		ret = 0;
 	}
+#if 0
 	/*
 	 * We don't allow for halt_io with a sync do_IO() requests pending.
 	 */
@@ -1987,6 +1997,7 @@
 	{
 		ret = -EBUSY;
 	}
+#endif
 	else
 	{
 		if (cio_debug_initialized) {
@@ -2141,7 +2152,7 @@
 			 * Let the common interrupt handler process the pending
 			 *  status. However, we must avoid calling the user
 			 *  action handler, as it won't be prepared to handle
-                        *  a pending status during do_IO() processing inline.
+			 *  a pending status during do_IO() processing inline.
 			 *  This also implies that s390_process_IRQ must
 			 *  terminate synchronously - especially if device
 			 *  sensing is required.
@@ -2216,14 +2227,11 @@
               unsigned long user_intparm,
               unsigned long flag)  /* possible DOIO_WAIT_FOR_INTERRUPT */
 {
-	int            ret;
+	int            ret = 0;
 	int            ccode;
 	char dbf_txt[15];
 
-	if ( irq > highest_subchannel || irq < 0 )
-	{
-		return -ENODEV;
-	}
+	SANITY_CHECK(irq);
 
 	if ( ioinfo[irq] == INVALID_STORAGE_AREA )
 	{
@@ -2231,22 +2239,23 @@
    }
 
 	/*
-	 * we only allow for halt_IO if the device has an I/O handler associated
+	 * we only allow for clear_IO if the device has an I/O handler associated
 	 */
-	else if ( !ioinfo[irq]->ui.flags.ready )
+	if ( !ioinfo[irq]->ui.flags.ready )
 	{
 		ret = -ENODEV;
 	}
 	/*
-	 * we ignore the halt_io() request if ending_status was received but
+	 * we ignore the clear_io() request if ending_status was received but
 	 *  a SENSE operation is waiting for completion.
 	 */
 	else if ( ioinfo[irq]->ui.flags.w4sense )
 	{
 		ret = 0;
 	}
+#if 0
 	/*
-	 * We don't allow for halt_io with a sync do_IO() requests pending.
+	 * We don't allow for clear_io with a sync do_IO() requests pending.
 	 *  Concurrent I/O is possible in SMP environments only, but the
 	 *  sync. I/O request can be gated to one CPU at a time only.
 	 */
@@ -2254,6 +2263,7 @@
 	{
 		ret = -EBUSY;
 	}
+#endif
 	else
 	{
 		if (cio_debug_initialized) {
@@ -2280,7 +2290,7 @@
 		} /* endif */
 
 		/*
-		 * Issue "Halt subchannel" and process condition code
+		 * Issue "Clear subchannel" and process condition code
 		 */
 		ccode = csch( irq );
 
@@ -2361,7 +2371,7 @@
 					                    | _PSW_IO_WAIT;
 					break;
 				default:
-					panic( "halt_IO() : unexpected "
+					panic( "clear_IO() : unexpected "
 					       "address-space-control %d\n",
 					       ccode);
 					break;
@@ -2394,65 +2404,13 @@
 			ret = 0;
 			break;
 
-		case 1 :            /* status pending */
-
-			ioinfo[irq]->devstat.flag |= DEVSTAT_STATUS_PENDING;
-
-			/*
-			 * initialize the device driver specific devstat irb area
-			 */
-			memset( &ioinfo[irq]->irq_desc.dev_id->ii.irb,
-			        '\0', sizeof( irb_t) );
-
-			/*
-			 * Let the common interrupt handler process the pending
-			 *  status. However, we must avoid calling the user
-			 *  action handler, as it won't be prepared to handle
-                        *  a pending status during do_IO() processing inline.
-			 *  This also implies that s390_process_IRQ must
-			 *  terminate synchronously - especially if device
-			 *  sensing is required.
-			 */
-			ioinfo[irq]->ui.flags.s_pend   = 1;
-			ioinfo[irq]->ui.flags.busy     = 1;
-			ioinfo[irq]->ui.flags.doio     = 1;
-
-			s390_process_IRQ( irq );
-			
-			ioinfo[irq]->ui.flags.s_pend   = 0;
-			ioinfo[irq]->ui.flags.busy     = 0;
-			ioinfo[irq]->ui.flags.doio     = 0;
-			ioinfo[irq]->ui.flags.repall   = 0;
-			ioinfo[irq]->ui.flags.w4final  = 0;
-
-			ioinfo[irq]->devstat.flag     |= DEVSTAT_FINAL_STATUS;
-
-			/*
-			 * In multipath mode a condition code 3 implies the last
-			 *  path has gone, except we have previously restricted
-			 *  the I/O to a particular path. A condition code 1
-			 *  (0 won't occur) results in return code EIO as well
-			 *  as 3 with another path than the one used (i.e. path available mask is non-zero).
-			 */
-			if ( ioinfo[irq]->devstat.ii.irb.scsw.cc == 3 )
-			{
-				ret                         = -ENODEV;
-				ioinfo[irq]->devstat.flag  |= DEVSTAT_NOT_OPER;
-				ioinfo[irq]->ui.flags.oper  = 0;
-			}
-			else
-			{
-				ret                         = -EIO;
-				ioinfo[irq]->devstat.flag  &= ~DEVSTAT_NOT_OPER;
-				ioinfo[irq]->ui.flags.oper  = 1;
-
-			} /* endif */ 
-
+		case 1 :            /* no status pending for csh */
+			BUG();
 			break;
 
-		case 2 :            /* busy */
 
-			ret = -EBUSY;
+		case 2 :            /* no busy for csh*/
+			BUG();
 			break;
 
 		default:            /* device not operational */
@@ -2572,7 +2530,6 @@
 	unsigned int           fctl;       /* function control */
 	unsigned int           stctl;      /* status   control */
 	unsigned int           actl;       /* activity control */
-	struct pt_regs         regs;       /* for interface compatibility only */
 
 	int               issense         = 0;
 	int               ending_status   = 0;
@@ -2582,11 +2539,15 @@
 	devstat_t        *udp;
 
 	char dbf_txt[15];
-#if 0
-	int               cpu             = smp_processor_id();
+	char buffer[80];
 
-	kstat.irqs[cpu][irq]++;
-#endif
+
+	if (cio_count_irqs) {
+		int cpu = smp_processor_id();
+		s390_irq_count[cpu]++;
+	}
+	
+	
 
 	if (cio_debug_initialized) {
 		debug_text_event(cio_debug_trace_id, 3, "procIRQ");
@@ -2688,9 +2649,28 @@
 	 *  secondary status are presented with different interrupts.
 	 */
 	if ( dp->ii.irb.scsw.stctl
-	           & (   SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_INTER_STATUS ) )
-	{
-		dp->rescnt = dp->ii.irb.scsw.count;
+	     & ( SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_INTER_STATUS ) ) {
+
+		/*
+		 * If the subchannel status shows status pending
+		 * and we received a check condition, the count
+		 * information is not meaningful.
+		 */
+		
+		 if ( !(    (dp->ii.irb.scsw.stctl & SCSW_STCTL_STATUS_PEND) 
+			 && (   dp->ii.irb.scsw.cstat 
+			      & (   SCHN_STAT_CHN_DATA_CHK
+				  | SCHN_STAT_CHN_CTRL_CHK
+				  | SCHN_STAT_INTF_CTRL_CHK
+				  | SCHN_STAT_PROG_CHECK
+				  | SCHN_STAT_PROT_CHECK
+				  | SCHN_STAT_CHAIN_CHECK )))) {
+
+			 dp->rescnt = dp->ii.irb.scsw.count;
+		 } else {
+			 dp->rescnt = SENSE_MAX_COUNT;
+		 }
+
 		dp->cpa    = dp->ii.irb.scsw.cpa;
 
 #ifdef CONFIG_DEBUG_IO
@@ -2743,13 +2723,13 @@
 		issense=0;
 	}
 	else if (    (dp->ii.irb.scsw.stctl == SCSW_STCTL_STATUS_PEND)
-	     &&	(dp->ii.irb.scsw.eswf  == 0                     ))
+	          && (dp->ii.irb.scsw.eswf  == 0                     ))
 	{
 		issense = 0;
 	}
-	else if (    (dp->ii.irb.scsw.stctl ==
-	                (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_INTER_STATUS)) 
-	          && ((dp->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED) == 0))
+	else if (   (dp->ii.irb.scsw.stctl ==
+		      (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_INTER_STATUS)) 
+		 && ((dp->ii.irb.scsw.actl & SCSW_ACTL_SUSPENDED) == 0)  )
 	{
 		issense = 0;
 	}
@@ -2797,8 +2777,6 @@
 
 		if ( chnchk )
 		{
-			char buffer[80];
-   	
 			sprintf( buffer, "s390_process_IRQ(%04X) - irb for "
 			         "device %04X after channel check\n",
 			         irq,
@@ -2824,8 +2802,8 @@
 
 		ending_status =    ( stctl & SCSW_STCTL_SEC_STATUS                          )
 			|| ( stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)         )
-		   || ( (fctl == SCSW_FCTL_HALT_FUNC)  && (stctl == SCSW_STCTL_STATUS_PEND) )
-		   || ( (fctl == SCSW_FCTL_CLEAR_FUNC) && (stctl == SCSW_STCTL_STATUS_PEND) );
+			|| ( (fctl == SCSW_FCTL_HALT_FUNC)  && (stctl == SCSW_STCTL_STATUS_PEND) )
+			|| ( (fctl == SCSW_FCTL_CLEAR_FUNC) && (stctl == SCSW_STCTL_STATUS_PEND) );
 
 		/*
 		 * Check for unsolicited interrupts - for debug purposes only
@@ -2838,10 +2816,9 @@
 		 *       unsolicited interrupt applies to the console device
 		 *       itself !
 		 */
-		if ( !( stctl & SCSW_STCTL_ALERT_STATUS )
-		     &&  ( ioinfo[irq]->ui.flags.busy == 0  ) )
+		if (    !( stctl & SCSW_STCTL_ALERT_STATUS )
+		     &&  ( ioinfo[irq]->ui.flags.busy == 0 ) )
 		{
-			char buffer[80];
 #ifdef CONFIG_DEBUG_IO
 			if (irq != cons_dev)
 				printk( "Unsolicited interrupt received for device %04X on subchannel %04X\n"
@@ -2895,7 +2872,7 @@
 		 *       violates the ESA/390 architecture and doesn't present an
 		 *       operand exception for virtual devices without concurrent
 		 *       sense facility available/supported when enabling the
-       *       concurrent sense facility.
+		 *       concurrent sense facility.
 		 */
 		if (    (    (dp->ii.irb.scsw.dstat & DEV_STAT_UNIT_CHECK )
 		          && (!issense                                    ) )
@@ -2992,8 +2969,8 @@
 		if ( allow4handler )
 		{
 			allow4handler =    ending_status
-			   || ( ioinfo[irq]->ui.flags.repall                                      )
-			   || ( stctl & SCSW_STCTL_INTER_STATUS                                   )
+				|| ( ioinfo[irq]->ui.flags.repall                                      )
+				|| ( stctl & SCSW_STCTL_INTER_STATUS                                   )
 				|| ( (ioinfo[irq]->ui.flags.fast ) && (stctl & SCSW_STCTL_PRIM_STATUS) )
 				|| ( ioinfo[irq]->ui.flags.oper == 0                                   );
 
@@ -3041,20 +3018,10 @@
 				}
 				else
 				{
-#if 1
 					panic( "s390_process_IRQ(%04x) encountered "
 					       "negative sense count\n",
 					       irq);
-#else
-					printk( KERN_CRIT"s390_process_IRQ(%04x) encountered "
-					        "negative sense count\n",
-					        irq);
-					if (cio_debug_initialized)
-						debug_sprintf_event(cio_debug_msg_id, 0,
-								    "s390_process_IRQ(%04x) encountered "
-								    "negative sense count\n",
-								    irq);		    
-#endif
+
 				} /* endif */
 			}
 			else
@@ -3063,7 +3030,7 @@
 
 			}  /* endif */
 
-      } /* endif */
+		} /* endif */
 
 		/*
 		 * for status pending situations other than deferred interrupt
@@ -3118,7 +3085,7 @@
 				dp->flag  |= DEVSTAT_FINAL_STATUS;
 				udp->flag |= DEVSTAT_FINAL_STATUS;
 
-				ioinfo[irq]->irq_desc.handler( irq, udp, &regs );
+				ioinfo[irq]->irq_desc.handler( irq, udp, NULL );
 
 				//
 				// reset intparm after final status or we will badly present unsolicited
@@ -3150,7 +3117,7 @@
 					 */
 					if ( ret )
 					{
-						ioinfo[irq]->irq_desc.handler( irq, udp, &regs );
+						ioinfo[irq]->irq_desc.handler( irq, udp, NULL );
 
 					} /* endif */
 
@@ -3178,7 +3145,7 @@
 
 				} /* endif */
 
-				ioinfo[irq]->irq_desc.handler( irq, udp, &regs );
+				ioinfo[irq]->irq_desc.handler( irq, udp, NULL );
 
 			} /* endif */
 
@@ -3261,7 +3228,7 @@
 
 		if ( !ioinfo[irq]->ui.flags.s_pend )
 		{
-			ioinfo[irq]->irq_desc.handler( irq, udp, &regs );
+			ioinfo[irq]->irq_desc.handler( irq, udp, NULL );
 
 		} /* endif */
 
@@ -3298,18 +3265,12 @@
 	int           rc = 0;
 	char dbf_txt[15];
 
+	SANITY_CHECK(irq);
+
 	if ( cons_dev != -1  )
 	{
 		rc = -EBUSY;
 	}
-	else if ( (irq > highest_subchannel) || (irq < 0) )
-	{
-		rc = -ENODEV;
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-   }
 	else
 	{
 		if (cio_debug_initialized) {
@@ -3366,18 +3327,12 @@
 	long    cr6 __attribute__ ((aligned (8)));
 	char dbf_txt[15];
 
+	SANITY_CHECK(irq);
+
 	if ( cons_dev != -1  )
 	{
 		rc = -EBUSY;
 	}
-	else if ( (irq > highest_subchannel) || (irq < 0) )
-	{
-		rc = -ENODEV;
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-   }
 	else
 	{
 		if (cio_debug_initialized) {
@@ -3496,7 +3451,7 @@
 	int             ccode;
 	long            cr6 __attribute__ ((aligned (8)));
 
-	int             count = 0;
+	int             retry = 3;
 	int             rc    = 0;
 	char dbf_txt[15];
 
@@ -3538,48 +3493,44 @@
 					ccode = msch( irq,
 					              &(ioinfo[irq]->schib) );
 
-					if (ccode == 0 )
-					{
+					switch (ccode) {
+					case 0: 
 						/*
 						 * enable special isc
 						 */
-					__ctl_store( cr6, 6, 6);
-					cr6 |= 0x04000000;  // enable sync isc 5
-					cr6 &= 0xEFFFFFFF;  // disable standard isc 3
-					__ctl_load( cr6, 6, 6);
-					}
-					else if (ccode == 3)
-					{
-						rc = -ENODEV;  // very unlikely
-
-					}
-					else if (ccode == 2)
-					{
-						rc = -EBUSY; // device busy ...
-
-					}
-					else if (ccode == 1)
-					{
+						__ctl_store( cr6, 6, 6);
+						cr6 |= 0x04000000;  // enable sync isc 5
+						cr6 &= 0xEFFFFFFF;  // disable standard isc 3
+						__ctl_load( cr6, 6, 6);
+						retry = 0;
+						break;
+					
+					case 1:
 						//
 						// process pending status
 						//
 						ioinfo[irq]->ui.flags.s_pend = 1;
-
 						s390_process_IRQ( irq );
-
 						ioinfo[irq]->ui.flags.s_pend = 0;
+						
+						rc = -EIO;  /* might be overwritten... */
+						retry--;
+						break;
 
-						count++;
+					case 2: /* busy */
+						retry = 0;
+						rc = -EBUSY; 
+						break;
 
-					} /* endif */
+					case 3: /* not oper*/
+						retry = 0;
+						rc = -ENODEV; 
+						break;
+					
+					}
 
-				} while ( ccode == 1 && count < 3 );
+				} while ( retry );
 
-				if ( count == 3)
-				{
-					rc = -EIO;
-                       	
-				} /* endif */
 			}
 			else
 			{
@@ -3651,6 +3602,7 @@
 
 			do
 			{
+			        retry2 = 5;
 				do
 				{
 					ccode = msch( irq, &(ioinfo[irq]->schib) );
@@ -3660,27 +3612,33 @@
 						/*
 						 * disable special interrupt subclass in CPU
 						 */
-				__ctl_store( cr6, 6, 6);
-				cr6 &= 0xFBFFFFFF; // disable sync isc 5
-				cr6 |= 0x10000000; // enable standard isc 3
-				__ctl_load( cr6, 6, 6);
+						__ctl_store( cr6, 6, 6);
+						cr6 &= 0xFBFFFFFF; // disable sync isc 5
+						cr6 |= 0x10000000; // enable standard isc 3
+						__ctl_load( cr6, 6, 6);
+
+						retry2 = 0;
 						break;
-					case 1:
+
+					case 1: /* status pending */
 						ioinfo[irq]->ui.flags.s_pend = 1;
 						s390_process_IRQ( irq );
 						ioinfo[irq]->ui.flags.s_pend = 0;
+
 						retry2--;
 						break;
-					case 2:
+
+					case 2: /* busy */
 					        retry2--;
 						udelay( 100); // give it time
 						break;
-					default:
+						
+					default: /* not oper */
 						retry2 = 0;
 						break;
 					} /* endswitch */
 
-				} while ( retry2 && (ccode != 0) );
+				} while ( retry2 );
 
 				retry1--;
 
@@ -4073,7 +4031,7 @@
 	ccw1_t       *rdc_ccw;
 	devstat_t     devstat;
 	char         *rdc_buf;
-	int           devflag;
+	int           devflag = 0;
 
 	int           ret      = 0;
 	int           emulated = 0;
@@ -4087,15 +4045,7 @@
 
 	} /* endif */
 
-	if ( (irq > highest_subchannel) || (irq < 0 ) )
-	{
-	return( -ENODEV );
-
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-	}
+	SANITY_CHECK(irq);
 
 	if ( ioinfo[irq]->ui.flags.oper == 0 )
 	{
@@ -4126,7 +4076,7 @@
 	{
 		ret = request_irq( irq,
 		                   init_IRQ_handler,
-		                   0, "RDC", &devstat );
+		                   SA_PROBE, "RDC", &devstat );
 
 		if ( !ret )
 		{
@@ -4159,22 +4109,27 @@
 				rdc_ccw->cmd_code = CCW_CMD_RDC;
 				rdc_ccw->count    = length;
 				rdc_ccw->flags    = CCW_FLAG_SLI;
-				set_normalized_cda( rdc_ccw, (unsigned long)rdc_buf );
+				ret = set_normalized_cda( rdc_ccw, (unsigned long)rdc_buf );
+				if (!ret) {
 
-				memset( ioinfo[irq]->irq_desc.dev_id,
-				        '\0',
-				        sizeof( devstat_t));
+					memset( ioinfo[irq]->irq_desc.dev_id,
+						'\0',
+						sizeof( devstat_t));
 
-				ret = s390_start_IO( irq,
-				                     rdc_ccw,
-				                     0x00524443, // RDC
-				                     0,          // n/a
-				                     DOIO_WAIT_FOR_INTERRUPT
-				                      | DOIO_DONT_CALL_INTHDLR );
-				retry--;
-				devflag = ioinfo[irq]->irq_desc.dev_id->flag;   
-    
-				clear_normalized_cda( rdc_ccw);  
+					ret = s390_start_IO( irq,
+							     rdc_ccw,
+							     0x00524443, // RDC
+							     0,          // n/a
+							     DOIO_WAIT_FOR_INTERRUPT
+							     | DOIO_DONT_CALL_INTHDLR );
+					retry--;
+					devflag = ioinfo[irq]->irq_desc.dev_id->flag;   
+					
+					clear_normalized_cda( rdc_ccw);  
+				} else {
+					udelay(100);  //wait for recovery
+					retry--;
+				}
 
 			} while (    ( retry                                     )
 			          && ( ret || (devflag & DEVSTAT_STATUS_PENDING) ) );
@@ -4183,7 +4138,7 @@
 
 		if ( !retry )
 		{
-			ret = -EBUSY;
+			ret = (ret==-ENOMEM)?-ENOMEM:-EBUSY;
 
 		} /* endif */
 
@@ -4222,15 +4177,9 @@
 
 	char dbf_txt[15];
 
-	if ( (irq > highest_subchannel) || (irq < 0 ) )
-	{
-		return( -ENODEV );
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-	}
-	else if ( !buffer || !length )
+	SANITY_CHECK(irq);
+
+	if ( !buffer || !length )
 	{
 		return( -EINVAL);
 	}
@@ -4267,11 +4216,11 @@
 
 			} /* endif */
 
-      	break;
+			break;
 
-      } /* endif */
+		} /* endif */
 
-   } /* endfor */
+	} /* endfor */
 
 	if ( found )
 	{
@@ -4292,7 +4241,7 @@
 			pdevstat = &devstat;
 			ret      = request_irq( irq,
 			                        init_IRQ_handler,
-			                        0, "RCD", pdevstat );
+			                        SA_PROBE, "RCD", pdevstat );
 
 			if ( !ret )
 			{
@@ -4358,30 +4307,29 @@
 					                     0x00524344,  // == RCD
 					                     lpm,
 					                     ioflags );
+					switch ( ret ) {
+					case 0:
+					case -EIO:
+						
+						if ( !(pdevstat->flag & (   DEVSTAT_STATUS_PENDING
+									    | DEVSTAT_NOT_OPER
+									    | DEVSTAT_FLAG_SENSE_AVAIL ) ) )
+						{
+							retry = 0;  // we got it ...
+						}
+						else
+						{
+							retry--;    // try again ...
+								
+						} /* endif */
+						
+						break;
 
-	            switch ( ret ) {
-   	         case 0    :
-      	      case -EIO :
-
-	               if ( !(pdevstat->flag & (   DEVSTAT_STATUS_PENDING
-   	                                      | DEVSTAT_NOT_OPER
-      	                                   | DEVSTAT_FLAG_SENSE_AVAIL ) ) )
-	               {
-   	               retry = 0;  // we got it ...
-      	         }
-         	      else
-            	   {
-               	   retry--;    // try again ...
-
-	               } /* endif */
-
-   	            break;
-
-	            default :   // -EBUSY, -ENODEV, ???
-   	            retry = 0;
-
-      	      } /* endswitch */
-
+					default:   // -EBUSY, -ENODEV, ???
+						retry = 0;
+						
+					} /* endswitch */
+					
 				} while ( retry );
 
 			} /* endif */
@@ -4440,31 +4388,16 @@
 
 static int __inline__ get_next_available_irq( ioinfo_t *pi)
 {
-	int ret_val;
+	int ret_val = -ENODEV;
 
-	while ( TRUE )
-	{
-		if ( pi->ui.flags.oper )
-		{
+	while ( pi!=NULL ) {
+		if ( pi->ui.flags.oper ) {
 			ret_val = pi->irq;
 			break;
-		}
-		else
-		{
+		} else {
 			pi = pi->next;
-
-			//
-			// leave at end of list unconditionally
-			//
-			if ( pi == NULL )
-			{
-				ret_val = -ENODEV;
-				break;
-			}
-
-		} /* endif */
-
-	} /* endwhile */
+		}
+	}
 
 	return ret_val;
 }
@@ -4536,54 +4469,44 @@
 int get_dev_info_by_irq( int irq, s390_dev_info_t *pdi)
 {
 
-	if ( irq > highest_subchannel || irq < 0 )
-	{
-		return -ENODEV;
-	}
-	else if ( pdi == NULL )
-	{
+	SANITY_CHECK(irq);
+
+	if ( pdi == NULL )
 		return -EINVAL;
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
+
+	pdi->devno = ioinfo[irq]->schib.pmcw.dev;
+	pdi->irq   = irq;
+	
+	if (   ioinfo[irq]->ui.flags.oper
+	    && !ioinfo[irq]->ui.flags.unknown ) 
 	{
-		return( -ENODEV);
+		pdi->status = 0;
+		memcpy( &(pdi->sid_data),
+			&ioinfo[irq]->senseid,
+			sizeof( senseid_t));
+	}
+	else if ( ioinfo[irq]->ui.flags.unknown )
+	{
+		pdi->status = DEVSTAT_UNKNOWN_DEV;
+		memset( &(pdi->sid_data),
+			'\0',
+			sizeof( senseid_t));
+		pdi->sid_data.cu_type = 0xFFFF;
+			
 	}
 	else
 	{
-		pdi->devno = ioinfo[irq]->schib.pmcw.dev;
-		pdi->irq   = irq;
-
-		if (     ioinfo[irq]->ui.flags.oper
-           && !ioinfo[irq]->ui.flags.unknown )
-		{
-			pdi->status = 0;
-			memcpy( &(pdi->sid_data),
-			        &ioinfo[irq]->senseid,
-			        sizeof( senseid_t));
-		}
-		else if ( ioinfo[irq]->ui.flags.unknown )
-		{
-			pdi->status = DEVSTAT_UNKNOWN_DEV;
-			memset( &(pdi->sid_data),
-			        '\0',
-			        sizeof( senseid_t));
-			pdi->sid_data.cu_type = 0xFFFF;
-
-		}
-		else
-		{
-			pdi->status = DEVSTAT_NOT_OPER;
-			memset( &(pdi->sid_data),
-			        '\0',
-			        sizeof( senseid_t));
-			pdi->sid_data.cu_type = 0xFFFF;
-
-		} /* endif */
-
-		if ( ioinfo[irq]->ui.flags.ready )
-			pdi->status |= DEVSTAT_DEVICE_OWNED;
-
+		pdi->status = DEVSTAT_NOT_OPER;
+		memset( &(pdi->sid_data),
+			'\0',
+			sizeof( senseid_t));
+		pdi->sid_data.cu_type = 0xFFFF;
+		
 	} /* endif */
+	
+	if ( ioinfo[irq]->ui.flags.ready )
+		pdi->status |= DEVSTAT_DEVICE_OWNED;
+
 
 	return 0;
 }
@@ -4595,70 +4518,60 @@
 	int rc = -ENODEV;
 
 	if ( devno > 0x0000ffff )
-	{
 		return -ENODEV;
-	}
-	else if ( pdi == NULL )
-	{
+        if ( pdi == NULL )
 		return -EINVAL;
-	}
-	else
-	{
 
-		for ( i=0; i <= highest_subchannel; i++ )
+	for ( i=0; i <= highest_subchannel; i++ ) {
+		
+		if (    ioinfo[i] != INVALID_STORAGE_AREA
+		     && ioinfo[i]->schib.pmcw.dev == devno )
 		{
-
-			if (    ioinfo[i] != INVALID_STORAGE_AREA
-			     && ioinfo[i]->schib.pmcw.dev == devno )
+			
+			pdi->irq   = i;
+			pdi->devno = devno;
+			
+			if (    ioinfo[i]->ui.flags.oper
+			     && !ioinfo[i]->ui.flags.unknown )
 			{
+				pdi->status = 0;
+				memcpy( &(pdi->sid_data),
+					&ioinfo[i]->senseid,
+					sizeof( senseid_t));
+			}
+			else if ( ioinfo[i]->ui.flags.unknown )
+			{
+				pdi->status = DEVSTAT_UNKNOWN_DEV;
 
-				pdi->irq   = i;
-				pdi->devno = devno;
-
-				if (    ioinfo[i]->ui.flags.oper
-                 && !ioinfo[i]->ui.flags.unknown )
-				{
-					pdi->status = 0;
-
-					memcpy( &(pdi->sid_data),
-					        &ioinfo[i]->senseid,
-					        sizeof( senseid_t));
-				}
-				else if ( ioinfo[i]->ui.flags.unknown )
-				{
-					pdi->status = DEVSTAT_UNKNOWN_DEV;
-
-					memset( &(pdi->sid_data),
-                       '\0',
-                       sizeof( senseid_t));
-
-					pdi->sid_data.cu_type = 0xFFFF;
-				}
-				else
-				{
-					pdi->status = DEVSTAT_NOT_OPER;
-	
-					memset( &(pdi->sid_data),
-                       '\0',
-                       sizeof( senseid_t));
+				memset( &(pdi->sid_data),
+					'\0',
+					sizeof( senseid_t));
 
-					pdi->sid_data.cu_type = 0xFFFF;
+				pdi->sid_data.cu_type = 0xFFFF;
+			}
+			else
+			{
+				pdi->status = DEVSTAT_NOT_OPER;
+				
+				memset( &(pdi->sid_data),
+					'\0',
+					sizeof( senseid_t));
 
-				} /* endif */
+				pdi->sid_data.cu_type = 0xFFFF;
 
-				if ( ioinfo[i]->ui.flags.ready )
-					pdi->status |= DEVSTAT_DEVICE_OWNED;
+			} /* endif */
 
-				rc = 0; /* found */
-				break;
+			if ( ioinfo[i]->ui.flags.ready )
+				pdi->status |= DEVSTAT_DEVICE_OWNED;
 
-			} /* endif */
+			rc = 0; /* found */
+			break;
 
-		} /* endfor */
+		} /* endif */
 
-		return( rc);
+	} /* endfor */
 
-	} /* endif */
+	return( rc);
 
 }
 
@@ -4742,7 +4655,7 @@
 
 		irq_ret = request_irq( irq,
 		                       init_IRQ_handler,
-		                       0,
+		                       SA_PROBE,
 		                       "INIT",
 		                       &devstat);
 
@@ -4804,7 +4717,6 @@
 					
 				} /* endif */
 #endif
-				s390_DevicePathVerification( irq, 0 );
 
 				disable_cpu_sync_isc( irq );
 
@@ -5040,8 +4952,8 @@
 				{
 					ioinfo_t *pi = ioinfo_head;
 
-					do
-					{
+					for (pi=ioinfo_head; pi!=NULL; pi=pi->next) {
+
 						if ( irq < pi->next->irq )
 						{
 							ioinfo[irq]->next = pi->next;
@@ -5051,11 +4963,7 @@
 							break;
 						
 						} /* endif */
-
-						pi = pi->next;
-
-					} while ( 1 );
-      	
+					}
 				} /* endif */
 
 			} /* endif */
@@ -5303,20 +5211,13 @@
 	int        io_retry;      /* retry indicator */
 
 	senseid_t *psid     = sid;/* start with the external buffer */	
-	int        sbuffer  = 0; /* switch SID data buffer */
+	int        sbuffer  = 0;  /* switch SID data buffer */
 
 	char dbf_txt[15];
 
-	if ( (irq > highest_subchannel) || (irq < 0 ) )
-	{
-		return( -ENODEV );
-
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
+	int failure = 0;          /* nothing went wrong yet */
 
-	} /* endif */
+	SANITY_CHECK(irq);
 
 	if ( ioinfo[irq]->ui.flags.oper == 0 )
 	{
@@ -5330,6 +5231,8 @@
 		debug_text_event(cio_debug_trace_id, 4, dbf_txt);
 	}
 
+	inlreq = 0; /* to make the compiler quiet... */
+
 	if ( !ioinfo[irq]->ui.flags.ready )
 	{
 
@@ -5341,7 +5244,7 @@
 		 *  requests and evaluate the devstat area on return therefore
 		 *  we don't need a real I/O handler in place.
 		 */
-		irq_ret = request_irq( irq, init_IRQ_handler, 0, "SID", &devstat);
+		irq_ret = request_irq( irq, init_IRQ_handler, SA_PROBE, "SID", &devstat);
 
 		if ( irq_ret == 0 )
 			inlreq = 1;
@@ -5403,6 +5306,9 @@
 
 			if ( domask )
 			{
+				failure = 0;
+				
+				psid->reserved   = 0;
 				psid->cu_type    = 0xFFFF;  /* initialize fields ... */
 				psid->cu_model   = 0;
 				psid->dev_type   = 0;
@@ -5423,23 +5329,18 @@
 					irq_ret = s390_start_IO( irq,
 					                         sense_ccw,
 					                         0x00E2C9C4,  // == SID
-			   		                      domask,
+								 domask,
 					                         DOIO_WAIT_FOR_INTERRUPT
 					                          | DOIO_TIMEOUT
 					                          | DOIO_VALID_LPM
 					                          | DOIO_DONT_CALL_INTHDLR );
 
-					//
-					// The OSA_E FE card possibly causes -ETIMEDOUT
-					//  conditions, as the SenseID may stay start
-					//  pending. This will cause start_IO() to finally
-					//  halt the operation we should retry. If the halt
-					//  fails this may cause -EBUSY we simply retry
-					//  and eventually clean up with free_irq().   	     		
-					//
 
 					if ( psid->cu_type  == 0xFFFF )
 					{
+
+						failure = 1;
+
 						if ( pdevstat->flag & DEVSTAT_STATUS_PENDING )
 						{
 #ifdef CONFIG_DEBUG_IO
@@ -5448,7 +5349,7 @@
 							        "reports pending status, "
 							        "retry : %d\n",
 							        ioinfo[irq]->schib.pmcw.dev,
-					   		     irq,
+								irq,
 							        retry);
 #endif
 							if (cio_debug_initialized)
@@ -5487,7 +5388,7 @@
 											    "intervention required\n",
 											    ioinfo[irq]->schib.pmcw.dev,
 											    irq);		    
-								io_retry = 1;
+								io_retry = 0;
 							}
 
 							else
@@ -5514,7 +5415,7 @@
 								        pdevstat->ii.sense.data[6],
 								        pdevstat->ii.sense.data[7]);
 #endif
-								if (cio_debug_initialized)
+								if (cio_debug_initialized) {
 									debug_sprintf_event(cio_debug_msg_id, 2,
 											    "SenseID : UC on "
 											    "dev %04X, "
@@ -5536,11 +5437,16 @@
 											    pdevstat->ii.sense.data[5],
 											    pdevstat->ii.sense.data[6],
 											    pdevstat->ii.sense.data[7]);	    
+									if (psid->reserved != 0xFF) 
+										debug_sprintf_event(cio_debug_msg_id, 2,
+												    "SenseID was not properly "
+												    "executed!\n");
+								}
 							} /* endif */
 
 						}
 						else if (    ( pdevstat->flag & DEVSTAT_NOT_OPER )
-					             || ( irq_ret        == -ENODEV         ) )
+							  || ( irq_ret        == -ENODEV         ) )
 						{
 #ifdef CONFIG_DEBUG_IO
 							printk( "SenseID : path %02X for "
@@ -5566,11 +5472,11 @@
       	
 						}
 
-						else if (     (pdevstat->flag !=
-						                    (   DEVSTAT_START_FUNCTION
-						                      | DEVSTAT_FINAL_STATUS    ) )
-						           && !(pdevstat->flag &
-						                    DEVSTAT_STATUS_PENDING        ) )
+						else if (     ( pdevstat->flag !=
+							       (   DEVSTAT_START_FUNCTION
+								 | DEVSTAT_FINAL_STATUS    ) )
+							   && !( pdevstat->flag &
+								DEVSTAT_STATUS_PENDING       ) )
 						{
 #ifdef CONFIG_DEBUG_IO
 							printk( "SenseID : start_IO() for "
@@ -5602,45 +5508,54 @@
 					}
 					else   // we got it ...
 					{
-						if ( !sbuffer )	// switch buffers
-						{
-							/*
-							 * we report back the
-							 *  first hit only
-							 */
-							psid = &isid;
+						if (psid->reserved != 0xFF) {
+							/* No, we failed after all... */
+							failure = 1;
+							retry--;
 
-							if ( ioinfo[irq]->schib.pmcw.pim != 0x80 )
-							{
-								sense_ccw[1].cda = (__u32)virt_to_phys( psid );
-							}
-							else
+						} else {
+					       
+							if ( !sbuffer )	// switch buffers
 							{
-								sense_ccw[0].cda = (__u32)virt_to_phys( psid );
-
+								/*
+								 * we report back the
+								 *  first hit only
+								 */
+								psid = &isid;
+								
+								if ( ioinfo[irq]->schib.pmcw.pim != 0x80 )
+								{
+									sense_ccw[1].cda = (__u32)virt_to_phys( psid );
+								}
+								else
+								{
+									sense_ccw[0].cda = (__u32)virt_to_phys( psid );
+
+								} /* endif */
+
+								/*
+								 * if just the very first
+								 *  was requested to be
+								 *  sensed disable further
+								 *  scans.
+								 */	
+								if ( !lpm )
+									lpm = domask;
+								
+								sbuffer = 1;
+								
 							} /* endif */
 
-							/*
-							 * if just the very first
-							 *  was requested to be
-							 *  sensed disable further
-							 *  scans.
-							 */	
-							if ( !lpm )
-								lpm = domask;
-
-							sbuffer = 1;
-
-						} /* endif */
-
-					   if ( pdevstat->rescnt < (sizeof( senseid_t) - 8) )
-						{
-							ioinfo[irq]->ui.flags.esid = 1;
+							if ( pdevstat->rescnt < (sizeof( senseid_t) - 8) )
+							{
+								ioinfo[irq]->ui.flags.esid = 1;
        							
-						} /* endif */
+							} /* endif */
 
-						io_retry = 0;
+							io_retry = 0;
 						
+						}
+
 					} /* endif */
 
 					if ( io_retry )
@@ -5654,7 +5569,19 @@
 						} /* endif */
       	
 					} /* endif */
-	
+
+					if ((failure) && (io_retry)) {
+						/* reset fields... */
+
+						failure = 0;
+						
+						psid->reserved   = 0;
+						psid->cu_type    = 0xFFFF;  
+						psid->cu_model   = 0;
+						psid->dev_type   = 0;
+						psid->dev_model  = 0;
+					}
+						
 				} while ( (io_retry) );
 
  			} /* endif - domask */
@@ -5685,7 +5612,7 @@
 		 *  only if we suffered a command reject, but it doesn't harm
 		 */
 		if (    ( sid->cu_type == 0xFFFF    )
-		     && ( MACHINE_IS_VM              ) )
+		     && ( MACHINE_IS_VM             ) )
 		{
 			VM_virtual_device_info( ioinfo[irq]->schib.pmcw.dev,
 			                        sid );
@@ -5715,9 +5642,9 @@
 		} /* endif */
 
 	
-			/*
-			 * Issue device info message if unit was operational .
-			 */
+		/*
+		 * Issue device info message if unit was operational .
+		 */
 		if ( !ioinfo[irq]->ui.flags.unknown ) {
 			if ( sid->dev_type != 0 ) {
 				if ( cio_show_msg ) 
@@ -5791,10 +5718,11 @@
  *  available. Further, a path group ID is set, if possible in multipath
  *  mode, otherwise in single path mode.
  *
+ * Note : This function must not be called during normal device recognition,
+ *         but during device driver initiated request_irq() processing only.
  */
 int s390_DevicePathVerification( int irq, __u8 usermask )
 {
-#if 1
 	int  ccode;
 	__u8 pathmask;
 	__u8 domask;
@@ -5971,9 +5899,7 @@
 	} /* endif */
 
 	return ret;
-#else
-	return 0;
-#endif
+
 }
 
 /*
@@ -5995,16 +5921,7 @@
 	int        inlreq  = 0; /* inline request_irq() */
 	int        mpath   = 1; /* try multi-path first */
 
-	if ( (irq > highest_subchannel) || (irq < 0 ) )
-	{
-		return( -ENODEV );
-
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-
-	} /* endif */
+	SANITY_CHECK(irq);
 
 	if ( ioinfo[irq]->ui.flags.oper == 0 )
 	{
@@ -6015,14 +5932,14 @@
 	if ( !ioinfo[irq]->ui.flags.ready )
 	{
 		/*
-		 * Perform SENSE ID command processing. We have to request device
+		 * Perform SetPGID command processing. We have to request device
 		 *  ownership and provide a dummy I/O handler. We issue sync. I/O
 		 *  requests and evaluate the devstat area on return therefore
 		 *  we don't need a real I/O handler in place.
 		 */
 		irq_ret = request_irq( irq,
 		                       init_IRQ_handler,
-		                       0,
+		                       SA_PROBE,
 		                       "SPID",
 		                       pdevstat);
 
@@ -6062,7 +5979,7 @@
 		pgid->inf.fc = SPID_FUNC_MULTI_PATH | SPID_FUNC_ESTABLISH;
 
 		/*
-		 * We now issue a SenseID request. In case of BUSY
+		 * We now issue a SetPGID request. In case of BUSY
 		 *  or STATUS PENDING conditions we retry 5 times.
 		 */
 		do
@@ -6099,12 +6016,15 @@
 								    ioinfo[irq]->schib.pmcw.dev,
 								    irq,
 								    retry);	    
+					retry--;
+					irq_ret = -EIO;
 				} /* endif */
 
 				if ( pdevstat->flag == (   DEVSTAT_START_FUNCTION
 				                         | DEVSTAT_FINAL_STATUS   ) )
 				{
 					retry = 0;	// successfully set ...
+					irq_ret = 0;
 				}
 				else if ( pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL )
 				{
@@ -6121,6 +6041,7 @@
 							               | SPID_FUNC_ESTABLISH;
 							mpath        = 0;
 							retry--;
+							irq_ret = -EIO;
 						}
 						else
 						{
@@ -6170,6 +6091,7 @@
 									    pdevstat->ii.sense.data[7]);
 
 						retry--;
+						irq_ret = -EIO;
 		    
 					} /* endif */
 
@@ -6201,20 +6123,17 @@
 			else if ( irq_ret != -ENODEV )
 			{
 				retry--;
+				irq_ret = -EIO;
 			}
 			else
 			{
 				retry = 0;
+				irq_ret = -ENODEV;
 
 			} /* endif */
 
 		} while ( retry > 0 );
 
-		if ( retry == 0 )
-		{
-			irq_ret = -EIO;
-
-		} /* endif */
 
 		if ( init_IRQ_complete )
 		{
@@ -6256,17 +6175,9 @@
 	int        irq_ret = 0; /* return code */
 	int        retry   = 5; /* retry count */
 	int        inlreq  = 0; /* inline request_irq() */
+	unsigned long flags;
 
-	if ( (irq > highest_subchannel) || (irq < 0 ) )
-	{
-		return( -ENODEV );
-
-	}
-	else if ( ioinfo[irq] == INVALID_STORAGE_AREA )
-	{
-		return( -ENODEV);
-
-	} /* endif */
+	SANITY_CHECK(irq);
 
 	if ( ioinfo[irq]->ui.flags.oper == 0 )
 	{
@@ -6277,14 +6188,14 @@
 	if ( !ioinfo[irq]->ui.flags.ready )
 	{
 		/*
-		 * Perform SENSE ID command processing. We have to request device
+		 * Perform SENSE PGID command processing. We have to request device
 		 *  ownership and provide a dummy I/O handler. We issue sync. I/O
 		 *  requests and evaluate the devstat area on return therefore
 		 *  we don't need a real I/O handler in place.
 		 */
 		irq_ret = request_irq( irq,
 		                       init_IRQ_handler,
-		                       0,
+		                       SA_PROBE,
 		                       "SNID",
 		                       pdevstat);
 
@@ -6300,7 +6211,7 @@
 
 	if ( irq_ret == 0 )
 	{
-		s390irq_spin_lock( irq);
+		s390irq_spin_lock_irqsave( irq, flags);
 
 		if ( init_IRQ_complete )
 		{
@@ -6318,7 +6229,7 @@
 		snid_ccw->flags    = CCW_FLAG_SLI;
 
 		/*
-		 * We now issue a SenseID request. In case of BUSY
+		 * We now issue a SensePGID request. In case of BUSY
 		 *  or STATUS PENDING conditions we retry 5 times.
 		 */
 		do
@@ -6391,6 +6302,7 @@
 									    pdevstat->ii.sense.data[6],
 									    pdevstat->ii.sense.data[7]);		    
 						retry--;
+						irq_ret = -EIO;
 
 					} /* endif */
 				}
@@ -6413,11 +6325,13 @@
 					}
 
 					retry = 0;
+					irq_ret = -EIO;
 
 				}
 				else
 				{
 					retry = 0; // success ...
+					irq_ret = 0;
 
 				} /* endif */
 			}
@@ -6458,20 +6372,17 @@
 							    ioinfo[irq]->schib.pmcw.dev,
 							    irq_ret);
 				retry--;
+				irq_ret = -EIO;
 			}
 			else	// -ENODEV ...
 			{
 				retry = 0;
+				irq_ret = -ENODEV;
 
 			} /* endif */
 
 		} while ( retry > 0 );
 
-		if ( retry == 0 )
-		{
-			irq_ret = -EIO;
-
-		} /* endif */
 
 		if ( init_IRQ_complete )
 		{
@@ -6483,7 +6394,7 @@
 
 		} /* endif */
 
-		s390irq_spin_unlock( irq);
+		s390irq_spin_unlock_irqrestore( irq, flags);
 
 		/*
 		 * If we installed the irq action handler we have to
@@ -6585,12 +6496,25 @@
 			if ( ioinfo[irq] != INVALID_STORAGE_AREA )
 			{
 #ifdef CONFIG_DEBUG_CRW
-				printk( "do_crw_pending : ioinfo at %08X\n",
+				printk( "do_crw_pending : ioinfo at "
+#ifdef CONFIG_ARCH_S390X
+					"%08lX\n",
+					(unsigned long)ioinfo[irq]);
+#else /* CONFIG_ARCH_S390X */
+					"%08X\n",
 				        (unsigned)ioinfo[irq]);
+#endif /* CONFIG_ARCH_S390X */
 #endif
 				if (cio_debug_initialized)
 					debug_sprintf_event(cio_debug_crw_id, 4,
-							    "ioinfo at %08X\n");
+							    "ioinfo at "
+#ifdef CONFIG_ARCH_S390X
+							    "%08lX\n",
+							    (unsigned long)ioinfo[irq]);
+#else /* CONFIG_ARCH_S390X */
+				                            "%08X\n",
+							    (unsigned)ioinfo[irq]);
+#endif /* CONFIG_ARCH_S390X */
 			} /* endif */
 
 
@@ -6892,7 +6816,7 @@
 				    ioinfo[i]->senseid.cu_model );
 	       } else {
 		    len += sprintf( info->data+len, 
-				    "%04X/%02X          ", 
+				    "          %04X/%02X", 
 				    ioinfo[i]->senseid.cu_type, 
 				    ioinfo[i]->senseid.cu_model );
 	       }
@@ -7034,30 +6958,6 @@
      }
 }
 
-int cio_search_devno_by_inode(struct inode *inode)
-{
-	int devno = -1;
-	struct proc_dir_entry *pde;
-	cio_procfs_device_t *tmp;
-	
-	pde = (struct proc_dir_entry *)inode->u.generic_ip;
-	tmp = cio_procfs_device_list;
-
-	while (tmp) {
-		if ((tmp->entry->cio_device_entry == pde) ||
-		    (tmp->entry->cio_sensedata_entry == pde) ||
-		    (tmp->entry->cio_in_use_entry == pde) ||
-		    (tmp->entry->cio_chpid_entry == pde))
-			break;
-		tmp = tmp->next;
-	}
-
-	if (tmp)
-		devno = tmp->entry->devno;
-		
-	return devno;
-}
-
 
 static int cio_sensedata_entry_open( struct inode *inode, struct file *file)
 {
@@ -7067,6 +6967,7 @@
 	tempinfo_t *info;
 	int irq;
 	int devno;
+	char * devno_str;
 
 	info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t));
 	if (info == NULL) {
@@ -7081,23 +6982,24 @@
 			vfree(info);
 			rc = -ENOMEM;
 		} else {
-			devno = cio_search_devno_by_inode(inode);
-			if (devno != 0xFFFF) {
-				irq = get_irq_by_devno(devno);
-				if (irq != -1) {
-					len += sprintf(info->data+len, "Dev Type/Mod: ");
-					if (ioinfo[irq]->senseid.dev_type == 0) {
-						len += sprintf(info->data+len, "%04X/%02X\n",
-							       ioinfo[irq]->senseid.cu_type,
-							       ioinfo[irq]->senseid.cu_model);
-					} else {
-						len += sprintf(info->data+len, "%04X/%02X\n",
-							       ioinfo[irq]->senseid.dev_type,
-							       ioinfo[irq]->senseid.dev_model);
-						len+= sprintf(info->data+len, "CU Type/Mod:  %04X/%02X\n",
-							      ioinfo[irq]->senseid.cu_type,
-							      ioinfo[irq]->senseid.cu_model);
-					}
+			devno_str = kmalloc(6*sizeof(char), GFP_KERNEL);
+			memset(devno_str, 0, 6*sizeof(char));
+			memcpy(devno_str,file->f_dentry->d_parent->d_name.name, strlen(file->f_dentry->d_parent->d_name.name)+1);
+			devno = simple_strtoul(devno_str, &devno_str, 16);
+			irq = get_irq_by_devno(devno);
+			if (irq != -1) {
+				len += sprintf(info->data+len, "Dev Type/Mod: ");
+				if (ioinfo[irq]->senseid.dev_type == 0) {
+					len += sprintf(info->data+len, "%04X/%02X\n",
+						       ioinfo[irq]->senseid.cu_type,
+						       ioinfo[irq]->senseid.cu_model);
+				} else {
+					len += sprintf(info->data+len, "%04X/%02X\n",
+						       ioinfo[irq]->senseid.dev_type,
+						       ioinfo[irq]->senseid.dev_model);
+					len+= sprintf(info->data+len, "CU Type/Mod:  %04X/%02X\n",
+						      ioinfo[irq]->senseid.cu_type,
+						      ioinfo[irq]->senseid.cu_model);
 				}
 			}
 			info->len = len;
@@ -7115,6 +7017,7 @@
 	tempinfo_t *info;
 	int irq;
 	int devno;
+	char * devno_str;
 
 	info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t));
 	if (info == NULL) {
@@ -7129,12 +7032,13 @@
 			vfree(info);
 			rc = -ENOMEM;
 		} else {
-			devno = cio_search_devno_by_inode(inode);
-			if (devno != -1) {
-				irq = get_irq_by_devno(devno);
-				if (irq != -1) {
-					len += sprintf(info->data+len, "%s\n", ioinfo[irq]->ui.flags.ready?"yes":"no");
-				}
+			devno_str = kmalloc(6*sizeof(char), GFP_KERNEL);
+			memset(devno_str, 0, 6*sizeof(char));
+			memcpy(devno_str,file->f_dentry->d_parent->d_name.name, strlen(file->f_dentry->d_parent->d_name.name)+1);
+			devno = simple_strtoul(devno_str, &devno_str, 16);
+			irq = get_irq_by_devno(devno);
+			if (irq != -1) {
+				len += sprintf(info->data+len, "%s\n", ioinfo[irq]->ui.flags.ready?"yes":"no");
 			}
 			info->len = len;
 		}
@@ -7152,6 +7056,7 @@
 	int irq;
 	int devno;
 	int i;
+	char * devno_str;
 
 	info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t));
 	if (info == NULL) {
@@ -7166,14 +7071,15 @@
 			vfree(info);
 			rc = -ENOMEM;
 		} else {
-			devno = cio_search_devno_by_inode(inode);
-			if (devno != -1) {
-				irq = get_irq_by_devno(devno);
-				if (irq != -1) {
-					for (i=0; i<8; i++) {
-						len += sprintf(info->data+len, "CHPID[%d]: ", i);
-						len += sprintf(info->data+len, "%02X\n", ioinfo[irq]->schib.pmcw.chpid[i]);
-					}
+			devno_str = kmalloc(6*sizeof(char), GFP_KERNEL);
+			memset(devno_str, 0, 6*sizeof(char));
+			memcpy(devno_str,file->f_dentry->d_parent->d_name.name, strlen(file->f_dentry->d_parent->d_name.name)+1);
+			devno = simple_strtoul(devno_str, &devno_str, 16);
+			irq = get_irq_by_devno(devno);
+			if (irq != -1) {
+				for (i=0; i<8; i++) {
+					len += sprintf(info->data+len, "CHPID[%d]: ", i);
+					len += sprintf(info->data+len, "%02X\n", ioinfo[irq]->schib.pmcw.chpid[i]);
 				}
 			}
 			info->len = len;
@@ -7377,6 +7283,8 @@
  * un-ignore devices by piping to /proc/cio_ignore:
  * free all frees all blacklisted devices, free <range>,<range>,...
  * frees specified ranges of devnos
+ * add <range>,<range>,... will add a range of devices to blacklist -
+ * but only for devices not already known
  */
 
 static struct proc_dir_entry *cio_ignore_proc_entry;
@@ -7388,6 +7296,7 @@
 	int len = 0;
 	tempinfo_t *info;
 	dev_blacklist_range_t *tmp;
+	long flags;
 
 	info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t));
 	if (info == NULL) {
@@ -7402,6 +7311,7 @@
 			vfree (info);
 			rc = -ENOMEM;
 		} else {
+			spin_lock_irqsave( &blacklist_lock, flags ); 
 			tmp = dev_blacklist_range_head;
 			while (tmp) {
 				len += sprintf(info->data+len, "%04x ", tmp->from);
@@ -7410,6 +7320,7 @@
 				len += sprintf(info->data+len, "\n");
 				tmp = tmp->next;
 			}
+			spin_unlock_irqrestore( &blacklist_lock, flags );
 			info->len = len;
 		}
 	}
@@ -7486,6 +7397,98 @@
 }
 
 __initcall(cio_ignore_proc_init);
+
+/*
+ * Entry /proc/irq_count
+ * display how many irqs have occured per cpu...
+ */
+
+static struct proc_dir_entry *cio_irq_proc_entry;
+
+static int cio_irq_proc_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	int size = 1;
+	int len = 0;
+	tempinfo_t *info;
+	int i;
+
+	info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t));
+	if (info == NULL) {
+		printk( KERN_WARNING "No memory available for data\n");
+		rc = -ENOMEM;
+	} else {
+		file->private_data = (void *) info;
+		size += NR_CPUS * 16;
+		info->data = (char *) vmalloc(size);
+		if (size && info->data == NULL) {
+			printk( KERN_WARNING "No memory available for data\n");
+			vfree (info);
+			rc = -ENOMEM;
+		} else {
+			for (i=0; i< NR_CPUS; i++) {
+				if (s390_irq_count[i] != 0) 
+					len += sprintf(info->data+len, "%lx\n", s390_irq_count[i]);
+			}
+			info->len = len;
+		}
+	}
+	return rc;
+}
+
+static int cio_irq_proc_close(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+
+	if (p_info) {
+		if (p_info->data) 
+			vfree(p_info->data);
+		vfree(p_info);
+	}
+
+	return rc;
+}
+
+static ssize_t cio_irq_proc_read( struct file *file, char *user_buf, size_t user_len, loff_t * offset)
+{
+	loff_t len;
+	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+	
+	if ( *offset>=p_info->len) {
+		return 0;
+	} else {
+		len = MIN(user_len, (p_info->len - *offset));
+		if (copy_to_user( user_buf, &(p_info->data[*offset]), len))
+			return -EFAULT; 
+		(* offset) += len;
+		return len;
+	}
+}
+
+static struct file_operations cio_irq_proc_file_ops = 
+	{
+		read:    cio_irq_proc_read,
+		open:    cio_irq_proc_open,
+		release: cio_irq_proc_close,
+	};
+
+static int cio_irq_proc_init(void)
+{
+
+	int i;
+
+	if (cio_count_irqs) {
+		for (i=0; i<NR_CPUS; i++) 
+			s390_irq_count[i]=0;
+		cio_irq_proc_entry = create_proc_entry("irq_count", S_IFREG|S_IRUGO, &proc_root);
+		cio_irq_proc_entry->proc_fops = &cio_irq_proc_file_ops;
+	}
+
+	return 1;
+}
+
+__initcall(cio_irq_proc_init);	
 
 /* end of procfs stuff */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- v2.4.10/linux/drivers/scsi/3w-xxxx.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/3w-xxxx.c	Sun Sep 30 12:26:07 2001
@@ -106,6 +106,8 @@
 
 MODULE_AUTHOR ("3ware Inc.");
 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
+MODULE_LICENSE("GPL");
+
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v2.4.10/linux/drivers/scsi/53c7,8xx.c	Fri Apr 27 14:04:32 2001
+++ linux/drivers/scsi/53c7,8xx.c	Sun Sep 30 12:26:07 2001
@@ -215,9 +215,7 @@
 
 #include <linux/version.h>
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -6429,6 +6427,7 @@
     return 1;
 }
 #endif /* def MODULE */
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = NCR53c7xx;
 #include "scsi_module.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/53c700.c linux/drivers/scsi/53c700.c
--- v2.4.10/linux/drivers/scsi/53c700.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/53c700.c	Sun Sep 30 12:26:08 2001
@@ -51,6 +51,19 @@
 
 /* CHANGELOG
  *
+ * Version 2.5
+ * 
+ * More Compatibility changes for 710 (now actually works).  Enhanced
+ * support for odd clock speeds which constrain SDTR negotiations.
+ * correct cacheline separation for scsi messages and status for
+ * incoherent architectures.  Use of the pci mapping functions on
+ * buffers to begin support for 64 bit drivers.
+ *
+ * Version 2.4
+ *
+ * Added support for the 53c710 chip (in 53c700 emulation mode only---no 
+ * special 53c710 instructions or registers are used).
+ *
  * Version 2.3
  *
  * More endianness/cache coherency changes.
@@ -77,7 +90,7 @@
  * Initial modularisation from the D700.  See NCR_D700.c for the rest of
  * the changelog.
  * */
-#define NCR_700_VERSION "2.3"
+#define NCR_700_VERSION "2.5"
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -98,6 +111,7 @@
 #include <asm/byteorder.h>
 #include <linux/blk.h>
 #include <linux/module.h>
+#include <linux/pci.h>
 
 #include "scsi.h"
 #include "hosts.h"
@@ -105,6 +119,14 @@
 
 #include "53c700.h"
 
+/* NOTE: For 64 bit drivers there are points in the code where we use
+ * a non dereferenceable pointer to point to a structure in dma-able
+ * memory (which is 32 bits) so that we can use all of the structure
+ * operations but take the address at the end.  This macro allows us
+ * to truncate the 64 bit pointer down to 32 bits without the compiler
+ * complaining */
+#define to32bit(x)	((__u32)((unsigned long)(x)))
+
 #ifdef NCR_700_DEBUG
 #define STATIC
 #else
@@ -195,12 +217,19 @@
 NCR_700_detect(Scsi_Host_Template *tpnt,
 	       struct NCR_700_Host_Parameters *hostdata)
 {
-	__u32 *script = kmalloc(sizeof(SCRIPT), GFP_KERNEL);
-	__u32 pScript;
+	dma_addr_t pScript, pSlots;
+	__u32 *script;
 	struct Scsi_Host *host;
 	static int banner = 0;
 	int j;
 
+	/* This separation of pScript and script is not strictly
+	 * necessay, but may be useful in architectures which can
+	 * allocate consistent memory on which virt_to_bus will not
+	 * work */
+	script = kmalloc(sizeof(SCRIPT), GFP_KERNEL);
+	pScript = virt_to_bus(script);
+
 	/* Fill in the missing routines from the host template */
 	tpnt->queuecommand = NCR_700_queuecommand;
 	tpnt->eh_abort_handler = NCR_700_abort;
@@ -228,40 +257,57 @@
 		return NULL;
 	}
 
-	hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST, GFP_KERNEL);
-	if(hostdata->slots == NULL) {
-		printk(KERN_ERR "53c700: Failed to allocate command slots, detatching\n");
+	/* This separation of slots and pSlots may facilitate later
+	 * migration to consistent memory on architectures which
+	 * support it */
+	hostdata->slots = kmalloc(sizeof(struct NCR_700_command_slot)
+				  * NCR_700_COMMAND_SLOTS_PER_HOST,
+				  GFP_KERNEL);
+	pSlots = virt_to_bus(hostdata->slots);
+
+	hostdata->msgin = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
+	hostdata->msgout = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
+	hostdata->status = kmalloc(MSG_ARRAY_SIZE, GFP_KERNEL);
+	if(hostdata->slots == NULL || hostdata->msgin == NULL
+	   || hostdata->msgout == NULL || hostdata->status==NULL) {
+		printk(KERN_ERR "53c700: Failed to allocate command slots or message buffers, detatching\n");
 		scsi_unregister(host);
 		return NULL;
 	}
-	memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) * NCR_700_COMMAND_SLOTS_PER_HOST);
+	memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
+	       * NCR_700_COMMAND_SLOTS_PER_HOST);
 	for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
+		dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0]
+					  - (unsigned long)&hostdata->slots[0].SG[0]);
+		hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset));
 		if(j == 0)
 			hostdata->free_list = &hostdata->slots[j];
 		else
 			hostdata->slots[j-1].ITL_forw = &hostdata->slots[j];
 		hostdata->slots[j].state = NCR_700_SLOT_FREE;
 	}
-	host->hostdata[0] = (__u32)hostdata;
+
 	for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) {
 		script[j] = bS_to_host(SCRIPT[j]);
 	}
-	/* bus physical address of script */
-	pScript = virt_to_bus(script);
+
 	/* adjust all labels to be bus physical */
 	for(j = 0; j < PATCHES; j++) {
 		script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
 	}
-	/* now patch up fixed addresses */
+	/* now patch up fixed addresses. 
+	 * NOTE: virt_to_bus may be wrong if consistent memory is used
+	 * for these in the future */
 	script_patch_32(script, MessageLocation,
 			virt_to_bus(&hostdata->msgout[0]));
 	script_patch_32(script, StatusAddress,
-			virt_to_bus(&hostdata->status));
+			virt_to_bus(&hostdata->status[0]));
 	script_patch_32(script, ReceiveMsgAddress,
 			virt_to_bus(&hostdata->msgin[0]));
 
 	hostdata->script = script;
 	hostdata->pScript = pScript;
+	dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
 	hostdata->state = NCR_700_HOST_FREE;
 	spin_lock_init(&hostdata->lock);
 	hostdata->cmd = NULL;
@@ -272,19 +318,22 @@
 	host->hostdata[0] = (unsigned long)hostdata;
 	/* kick the chip */
 	NCR_700_writeb(0xff, host, CTEST9_REG);
-	hostdata->rev = (NCR_700_readb(host, CTEST7_REG)<<4) & 0x0f;
+	if(hostdata->chip710) 
+		hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f;
+	else
+		hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f;
 	hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0);
 	if(banner == 0) {
 		printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n");
 		banner = 1;
 	}
 	printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
-	       hostdata->fast ? "53c700-66" : "53c700",
+	       hostdata->chip710 ? "53c710" : 
+	       (hostdata->fast ? "53c700-66" : "53c700"),
 	       hostdata->rev, hostdata->differential ?
 	       "(Differential)" : "");
 	/* reset the chip */
 	NCR_700_chip_reset(host);
-	NCR_700_writeb(ASYNC_OPERATION , host, SXFER_REG);
 
 	return host;
 }
@@ -295,7 +344,13 @@
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)host->hostdata[0];
 
+	/* NOTE: these may be NULL if we weren't fully initialised before
+	 * the scsi_unregister was called */
 	kfree(hostdata->script);
+	kfree(hostdata->slots);
+	kfree(hostdata->msgin);
+	kfree(hostdata->msgout);
+	kfree(hostdata->status);
 	return 1;
 }
 
@@ -308,24 +363,32 @@
 }
 
 /*
- * Function : static int datapath_residual (Scsi_Host *host)
+ * Function : static int data_residual (Scsi_Host *host)
  *
  * Purpose : return residual data count of what's in the chip.  If you
  * really want to know what this function is doing, it's almost a
  * direct transcription of the algorithm described in the 53c710
  * guide, except that the DBC and DFIFO registers are only 6 bits
- * wide.
+ * wide on a 53c700.
  *
  * Inputs : host - SCSI host */
 static inline int
 NCR_700_data_residual (struct Scsi_Host *host) {
-	int count, synchronous;
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+	int count, synchronous = 0;
 	unsigned int ddir;
 
-	count = ((NCR_700_readb(host, DFIFO_REG) & 0x3f) -
-		 (NCR_700_readl(host, DBC_REG) & 0x3f)) & 0x3f;
+	if(hostdata->chip710) {
+		count = ((NCR_700_readb(host, DFIFO_REG) & 0x7f) -
+			 (NCR_700_readl(host, DBC_REG) & 0x7f)) & 0x7f;
+	} else {
+		count = ((NCR_700_readb(host, DFIFO_REG) & 0x3f) -
+			 (NCR_700_readl(host, DBC_REG) & 0x3f)) & 0x3f;
+	}
 	
-	synchronous = NCR_700_readb(host, SXFER_REG) & 0x0f;
+	if(hostdata->fast)
+		synchronous = NCR_700_readb(host, SXFER_REG) & 0x0f;
 	
 	/* get the data direction */
 	ddir = NCR_700_readb(host, CTEST0_REG) & 0x01;
@@ -345,6 +408,10 @@
 		if (synchronous && (sstat & SODR_REG_FULL))
 			++count;
 	}
+#ifdef NCR_700_DEBUG
+	if(count)
+		printk("RESIDUAL IS %d (ddir %d)\n", count, ddir);
+#endif
 	return count;
 }
 
@@ -530,21 +597,26 @@
 			       __u8 offset, __u8 period)
 {
 	int XFERP;
-
-	if(period*4 < NCR_700_MIN_PERIOD) {
-		printk(KERN_WARNING "53c700: Period %dns is less than SCSI-2 minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD);
-		period = NCR_700_MIN_PERIOD/4;
+	__u8 min_xferp = (hostdata->chip710
+			  ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
+	__u8 max_offset = (hostdata->chip710
+			   ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET);
+	/* NOTE: NCR_700_SDTR_msg[3] contains our offer of the minimum
+	 * period.  It is set in NCR_700_chip_setup() */
+	if(period < NCR_700_SDTR_msg[3]) {
+		printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4);
+		period = NCR_700_SDTR_msg[3];
 	}
 	XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
-	if(offset > NCR_700_MAX_OFFSET) {
-		printk(KERN_WARNING "53c700: Offset %d exceeds maximum, setting to %d\n",
-		       offset, NCR_700_MAX_OFFSET);
-		offset = NCR_700_MAX_OFFSET;
+	if(offset > max_offset) {
+		printk(KERN_WARNING "53c700: Offset %d exceeds chip maximum, setting to %d\n",
+		       offset, max_offset);
+		offset = max_offset;
 	}
-	if(XFERP < NCR_700_MIN_XFERP) {
+	if(XFERP < min_xferp) {
 		printk(KERN_WARNING "53c700: XFERP %d is less than minium, setting to %d\n",
-		       XFERP,  NCR_700_MIN_XFERP);
-		XFERP =  NCR_700_MIN_XFERP;
+		       XFERP,  min_xferp);
+		XFERP =  min_xferp;
 	}
 	return (offset & 0x0f) | (XFERP & 0x07)<<4;
 }
@@ -563,14 +635,28 @@
 
 		if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
 #ifdef NCR_700_DEBUG
-			printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is",
+			printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
 			       SCp, SCp->cmnd[7], result);
 			print_sense("53c700", SCp);
 #endif
 			if(result == 0)
 				result = SCp->cmnd[7];
 		}
-			
+
+		if(SCp->sc_data_direction != SCSI_DATA_NONE &&
+		   SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
+			int pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
+			if(SCp->use_sg) {
+				pci_unmap_sg(hostdata->pci_dev, SCp->buffer,
+					     SCp->use_sg, pci_direction);
+			} else {
+				pci_unmap_single(hostdata->pci_dev,
+						 slot->dma_handle,
+						 SCp->request_bufflen,
+						 pci_direction);
+			}
+		}
+
 		free_slot(slot, hostdata);
 
 		SCp->host_scribble = NULL;
@@ -602,19 +688,47 @@
 {
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+	__u32 dcntl_extra = 0;
+	__u8 min_period;
+	__u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
+
+	if(hostdata->chip710) {
+		__u8 burst_disable = hostdata->burst_disable
+			? BURST_DISABLE : 0;
+		dcntl_extra = COMPAT_700_MODE;
+
+		NCR_700_writeb(dcntl_extra, host, DCNTL_REG);
+		NCR_700_writeb(BURST_LENGTH_8  | hostdata->dmode_extra,
+			       host, DMODE_710_REG);
+		NCR_700_writeb(burst_disable | (hostdata->differential ? 
+						DIFF : 0), host, CTEST7_REG);
+		NCR_700_writeb(BTB_TIMER_DISABLE, host, CTEST0_REG);
+		NCR_700_writeb(FULL_ARBITRATION | ENABLE_PARITY | PARITY
+			       | AUTO_ATN, host, SCNTL0_REG);
+	} else {
+		NCR_700_writeb(BURST_LENGTH_8 | hostdata->dmode_extra,
+			       host, DMODE_700_REG);
+		NCR_700_writeb(hostdata->differential ? 
+			       DIFF : 0, host, CTEST7_REG);
+		if(hostdata->fast) {
+			/* this is for 700-66, does nothing on 700 */
+			NCR_700_writeb(LAST_DIS_ENBL | ENABLE_ACTIVE_NEGATION 
+				       | GENERATE_RECEIVE_PARITY, host,
+				       CTEST8_REG);
+		} else {
+			NCR_700_writeb(FULL_ARBITRATION | ENABLE_PARITY
+				       | PARITY | AUTO_ATN, host, SCNTL0_REG);
+		}
+	}
 
 	NCR_700_writeb(1 << host->this_id, host, SCID_REG);
 	NCR_700_writeb(0, host, SBCL_REG);
-	NCR_700_writeb(0, host, SXFER_REG);
+	NCR_700_writeb(ASYNC_OPERATION, host, SXFER_REG);
 
 	NCR_700_writeb(PHASE_MM_INT | SEL_TIMEOUT_INT | GROSS_ERR_INT | UX_DISC_INT
 	     | RST_INT | PAR_ERR_INT | SELECT_INT, host, SIEN_REG);
 
 	NCR_700_writeb(ABORT_INT | INT_INST_INT | ILGL_INST_INT, host, DIEN_REG);
-	NCR_700_writeb(BURST_LENGTH_8, host, DMODE_REG);
-	NCR_700_writeb(FULL_ARBITRATION | PARITY | AUTO_ATN, host, SCNTL0_REG);
-	NCR_700_writeb(LAST_DIS_ENBL | ENABLE_ACTIVE_NEGATION|GENERATE_RECEIVE_PARITY,
-	     host, CTEST8_REG);
 	NCR_700_writeb(ENABLE_SELECT, host, SCNTL1_REG);
 	if(hostdata->clock > 75) {
 		printk(KERN_ERR "53c700: Clock speed %dMHz is too high: 75Mhz is the maximum this chip can be driven at\n", hostdata->clock);
@@ -622,13 +736,13 @@
 		 * of spec: sync divider 2, async divider 3 */
 		DEBUG(("53c700: sync 2 async 3\n"));
 		NCR_700_writeb(SYNC_DIV_2_0, host, SBCL_REG);
-		NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG);
+		NCR_700_writeb(ASYNC_DIV_3_0 | dcntl_extra, host, DCNTL_REG);
 		hostdata->sync_clock = hostdata->clock/2;
 	} else	if(hostdata->clock > 50  && hostdata->clock <= 75) {
 		/* sync divider 1.5, async divider 3 */
 		DEBUG(("53c700: sync 1.5 async 3\n"));
 		NCR_700_writeb(SYNC_DIV_1_5, host, SBCL_REG);
-		NCR_700_writeb(ASYNC_DIV_3_0, host, DCNTL_REG);
+		NCR_700_writeb(ASYNC_DIV_3_0 | dcntl_extra, host, DCNTL_REG);
 		hostdata->sync_clock = hostdata->clock*2;
 		hostdata->sync_clock /= 3;
 		
@@ -636,30 +750,49 @@
 		/* sync divider 1, async divider 2 */
 		DEBUG(("53c700: sync 1 async 2\n"));
 		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
-		NCR_700_writeb(ASYNC_DIV_2_0, host, DCNTL_REG);
+		NCR_700_writeb(ASYNC_DIV_2_0 | dcntl_extra, host, DCNTL_REG);
 		hostdata->sync_clock = hostdata->clock;
 	} else if(hostdata->clock > 25 && hostdata->clock <=37) {
 		/* sync divider 1, async divider 1.5 */
 		DEBUG(("53c700: sync 1 async 1.5\n"));
 		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
-		NCR_700_writeb(ASYNC_DIV_1_5, host, DCNTL_REG);
+		NCR_700_writeb(ASYNC_DIV_1_5 | dcntl_extra, host, DCNTL_REG);
 		hostdata->sync_clock = hostdata->clock;
 	} else {
 		DEBUG(("53c700: sync 1 async 1\n"));
 		NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
-		NCR_700_writeb(ASYNC_DIV_1_0, host, DCNTL_REG);
+		NCR_700_writeb(ASYNC_DIV_1_0 | dcntl_extra, host, DCNTL_REG);
 		/* sync divider 1, async divider 1 */
+		hostdata->sync_clock = hostdata->clock;
+	}
+	/* Calculate the actual minimum period that can be supported
+	 * by our synchronous clock speed.  See the 710 manual for
+	 * exact details of this calculation which is based on a
+	 * setting of the SXFER register */
+	min_period = 1000*(4+min_xferp)/(4*hostdata->sync_clock);
+	if(min_period > NCR_700_MIN_PERIOD) {
+		NCR_700_SDTR_msg[3] = min_period;
 	}
+	if(hostdata->chip710)
+		NCR_700_SDTR_msg[4] = NCR_710_MAX_OFFSET;
 }
 
 STATIC void
 NCR_700_chip_reset(struct Scsi_Host *host)
 {
-	/* Chip reset */
-	NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG);
-	udelay(100);
+	struct NCR_700_Host_Parameters *hostdata = 
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
+	if(hostdata->chip710) {
+		NCR_700_writeb(SOFTWARE_RESET_710, host, ISTAT_REG);
+		udelay(100);
 
-	NCR_700_writeb(0, host, DCNTL_REG);
+		NCR_700_writeb(0, host, ISTAT_REG);
+	} else {
+		NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG);
+		udelay(100);
+		
+		NCR_700_writeb(0, host, DCNTL_REG);
+	}
 
 	mdelay(1000);
 
@@ -717,7 +850,7 @@
 			printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
 			       host->host_no);
 			hostdata->msgout[0] = A_REJECT_MSG;
-			dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+			dma_cache_wback((unsigned long)hostdata->msgout, 1);
 			script_patch_16(hostdata->script, MessageCount, 1);
 			/* SendMsgOut returns, so set up the return
 			 * address */
@@ -729,7 +862,7 @@
 		printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
 		       host->host_no, pun, lun);
 		hostdata->msgout[0] = A_REJECT_MSG;
-		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		dma_cache_wback((unsigned long)hostdata->msgout, 1);
 		script_patch_16(hostdata->script, MessageCount, 1);
 		resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
 
@@ -743,7 +876,7 @@
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
-		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		dma_cache_wback((unsigned long)hostdata->msgout, 1);
 		script_patch_16(hostdata->script, MessageCount, 1);
 		/* SendMsgOut returns, so set up the return
 		 * address */
@@ -761,8 +894,6 @@
 	__u32 temp = dsp + 8, resume_offset = dsp;
 	__u8 pun = 0xff, lun = 0xff;
 
-	dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
-
 	if(SCp != NULL) {
 		pun = SCp->target;
 		lun = SCp->lun;
@@ -778,8 +909,9 @@
 	switch(hostdata->msgin[0]) {
 
 	case A_EXTENDED_MSG:
-		return process_extended_message(host, hostdata, SCp,
-						dsp, dsps);
+		resume_offset =  process_extended_message(host, hostdata, SCp,
+							  dsp, dsps);
+		break;
 
 	case A_REJECT_MSG:
 		if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
@@ -792,6 +924,8 @@
 			printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
 			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
 			hostdata->tag_negotiated &= ~(1<<SCp->target);
+			SCp->device->tagged_queue = 0;
+			SCp->device->tagged_supported = 0;
 		} else {
 			printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n",
 			       host->host_no, pun, lun,
@@ -820,7 +954,7 @@
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
-		dma_cache_wback((unsigned long)hostdata->msgout, sizeof(hostdata->msgout));
+		dma_cache_wback((unsigned long)hostdata->msgout, 1);
 		script_patch_16(hostdata->script, MessageCount, 1);
 		/* SendMsgOut returns, so set up the return
 		 * address */
@@ -829,6 +963,8 @@
 		break;
 	}
 	NCR_700_writel(temp, host, TEMP_REG);
+	/* set us up to receive another message */
+	dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
 	return resume_offset;
 }
 
@@ -846,25 +982,26 @@
 	}
 
 	if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
-		dma_cache_inv((unsigned long)hostdata->status, sizeof(hostdata->status));
 		DEBUG(("  COMMAND COMPLETE, status=%02x\n",
-		       hostdata->status));
+		       hostdata->status[0]));
 		/* OK, if TCQ still on, we know it works */
 		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
 		/* check for contingent allegiance contitions */
-		if(status_byte(hostdata->status) == CHECK_CONDITION ||
-		   status_byte(hostdata->status) == COMMAND_TERMINATED) {
+		if(status_byte(hostdata->status[0]) == CHECK_CONDITION ||
+		   status_byte(hostdata->status[0]) == COMMAND_TERMINATED) {
 			struct NCR_700_command_slot *slot =
 				(struct NCR_700_command_slot *)SCp->host_scribble;
 			if(SCp->cmnd[0] == REQUEST_SENSE) {
 				/* OOPS: bad device, returning another
 				 * contingent allegiance condition */
 				printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);
-				NCR_700_scsi_done(hostdata, SCp, hostdata->status);
+				NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
 			} else {
-
-				DEBUG(("  cmd %p has status %d, requesting sense\n",
-				       SCp, hostdata->status));
+#ifdef NCR_DEBUG
+				print_command(SCp->cmnd);
+				printk("  cmd %p has status %d, requesting sense\n",
+				       SCp, hostdata->status[0]);
+#endif
 				/* we can destroy the command here because the
 				 * contingent allegiance condition will cause a 
 				 * retry which will re-copy the command from the
@@ -881,7 +1018,9 @@
 				 * was an internal sense request and the original
 				 * status at the end of the command */
 				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
-				SCp->cmnd[7] = hostdata->status;
+				SCp->cmnd[7] = hostdata->status[0];
+				SCp->sc_data_direction = SCSI_DATA_READ;
+				dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
 				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
 				slot->SG[0].pAddr = bS_to_host(virt_to_bus(SCp->sense_buffer));
 				slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
@@ -896,20 +1035,27 @@
 				hostdata->cmd = NULL;
 			}
 		} else {
-			if(status_byte(hostdata->status) == GOOD &&
-			   SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) {
-				/* Piggy back the tag queueing support
-				 * on this command */
-				if(((char *)SCp->request_buffer)[7] & 0x02) {
-					printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
-					hostdata->tag_negotiated |= (1<<SCp->target);
-					NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
-				} else {
-					NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
-					hostdata->tag_negotiated &= ~(1<<SCp->target);
-				}
-			}
-			NCR_700_scsi_done(hostdata, SCp, hostdata->status);
+			// Currently rely on the mid layer evaluation
+			// of the tag queuing capability
+			//
+			//if(status_byte(hostdata->status[0]) == GOOD &&
+			//   SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) {
+			//	/* Piggy back the tag queueing support
+			//	 * on this command */
+			//	pci_dma_sync_single(hostdata->pci_dev,
+			//			    slot->dma_handle,
+			//			    SCp->request_bufflen,
+			//			    PCI_DMA_FROMDEVICE);
+			//	if(((char *)SCp->request_buffer)[7] & 0x02) {
+			//		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
+			//		hostdata->tag_negotiated |= (1<<SCp->target);
+			//		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+			//	} else {
+			//		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+			//		hostdata->tag_negotiated &= ~(1<<SCp->target);
+			//	}
+			//}
+			NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
 		}
 	} else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
 		__u8 i = (dsps & 0xf00) >> 8;
@@ -947,8 +1093,6 @@
 		struct NCR_700_command_slot *slot;
 		__u8 reselection_id = hostdata->reselection_id;
 
-		dma_cache_inv((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
-
 		lun = hostdata->msgin[0] & 0x1f;
 
 		hostdata->reselection_id = 0xff;
@@ -996,7 +1140,7 @@
 			script_patch_16(hostdata->script,
 					CommandCount, slot->cmnd->cmd_len);
 			script_patch_32_abs(hostdata->script, SGScriptStartAddress,
-					    virt_to_bus(&slot->SG[0].ins));
+					    to32bit(&slot->pSG[0].ins));
 
 			/* Note: setting SXFER only works if we're
 			 * still in the MESSAGE phase, so it is vital
@@ -1005,6 +1149,16 @@
 			 * should therefore always clear ACK */
 			NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
 				       host, SXFER_REG);
+			dma_cache_inv((unsigned long)hostdata->msgin,
+				      MSG_ARRAY_SIZE);
+			dma_cache_wback((unsigned long)hostdata->msgout,
+					MSG_ARRAY_SIZE);
+			/* I'm just being paranoid here, the command should
+			 * already have been flushed from the cache */
+			dma_cache_wback((unsigned long)slot->cmnd->cmnd,
+					slot->cmnd->cmd_len);
+
+
 			
 		}
 	} else if(dsps == A_RESELECTED_DURING_SELECTION) {
@@ -1022,20 +1176,22 @@
 		/* Take out our own ID */
 		reselection_id &= ~(1<<host->this_id);
 		
-		printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%p[%04x] state=%d, count=%d\n",
-		       host->host_no, reselection_id, lun, (void *)dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count);
+		/* I've never seen this happen, so keep this as a printk rather
+		 * than a debug */
+		printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%08x[%04x] state=%d, count=%d\n",
+		       host->host_no, reselection_id, lun, dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count);
 
 		{
 			/* FIXME: DEBUGGING CODE */
-			__u32 SG = (__u32)bus_to_virt(hostdata->script[A_SGScriptStartAddress_used[0]]);
+			__u32 SG = (__u32)bS_to_cpu(hostdata->script[A_SGScriptStartAddress_used[0]]);
 			int i;
 
 			for(i=0; i< NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
-				if(SG >= (__u32)(&hostdata->slots[i].SG[0])
-				   && SG <= (__u32)(&hostdata->slots[i].SG[NCR_700_SG_SEGMENTS]))
+				if(SG >= to32bit(&hostdata->slots[i].pSG[0])
+				   && SG <= to32bit(&hostdata->slots[i].pSG[NCR_700_SG_SEGMENTS]))
 					break;
 			}
-			printk(KERN_INFO "IDENTIFIED SG segment as being %p in slot %p, cmd %p, slot->resume_offset=%p\n", (void *)SG, &hostdata->slots[i], hostdata->slots[i].cmnd, (void *)hostdata->slots[i].resume_offset);
+			printk(KERN_INFO "IDENTIFIED SG segment as being %08x in slot %p, cmd %p, slot->resume_offset=%08x\n", SG, &hostdata->slots[i], hostdata->slots[i].cmnd, hostdata->slots[i].resume_offset);
 			SCp =  hostdata->slots[i].cmnd;
 		}
 
@@ -1061,8 +1217,9 @@
 			reselection_id = bitmap_to_number(reselection_id);
 		}
 		hostdata->reselection_id = reselection_id;
+		/* just in case we have a stale simple tag message, clear it */
 		hostdata->msgin[1] = 0;
-		dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+		dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
 		if(hostdata->tag_negotiated & (1<<reselection_id)) {
 			resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
 		} else {
@@ -1092,8 +1249,8 @@
 		}	       
 		NCR_700_internal_bus_reset(host);
 	} else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) {
-		printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %p[%04x], continuing\n",
-		       host->host_no, pun, lun, dsps & 0xfff, (void *)dsp, dsp - hostdata->pScript);
+		printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %08x[%04x], continuing\n",
+		       host->host_no, pun, lun, dsps & 0xfff, dsp, dsp - hostdata->pScript);
 		resume_offset = dsp;
 	} else {
 		printk(KERN_ERR "scsi%d: (%d:%d), unidentified script interrupt 0x%x at %04x\n",
@@ -1122,7 +1279,8 @@
 	__u8 sbcl;
 
 	for(count = 0; count < 5; count++) {
-		id = NCR_700_readb(host, SFBR_REG);
+		id = NCR_700_readb(host, hostdata->chip710 ?
+				   CTEST9_REG : SFBR_REG);
 
 		/* Take out our own ID */
 		id &= ~(1<<host->this_id);
@@ -1174,8 +1332,9 @@
 	}
 	hostdata->state = NCR_700_HOST_BUSY;
 	hostdata->cmd = NULL;
+	/* clear any stale simple tag message */
 	hostdata->msgin[1] = 0;
-	dma_cache_wback((unsigned long)hostdata->msgin, sizeof(hostdata->msgin));
+	dma_cache_wback_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
 
 	if(id == 0xff) {
 		/* Selected as target, Ignore */
@@ -1188,6 +1347,32 @@
 	return resume_offset;
 }
 
+static inline void
+NCR_700_clear_fifo(struct Scsi_Host *host) {
+	const struct NCR_700_Host_Parameters *hostdata
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+	if(hostdata->chip710) {
+		NCR_700_writeb(CLR_FIFO_710, host, CTEST8_REG);
+	} else {
+		NCR_700_writeb(CLR_FIFO, host, DFIFO_REG);
+	}
+}
+
+static inline void
+NCR_700_flush_fifo(struct Scsi_Host *host) {
+	const struct NCR_700_Host_Parameters *hostdata
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+	if(hostdata->chip710) {
+		NCR_700_writeb(FLUSH_DMA_FIFO_710, host, CTEST8_REG);
+		udelay(10);
+		NCR_700_writeb(0, host, CTEST8_REG);
+	} else {
+		NCR_700_writeb(FLUSH_DMA_FIFO, host, DFIFO_REG);
+		udelay(10);
+		NCR_700_writeb(0, host, DFIFO_REG);
+	}
+}
+
 
 STATIC int
 NCR_700_start_command(Scsi_Cmnd *SCp)
@@ -1227,9 +1412,10 @@
 		NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
 	}
 
-	/* REQUEST_SENSE is asking for contingent I_T_L status.  If a
-	 * contingent allegiance condition exists, the device will
-	 * refuse all tags, so send the request sense as untagged */
+	/* REQUEST_SENSE is asking for contingent I_T_L(_Q) status.
+	 * If a contingent allegiance condition exists, the device
+	 * will refuse all tags, so send the request sense as untagged
+	 * */
 	if((hostdata->tag_negotiated & (1<<SCp->target))
 	   && (slot->tag != NCR_700_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
 		hostdata->msgout[count++] = A_SIMPLE_TAG_MSG;
@@ -1244,8 +1430,6 @@
 		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
 	}
 
-	dma_cache_wback((unsigned long)hostdata->msgout, count);
-
 	script_patch_16(hostdata->script, MessageCount, count);
 
 
@@ -1258,20 +1442,27 @@
 	/* finally plumb the beginning of the SG list into the script
 	 * */
 	script_patch_32_abs(hostdata->script, SGScriptStartAddress,
-			    virt_to_bus(&slot->SG[0].ins));
-	NCR_700_writeb(CLR_FIFO, SCp->host, DFIFO_REG);
+			    to32bit(&slot->pSG[0].ins));
+	NCR_700_clear_fifo(SCp->host);
 
-	/* set the synchronous period/offset */
 	if(slot->resume_offset == 0)
 		slot->resume_offset = hostdata->pScript;
+	/* now perform all the writebacks and invalidates */
+	dma_cache_wback((unsigned long)hostdata->msgout, count);
+	dma_cache_inv((unsigned long)hostdata->msgin, MSG_ARRAY_SIZE);
+	dma_cache_wback((unsigned long)SCp->cmnd, SCp->cmd_len);
+	dma_cache_inv((unsigned long)hostdata->status, 1);
+
+	/* set the synchronous period/offset */
 	NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
-	     SCp->host, SXFER_REG);
+		       SCp->host, SXFER_REG);
+	NCR_700_writel(slot->temp, SCp->host, TEMP_REG);
+	NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG);
+
 	/* allow interrupts here so that if we're selected we can take
 	 * a selection interrupt.  The script start may not be
 	 * effective in this case, but the selection interrupt will
 	 * save our command in that case */
-	NCR_700_writel(slot->temp, SCp->host, TEMP_REG);
-	NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG);
 	restore_flags(flags);
 
 	return 1;
@@ -1342,8 +1533,8 @@
 
 			hostdata->state = NCR_700_HOST_BUSY;
 
-			printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %p[%04x]\n",
-			       host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, (void *)dsp, dsp - hostdata->pScript);
+			printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %08x[%04x]\n",
+			       host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, dsp, dsp - hostdata->pScript);
 
 			/* clear all the negotiated parameters */
 			for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next)
@@ -1396,13 +1587,15 @@
 				printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
 #endif
 				resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
-			} else if(dsp >= virt_to_bus(&slot->SG[0].ins) &&
-				  dsp <= virt_to_bus(&slot->SG[NCR_700_SG_SEGMENTS].ins)) {
+			} else if(dsp >= to32bit(&slot->pSG[0].ins) &&
+				  dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) {
 				int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
-				int SGcount = (dsp - virt_to_bus(&slot->SG[0].ins))/sizeof(struct NCR_700_SG_List);
+				int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List);
 				int residual = NCR_700_data_residual(host);
 				int i;
 #ifdef NCR_700_DEBUG
+				__u32 naddr = NCR_700_readl(host, DNAD_REG);
+
 				printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
 				       host->host_no, pun, lun,
 				       SGcount, data_transfer);
@@ -1427,6 +1620,11 @@
 					slot->SG[SGcount].ins |= bS_to_host(data_transfer);
 					pAddr = bS_to_cpu(slot->SG[SGcount].pAddr);
 					pAddr += (count - data_transfer);
+#ifdef NCR_700_DEBUG
+					if(pAddr != naddr) {
+						printk("scsi%d (%d:%d) transfer mismatch pAddr=%lx, naddr=%lx, data_transfer=%d, residual=%d\n", host->host_no, pun, lun, (unsigned long)pAddr, (unsigned long)naddr, data_transfer, residual);
+					}
+#endif
 					slot->SG[SGcount].pAddr = bS_to_host(pAddr);
 				}
 				/* set the executed moves to nops */
@@ -1438,6 +1636,8 @@
 				/* and pretend we disconnected after
 				 * the command phase */
 				resume_offset = hostdata->pScript + Ent_MsgInDuringData;
+				/* make sure all the data is flushed */
+				NCR_700_flush_fifo(host);
 			} else {
 				__u8 sbcl = NCR_700_readb(host, SBCL_REG);
 				printk(KERN_ERR "scsi%d: (%d:%d) phase mismatch at %04x, phase %s\n",
@@ -1449,15 +1649,19 @@
 			printk(KERN_ERR "scsi%d: (%d:%d) GROSS ERROR\n",
 			       host->host_no, pun, lun);
 			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
+		} else if(sstat0 & PARITY_ERROR) {
+			printk(KERN_ERR "scsi%d: (%d:%d) PARITY ERROR\n",
+			       host->host_no, pun, lun);
+			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
 		} else if(dstat & SCRIPT_INT_RECEIVED) {
 			DEBUG(("scsi%d: (%d:%d) ====>SCRIPT INTERRUPT<====\n",
 			       host->host_no, pun, lun));
 			resume_offset = process_script_interrupt(dsps, dsp, SCp, host, hostdata);
 		} else if(dstat & (ILGL_INST_DETECTED)) {
-			printk(KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%p[0x%x]!!!\n"
+			printk(KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%08x[0x%x]!!!\n"
 			       "         Please email James.Bottomley@HansenPartnership.com with the details\n",
 			       host->host_no, pun, lun,
-			       (void *)dsp, dsp - hostdata->pScript);
+			       dsp, dsp - hostdata->pScript);
 			NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
 		} else if(dstat & (WATCH_DOG_INTERRUPT|ABORTED)) {
 			printk(KERN_ERR "scsi%d: (%d:%d) serious DMA problem, dstat=%02x\n",
@@ -1495,13 +1699,13 @@
 
 	if(resume_offset) {
 		if(hostdata->state != NCR_700_HOST_BUSY) {
-			printk(KERN_ERR "scsi%d: Driver error: resume at %p [%04x] with non busy host!\n",
-			       host->host_no, (void *)resume_offset, resume_offset - hostdata->pScript);
+			printk(KERN_ERR "scsi%d: Driver error: resume at 0x%08x [0x%04x] with non busy host!\n",
+			       host->host_no, resume_offset, resume_offset - hostdata->pScript);
 			hostdata->state = NCR_700_HOST_BUSY;
 		}
 
 		DEBUG(("Attempting to resume at %x\n", resume_offset));
-		NCR_700_writeb(CLR_FIFO, host, DFIFO_REG);
+		NCR_700_clear_fifo(host);
 		NCR_700_writel(resume_offset, host, DSP_REG);
 	} 
 	/* There is probably a technical no-no about this: If we're a
@@ -1579,6 +1783,7 @@
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
 	__u32 move_ins;
+	int pci_direction;
 	struct NCR_700_command_slot *slot;
 	int hash;
 
@@ -1618,6 +1823,20 @@
 	printk("53c700: scsi%d, command ", SCp->host->host_no);
 	print_command(SCp->cmnd);
 #endif
+	if(SCp->device->tagged_supported && !SCp->device->tagged_queue
+	   && (hostdata->tag_negotiated &(1<<SCp->target)) == 0
+	   && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
+		/* upper layer has indicated tags are supported.  We don't
+		 * necessarily believe it yet.
+		 *
+		 * NOTE: There is a danger here: the mid layer supports
+		 * tag queuing per LUN.  We only support it per PUN because
+		 * of potential reselection issues */
+		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->target, SCp->lun);
+		hostdata->tag_negotiated |= (1<<SCp->target);
+		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+		SCp->device->tagged_queue = 1;
+	}
 
 	if(hostdata->tag_negotiated &(1<<SCp->target)) {
 
@@ -1681,36 +1900,11 @@
 		hostdata->ITL_Hash_back[hash] = slot;
 	slot->ITL_back = NULL;
 
-		
-	/* This is f****g ridiculous; every low level HBA driver has
-	 * to determine the direction of the commands, why isn't this
-	 * done inside the scsi_lib !!??? */
 	switch (SCp->cmnd[0]) {
 	case REQUEST_SENSE:
 		/* clear the internal sense magic */
 		SCp->cmnd[6] = 0;
 		/* fall through */
-	case INQUIRY:
-	case MODE_SENSE:
-	case READ_6:
-	case READ_10:
-	case READ_12:
-	case READ_CAPACITY:
-	case READ_BLOCK_LIMITS:
-	case READ_TOC:
-		move_ins = SCRIPT_MOVE_DATA_IN;
-		break;
-	case MODE_SELECT:
-	case WRITE_6:
-	case WRITE_10:
-	case WRITE_12:
-		move_ins = SCRIPT_MOVE_DATA_OUT;
-		break;
-	case TEST_UNIT_READY:
-	case ALLOW_MEDIUM_REMOVAL:
-	case START_STOP:
-		move_ins = 0;
-		break;
 	default:
 		/* OK, get it from the command */
 		switch(SCp->sc_data_direction) {
@@ -1734,26 +1928,40 @@
 	}
 
 	/* now build the scatter gather list */
+	pci_direction = scsi_to_pci_dma_dir(SCp->sc_data_direction);
 	if(move_ins != 0) {
 		int i;
+		int sg_count;
+		dma_addr_t vPtr = 0;
+		__u32 count = 0;
+
+		if(SCp->use_sg) {
+			sg_count = pci_map_sg(hostdata->pci_dev, SCp->buffer,
+					      SCp->use_sg, pci_direction);
+		} else {
+			vPtr = pci_map_single(hostdata->pci_dev,
+					      SCp->request_buffer, 
+					      SCp->request_bufflen,
+					      pci_direction);
+			count = SCp->request_bufflen;
+			slot->dma_handle = vPtr;
+			sg_count = 1;
+		}
+			
 
-		for(i = 0; i < (SCp->use_sg ? SCp->use_sg : 1); i++) {
-			void *vPtr;
-			__u32 count;
+		for(i = 0; i < sg_count; i++) {
 
 			if(SCp->use_sg) {
-				vPtr = (((struct scatterlist *)SCp->buffer)[i].address);
-				count = ((struct scatterlist *)SCp->buffer)[i].length;
-			} else {
-				vPtr = SCp->request_buffer;
-				count = SCp->request_bufflen;
+				struct scatterlist *sg = SCp->buffer;
+
+				vPtr = sg_dma_address(&sg[i]);
+				count = sg_dma_len(&sg[i]);
 			}
+
 			slot->SG[i].ins = bS_to_host(move_ins | count);
 			DEBUG((" scatter block %d: move %d[%08x] from 0x%lx\n",
-			       i, count, slot->SG[i].ins, 
-			       virt_to_bus(vPtr)));
-			dma_cache_wback_inv((unsigned long)vPtr, count);
-			slot->SG[i].pAddr = bS_to_host(virt_to_bus(vPtr));
+			       i, count, slot->SG[i].ins, (unsigned long)vPtr));
+			slot->SG[i].pAddr = bS_to_host(vPtr);
 		}
 		slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
 		slot->SG[i].pAddr = 0;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/53c700.h linux/drivers/scsi/53c700.h
--- v2.4.10/linux/drivers/scsi/53c700.h	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/53c700.h	Sun Sep 30 12:26:08 2001
@@ -36,8 +36,8 @@
 /* WARNING: Leave this in for now: the dependency preprocessor doesn't
  * pick up file specific flags, so must define here if they are not
  * set */
-#if !defined(IO_MAPPED) && !defined(MEM_MAPPED)
-#define IO_MAPPED
+#if !defined(CONFIG_53C700_IO_MAPPED) && !defined(CONFIG_53C700_MEM_MAPPED)
+#error "Config.in must define either CONFIG_53C700_IO_MAPPED or CONFIG_53C700_MEM_MAPPED to use this scsi core."
 #endif
 
 
@@ -90,43 +90,43 @@
 static inline void
 NCR_700_set_SXFER(Scsi_Device *SDp, __u8 sxfer)
 {
-	((__u32)SDp->hostdata) &= 0xffffff00;
-	((__u32)SDp->hostdata) |= sxfer & 0xff;
+	((unsigned long)SDp->hostdata) &= 0xffffff00;
+	((unsigned long)SDp->hostdata) |= sxfer & 0xff;
 }
 static inline __u8 NCR_700_get_SXFER(Scsi_Device *SDp)
 {
-	return (((__u32)SDp->hostdata) & 0xff);
+	return (((unsigned long)SDp->hostdata) & 0xff);
 }
 static inline void
 NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
 {
-	((__u32)SDp->hostdata) &= 0xffff00ff;
-	((__u32)SDp->hostdata) |= (0xff00 & (depth << 8));
+	((unsigned long)SDp->hostdata) &= 0xffff00ff;
+	((unsigned long)SDp->hostdata) |= (0xff00 & (depth << 8));
 }
 static inline __u8
 NCR_700_get_depth(Scsi_Device *SDp)
 {
-	return ((((__u32)SDp->hostdata) & 0xff00)>>8);
+	return ((((unsigned long)SDp->hostdata) & 0xff00)>>8);
 }
 static inline int
 NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag)
 {
-	return (((__u32)SDp->hostdata) & flag) == flag;
+	return (((unsigned long)SDp->hostdata) & flag) == flag;
 }
 static inline int
 NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag)
 {
-	return (((__u32)SDp->hostdata) & flag) == 0;
+	return (((unsigned long)SDp->hostdata) & flag) == 0;
 }
 static inline void
 NCR_700_set_flag(Scsi_Device *SDp, __u32 flag)
 {
-	((__u32)SDp->hostdata) |= (flag & 0xffff0000);
+	((unsigned long)SDp->hostdata) |= (flag & 0xffff0000);
 }
 static inline void
 NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag)
 {
-	((__u32)SDp->hostdata) &= ~(flag & 0xffff0000);
+	((unsigned long)SDp->hostdata) &= ~(flag & 0xffff0000);
 }
 
 /* These represent the Nexus hashing functions.  A Nexus in SCSI terms
@@ -162,6 +162,8 @@
 }
 
 struct NCR_700_command_slot {
+	struct NCR_700_SG_List	SG[NCR_700_SG_SEGMENTS+1];
+	struct NCR_700_SG_List	*pSG;
 	#define NCR_700_SLOT_MASK 0xFC
 	#define NCR_700_SLOT_MAGIC 0xb8
 	#define	NCR_700_SLOT_FREE (0|NCR_700_SLOT_MAGIC) /* slot may be used */
@@ -170,10 +172,12 @@
 	__u8	state;
 	#define NCR_700_NO_TAG	0xdead
 	__u16	tag;
-	struct NCR_700_SG_List	SG[NCR_700_SG_SEGMENTS+1];
 	__u32	resume_offset;
 	Scsi_Cmnd	*cmnd;
 	__u32		temp;
+	/* if this command is a pci_single mapping, holds the dma address
+	 * for later unmapping in the done routine */
+	dma_addr_t	dma_handle;
 	/* Doubly linked ITL/ITLQ list kept in strict time order
 	 * (latest at the back) */
 	struct NCR_700_command_slot *ITL_forw;
@@ -186,12 +190,16 @@
 	/* These must be filled in by the calling driver */
 	int	clock;			/* board clock speed in MHz */
 	__u32	base;			/* the base for the port (copied to host) */
+	struct pci_dev	*pci_dev;
+	__u8	dmode_extra;	/* adjustable bus settings */
 	__u8	differential:1;	/* if we are differential */
-#ifdef __hppa__
+#ifdef CONFIG_53C700_LE_ON_BE
 	/* This option is for HP only.  Set it if your chip is wired for
 	 * little endian on this platform (which is big endian) */
 	__u8	force_le_on_be:1;
 #endif
+	__u8	chip710:1;	/* set if really a 710 not 700 */
+	__u8	burst_disable:1;	/* set to 1 to disable 710 bursting */
 
 	/* NOTHING BELOW HERE NEEDS ALTERING */
 	__u8	fast:1;		/* if we can alter the SCSI bus clock
@@ -209,10 +217,11 @@
 	enum NCR_700_Host_State state; /* protected by state lock */
 	Scsi_Cmnd *cmd;
 
-	__u8	msgout[8];
+	__u8	*msgout;
+#define	MSG_ARRAY_SIZE	16
 	__u8	tag_negotiated;
-	__u8	status;
-	__u8	msgin[8];
+	__u8	*status;
+	__u8	*msgin;
 	struct NCR_700_command_slot	*slots;
 	int	saved_slot_position;
 	int	command_slot_count; /* protected by state lock */
@@ -237,7 +246,7 @@
 /*
  *	53C700 Register Interface - the offset from the Selected base
  *	I/O address */
-#ifdef __hppa__
+#ifdef CONFIG_53C700_LE_ON_BE
 #define bE	(hostdata->force_le_on_be ? 0 : 3)
 #define	bSWAP	(hostdata->force_le_on_be)
 #elif defined(__BIG_ENDIAN)
@@ -310,6 +319,7 @@
 #define		SODL_REG_FULL		0x20
 #define SSTAT2_REG                      0x0F
 #define CTEST0_REG                      0x14
+#define		BTB_TIMER_DISABLE	0x40
 #define CTEST1_REG                      0x15
 #define CTEST2_REG                      0x16
 #define CTEST3_REG                      0x17
@@ -327,6 +337,8 @@
 #define         MASTER_CONTROL          0x10
 #define         DMA_DIRECTION           0x08
 #define CTEST7_REG                      0x1B
+#define		BURST_DISABLE		0x80 /* 710 only */
+#define		SEL_TIMEOUT_DISABLE	0x10 /* 710 only */
 #define         DFP                     0x08
 #define         EVP                     0x04
 #define		DIFF			0x01
@@ -337,6 +349,7 @@
 #define		CLR_FIFO		0x40
 #define	ISTAT_REG			0x21
 #define		ABORT_OPERATION		0x80
+#define		SOFTWARE_RESET_710	0x40
 #define		DMA_INT_PENDING		0x01
 #define		SCSI_INT_PENDING	0x02
 #define		CONNECTED		0x08
@@ -345,27 +358,34 @@
 #define		SHORTEN_FILTERING	0x04
 #define		ENABLE_ACTIVE_NEGATION	0x10
 #define		GENERATE_RECEIVE_PARITY	0x20
+#define		CLR_FIFO_710		0x04
+#define		FLUSH_DMA_FIFO_710	0x08
 #define CTEST9_REG                      0x23
 #define	DBC_REG				0x24
 #define	DCMD_REG			0x27
 #define	DNAD_REG			0x28
 #define	DIEN_REG			0x39
+#define		BUS_FAULT		0x20
 #define 	ABORT_INT		0x10
 #define 	INT_INST_INT		0x04
 #define 	WD_INT			0x02
 #define 	ILGL_INST_INT		0x01
 #define	DCNTL_REG			0x3B
 #define		SOFTWARE_RESET		0x01
+#define		COMPAT_700_MODE		0x01
 #define 	SCRPTS_16BITS		0x20
 #define		ASYNC_DIV_2_0		0x00
-#define		ASYNC_DIV_1_5		0x01
-#define		ASYNC_DIV_1_0		0x02
-#define		ASYNC_DIV_3_0		0x03
-#define	DMODE_REG			0x34
+#define		ASYNC_DIV_1_5		0x40
+#define		ASYNC_DIV_1_0		0x80
+#define		ASYNC_DIV_3_0		0xc0
+#define DMODE_710_REG			0x38
+#define	DMODE_700_REG			0x34
 #define		BURST_LENGTH_1		0x00
 #define		BURST_LENGTH_2		0x40
 #define		BURST_LENGTH_4		0x80
 #define		BURST_LENGTH_8		0xC0
+#define		DMODE_FC1		0x10
+#define		DMODE_FC2		0x20
 #define 	BW16			32 
 #define 	MODE_286		16
 #define 	IO_XFER			8
@@ -377,7 +397,11 @@
 /* Parameters to begin SDTR negotiations.  Empirically, I find that
  * the 53c700-66 cannot handle an offset >8, so don't change this  */
 #define NCR_700_MAX_OFFSET	8
+/* Was hoping the max offset would be greater for the 710, but
+ * empirically it seems to be 8 also */
+#define NCR_710_MAX_OFFSET	8
 #define NCR_700_MIN_XFERP	1
+#define NCR_710_MIN_XFERP	0
 #define NCR_700_MIN_PERIOD	25 /* for SDTR message, 100ns */
 
 #define script_patch_32(script, symbol, value) \
@@ -427,14 +451,14 @@
 		val |= ((value) & 0xffff); \
 		(script)[A_##symbol##_used[i]] = bS_to_host(val); \
 		dma_cache_wback((unsigned long)&(script)[A_##symbol##_used[i]], 4); \
-		DEBUG((" script, patching ID field %s at %d to 0x%x\n", \
+		DEBUG((" script, patching short field %s at %d to 0x%x\n", \
 		       #symbol, A_##symbol##_used[i], val)); \
 	} \
 }
 
 #endif
 
-#ifdef MEM_MAPPED
+#ifdef CONFIG_53C700_MEM_MAPPED
 static inline __u8
 NCR_700_readb(struct Scsi_Host *host, __u32 reg)
 {
@@ -482,7 +506,7 @@
 
 	writel(bS_to_host(value), host->base + reg);
 }
-#elif defined(IO_MAPPED)
+#elif defined(CONFIG_53C700_IO_MAPPED)
 static inline __u8
 NCR_700_readb(struct Scsi_Host *host, __u32 reg)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/53c700.scr linux/drivers/scsi/53c700.scr
--- v2.4.10/linux/drivers/scsi/53c700.scr	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/53c700.scr	Sun Sep 30 12:26:08 2001
@@ -81,6 +81,7 @@
 ABSOLUTE	DISCONNECT_AFTER_CMD = 0x380
 ABSOLUTE	SDTR_MSG_AFTER_CMD = 0x360
 ABSOLUTE	WDTR_MSG_AFTER_CMD = 0x3A0
+ABSOLUTE	MSG_IN_AFTER_STATUS = 0x440
 ABSOLUTE	DISCONNECT_AFTER_DATA = 0x580
 ABSOLUTE	MSG_IN_AFTER_DATA_IN = 0x550
 ABSOLUTE	MSG_IN_AFTER_DATA_OUT = 0x650
@@ -116,7 +117,8 @@
 
 ;
 ; SCSI Messages we interpret in the script
-; 
+;
+ABSOLUTE	COMMAND_COMPLETE_MSG	= 0x00
 ABSOLUTE	EXTENDED_MSG		= 0x01
 ABSOLUTE	SDTR_MSG		= 0x01
 ABSOLUTE	SAVE_DATA_PTRS_MSG	= 0x02
@@ -393,7 +395,12 @@
 Finish:
 	MOVE	1, StatusAddress, WHEN STATUS
 	INT	NOT_MSG_IN_AFTER_STATUS, WHEN NOT MSG_IN
-	CALL	ReceiveMessage
+	MOVE	1, ReceiveMsgAddress, WHEN MSG_IN
+	JUMP	FinishCommandComplete, IF COMMAND_COMPLETE_MSG
+	CALL	ProcessReceiveMessage
+	INT	MSG_IN_AFTER_STATUS
+	ENTRY	FinishCommandComplete
+FinishCommandComplete:
 	CLEAR	ACK
 	WAIT	DISCONNECT
 	ENTRY	Finish1
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c
--- v2.4.10/linux/drivers/scsi/53c7xx.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/scsi/53c7xx.c	Sun Sep 30 12:26:07 2001
@@ -230,9 +230,7 @@
  *
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <linux/config.h>
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c
--- v2.4.10/linux/drivers/scsi/AM53C974.c	Fri Apr 27 13:59:17 2001
+++ linux/drivers/scsi/AM53C974.c	Sun Sep 30 12:26:07 2001
@@ -2449,6 +2449,8 @@
 /* You can specify overrides=a,b,c,d in the same format at AM53C974=a,b,c,d
    on boot up */
 MODULE_PARM(overrides, "1-32i");
+MODULE_LICENSE("GPL");
+
 
 static Scsi_Host_Template driver_template = AM53C974;
 #include "scsi_module.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- v2.4.10/linux/drivers/scsi/BusLogic.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/scsi/BusLogic.c	Sun Sep 30 12:26:07 2001
@@ -4993,6 +4993,7 @@
 /*
   Get it all started
 */
+MODULE_LICENSE("GPL");
 
 static SCSI_Host_Template_T driver_template = BUSLOGIC;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ChangeLog.serverraid linux/drivers/scsi/ChangeLog.serverraid
--- v2.4.10/linux/drivers/scsi/ChangeLog.serverraid	Mon Aug 30 10:43:25 1999
+++ linux/drivers/scsi/ChangeLog.serverraid	Sun Sep 30 12:26:08 2001
@@ -1,25 +1,103 @@
-Change Log
-~~~~~~~~~~
+IBM ServeRAID driver Change Log
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-	1.00.00 - Initial Public Release
-		- Functionally equivalent to 0.99.05
+        4.80.20  - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )
+                 - 5 second delay needed after resetting an i960 adapter
+        
+        4.80.14  - Take all semaphores off stack                    
+                   Clean Up New_IOCTL path
+                   
+        4.80.04  - Eliminate calls to strtok() if 2.4.x or greater 
+                 - Adjustments to Device Queue Depth               
+
+        4.80.00  - Make ia64 Safe    
+        
+        4.72.01  - I/O Mapped Memory release ( so "insmod ips" does not Fail )    
+                   Don't Issue Internal FFDC Command if there are Active Commands 
+                   Close Window for getting too many IOCTL's active 
+                   
+        4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     
+        
+        4.71.00  - Change all memory allocations to not use GFP_DMA flag 
+                   Code Clean-Up for 2.4.x kernel      
+        
+        4.70.15  - Fix Breakup for very large ( non-SG ) requests
+        
+        4.70.13  - Don't release HA Lock in ips_next() until SC taken off queue  
+                 - Unregister SCSI device in ips_release()                        
+                 - Don't Send CDB's if we already know the device is not present  
+                 
+        4.70.12  - Corrective actions for bad controller ( during initialization )
+        
+        4.70.09  - Use a Common ( Large Buffer ) for Flashing from the JCRM CD    
+                 - Add IPSSEND Flash Support                                      
+                 - Set Sense Data for Unknown SCSI Command                        
+                 - Use Slot Number from NVRAM Page 5 
+                 - Restore caller's DCDB Structure
+                                       
+        4.20.14  - Update patch files for kernel 2.4.0-test5
+
+        4.20.13  - Fix some failure cases / reset code
+                 - Hook into the reboot_notifier to flush the controller
+                   cache
+
+        4.20.03 - Rename version to coincide with new release schedules
+                - Performance fixes
+                - Fix truncation of /proc files with cat
+                - Merge in changes through kernel 2.4.0test1ac21
+
+        4.10.13 - Fix for dynamic unload and proc file system
+
+        4.10.00 - Add support for ServeRAID 4M/4L
+
+        4.00.06 - Fix timeout with initial FFDC command
+
+        4.00.05 - Remove wish_block from init routine
+                - Use linux/spinlock.h instead of asm/spinlock.h for kernels
+                  2.3.18 and later
+                - Sync with other changes from the 2.3 kernels
+
+        4.00.04 - Rename structures/constants to be prefixed with IPS_
+
+        4.00.03 - Add alternative passthru interface
+                - Add ability to flash ServeRAID BIOS
+
+        4.00.02 - Fix problem with PT DCDB with no buffer
+
+        4.00.01 - Add support for First Failure Data Capture
+
+        4.00.00 - Add support for ServeRAID 4
+
+        3.60.02 - Make DCDB direction based on lookup table.
+                - Only allow one DCDB command to a SCSI ID at a time.
+
+        3.60.01 - Remove bogus error check in passthru routine.
+
+        3.60.00 - Bump max commands to 128 for use with ServeRAID
+                  firmware 3.60.
+                - Change version to 3.60 to coincide with ServeRAID release
+                  numbering.
+
+        1.00.00 - Initial Public Release
+                - Functionally equivalent to 0.99.05
 
         0.99.05 - Fix an oops on certain passthru commands
 
-	0.99.04 - Fix race condition in the passthru mechanism
+        0.99.04 - Fix race condition in the passthru mechanism
                   -- this required the interface to the utilities to change
-		- Fix error recovery code
+                - Fix error recovery code
 
-	0.99.03 - Make interrupt routine handle all completed request on the
-		  adapter not just the first one
-		- Make sure passthru commands get woken up if we run out of
-		  SCBs
-		- Send all of the commands on the queue at once rather than
-		  one at a time since the card will support it.
+        0.99.03 - Make interrupt routine handle all completed request on the
+                  adapter not just the first one
+                - Make sure passthru commands get woken up if we run out of
+                  SCBs
+                - Send all of the commands on the queue at once rather than
+                  one at a time since the card will support it.
 
-	0.99.02 - Added some additional debug statements to print out
+        0.99.02 - Added some additional debug statements to print out
                   errors if an error occurs while trying to read/write
                   to a logical drive (IPS_DEBUG).
 
-                  Fixed read/write errors when the adapter is using an
+                - Fixed read/write errors when the adapter is using an
                   8K stripe size.
+
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.4.10/linux/drivers/scsi/Config.in	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/Config.in	Sun Sep 30 12:26:08 2001
@@ -115,9 +115,18 @@
    fi
 fi
 dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI
-dep_tristate 'NCR Dual 700 MCA SCSI support' CONFIG_SCSI_NCR_D700 $CONFIG_SCSI $CONFIG_MCA
+if [ "$CONFIG_MCA" = "y" ]; then
+   dep_tristate 'NCR Dual 700 MCA SCSI support' CONFIG_SCSI_NCR_D700 $CONFIG_SCSI
+   if [ "$CONFIG_SCSI_NCR_D700" != "n" ]; then
+      define_bool CONFIG_53C700_IO_MAPPED y
+   fi
+fi
 if [ "$CONFIG_PARISC" = "y" ]; then
-   dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI70 $CONFIG_SCSI
+   dep_tristate 'HP LASI SCSI support for 53c700' CONFIG_SCSI_LASI700 $CONFIG_SCSI
+   if [ "$CONFIG_SCSI_LASI700" != "n" ]; then
+      define_bool CONFIG_53C700_MEM_MAPPED y
+      define_bool CONFIG_53C700_LE_ON_BE y
+   fi
 fi
 dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI $CONFIG_PCI
 if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v2.4.10/linux/drivers/scsi/Makefile	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/Makefile	Sun Sep 30 12:26:08 2001
@@ -13,29 +13,21 @@
 # satisfy certain initialization assumptions in the SCSI layer.
 # *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
 
-O_TARGET := scsidrv.o
 
-SUB_DIRS	:=
-MOD_SUB_DIRS	:=
-MOD_IN_SUB_DIRS	:=
-ALL_SUB_DIRS	:= $(SUB_DIRS) pcmcia
+CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
+CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
+CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
 
-subdir-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx
 
-ifeq ($(CONFIG_PCMCIA),y)
-  SUB_DIRS += pcmcia
-  MOD_IN_SUB_DIRS += pcmcia
-else
-  ifeq ($(CONFIG_PCMCIA),m)
-    MOD_IN_SUB_DIRS += pcmcia
-  endif
-endif
+O_TARGET := scsidrv.o
 
-export-objs	:= scsi_syms.o 53c700.o 53c700-mem.o
+export-objs	:= scsi_syms.o 53c700.o
+mod-subdirs	:= pcmcia ../acorn/scsi
+
+
+subdir-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx
+subdir-$(CONFIG_PCMCIA)		+= pcmcia
 
-CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
-CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
-CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
 
 obj-$(CONFIG_SCSI)		+= scsi_mod.o
 
@@ -125,13 +117,10 @@
 obj-$(CONFIG_SCSI_DEBUG)	+= scsi_debug.o
 obj-$(CONFIG_SCSI_FCAL)		+= fcal.o
 obj-$(CONFIG_SCSI_CPQFCTS)	+= cpqfc.o
-obj-$(CONFIG_SCSI_LASI700)	+= lasi700.o 53c700-mem.o
+obj-$(CONFIG_SCSI_LASI700)	+= lasi700.o 53c700.o
 
-ifeq ($(CONFIG_ARCH_ACORN),y)
-mod-subdirs	+= ../acorn/scsi
-subdir-y	+= ../acorn/scsi
-obj-y		+= ../acorn/scsi/acorn-scsi.o
-endif
+subdir-$(CONFIG_ARCH_ACORN)	+= ../acorn/scsi
+obj-$(CONFIG_ARCH_ACORN)	+= ../acorn/scsi/acorn-scsi.o
 
 obj-$(CONFIG_CHR_DEV_ST)	+= st.o
 obj-$(CONFIG_CHR_DEV_OSST)	+= osst.o
@@ -149,7 +138,8 @@
 sr_mod-objs	:= sr.o sr_ioctl.o sr_vendor.o
 initio-objs	:= ini9100u.o i91uscsi.o
 a100u2w-objs	:= inia100.o i60uscsi.o
-cpqfc-objs	:= cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o cpqfcTSworker.o cpqfcTStrigger.o
+cpqfc-objs	:= cpqfcTSinit.o cpqfcTScontrol.o cpqfcTSi2c.o \
+		   cpqfcTSworker.o cpqfcTStrigger.o
 
 include $(TOPDIR)/Rules.make
 
@@ -209,10 +199,3 @@
 	mv script.h 53c700_d.h
 
 53c700.o: 53c700_d.h
-
-53c700-mem.o: 53c700_d.h
-
-53c700-mem.c: 53c700.c
-	echo "/* WARNING: GENERATED FILE (from $<), DO NOT MODIFY */" > $@
-	echo "#define MEM_MAPPED" >> $@
-	cat $< >> $@
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c
--- v2.4.10/linux/drivers/scsi/NCR53C9x.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/scsi/NCR53C9x.c	Sun Sep 30 12:26:07 2001
@@ -21,9 +21,7 @@
  * 4) Maybe change use of "esp" to something more "NCR"'ish.
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <linux/config.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c
--- v2.4.10/linux/drivers/scsi/NCR53c406a.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/scsi/NCR53c406a.c	Sun Sep 30 12:26:07 2001
@@ -1074,6 +1074,7 @@
     /* SIGNATURE	= (port_base+0x0E);*/
     /* CONFIG6		= (port_base+0x0F);*/
 }
+MODULE_LICENSE("GPL");
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = NCR53c406a;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- v2.4.10/linux/drivers/scsi/advansys.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/advansys.c	Sun Sep 30 12:26:07 2001
@@ -775,9 +775,7 @@
  */
 
 #include <linux/config.h>
-#ifdef MODULE
 #include <linux/module.h>
-#endif /* MODULE */
 
 #if defined(CONFIG_X86) && !defined(CONFIG_ISA)
 #define CONFIG_ISA
@@ -18682,3 +18680,4 @@
         }
     }
 }
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.4.10/linux/drivers/scsi/aha152x.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/aha152x.c	Sun Sep 30 12:26:07 2001
@@ -333,6 +333,8 @@
 #if defined(MODULE)
 MODULE_AUTHOR("Jürgen Fischer");
 MODULE_DESCRIPTION(AHA152X_REVID);
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "1-2i");
 MODULE_PARM_DESC(io,"base io address of controller");
 static int io[] = {0, 0};
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v2.4.10/linux/drivers/scsi/aha1542.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/aha1542.c	Sun Sep 30 12:26:07 2001
@@ -1800,6 +1800,7 @@
 
 	return 0;
 }
+MODULE_LICENSE("GPL");
 
 
 /* Eventually this will go into an include file, but this will be later */
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- v2.4.10/linux/drivers/scsi/aha1740.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/scsi/aha1740.c	Sun Sep 30 12:26:07 2001
@@ -22,10 +22,7 @@
  * if it doesn't work for your devices, take a look.
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
-
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -613,6 +610,8 @@
     }
     return 0;
 }
+
+MODULE_LICENSE("GPL");
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = AHA1740;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/aic7xxx/aic7xxx_linux.c linux/drivers/scsi/aic7xxx/aic7xxx_linux.c
--- v2.4.10/linux/drivers/scsi/aic7xxx/aic7xxx_linux.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/aic7xxx/aic7xxx_linux.c	Fri Oct  5 11:19:02 2001
@@ -120,9 +120,7 @@
  * under normal conditions.
  */
 
-#if defined(MODULE)
 #include <linux/module.h>
-#endif
 
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
@@ -1177,6 +1175,7 @@
 	host->irq = ahc->platform_data->irq;
 	host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
 	host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
+	host->max_lun = AHC_NUM_LUNS;
 	ahc_set_unit(ahc, ahc_linux_next_unit());
 	sprintf(buf, "scsi%d", host->host_no);
 	new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
@@ -2869,6 +2868,8 @@
 		}
 	}
 }
+
+MODULE_LICENSE("Dual BSD/GPL");
 
 #if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static Scsi_Host_Template driver_template = AIC7XXX;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- v2.4.10/linux/drivers/scsi/aic7xxx_old.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/aic7xxx_old.c	Sun Sep 30 12:26:07 2001
@@ -11963,6 +11963,9 @@
 
 #include "aic7xxx_old/aic7xxx_proc.c"
 
+MODULE_LICENSE("Dual BSD/GPL");
+
+
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = AIC7XXX;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c
--- v2.4.10/linux/drivers/scsi/atp870u.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/atp870u.c	Sun Sep 30 12:26:07 2001
@@ -2872,6 +2872,7 @@
 	panic("atp870u: bad scsi host passed.\n");
 
 }
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = ATP870U;
 #include "scsi_module.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/cpqfcTSinit.c linux/drivers/scsi/cpqfcTSinit.c
--- v2.4.10/linux/drivers/scsi/cpqfcTSinit.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/cpqfcTSinit.c	Sun Sep 30 12:26:07 2001
@@ -68,6 +68,7 @@
 /* Embedded module documentation macros - see module.h */
 MODULE_AUTHOR("Compaq Computer Corporation");
 MODULE_DESCRIPTION("Driver for Compaq 64-bit/66Mhz PCI Fibre Channel HBA");
+MODULE_LICENSE("GPL");
   
 int cpqfcTS_TargetDeviceReset( Scsi_Device *ScsiDev, unsigned int reset_flags);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/dmx3191d.c linux/drivers/scsi/dmx3191d.c
--- v2.4.10/linux/drivers/scsi/dmx3191d.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/scsi/dmx3191d.c	Sun Sep 30 12:26:07 2001
@@ -119,6 +119,7 @@
 	return 0;
 }
 
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = DMX3191D;
 #include "scsi_module.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/dpt_i2o.c linux/drivers/scsi/dpt_i2o.c
--- v2.4.10/linux/drivers/scsi/dpt_i2o.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/dpt_i2o.c	Sun Sep 30 12:26:07 2001
@@ -3324,3 +3324,4 @@
 static Scsi_Host_Template driver_template = DPT_I2O;
 #include "scsi_module.c"
 EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/dtc.c linux/drivers/scsi/dtc.c
--- v2.4.10/linux/drivers/scsi/dtc.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/dtc.c	Sun Sep 30 12:26:07 2001
@@ -73,6 +73,7 @@
 
 
 #include <asm/system.h>
+#include <linux/module.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/blk.h>
@@ -432,6 +433,8 @@
       dtc_wmaxi = i;
    return (0);
 }
+
+MODULE_LICENSE("GPL");
 
 #include "NCR5380.c"
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v2.4.10/linux/drivers/scsi/eata.c	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/eata.c	Sun Sep 30 12:26:07 2001
@@ -2077,3 +2077,4 @@
 #ifndef MODULE
 __setup("eata=", option_setup);
 #endif /* end MODULE */
+MODULE_LICENSE("BSD");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v2.4.10/linux/drivers/scsi/eata_dma.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/scsi/eata_dma.c	Sun Sep 30 12:26:07 2001
@@ -1545,6 +1545,8 @@
     return(registered_HBAs);
 }
 
+MODULE_LICENSE("GPL");
+
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = EATA_DMA;
 #include "scsi_module.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c
--- v2.4.10/linux/drivers/scsi/eata_pio.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/eata_pio.c	Sun Sep 30 12:26:07 2001
@@ -995,6 +995,7 @@
 static Scsi_Host_Template driver_template = EATA_PIO;
 
 #include "scsi_module.c"
+MODULE_LICENSE("GPL");
 
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/fd_mcs.c linux/drivers/scsi/fd_mcs.c
--- v2.4.10/linux/drivers/scsi/fd_mcs.c	Mon Sep 18 13:36:25 2000
+++ linux/drivers/scsi/fd_mcs.c	Sun Sep 30 12:26:07 2001
@@ -77,9 +77,7 @@
 
  **************************************************************************/
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <linux/sched.h>
 #include <linux/blk.h>
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v2.4.10/linux/drivers/scsi/fdomain.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/fdomain.c	Sun Sep 30 12:26:07 2001
@@ -2035,6 +2035,8 @@
    return 0;
 }
 
+MODULE_LICENSE("GPL");
+
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = FDOMAIN_16X0;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- v2.4.10/linux/drivers/scsi/g_NCR5380.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/g_NCR5380.c	Sun Sep 30 12:26:07 2001
@@ -912,7 +912,7 @@
 MODULE_PARM(ncr_53c400, "i");
 MODULE_PARM(ncr_53c400a, "i");
 MODULE_PARM(dtc_3181e, "i");
-
+MODULE_LICENSE("GPL");
 #else
 
 static int __init do_NCR5380_setup(char *str)
@@ -970,6 +970,8 @@
 };
 
 MODULE_DEVICE_TABLE(isapnp, id_table);
+MODULE_LICENSE("GPL");
+
 
 #endif
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- v2.4.10/linux/drivers/scsi/gdth.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/gdth.c	Sun Sep 30 12:26:07 2001
@@ -295,9 +295,7 @@
  * phase:                       Service/parameter/return code special command
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <linux/version.h>
 #include <linux/kernel.h>
@@ -687,6 +685,7 @@
 MODULE_PARM(virt_ctr, "i");
 MODULE_PARM(shared_access, "i");
 MODULE_AUTHOR("Achim Leubner");
+MODULE_LICENSE("GPL");
 #endif
 #endif
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- v2.4.10/linux/drivers/scsi/ide-scsi.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/scsi/ide-scsi.c	Sun Sep 30 12:26:07 2001
@@ -849,3 +849,4 @@
 
 module_init(init_idescsi_module);
 module_exit(exit_idescsi_module);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/imm.c linux/drivers/scsi/imm.c
--- v2.4.10/linux/drivers/scsi/imm.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/imm.c	Sun Sep 30 12:26:07 2001
@@ -1270,3 +1270,4 @@
     printk("imm: No devices found, aborting driver load.\n");
     return 1;
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c
--- v2.4.10/linux/drivers/scsi/in2000.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/in2000.c	Sun Sep 30 12:26:07 2001
@@ -2360,6 +2360,8 @@
 
 }
 
+MODULE_LICENSE("GPL");
+
 
 static Scsi_Host_Template driver_template = IN2000;
 #include "scsi_module.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ini9100u.c linux/drivers/scsi/ini9100u.c
--- v2.4.10/linux/drivers/scsi/ini9100u.c	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/ini9100u.c	Sun Sep 30 12:26:07 2001
@@ -112,9 +112,7 @@
 #include <linux/version.h>
 #endif
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <stdarg.h>
 #include <asm/irq.h>
@@ -828,3 +826,4 @@
 	release_region(hreg->io_port, 256);
 	return 0;
 }
+MODULE_LICENSE("Dual BSD/GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/inia100.c linux/drivers/scsi/inia100.c
--- v2.4.10/linux/drivers/scsi/inia100.c	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/inia100.c	Sun Sep 30 12:26:07 2001
@@ -67,9 +67,7 @@
 #include <linux/version.h>
 #endif
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <stdarg.h>
 #include <asm/irq.h>
@@ -796,4 +794,5 @@
         return 0;
 } 
 
+MODULE_LICENSE("Dual BSD/GPL");
 /*#include "inia100scsi.c" */
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ips.c linux/drivers/scsi/ips.c
--- v2.4.10/linux/drivers/scsi/ips.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/ips.c	Mon Oct  8 11:09:28 2001
@@ -3,7 +3,7 @@
 /*                                                                           */
 /* Written By: Keith Mitchell, IBM Corporation                               */
 /*                                                                           */
-/* Copyright (C) 1999 IBM Corporation                                        */
+/* Copyright (C) 2000 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      */
@@ -39,8 +39,12 @@
 /* along with this program; if not, write to the Free Software               */
 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 /*                                                                           */
-/* Bugs/Comments/Suggestions should be mailed to:                            */
-/*      ipslinux@us.ibm.com                                                  */
+/* Bugs/Comments/Suggestions about this driver should be mailed to:          */
+/*      ipslinux@us.ibm.com          	                                      */
+/*                                                                           */
+/* For system support issues, contact your local IBM Customer support.       */
+/* Directions to find IBM Customer Support for each country can be found at: */
+/*      http://www.ibm.com/planetwide/                                       */
 /*                                                                           */
 /*****************************************************************************/
 
@@ -86,7 +90,7 @@
 /*            Merge in changes through kernel 2.4.0test1ac21                 */
 /* 4.20.13  - Fix some failure cases / reset code                            */
 /*          - Hook into the reboot_notifier to flush the controller cache    */
-/* 4.50.01  - Fix problem when there is a hole in logical drive numbering   */
+/* 4.50.01  - Fix problem when there is a hole in logical drive numbering    */
 /* 4.70.09  - Use a Common ( Large Buffer ) for Flashing from the JCRM CD    */
 /*          - Add IPSSEND Flash Support                                      */
 /*          - Set Sense Data for Unknown SCSI Command                        */
@@ -100,7 +104,16 @@
 /* 4.71.00  - Change all memory allocations to not use GFP_DMA flag          */
 /*            Code Clean-Up for 2.4.x kernel                                 */
 /* 4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     */
-/*                                                                           */
+/* 4.72.01  - I/O Mapped Memory release ( so "insmod ips" does not Fail )    */
+/*            Don't Issue Internal FFDC Command if there are Active Commands */
+/*            Close Window for getting too many IOCTL's active               */
+/* 4.80.00    Make ia64 Safe                                                 */
+/* 4.80.04    Eliminate calls to strtok() if 2.4.x or greater                */
+/*            Adjustments to Device Queue Depth                              */
+/* 4.80.14    Take all semaphores off stack                                  */
+/*            Clean Up New_IOCTL path                                        */
+/* 4.80.20    Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )  */
+/*            5 second delay needed after resetting an i960 adapter          */
 /*****************************************************************************/
 
 /*
@@ -126,15 +139,16 @@
  * nommap               - Don't use memory mapped I/O
  * ioctlsize            - Initial size of the IOCTL buffer
  */
-
+ 
 #include <asm/io.h>
 #include <asm/byteorder.h>
+#include <asm/page.h>
 #include <linux/stddef.h>
 #include <linux/version.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/ioport.h> 
+#include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
@@ -182,9 +196,8 @@
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "4.72"
-#define IPS_VERSION_LOW         ".00 "
-
+#define IPS_VERSION_HIGH        "4.80"
+#define IPS_VERSION_LOW         ".26 "
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
 struct proc_dir_entry proc_scsi_ips = {
@@ -194,8 +207,8 @@
 };
 #endif
 
-#if !defined(__i386__)
-   #error "This driver has only been tested on the x86 platform"
+#if !defined(__i386__) && !defined(__ia64__)
+   #error "This driver has only been tested on the x86/ia64 platforms"
 #endif
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
@@ -219,7 +232,7 @@
 /*
  * global variables
  */
-static const char * ips_name = "ips";
+static const char   ips_name[] = "ips";
 static struct Scsi_Host * ips_sh[IPS_MAX_ADAPTERS];  /* Array of host controller structures */
 static ips_ha_t * ips_ha[IPS_MAX_ADAPTERS];          /* Array of HA structures */
 static unsigned int ips_next_controller = 0;
@@ -367,9 +380,12 @@
 static int ips_isinit_copperhead(ips_ha_t *);
 static int ips_isinit_copperhead_memio(ips_ha_t *);
 static int ips_isinit_morpheus(ips_ha_t *);
-static u32 ips_statupd_copperhead(ips_ha_t *);
-static u32 ips_statupd_copperhead_memio(ips_ha_t *);
-static u32 ips_statupd_morpheus(ips_ha_t *);
+static int ips_erase_bios(ips_ha_t *);
+static int ips_program_bios(ips_ha_t *, char *, u_int32_t, u_int32_t);
+static int ips_verify_bios(ips_ha_t *, char *, u_int32_t, u_int32_t);
+static int ips_erase_bios_memio(ips_ha_t *);
+static int ips_program_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t);
+static int ips_verify_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t);
 static void ips_flash_bios_section(void *);
 static void ips_flash_bios_segment(void *);
 static void ips_scheduled_flash_bios(void *);
@@ -395,25 +411,22 @@
 static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
 static void ips_ffdc_reset(ips_ha_t *, int);
 static void ips_ffdc_time(ips_ha_t *, int);
+static u_int32_t ips_statupd_copperhead(ips_ha_t *);
+static u_int32_t ips_statupd_copperhead_memio(ips_ha_t *);
+static u_int32_t ips_statupd_morpheus(ips_ha_t *);
 static ips_scb_t * ips_getscb(ips_ha_t *);
 static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
 static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *);
-static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *);
-static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
 static inline void ips_putq_wait_head(ips_wait_queue_t *, Scsi_Cmnd *);
 static inline void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
-static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *);
-static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
 static inline void ips_putq_copp_head(ips_copp_queue_t *, ips_copp_wait_item_t *);
 static inline void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *);
+static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *);
+static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
+static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *);
+static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
 static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *);
 static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *);
-static int ips_erase_bios(ips_ha_t *);
-static int ips_program_bios(ips_ha_t *, char *, u32, u32);
-static int ips_verify_bios(ips_ha_t *, char *, u32, u32);
-static int ips_erase_bios_memio(ips_ha_t *);
-static int ips_program_bios_memio(ips_ha_t *, char *, u32, u32);
-static int ips_verify_bios_memio(ips_ha_t *, char *, u32, u32);
 
 #ifndef NO_IPS_CMDLINE
 static int ips_is_passthru(Scsi_Cmnd *);
@@ -449,10 +462,14 @@
 ips_setup(char *ips_str, int *dummy) {
 #endif
    int        i;
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
    char      *p;
+   char       tokens[3] = {',', '.', 0};
+#endif
+
    char      *key;
    char      *value;
-   char       tokens[3] = {',', '.', 0};
    IPS_OPTION options[] = {
       {"noreset", &ips_resetcontroller, 0},
 #ifdef IPS_DEBUG
@@ -467,6 +484,30 @@
 
    METHOD_TRACE("ips_setup", 1);
 
+/* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+   /* Search for value */
+   while ((key = strsep(&ips_str, ",."))) {
+      if (!*key)
+         continue;
+      value = strchr(key, ':');
+      if (value)
+         *value++ = '\0';
+     /*
+      * We now have key/value pairs.
+      * Update the variables
+      */
+      for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) {
+        if (strnicmp(key, options[i].option_name, strlen(options[i].option_name)) == 0) {
+           if (value)
+              *options[i].option_flag = simple_strtoul(value, NULL, 0);
+           else
+              *options[i].option_flag = options[i].option_value;
+           break;
+        }
+      }
+   }
+#else
    for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) {
       p = key;
 
@@ -495,6 +536,8 @@
          }
       }
    }
+#endif
+
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
    return (1);
 #endif
@@ -519,29 +562,29 @@
 ips_detect(Scsi_Host_Template *SHT) {
    struct Scsi_Host *sh;
    ips_ha_t         *ha;
-   u32               io_addr;
-   u32               mem_addr;
-   u32               io_len;
-   u32               mem_len;
-   u16               planer;
-   u8                revision_id;
-   u8                bus;
-   u8                func;
-   u8                irq;
-   u16               deviceID[2];
-   u16               subdevice_id;
+   u_int32_t         io_addr;
+   u_int32_t         mem_addr;
+   u_int32_t         io_len;
+   u_int32_t         mem_len;
+   u_int16_t         planer;
+   u_int8_t          revision_id;
+   u_int8_t          bus;
+   u_int8_t          func;
+   u_int8_t          irq;
+   u_int16_t         deviceID[2];
+   u_int16_t         subdevice_id;
    int               i;
    int               j;
-   u32               count;
+   u_int32_t         count;
    char             *ioremap_ptr;
    char             *mem_ptr;
    struct pci_dev   *dev[2];
    struct pci_dev   *morpheus = NULL;
    struct pci_dev   *trombone = NULL;
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,14)
-   u32               currbar;
-   u32               maskbar;
-   u8                barnum;
+   u_int32_t         currbar;
+   u_int32_t         maskbar;
+   u_int8_t          barnum;
 #endif
 
    METHOD_TRACE("ips_detect", 1);
@@ -557,8 +600,8 @@
 
    /* If Booting from the ServeRAID Manager CD, Allocate a large Flash  */
    /* Buffer ( so we won't need to allocate one for each adapter ).     */
-    if ( ips_cd_boot ) {                                                            
-      ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 ); 
+    if ( ips_cd_boot ) {            
+      ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 );   
       if (ips_FlashData == NULL) {
          /* The validity of this pointer is checked in ips_make_passthru() before it is used */
          printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" );
@@ -598,12 +641,12 @@
       deviceID[0] = IPS_DEVICEID_MORPHEUS;
    } else {
       /* we have both in the system */
-      if (trombone->bus < morpheus->bus) {
+      if (trombone->bus->number < morpheus->bus->number) {
          dev[0] = trombone;
          dev[1] = morpheus;
          deviceID[0] = IPS_DEVICEID_COPPERHEAD;
          deviceID[1] = IPS_DEVICEID_MORPHEUS;
-      } else if (trombone->bus > morpheus->bus) {
+      } else if (trombone->bus->number > morpheus->bus->number) {
          dev[0] = morpheus;
          dev[1] = trombone;
          deviceID[0] = IPS_DEVICEID_MORPHEUS;
@@ -704,8 +747,8 @@
 
          /* setup memory mapped area (if applicable) */
          if (mem_addr) {
-            u32 base;
-            u32 offs;
+            u_int32_t base;
+            u_int32_t offs;
 
             DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d",
                       ips_name, ips_next_controller, mem_addr, mem_len);
@@ -773,11 +816,11 @@
             continue;
          }
 
-         DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %x",
-                   ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, (u32) mem_ptr);
+         DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %p",
+                   ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, mem_ptr);
 
          /* get the revision ID */
-         if (pci_read_config_byte(dev[i], 0x08, &revision_id)) {
+         if (pci_read_config_byte(dev[i], PCI_REVISION_ID, &revision_id)) {
             printk(KERN_WARNING "(%s%d) can't get revision id.\n",
                    ips_name, ips_next_controller);
 
@@ -788,7 +831,7 @@
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,15)
          /* get the subdevice id */
-         if (pci_read_config_word(dev[i], 0x2e, &subdevice_id)) {
+         if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) {
             printk(KERN_WARNING "(%s%d) can't get subdevice id.\n",
                    ips_name, ips_next_controller);
 
@@ -828,7 +871,7 @@
          ips_num_controllers++;
          ha->active = 1;
 
-         ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_ATOMIC);
+         ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL);
 
          if (!ha->enq) {
             printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n",
@@ -845,7 +888,7 @@
             continue;
          }
 
-         ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_ATOMIC);
+         ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL);
 
          if (!ha->adapt) {
             printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n",
@@ -862,7 +905,7 @@
             continue;
          }
 
-         ha->conf = kmalloc(sizeof(IPS_CONF), GFP_ATOMIC);
+         ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL);
 
          if (!ha->conf) {
             printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n",
@@ -879,7 +922,7 @@
             continue;
          }
 
-         ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_ATOMIC);
+         ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL);
 
          if (!ha->nvram) {
             printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n",
@@ -896,7 +939,7 @@
             continue;
          }
 
-         ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_ATOMIC);
+         ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL);
 
          if (!ha->subsys) {
             printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n",
@@ -913,7 +956,7 @@
             continue;
          }
 
-         ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_ATOMIC);
+         ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL);
 
          if (!ha->dummy) {
             printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n",
@@ -957,11 +1000,10 @@
          sh->cmd_per_lun = sh->hostt->cmd_per_lun;
          sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
          sh->use_clustering = sh->hostt->use_clustering;
-/***** Implement the following if it gets into a future kernel
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,4)
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
          sh->max_sectors = 128;
 #endif
-******/
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,32)
          sh->wish_block = FALSE;
@@ -1075,7 +1117,7 @@
          /*
           * Allocate a temporary SCB for initialization
           */
-         ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_ATOMIC);
+         ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_KERNEL);
          if (!ha->scbs) {
             /* couldn't allocate a temp SCB */
             printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
@@ -1094,7 +1136,7 @@
          }
 
          memset(ha->scbs, 0, sizeof(ips_scb_t));
-         ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC);
+         ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL);
          if (!ha->scbs->sg_list) {
             /* couldn't allocate a temp SCB S/G list */
             printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
@@ -1217,9 +1259,14 @@
 
    for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++);
 
-   if (i == IPS_MAX_ADAPTERS)
-      panic("(%s) release, invalid Scsi_Host pointer.\n",
+   if (i == IPS_MAX_ADAPTERS) {
+      printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n",
             ips_name);
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+      BUG();
+#endif
+      return (FALSE);
+   }
 
    ha = IPS_HA(sh);
 
@@ -1242,13 +1289,13 @@
    scb->cmd.flush_cache.reserved3 = 0;
    scb->cmd.flush_cache.reserved4 = 0;
 
-   printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
+   printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
 
    /* send command */
    if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
-      printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
+      printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
 
-   printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
+   printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
 
    ips_sh[i] = NULL;
    ips_ha[i] = NULL;
@@ -1260,11 +1307,6 @@
    if (ha->io_addr)
       release_region(ha->io_addr, ha->io_len);
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
-   if (ha->mem_addr)
-      release_mem_region(ha->mem_addr, ha->mem_len);
-#endif
-
    /* free IRQ */
    free_irq(ha->irq, ha);
 
@@ -1322,16 +1364,15 @@
       scb->cmd.flush_cache.reserved3 = 0;
       scb->cmd.flush_cache.reserved4 = 0;
 
-      printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
+      printk(KERN_NOTICE "(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
 
       /* send command */
       if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
-         printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
+         printk(KERN_NOTICE "(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
       else
-         printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
+         printk(KERN_NOTICE "(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
    }
 
-   unregister_reboot_notifier(&ips_notifier);
    return (NOTIFY_OK);
 }
 
@@ -1416,10 +1457,10 @@
 ips_eh_reset(Scsi_Cmnd *SC) {
    int                   ret;
    int                   i;
-   unsigned long         cpu_flags;
    ips_ha_t             *ha;
    ips_scb_t            *scb;
    ips_copp_wait_item_t *item;
+   unsigned long         cpu_flags;
 
    METHOD_TRACE("ips_eh_reset", 1);
 
@@ -1543,7 +1584,7 @@
    }
 
    /* FFDC */
-   if (ha->subsys->param[3] & 0x300000) {
+   if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
       struct timeval tv;
 
       do_gettimeofday(&tv);
@@ -1608,7 +1649,6 @@
 ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
    ips_ha_t         *ha;
    unsigned long     cpu_flags;
-   DECLARE_MUTEX_LOCKED(sem);
 
    METHOD_TRACE("ips_queue", 1);
 
@@ -1669,8 +1709,23 @@
 
 #ifndef NO_IPS_CMDLINE
    if (ips_is_passthru(SC)) {
+
       ips_copp_wait_item_t *scratch;
 
+      /* The IPS_IOCTL_NEW_COMMAND is only used to flash an adapter.  This should */
+      /* never happen when the adapter is active.  Just in case, check here, and  */
+      /* reject the command if anything else is going on.                         */
+      if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
+         if (ha->scb_activelist.count != 0) {
+            /* printk( KERN_WARNING "New IOCTL Cmd Return BUSY: %d Cmds Active\n", */
+            /*                       ha->scb_activelist.count );                   */
+            SC->result = DID_BUS_BUSY << 16;
+            done(SC);
+
+            return (0);
+         }
+      }
+
       /* allocate space for the scribble */
       scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC);
 
@@ -1682,7 +1737,8 @@
       }
 
       scratch->scsi_cmd = SC;
-      scratch->sem = &sem;
+      sema_init(&ha->ioctl_sem, 0);
+      scratch->sem = &ha->ioctl_sem;
       scratch->next = NULL;
 
       ips_putq_copp_tail(&ha->copp_waitlist, scratch);
@@ -1709,15 +1765,15 @@
     * not cause contention problems
     */
    if (ips_is_passthru(SC) && SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-      char *user_area;
-      char *kern_area;
-      u32   datasize;
+      char      *user_area;
+      char      *kern_area;
+      u_int32_t  datasize;
 
       /* free io_request_lock */
       spin_unlock_irq(&io_request_lock);
 
       /* wait for the command to finish */
-      down(&sem);
+      down(&ha->ioctl_sem);
 
       /* reobtain the lock */
       spin_lock_irq(&io_request_lock);
@@ -1725,21 +1781,17 @@
       /* command finished -- copy back */
       user_area = *((char **) &SC->cmnd[4]);
       kern_area = ha->ioctl_data;
-      datasize = *((u32 *) &SC->cmnd[8]);
+      datasize = *((u_int32_t *) &SC->cmnd[8]);
 
       if (datasize) {
          if (copy_to_user(user_area, kern_area, datasize) > 0) {
             DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy out user data",
                       ips_name, ha->host_num);
-
             SC->result = DID_ERROR << 16;
-            SC->scsi_done(SC);
-         } else {
-            SC->scsi_done(SC);
          }
-      } else {
-         SC->scsi_done(SC);
       }
+
+      SC->scsi_done(SC);
    }
 
    /* If We were using the CD Boot Flash Buffer, Restore the Old Values */
@@ -1819,8 +1871,10 @@
    Scsi_Device *device;
    ips_ha_t    *ha;
    int          count = 0;
+   int          min;
 
    ha = IPS_HA(host);
+   min = ha->max_cmds / 4;
 
    for (device = scsi_devs; device; device = device->next) {
      if (device->host == host) {
@@ -1831,10 +1885,14 @@
 
    for (device = scsi_devs; device; device = device->next) {
       if (device->host == host) {
-         if ((device->channel == 0) && (device->type == 0))
-            device->queue_depth = ha->max_cmds / count - 1;
-         else
+         if ((device->channel == 0) && (device->type == 0)) {
+            device->queue_depth = ( ha->max_cmds - 1 ) / count;
+            if (device->queue_depth < min) 
+               device->queue_depth = min;
+         }
+         else {
             device->queue_depth = 2;
+         }
 
          if (device->queue_depth < 2)
             device->queue_depth = 2;
@@ -1943,9 +2001,7 @@
          cstatus.value = (*ha->func.statupd)(ha);
 
       if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
-         printk(KERN_WARNING "(%s%d) Spurious interrupt; no ccb.\n",
-                ips_name, ha->host_num);
-
+         /* Spurious Interupt ? */
          continue;
       }
 
@@ -2065,9 +2121,7 @@
    bp = &buffer[0];
    memset(bp, 0, sizeof(buffer));
 
-   strcpy(bp, "IBM PCI ServeRAID ");
-   strcat(bp, IPS_VERSION_HIGH);
-   strcat(bp, IPS_VERSION_LOW);
+   sprintf(bp, "%s%s%s", "IBM PCI ServeRAID ", IPS_VERSION_HIGH, IPS_VERSION_LOW );
 
    if (ha->ad_type > 0 &&
        ha->ad_type <= MAX_ADAPTER_NAME) {
@@ -2250,37 +2304,14 @@
             return (IPS_FAILURE);
          }
 
-         if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) &&
-             (pt->CoppCP.cmd.nvram.page == 5) &&
-             (pt->CoppCP.cmd.nvram.write == 0)) {
-
-            if (pt->CmdBSize < sizeof(IPS_NVRAM_P5)) {
-               SC->result = DID_ERROR << 16;
-
-               return (IPS_FAILURE);
-            }
-
-            ips_get_bios_version(ha, IPS_INTR_IORL);
-            ips_create_nvrampage5(ha, &nvram);
-
-            /* Copy the result back */
-            memcpy(SC->request_buffer + sizeof(ips_passthru_t), &nvram, sizeof(IPS_NVRAM_P5));
-
-            SC->result = DID_OK << 16;
-            pt->BasicStatus = 0x00;
-            pt->ExtendedStatus = 0x00;
-
-            return (IPS_SUCCESS_IMM);
-         }
-
          if (ips_usrcmd(ha, pt, scb))
             return (IPS_SUCCESS);
          else
             return (IPS_FAILURE);
       } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-         char           *user_area;
-         char           *kern_area;
-         u32             datasize;
+         char      *user_area;
+         char      *kern_area;
+         u_int32_t  datasize;
 
          if (SC->request_bufflen < (sizeof(ips_passthru_t))) {
             /* wrong size */
@@ -2292,7 +2323,6 @@
             return (IPS_FAILURE);
          }
 
-
          /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can     */
          /* avoid allocating a huge buffer per adapter ( which can fail ). */
          if ( (ips_FlashData) &&                                            
@@ -2305,28 +2335,28 @@
             ha->ioctl_data  = ips_FlashData;                                
             ha->ioctl_order = 7;                                            
             ha->ioctl_datasize = IPS_IMAGE_SIZE;                                    
-         }                                                                  
+         }  
 
          if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) &&
              (pt->CoppCP.cmd.nvram.page == 5) &&
              (pt->CoppCP.cmd.nvram.write == 0)) {
 
-            datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
+            datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
 
             if (datasize < sizeof(IPS_NVRAM_P5)) {
                pt->BasicStatus = 0x0B;
                pt->ExtendedStatus = 0x00;
                SC->result = DID_ERROR << 16;
 
-               return (IPS_FAILURE);
-            }
+            return (IPS_FAILURE);
+      }
 
             ips_get_bios_version(ha, IPS_INTR_IORL);
             ips_create_nvrampage5(ha, &nvram);
 
             user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
             kern_area = (char *) &nvram;
-            datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
+            datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
 
             if (datasize > sizeof(IPS_NVRAM_P5))
                datasize = sizeof(IPS_NVRAM_P5);
@@ -2337,7 +2367,7 @@
                pt->ExtendedStatus = 0x00;
                SC->result = DID_ERROR << 16;
 
-               return (IPS_FAILURE);
+               return (EFAULT);
             }
 
             pt->BasicStatus = 0x00;
@@ -2356,7 +2386,6 @@
              (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
             struct tq_struct  task;
             IPS_FLASH_DATA    flash_data;
-            DECLARE_MUTEX_LOCKED(sem);
 
             /* We only support one packet */
             if (pt->CoppCP.cmd.flashfw.total_packets != 1) {
@@ -2371,8 +2400,8 @@
             memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
             memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
 
-            if (pt->CmdBSize > pt->CoppCP.cmd.flashfw.count) {
-               pt->CmdBSize = pt->CoppCP.cmd.flashfw.count;
+            if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashfw.count)) {
+               pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashfw.count);
             } else {
                /* ERROR: Command/Buffer mismatch */
                pt->BasicStatus = 0x0B;
@@ -2382,8 +2411,8 @@
                return (IPS_FAILURE);
             }
 
-            if ((!ha->func.programbios) ||
-                (!ha->func.erasebios) ||
+      if ((!ha->func.programbios) ||
+          (!ha->func.erasebios) ||
                 (!ha->func.verifybios)) {
                pt->BasicStatus = 0x0B;
                pt->ExtendedStatus = 0x00;
@@ -2404,8 +2433,8 @@
             /* make sure buffer is big enough */
             if (pt->CmdBSize > ha->ioctl_datasize) {
                void *bigger_struct;
-               u32   count;
-               u32   order;
+               u_int32_t count;
+               u_int32_t order;
 
                /* try to allocate a bigger struct */
                for (count = PAGE_SIZE, order = 0;
@@ -2451,7 +2480,8 @@
             flash_data.SC = (void *) SC;
             flash_data.pt = (void *) pt;
             flash_data.ha = (void *) ha;
-            flash_data.sem = &sem;
+            sema_init( &ha->flash_ioctl_sem, 0 );
+            flash_data.sem = &ha->flash_ioctl_sem;
 
             task.sync = 0;
             task.routine = ips_scheduled_flash_bios;
@@ -2462,9 +2492,9 @@
 
             queue_task(&task, &tq_immediate);
             mark_bh(IMMEDIATE_BH);
-
+            
             /* Wait for the flash to complete */
-            down(&sem);
+            down(&ha->flash_ioctl_sem);
 
             /* Obtain the master lock */
             spin_lock_irq(&io_request_lock);
@@ -2481,14 +2511,13 @@
              (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
             struct tq_struct  task;
             IPS_FLASH_DATA    flash_data;
-            DECLARE_MUTEX_LOCKED(sem);
 
-            /* copy in the size/buffer ptr from the scsi command */
-            memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
-            memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
+      /* copy in the size/buffer ptr from the scsi command */
+      memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
+      memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
 
-            if (pt->CmdBSize > pt->CoppCP.cmd.flashbios.count) {
-               pt->CmdBSize = pt->CoppCP.cmd.flashbios.count;
+            if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashbios.count)) {
+               pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashbios.count);
             } else {
                /* ERROR: Command/Buffer mismatch */
                pt->BasicStatus = 0x0B;
@@ -2509,32 +2538,32 @@
                return (IPS_FAILURE);
             }
 
-            /* must have a buffer */
+      /* must have a buffer */
             if ((!pt->CmdBSize) || (!pt->CmdBuffer)) {
                pt->BasicStatus = 0x0B;
                pt->ExtendedStatus = 0x00;
                SC->result = DID_ERROR << 16;
 
-               return (IPS_FAILURE);
+         return (IPS_FAILURE);
             }
 
-            /* make sure buffer is big enough */
-            if (pt->CmdBSize > ha->ioctl_datasize) {
-               void *bigger_struct;
-               u32   count;
-               u32   order;
+      /* make sure buffer is big enough */
+      if (pt->CmdBSize > ha->ioctl_datasize) {
+         void *bigger_struct;
+               u_int32_t count;
+               u_int32_t order;
 
-               /* try to allocate a bigger struct */
+         /* try to allocate a bigger struct */
                for (count = PAGE_SIZE, order = 0;
                     count < pt->CmdBSize;
                     order++, count <<= 1);
 
                bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
-               if (bigger_struct) {
-                  /* free the old memory */
+         if (bigger_struct) {
+            /* free the old memory */
                   free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
 
-                  /* use the new memory */
+            /* use the new memory */
                   ha->ioctl_data = (char *) bigger_struct;
                   ha->ioctl_order = order;
                   ha->ioctl_datasize = count;
@@ -2549,26 +2578,27 @@
                }
             }
 
-            /* copy in the buffer */
-            if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
-               DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
-                         ips_name, ha->host_num);
+      /* copy in the buffer */
+      if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
+                   ips_name, ha->host_num);
                pt->BasicStatus = 0x0B;
                pt->ExtendedStatus = 0x00;
                SC->result = DID_ERROR << 16;
 
-               return (IPS_FAILURE);
+               return (EFAULT);
             }
 
             flash_data.userbuffer = pt->CmdBuffer;
             flash_data.usersize = pt->CmdBSize;
             flash_data.kernbuffer = ha->ioctl_data;
             flash_data.kernsize = ha->ioctl_datasize;
-            flash_data.offset = pt->CoppCP.cmd.flashbios.offset;
+            flash_data.offset = le32_to_cpu(pt->CoppCP.cmd.flashbios.offset);
             flash_data.SC = (void *) SC;
             flash_data.pt = (void *) pt;
             flash_data.ha = (void *) ha;
-            flash_data.sem = &sem;
+            sema_init( &ha->flash_ioctl_sem, 0 );
+            flash_data.sem = &ha->flash_ioctl_sem;
 
             task.sync = 0;
             task.routine = ips_flash_bios_section;
@@ -2579,9 +2609,9 @@
 
             queue_task(&task, &tq_immediate);
             mark_bh(IMMEDIATE_BH);
-           
+            
             /* Wait for the flash to complete */
-            down(&sem);
+            down(&ha->flash_ioctl_sem);
 
             /* Obtain the master lock */
             spin_lock_irq(&io_request_lock);
@@ -2602,9 +2632,9 @@
                return (IPS_FAILURE);
             }
 
-            if ((*ha->func.erasebios)(ha)) {
-               DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
-                         ips_name, ha->host_num);
+      if ((*ha->func.erasebios)(ha)) {
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
+                   ips_name, ha->host_num);
                pt->BasicStatus = 0x0B;
                pt->ExtendedStatus = 0x00;
                SC->result = DID_ERROR << 16;
@@ -2629,8 +2659,8 @@
 
    } /* end switch */
 
-   return (IPS_FAILURE);
-}
+         return (IPS_FAILURE);
+      }
 
 /****************************************************************************/
 /*                                                                          */
@@ -2673,7 +2703,7 @@
 
    if ((*ha->func.erasebios)(ha)) {
       DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
-                ips_name, ha->host_num);
+                   ips_name, ha->host_num);
       pt->BasicStatus = 0x0B;
       pt->ExtendedStatus = 0x00;
       SC->result = DID_ERROR << 16;
@@ -2689,8 +2719,8 @@
       return ;
 
    if ((*ha->func.verifybios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) {
-      DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
-                ips_name, ha->host_num);
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
+                   ips_name, ha->host_num);
       pt->BasicStatus = 0x0B;
       pt->ExtendedStatus = 0x00;
       SC->result = DID_ERROR << 16;
@@ -2827,13 +2857,13 @@
    }
 
    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
-      scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
+      scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb));
 
    if (pt->CmdBSize) {
       if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
-         scb->dcdb.buffer_pointer = scb->data_busaddr;
+         scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
       else
-         scb->cmd.basic_io.sg_addr = scb->data_busaddr;
+         scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
    }
 
    /* set timeouts */
@@ -2869,7 +2899,7 @@
    IPS_SG_LIST    *sg_list;
    char           *user_area;
    char           *kern_area;
-   u32             datasize;
+   u_int32_t       datasize;
 
    METHOD_TRACE("ips_usrcmd", 1);
 
@@ -2906,8 +2936,8 @@
    if (pt->CmdBSize) {
       if (pt->CmdBSize > ha->ioctl_datasize) {
          void *bigger_struct;
-         u32   count;
-         u32   order;
+         u_int32_t count;
+         u_int32_t order;
 
          /* try to allocate a bigger struct */
          for (count = PAGE_SIZE, order = 0;
@@ -2933,7 +2963,7 @@
       /* Attempt to copy in the data */
       user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
       kern_area = ha->ioctl_data;
-      datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
+      datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
 
       if (copy_from_user(kern_area, user_area, datasize) > 0) {
          DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
@@ -2947,13 +2977,13 @@
    }
 
    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
-      scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
+      scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb));
 
    if (pt->CmdBSize) {
       if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
-         scb->dcdb.buffer_pointer = scb->data_busaddr;
+         scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
       else
-         scb->cmd.basic_io.sg_addr = scb->data_busaddr;
+         scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
    }
 
    /* set timeouts */
@@ -3000,19 +3030,15 @@
    pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
 
    /* Copy data back to the user */
-   if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) {       /* Copy DCDB Back to Caller's Area */
+   if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)        /* Copy DCDB Back to Caller's Area */
       memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof(IPS_DCDB_TABLE));
-   }
+   
+   pt->BasicStatus = scb->basic_status;
+   pt->ExtendedStatus = scb->extended_status;
 
-   if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_COMMAND) {
-      /* Copy data back to the user */
-      pt->BasicStatus = scb->basic_status;
-      pt->ExtendedStatus = scb->extended_status;
-   } else {
-      pt->BasicStatus = scb->basic_status;
-      pt->ExtendedStatus = scb->extended_status;
-      up(scb->sem);
-   }
+   if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) 
+      up(&ha->ioctl_sem);
+   
 }
 
 #endif
@@ -3040,8 +3066,8 @@
 
    copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
 
-   if ((ha->nvram->signature == IPS_NVRAM_P5_SIG) &&
-       (ha->nvram->adapter_type != 0))
+   if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
+       (le16_to_cpu(ha->nvram->adapter_type) != 0))
       copy_info(&info, "\tController Type                   : %s\n", ips_adapter_name[ha->ad_type-1]);
    else
       copy_info(&info, "\tController Type                   : Unknown\n");
@@ -3058,7 +3084,7 @@
 
    copy_info(&info, "\tIRQ number                        : %d\n", ha->irq);
 
-   if (ha->nvram->signature == IPS_NVRAM_P5_SIG)
+   if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG)
       copy_info(&info, "\tBIOS Version                      : %c%c%c%c%c%c%c%c\n",
                 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
                 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
@@ -3254,10 +3280,10 @@
 ips_get_bios_version(ips_ha_t *ha, int intr) {
    ips_scb_t *scb;
    int        ret;
-   u8         major;
-   u8         minor;
-   u8         subminor; 
-   u8        *buffer;
+   u_int8_t   major;
+   u_int8_t   minor;
+   u_int8_t   subminor;
+   u_int8_t  *buffer;
    char       hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 
    METHOD_TRACE("ips_get_bios_version", 1);
@@ -3279,7 +3305,7 @@
          if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
             return;
 
-         writel(1, ha->mem_ptr + IPS_REG_FLAP);
+         writel(cpu_to_le32(1), ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
             udelay(5); /* 5 us */
 
@@ -3287,27 +3313,24 @@
             return;
 
          /* Get Major version */
-         writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
+         writel(cpu_to_le32(0x1FF), ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
             udelay(5); /* 5 us */
 
          major = readb(ha->mem_ptr + IPS_REG_FLDP);
 
          /* Get Minor version */
-         writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
+         writel(cpu_to_le32(0x1FE), ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
             udelay(5); /* 5 us */
-
          minor = readb(ha->mem_ptr + IPS_REG_FLDP);
 
-         /* Get Sub Minor version */
-         writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
+         /* Get SubMinor version */
+         writel(cpu_to_le32(0x1FD), ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5);/* 5 us */
-
+            udelay(5); /* 5 us */
          subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
 
-
       } else {
          /* Programmed I/O */
 
@@ -3319,7 +3342,7 @@
          if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
             return ;
 
-         outl(1, ha->io_addr + IPS_REG_FLAP);
+         outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
             udelay(5); /* 5 us */
 
@@ -3327,21 +3350,21 @@
             return ;
 
          /* Get Major version */
-         outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
+         outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
             udelay(5); /* 5 us */
 
          major = inb(ha->io_addr + IPS_REG_FLDP);
 
          /* Get Minor version */
-         outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
+         outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
             udelay(5); /* 5 us */
 
          minor = inb(ha->io_addr + IPS_REG_FLDP);
-         
+
          /* Get SubMinor version */
-         outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
+         outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
             udelay(5); /* 5 us */
 
@@ -3368,8 +3391,8 @@
       scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
       scb->cmd.flashfw.type = 1;
       scb->cmd.flashfw.direction = 0;
-      scb->cmd.flashfw.count = 0x800;
-      scb->cmd.flashfw.buffer_addr = VIRT_TO_BUS(buffer);
+      scb->cmd.flashfw.count = cpu_to_le32(0x800);
+      scb->cmd.flashfw.buffer_addr = cpu_to_le32(VIRT_TO_BUS(buffer));
       scb->cmd.flashfw.total_packets = 1;
       scb->cmd.flashfw.packet_num = 0;
 
@@ -3384,10 +3407,9 @@
       }
 
       if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
-         major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */
-         minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
-         subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
-
+         major    = buffer[0x1ff + 0xC0];  /* Offset 0x1ff after the header (0xc0) */
+         minor    = buffer[0x1fe + 0xC0];  /* Offset 0x1fe after the header (0xc0) */
+         subminor = buffer[0x1fd + 0xC0];  /* Offset 0x1fd after the header (0xc0) */
       } else {
          return;
       }
@@ -3495,7 +3517,7 @@
    }
 
    /* setup max concurrent commands */
-   if (ha->subsys->param[4] & 0x1) {
+   if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
       /* Use the new method */
       ha->max_cmds = ha->enq->ucConcurrentCmdCount;
    } else {
@@ -3570,7 +3592,7 @@
        cpu_flags2 = 0;
    }
 
-   if (ha->subsys->param[3] & 0x300000) {
+   if ((ha->subsys->param[3] & 0x300000)  && ( ha->scb_activelist.count == 0 )) {
       struct timeval tv;
 
       do_gettimeofday(&tv);
@@ -3604,6 +3626,7 @@
 
       IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
       item = ips_removeq_copp_head(&ha->copp_waitlist);
+      ha->num_ioctl++;
       IPS_HA_UNLOCK(cpu_flags);
       scb->scsi_cmd = item->scsi_cmd;
       scb->sem = item->sem;
@@ -3618,14 +3641,14 @@
 
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-               u32 datasize;
+               u_int32_t datasize;
 
                datasize = 0;
                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
-               up(scb->sem);
+               up(&ha->ioctl_sem);
             } else {
                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
-            }
+         }
          }
 
          ips_freescb(ha, scb);
@@ -3636,11 +3659,11 @@
 
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-               u32 datasize;
+               u_int32_t datasize;
 
                datasize = 0;
                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
-               up(scb->sem);
+               up(&ha->ioctl_sem);
             } else {
                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
             }
@@ -3655,22 +3678,23 @@
       if (ret != IPS_SUCCESS) {
          IPS_HA_LOCK(cpu_flags);
          IPS_QUEUE_LOCK(&ha->copp_waitlist);
+         ha->num_ioctl--;
          continue;
       }
 
       ret = ips_send_cmd(ha, scb);
 
-      if (ret == IPS_SUCCESS) {
+      if (ret == IPS_SUCCESS) 
          ips_putq_scb_head(&ha->scb_activelist, scb);
-         ha->num_ioctl++;
-      }
+      else
+         ha->num_ioctl--;
 
       switch(ret) {
       case IPS_FAILURE:
          if (scb->scsi_cmd) {
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
-               up(scb->sem);
+               up(&ha->ioctl_sem);
 
             scb->scsi_cmd->result = DID_ERROR << 16;
          }
@@ -3681,7 +3705,7 @@
          if (scb->scsi_cmd) {
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
-               up(scb->sem);
+               up(&ha->ioctl_sem);
          }
 
          ips_freescb(ha, scb);
@@ -3716,7 +3740,7 @@
       SC = ips_removeq_wait(&ha->scb_waitlist, q);
       if (SC == NULL)                    /* Should never happen, but good to check anyway */
          continue;
-      
+
       IPS_HA_UNLOCK(cpu_flags);          /* Unlock HA after command is taken off queue */
 
       SC->result = DID_OK;
@@ -3757,17 +3781,17 @@
          } else {
             /* Check for the first Element being bigger than MAX_XFER */
             if (sg[0].length > ha->max_xfer) {
-               scb->sg_list[0].address = VIRT_TO_BUS(sg[0].address);
+               scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[0].address));
                scb->sg_list[0].length = ha->max_xfer;
                scb->data_len = ha->max_xfer;
                scb->breakup = 0; 
-	            scb->sg_break=1;  
+               scb->sg_break=1;  
                scb->sg_len = 1;
-	         }
+            }
             else {
                for (i = 0; i < SC->use_sg; i++) {
-                  scb->sg_list[i].address = VIRT_TO_BUS(sg[i].address);
-                  scb->sg_list[i].length = sg[i].length;
+                  scb->sg_list[i].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
+                  scb->sg_list[i].length = cpu_to_le32(sg[i].length);
             
                   if (scb->data_len + sg[i].length > ha->max_xfer) {
                      /*
@@ -3776,7 +3800,7 @@
                      scb->breakup = i;
                      break;
                   }
-
+               
                   scb->data_len += sg[i].length;
                }
 
@@ -4423,9 +4447,9 @@
        * data and had to be broke up.  If so, queue
        * the rest of the data and continue.
        */
-      if (scb->breakup || scb->sg_break) { 
-         /* We had a data breakup */
-         u8 bk_save;
+      if (scb->breakup) {
+         /* we had a data breakup */
+         u_int8_t bk_save;
 
          bk_save = scb->breakup;
          scb->breakup = 0;
@@ -4438,7 +4462,7 @@
             sg = scb->scsi_cmd->request_buffer;
 
             if (scb->scsi_cmd->use_sg == 1) {
-               if (sg[0].length - (bk_save * ha->max_xfer)) {
+               if (sg[0].length - (bk_save * ha->max_xfer) > ha->max_xfer) {
                   /* Further breakup required */
                   scb->data_len = ha->max_xfer;
                   scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
@@ -4480,7 +4504,7 @@
                } else {
 			         /* ( sg_break == 0 ), so this is our first look at a new sg piece */
                   if (sg[bk_save].length > ha->max_xfer) {
-			            scb->sg_list[0].address = VIRT_TO_BUS(sg[bk_save].address);
+			            scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[bk_save].address));
 				         scb->sg_list[0].length = ha->max_xfer;
 				         scb->breakup = bk_save;
 				         scb->sg_break = 1;
@@ -4493,8 +4517,8 @@
       			      scb->sg_break = 0;
                      /*   We're only doing full units here */
 				         for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) {
-					         scb->sg_list[i - bk_save].address = VIRT_TO_BUS(sg[i].address);
-				            scb->sg_list[i - bk_save].length = sg[i].length;
+					         scb->sg_list[i - bk_save].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
+				            scb->sg_list[i - bk_save].length = cpu_to_le32(sg[i].length);
                         if (scb->data_len + sg[i].length > ha->max_xfer) {
 					            scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
 					            break;
@@ -4510,7 +4534,8 @@
                scb->dcdb.transfer_length = scb->data_len;
                scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
             }
-         } else {
+                                              
+             } else {
             /* Non S/G Request */
             if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) {
                /* Further breakup required */
@@ -4751,7 +4776,7 @@
    int       ret;
    char     *sp;
    int       device_error;
-  
+
    METHOD_TRACE("ips_send_cmd", 1);
 
    ret = IPS_SUCCESS;
@@ -4800,27 +4825,29 @@
                scb->scsi_cmd->result = DID_OK << 16;
 
             if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
-               IPS_INQ_DATA inq;
+               IPS_SCSI_INQ_DATA inquiry;
 
-               memset(&inq, 0, sizeof(IPS_INQ_DATA));
+               memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA));
 
-               inq.DeviceType = TYPE_PROCESSOR;
-               inq.DeviceTypeQualifier = 0;
-               inq.RemoveableMedia = 0;
-               inq.Versions = 0x1;  /* SCSI I */
-               inq.AdditionalLength = 31;
-               strncpy(inq.VendorId, "IBM     ", 8);
-               strncpy(inq.ProductId, "SERVERAID       ", 16);
-               strncpy(inq.ProductRevisionLevel, "1.00", 4);
+               inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR;
+               inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
+               inquiry.Version = IPS_SCSI_INQ_REV2;
+               inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
+               inquiry.AdditionalLength = 31;
+               inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
+               inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync;
+               strncpy(inquiry.VendorId, "IBM     ", 8);
+               strncpy(inquiry.ProductId, "SERVERAID       ", 16);
+               strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
 
-               memcpy(scb->scsi_cmd->request_buffer, &inq, scb->scsi_cmd->request_bufflen);
+               memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen);
 
                scb->scsi_cmd->result = DID_OK << 16;
             }
          } else {
             scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
             scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
-            scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info);
+            scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info));
             scb->cmd.logical_info.reserved = 0;
             scb->cmd.logical_info.reserved2 = 0;
             ret = IPS_SUCCESS;
@@ -4846,19 +4873,20 @@
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
          scb->cmd.basic_io.log_drv = scb->target_id;
          scb->cmd.basic_io.sg_count = scb->sg_len;
-         scb->cmd.basic_io.sg_addr = scb->data_busaddr;
+         scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
 
          if (scb->cmd.basic_io.lba)
-            scb->cmd.basic_io.lba += scb->cmd.basic_io.sector_count;
+            scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
+                                                le16_to_cpu(scb->cmd.basic_io.sector_count));
          else
             scb->cmd.basic_io.lba = (((scb->scsi_cmd->cmnd[1] & 0x1f) << 16) |
                                      (scb->scsi_cmd->cmnd[2] << 8) |
                                      (scb->scsi_cmd->cmnd[3]));
 
-         scb->cmd.basic_io.sector_count = scb->data_len / IPS_BLKSIZE;
+         scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE);
 
-         if (scb->cmd.basic_io.sector_count == 0)
-            scb->cmd.basic_io.sector_count = 256;
+         if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
+            scb->cmd.basic_io.sector_count = cpu_to_le16(256);
 
          scb->cmd.basic_io.reserved = 0;
          ret = IPS_SUCCESS;
@@ -4877,21 +4905,22 @@
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
          scb->cmd.basic_io.log_drv = scb->target_id;
          scb->cmd.basic_io.sg_count = scb->sg_len;
-         scb->cmd.basic_io.sg_addr = scb->data_busaddr;
+         scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
 
          if (scb->cmd.basic_io.lba)
-            scb->cmd.basic_io.lba += scb->cmd.basic_io.sector_count;
+            scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
+                                                le16_to_cpu(scb->cmd.basic_io.sector_count));
          else
             scb->cmd.basic_io.lba = ((scb->scsi_cmd->cmnd[2] << 24) |
                                      (scb->scsi_cmd->cmnd[3] << 16) |
                                      (scb->scsi_cmd->cmnd[4] << 8) |
                                      scb->scsi_cmd->cmnd[5]);
 
-         scb->cmd.basic_io.sector_count = scb->data_len / IPS_BLKSIZE;
+         scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE);
 
          scb->cmd.basic_io.reserved = 0;
 
-         if (scb->cmd.basic_io.sector_count == 0) {
+         if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
             /*
              * This is a null condition
              * we don't have to do anything
@@ -4911,14 +4940,14 @@
       case MODE_SENSE:
          scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
-         scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq);
+         scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq));
          ret = IPS_SUCCESS;
          break;
 
       case READ_CAPACITY:
          scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
          scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
-         scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info);
+         scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info));
          scb->cmd.logical_info.reserved = 0;
          scb->cmd.logical_info.reserved2 = 0;
          scb->cmd.logical_info.reserved3 = 0;
@@ -4974,7 +5003,7 @@
 
       ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id);
       scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
-      scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
+      scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb));
       scb->cmd.dcdb.reserved = 0;
       scb->cmd.dcdb.reserved2 = 0;
       scb->cmd.dcdb.reserved3 = 0;
@@ -4995,7 +5024,7 @@
          scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
 
       scb->dcdb.sense_length = sizeof(scb->scsi_cmd->sense_buffer);
-      scb->dcdb.buffer_pointer = scb->data_busaddr;
+      scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
       scb->dcdb.sg_count = scb->sg_len;
       scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
       memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
@@ -5017,8 +5046,8 @@
 ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
    ips_scb_t  *scb;
    ips_stat_t *sp;
-   u8          basic_status;
-   u8          ext_status;
+   u_int8_t    basic_status;
+   u_int8_t    ext_status;
    int         errcode;
 
    METHOD_TRACE("ips_chkstatus", 1);
@@ -5029,7 +5058,7 @@
 
    sp = &ha->sp;
    sp->residue_len = 0;
-   sp->scb_addr = (u32) scb;
+   sp->scb_addr = (void *) scb;
 
    /* Remove the item from the active queue */
    ips_removeq_scb(&ha->scb_activelist, scb);
@@ -5198,22 +5227,24 @@
 /****************************************************************************/
 static int
 ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
-   IPS_INQ_DATA inq;
+   IPS_SCSI_INQ_DATA inquiry;
 
    METHOD_TRACE("ips_inquiry", 1);
 
-   memset(&inq, 0, sizeof(IPS_INQ_DATA));
+   memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA));
 
-   inq.DeviceType = TYPE_DISK;
-   inq.DeviceTypeQualifier = 0;
-   inq.RemoveableMedia = 0;
-   inq.Versions = 0x1;  /* SCSI I */
-   inq.AdditionalLength = 31;
-   strncpy(inq.VendorId, "IBM     ", 8);
-   strncpy(inq.ProductId, "SERVERAID       ", 16);
-   strncpy(inq.ProductRevisionLevel, "1.00", 4);
+   inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
+   inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
+   inquiry.Version = IPS_SCSI_INQ_REV2;
+   inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
+   inquiry.AdditionalLength = 31;
+   inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
+   inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync;
+   strncpy(inquiry.VendorId, "IBM     ", 8);
+   strncpy(inquiry.ProductId, "SERVERAID       ", 16);
+   strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
 
-   memcpy(scb->scsi_cmd->request_buffer, &inq, scb->scsi_cmd->request_bufflen);
+   memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen);
 
    return (1);
 }
@@ -5229,17 +5260,17 @@
 /****************************************************************************/
 static int
 ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) {
-   IPS_CAPACITY *cap;
+   IPS_SCSI_CAPACITY *cap;
 
    METHOD_TRACE("ips_rdcap", 1);
 
    if (scb->scsi_cmd->bufflen < 8)
       return (0);
 
-   cap = (IPS_CAPACITY *) scb->scsi_cmd->request_buffer;
+   cap = (IPS_SCSI_CAPACITY *) scb->scsi_cmd->request_buffer;
 
-   cap->lba = htonl(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count - 1);
-   cap->len = htonl((u32) IPS_BLKSIZE);
+   cap->lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1);
+   cap->len = cpu_to_be32((u_int32_t) IPS_BLKSIZE);
 
    return (1);
 }
@@ -5255,14 +5286,14 @@
 /****************************************************************************/
 static int
 ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
-   u16          heads;
-   u16          sectors;
-   u32          cylinders;
-   ips_mdata_t  mdata;
+   u_int16_t               heads;
+   u_int16_t               sectors;
+   u_int32_t               cylinders;
+   IPS_SCSI_MODE_PAGE_DATA mdata;
 
    METHOD_TRACE("ips_msense", 1);
 
-   if (ha->enq->ulDriveSize[scb->target_id] > 0x400000 &&
+   if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
        (ha->enq->ucMiscFlag & 0x8) == 0) {
       heads = IPS_NORM_HEADS;
       sectors = IPS_NORM_SECTORS;
@@ -5271,51 +5302,48 @@
       sectors = IPS_COMP_SECTORS;
    }
 
-   cylinders = ha->enq->ulDriveSize[scb->target_id] / (heads * sectors);
+   cylinders = (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) - 1) / (heads * sectors);
+
+   memset(&mdata, 0, sizeof(IPS_SCSI_MODE_PAGE_DATA));
 
-   mdata.plh.plh_type = 0;
-   mdata.plh.plh_wp = 0;
-   mdata.plh.plh_bdl = 8;
+   mdata.hdr.BlockDescLength = 8;
 
    switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
    case 0x03: /* page 3 */
-      mdata.pdata.pg3.pg_pc = 0x3;
-      mdata.pdata.pg3.pg_res1 = 0;
-      mdata.pdata.pg3.pg_len = sizeof(IPS_DADF);
-      mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg3.pg_len;
-      mdata.pdata.pg3.pg_trk_z = 0;
-      mdata.pdata.pg3.pg_asec_z = 0;
-      mdata.pdata.pg3.pg_atrk_z = 0;
-      mdata.pdata.pg3.pg_atrk_v = 0;
-      mdata.pdata.pg3.pg_sec_t = htons(sectors);
-      mdata.pdata.pg3.pg_bytes_s = htons(IPS_BLKSIZE);
-      mdata.pdata.pg3.pg_intl = htons(1);
-      mdata.pdata.pg3.pg_trkskew = 0;
-      mdata.pdata.pg3.pg_cylskew = 0;
-      mdata.pdata.pg3.pg_res2 = 0;
-      mdata.pdata.pg3.pg_ins = 0;
-      mdata.pdata.pg3.pg_surf = 0;
-      mdata.pdata.pg3.pg_rmb = 0;
-      mdata.pdata.pg3.pg_hsec = 0;
-      mdata.pdata.pg3.pg_ssec = 1;
+      mdata.pdata.pg3.PageCode = 3;
+      mdata.pdata.pg3.PageLength = sizeof(IPS_SCSI_MODE_PAGE3);
+      mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
+      mdata.pdata.pg3.TracksPerZone = 0;
+      mdata.pdata.pg3.AltSectorsPerZone = 0;
+      mdata.pdata.pg3.AltTracksPerZone = 0;
+      mdata.pdata.pg3.AltTracksPerVolume = 0;
+      mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
+      mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
+      mdata.pdata.pg3.Interleave = cpu_to_be16(1);
+      mdata.pdata.pg3.TrackSkew = 0;
+      mdata.pdata.pg3.CylinderSkew = 0;
+      mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
       break;
 
    case 0x4:
-      mdata.pdata.pg4.pg_pc = 0x4;
-      mdata.pdata.pg4.pg_res1 = 0;
-      mdata.pdata.pg4.pg_len = sizeof(IPS_RDDG);
-      mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg4.pg_len;
-      mdata.pdata.pg4.pg_cylu = (cylinders >> 8) & 0xffff;
-      mdata.pdata.pg4.pg_cyll = cylinders & 0xff;
-      mdata.pdata.pg4.pg_head = heads;
-      mdata.pdata.pg4.pg_wrpcompu = 0;
-      mdata.pdata.pg4.pg_wrpcompl = 0;
-      mdata.pdata.pg4.pg_redwrcur = 0;
-      mdata.pdata.pg4.pg_drstep = htons(1);
-      mdata.pdata.pg4.pg_landu = 0;
-      mdata.pdata.pg4.pg_landl = 0;
-      mdata.pdata.pg4.pg_res2 = 0;
+      mdata.pdata.pg4.PageCode = 4;
+      mdata.pdata.pg4.PageLength = sizeof(IPS_SCSI_MODE_PAGE4);
+      mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
+      mdata.pdata.pg4.CylindersHigh = cpu_to_be16((cylinders >> 8) & 0xFFFF);
+      mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
+      mdata.pdata.pg4.Heads = heads;
+      mdata.pdata.pg4.WritePrecompHigh = 0;
+      mdata.pdata.pg4.WritePrecompLow = 0;
+      mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
+      mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
+      mdata.pdata.pg4.StepRate = cpu_to_be16(1);
+      mdata.pdata.pg4.LandingZoneHigh = 0;
+      mdata.pdata.pg4.LandingZoneLow = 0;
+      mdata.pdata.pg4.flags = 0;
+      mdata.pdata.pg4.RotationalOffset = 0;
+      mdata.pdata.pg4.MediumRotationRate = 0;
       break;
+
    default:
       return (0);
    } /* end switch */
@@ -5336,19 +5364,20 @@
 /****************************************************************************/
 static int
 ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) {
-   char *sp;
+   IPS_SCSI_REQSEN reqsen;
 
    METHOD_TRACE("ips_reqsen", 1);
 
-   sp = (char *) scb->scsi_cmd->sense_buffer;
-   memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer));
+   memset(&reqsen, 0, sizeof(IPS_SCSI_REQSEN));
 
-   sp[0] = 0x70;
-   sp[3] = NO_SENSE;
-   sp[7] = 0xe;
-   sp[12] = NO_SENSE;
+   reqsen.ResponseCode = IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
+   reqsen.AdditionalLength = 10;
+   reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
+   reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
 
-   return (0);
+   memcpy(scb->scsi_cmd->request_buffer, &reqsen, scb->scsi_cmd->request_bufflen);
+
+   return (1);
 }
 
 /****************************************************************************/
@@ -5419,8 +5448,14 @@
          iounmap(ha->ioremap_ptr);
          ha->ioremap_ptr = NULL;
          ha->mem_ptr = NULL;
-         ha->mem_addr = 0;
       }
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
+      if (ha->mem_addr) 
+          release_mem_region(ha->mem_addr, ha->mem_len);
+#endif
+      ha->mem_addr = 0;
+
    }
 }
 
@@ -5441,10 +5476,9 @@
    METHOD_TRACE("ips_allocatescbs", 1);
 
    /* Allocate memory for the CCBs */
-   ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_ATOMIC);
+   ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_KERNEL);
    if (ha->scbs == NULL)
-    	return 0;
-
+      return 0;
 
    memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t));
 
@@ -5494,7 +5528,7 @@
 
    /* Initialize dummy command bucket */
    ha->dummy->op_code = 0xFF;
-   ha->dummy->ccsar = VIRT_TO_BUS(ha->dummy);
+   ha->dummy->ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy));
    ha->dummy->command_id = IPS_MAX_CMDS;
 
    /* set bus address of scb */
@@ -5502,8 +5536,8 @@
    scb->sg_list = sg_list;
 
    /* Neptune Fix */
-   scb->cmd.basic_io.cccr = IPS_BIT_ILE;
-   scb->cmd.basic_io.ccsar = VIRT_TO_BUS(ha->dummy);
+   scb->cmd.basic_io.cccr = cpu_to_le32((u_int32_t) IPS_BIT_ILE);
+   scb->cmd.basic_io.ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy));
 }
 
 /****************************************************************************/
@@ -5578,8 +5612,8 @@
 /****************************************************************************/
 static int
 ips_isinit_copperhead(ips_ha_t *ha) {
-   u8 scpr;
-   u8 isr;
+   u_int8_t scpr;
+   u_int8_t isr;
 
    METHOD_TRACE("ips_isinit_copperhead", 1);
 
@@ -5603,8 +5637,8 @@
 /****************************************************************************/
 static int
 ips_isinit_copperhead_memio(ips_ha_t *ha) {
-   u8 isr=0;
-   u8 scpr;
+   u_int8_t isr=0;
+   u_int8_t scpr;
 
    METHOD_TRACE("ips_is_init_copperhead_memio", 1);
 
@@ -5628,13 +5662,13 @@
 /****************************************************************************/
 static int
 ips_isinit_morpheus(ips_ha_t *ha) {
-   u32 post;
-   u32 bits;
+   u_int32_t post;
+   u_int32_t bits;
 
    METHOD_TRACE("ips_is_init_morpheus", 1);
 
-   post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
-   bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+   post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0));
+   bits = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
 
    if (post == 0)
        return (0);
@@ -5684,13 +5718,13 @@
 /****************************************************************************/
 static void
 ips_enable_int_morpheus(ips_ha_t *ha) {
-   u32              Oimr;
+   u_int32_t  Oimr;
 
    METHOD_TRACE("ips_enable_int_morpheus", 1);
 
-   Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
+   Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR));
    Oimr &= ~0x08;
-   writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
+   writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR);
 }
 
 /****************************************************************************/
@@ -5704,10 +5738,10 @@
 /****************************************************************************/
 static int
 ips_init_copperhead(ips_ha_t *ha) {
-   u8  Isr;
-   u8  Cbsp;
-   u8  PostByte[IPS_MAX_POST_BYTES];
-   u8  ConfigByte[IPS_MAX_CONFIG_BYTES];
+   u_int8_t  Isr;
+   u_int8_t  Cbsp;
+   u_int8_t  PostByte[IPS_MAX_POST_BYTES];
+   u_int8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
    int i, j;
 
    METHOD_TRACE("ips_init_copperhead", 1);
@@ -5742,7 +5776,7 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
-         MDELAY(IPS_ONE_SEC); /* 100 msec */
+         MDELAY(IPS_ONE_SEC);    /* 1 sec */
       }
 
       if (j >= 240)
@@ -5767,7 +5801,7 @@
       return (0);
 
    /* setup CCCR */
-   outw(0x1010, ha->io_addr + IPS_REG_CCCR);
+   outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
 
    /* Enable busmastering */
    outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
@@ -5793,10 +5827,10 @@
 /****************************************************************************/
 static int
 ips_init_copperhead_memio(ips_ha_t *ha) {
-   u8  Isr=0;
-   u8  Cbsp;
-   u8  PostByte[IPS_MAX_POST_BYTES];
-   u8  ConfigByte[IPS_MAX_CONFIG_BYTES];
+   u_int8_t  Isr=0;
+   u_int8_t  Cbsp;
+   u_int8_t  PostByte[IPS_MAX_POST_BYTES];
+   u_int8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
    int i, j;
 
    METHOD_TRACE("ips_init_copperhead_memio", 1);
@@ -5856,7 +5890,7 @@
       return (0);
 
    /* setup CCCR */
-   writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
+   writel(cpu_to_le32(0x1010), ha->mem_ptr + IPS_REG_CCCR);
 
    /* Enable busmastering */
    writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
@@ -5883,17 +5917,17 @@
 /****************************************************************************/
 static int
 ips_init_morpheus(ips_ha_t *ha) {
-   u32 Post;
-   u32 Config;
-   u32 Isr;
-   u32 Oimr;
-   int i;
+   u_int32_t Post;
+   u_int32_t Config;
+   u_int32_t Isr;
+   u_int32_t Oimr;
+   int       i;
 
    METHOD_TRACE("ips_init_morpheus", 1);
 
    /* Wait up to 45 secs for Post */
    for (i = 0; i < 45; i++) {
-      Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+      Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
 
       if (Isr & IPS_BIT_I960_MSG0I)
          break;
@@ -5909,11 +5943,11 @@
       return (0);
    }
 
-   Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+   Post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0));
 
    /* Clear the interrupt bit */
-   Isr = (u32) IPS_BIT_I960_MSG0I;
-   writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
+   Isr = (u_int32_t) IPS_BIT_I960_MSG0I;
+   writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR);
 
    if (Post < (IPS_GOOD_POST_STATUS << 8)) {
       printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).\n",
@@ -5924,7 +5958,7 @@
 
    /* Wait up to 240 secs for config bytes */
    for (i = 0; i < 240; i++) {
-      Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+      Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
 
       if (Isr & IPS_BIT_I960_MSG1I)
          break;
@@ -5940,16 +5974,16 @@
       return (0);
    }
 
-   Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
+   Config = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG1));
 
    /* Clear interrupt bit */
-   Isr = (u32) IPS_BIT_I960_MSG1I;
-   writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
+   Isr = (u_int32_t) IPS_BIT_I960_MSG1I;
+   writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR);
 
    /* Turn on the interrupts */
-   Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
+   Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR));
    Oimr &= ~0x8;
-   writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
+   writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR);
 
    /* if we get here then everything went OK */
    return (1);
@@ -6056,8 +6090,8 @@
 /****************************************************************************/
 static int
 ips_reset_morpheus(ips_ha_t *ha) {
-   int reset_counter;
-   u8  junk;
+   int           reset_counter;
+   u_int8_t      junk;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_reset_morpheus", 1);
@@ -6072,10 +6106,10 @@
    while (reset_counter < 2) {
       reset_counter++;
 
-      writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
+      writel(cpu_to_le32(0x80000000), ha->mem_ptr + IPS_REG_I960_IDR);
 
-      /* Delay for 300 msec */
-      MDELAY(300 * IPS_ONE_MSEC);
+      /* Delay for 5 sec */
+      MDELAY(5 * IPS_ONE_SEC);
 
       /* Do a PCI config read to wait for adapter */
       pci_read_config_byte(ha->pcidev, 4, &junk);
@@ -6105,7 +6139,7 @@
 /****************************************************************************/
 static void
 ips_statinit(ips_ha_t *ha) {
-   u32        phys_status_start;
+   u_int32_t phys_status_start;
 
    METHOD_TRACE("ips_statinit", 1);
 
@@ -6114,10 +6148,10 @@
    ha->adapt->p_status_tail = ha->adapt->status;
 
    phys_status_start = VIRT_TO_BUS(ha->adapt->status);
-   outl(phys_status_start, ha->io_addr + IPS_REG_SQSR);
-   outl(phys_status_start + IPS_STATUS_Q_SIZE, ha->io_addr + IPS_REG_SQER);
-   outl(phys_status_start + IPS_STATUS_SIZE, ha->io_addr + IPS_REG_SQHR);
-   outl(phys_status_start, ha->io_addr + IPS_REG_SQTR);
+   outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
+   outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->io_addr + IPS_REG_SQER);
+   outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->io_addr + IPS_REG_SQHR);
+   outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
 
    ha->adapt->hw_status_start = phys_status_start;
    ha->adapt->hw_status_tail = phys_status_start;
@@ -6134,7 +6168,7 @@
 /****************************************************************************/
 static void
 ips_statinit_memio(ips_ha_t *ha) {
-   u32        phys_status_start;
+   u_int32_t phys_status_start;
 
    METHOD_TRACE("ips_statinit_memio", 1);
 
@@ -6143,10 +6177,10 @@
    ha->adapt->p_status_tail = ha->adapt->status;
 
    phys_status_start = VIRT_TO_BUS(ha->adapt->status);
-   writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
-   writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER);
-   writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
-   writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
+   writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQSR);
+   writel(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->mem_ptr + IPS_REG_SQER);
+   writel(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->mem_ptr + IPS_REG_SQHR);
+   writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQTR);
 
    ha->adapt->hw_status_start = phys_status_start;
    ha->adapt->hw_status_tail = phys_status_start;
@@ -6161,7 +6195,7 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u32
+static u_int32_t
 ips_statupd_copperhead(ips_ha_t *ha) {
    METHOD_TRACE("ips_statupd_copperhead", 1);
 
@@ -6173,7 +6207,7 @@
       ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
    }
 
-   outl(ha->adapt->hw_status_tail, ha->io_addr + IPS_REG_SQTR);
+   outl(cpu_to_le32(ha->adapt->hw_status_tail), ha->io_addr + IPS_REG_SQTR);
 
    return (ha->adapt->p_status_tail->value);
 }
@@ -6187,7 +6221,7 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u32
+static u_int32_t
 ips_statupd_copperhead_memio(ips_ha_t *ha) {
    METHOD_TRACE("ips_statupd_copperhead_memio", 1);
 
@@ -6199,7 +6233,7 @@
       ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
    }
 
-   writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
+   writel(cpu_to_le32(ha->adapt->hw_status_tail), ha->mem_ptr + IPS_REG_SQTR);
 
    return (ha->adapt->p_status_tail->value);
 }
@@ -6213,13 +6247,13 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u32
+static u_int32_t
 ips_statupd_morpheus(ips_ha_t *ha) {
-   u32       val;
+   u_int32_t val;
 
    METHOD_TRACE("ips_statupd_morpheus", 1);
 
-   val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
+   val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ));
 
    return (val);
 }
@@ -6235,9 +6269,9 @@
 /****************************************************************************/
 static int
 ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
-   u32       TimeOut;
-   u16       val;
-   unsigned long       cpu_flags;
+   u_int32_t TimeOut;
+   u_int32_t val;
+   unsigned long cpu_flags;
 
    METHOD_TRACE("ips_issue_copperhead", 1);
 
@@ -6261,7 +6295,7 @@
 
    TimeOut = 0;
 
-   while ((val = inw(ha->io_addr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
+   while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
       udelay(1000);
 
       if (++TimeOut >= IPS_SEM_TIMEOUT) {
@@ -6279,8 +6313,8 @@
       } /* end if */
    } /* end while */
 
-   outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR);
-   outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR);
+   outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
+   outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6298,8 +6332,8 @@
 /****************************************************************************/
 static int
 ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
-   u32       TimeOut;
-   u32       val;
+   u_int32_t     TimeOut;
+   u_int32_t     val;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_issue_copperhead_memio", 1);
@@ -6324,7 +6358,7 @@
 
    TimeOut = 0;
 
-   while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
+   while ((val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
       udelay(1000);
 
       if (++TimeOut >= IPS_SEM_TIMEOUT) {
@@ -6342,8 +6376,8 @@
       } /* end if */
    } /* end while */
 
-   writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
-   writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
+   writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_CCSAR);
+   writel(cpu_to_le32(IPS_BIT_START_CMD), ha->mem_ptr + IPS_REG_CCCR);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6383,7 +6417,7 @@
 
    IPS_HA_LOCK(cpu_flags);
 
-   outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ);
+   outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6423,7 +6457,7 @@
 
    IPS_HA_LOCK(cpu_flags);
 
-   writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
+   writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_I2O_INMSGQ);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6441,7 +6475,7 @@
 /****************************************************************************/
 static int
 ips_isintr_copperhead(ips_ha_t *ha) {
-   u8 Isr;
+   u_int8_t Isr;
 
    METHOD_TRACE("ips_isintr_copperhead", 2);
 
@@ -6473,7 +6507,7 @@
 /****************************************************************************/
 static int
 ips_isintr_copperhead_memio(ips_ha_t *ha) {
-   u8 Isr;
+   u_int8_t Isr;
 
    METHOD_TRACE("ips_isintr_memio", 2);
 
@@ -6505,11 +6539,11 @@
 /****************************************************************************/
 static int
 ips_isintr_morpheus(ips_ha_t *ha) {
-   u32 Isr;
+   u_int32_t Isr;
 
    METHOD_TRACE("ips_isintr_morpheus", 2);
 
-   Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+   Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
 
    if (Isr & IPS_BIT_I2O_OPQI)
       return (1);
@@ -6529,7 +6563,7 @@
 static int
 ips_wait(ips_ha_t *ha, int time, int intr) {
    int        ret;
-   u8         done;
+   u_int8_t   done;
 
    METHOD_TRACE("ips_wait", 1);
 
@@ -6628,7 +6662,7 @@
 
    /* check to make sure the page has a valid */
    /* signature */
-   if (ha->nvram->signature != IPS_NVRAM_P5_SIG) {
+   if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
       DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.",
                 ips_name, ha->host_num, ha->nvram->signature);
 
@@ -6636,16 +6670,22 @@
    }
 
    DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
-             ips_name, ha->host_num, ha->nvram->adapter_type, ha->nvram->adapter_slot,
+             ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type),
+             ha->nvram->adapter_slot,
              ha->nvram->bios_high[0], ha->nvram->bios_high[1],
              ha->nvram->bios_high[2], ha->nvram->bios_high[3],
              ha->nvram->bios_low[0], ha->nvram->bios_low[1],
              ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
 
+   ips_get_bios_version(ha, intr);
+
    /* change values (as needed) */
    ha->nvram->operating_system = IPS_OS_LINUX;
+   ha->nvram->adapter_type = ha->ad_type;
    strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
    strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
+   strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
+   strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
 
    /* now update the page */
    if (!ips_readwrite_page5(ha, TRUE, intr)) {
@@ -6658,6 +6698,7 @@
    /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */
    ha->slot_num = ha->nvram->adapter_slot;
 
+
    return (1);
 }
 
@@ -6687,7 +6728,7 @@
    scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.basic_io.sg_count = 0;
-   scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq);
+   scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq));
    scb->cmd.basic_io.lba = 0;
    scb->cmd.basic_io.sector_count = 0;
    scb->cmd.basic_io.log_drv = 0;
@@ -6728,7 +6769,7 @@
    scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.basic_io.sg_count = 0;
-   scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->subsys);
+   scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->subsys));
    scb->cmd.basic_io.lba = 0;
    scb->cmd.basic_io.sector_count = 0;
    scb->cmd.basic_io.log_drv = 0;
@@ -6761,8 +6802,7 @@
    METHOD_TRACE("ips_read_config", 1);
 
    /* set defaults for initiator IDs */
-   ha->conf->init_id[0] = IPS_ADAPTER_ID;
-   for (i = 1; i < 4; i++)
+   for (i = 0; i < 4; i++)
       ha->conf->init_id[i] = 7;
 
    scb = &ha->scbs[ha->max_cmds-1];
@@ -6774,7 +6814,7 @@
 
    scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
-   scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->conf);
+   scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->conf));
 
    /* send command */
    if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
@@ -6784,8 +6824,7 @@
       memset(ha->conf, 0, sizeof(IPS_CONF));
 
       /* reset initiator IDs */
-      ha->conf->init_id[0] = IPS_ADAPTER_ID;
-      for (i = 1; i < 4; i++)
+      for (i = 0; i < 4; i++)
          ha->conf->init_id[i] = 7;
 
       return (0);
@@ -6821,7 +6860,7 @@
    scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
    scb->cmd.nvram.page = 5;
    scb->cmd.nvram.write = write;
-   scb->cmd.nvram.buffer_addr = VIRT_TO_BUS(ha->nvram);
+   scb->cmd.nvram.buffer_addr = cpu_to_le32(VIRT_TO_BUS(ha->nvram));
    scb->cmd.nvram.reserved = 0;
    scb->cmd.nvram.reserved2 = 0;
 
@@ -7043,11 +7082,13 @@
 /****************************************************************************/
 static int
 ips_erase_bios(ips_ha_t *ha) {
-   int   timeout;
-   u8    status=0;
+   int      timeout;
+   u_int8_t status=0;
 
    METHOD_TRACE("ips_erase_bios", 1);
 
+   status = 0;
+
    /* Clear the status register */
    outl(0, ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
@@ -7152,11 +7193,13 @@
 /****************************************************************************/
 static int
 ips_erase_bios_memio(ips_ha_t *ha) {
-   int   timeout;
-   u8    status;
+   int      timeout;
+   u_int8_t status;
 
    METHOD_TRACE("ips_erase_bios_memio", 1);
 
+   status = 0;
+
    /* Clear the status register */
    writel(0, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
@@ -7260,16 +7303,18 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_program_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
-   int   i;
-   int   timeout;
-   u8    status=0;
+ips_program_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+   int      i;
+   int      timeout;
+   u_int8_t status=0;
 
    METHOD_TRACE("ips_program_bios", 1);
 
+   status = 0;
+
    for (i = 0; i < buffersize; i++) {
       /* write a byte */
-      outl(i + offset, ha->io_addr + IPS_REG_FLAP);
+      outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
          udelay(5); /* 5 us */
 
@@ -7347,16 +7392,18 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_program_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
-   int   i;
-   int   timeout;
-   u8    status=0;
+ips_program_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+   int      i;
+   int      timeout;
+   u_int8_t status=0;
 
    METHOD_TRACE("ips_program_bios_memio", 1);
 
+   status = 0;
+
    for (i = 0; i < buffersize; i++) {
       /* write a byte */
-      writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
+      writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
          udelay(5); /* 5 us */
 
@@ -7434,9 +7481,9 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_verify_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
-   u8    checksum;
-   int   i;
+ips_verify_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+   u_int8_t checksum;
+   int      i;
 
    METHOD_TRACE("ips_verify_bios", 1);
 
@@ -7448,7 +7495,7 @@
    if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
       return (1);
 
-   outl(1, ha->io_addr + IPS_REG_FLAP);
+   outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
       udelay(5); /* 5 us */
    if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
@@ -7457,11 +7504,11 @@
    checksum = 0xff;
    for (i = 2; i < buffersize; i++) {
 
-      outl(i + offset, ha->io_addr + IPS_REG_FLAP);
+      outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
          udelay(5); /* 5 us */
 
-      checksum = (u8) checksum + inb(ha->io_addr + IPS_REG_FLDP);
+      checksum = (u_int8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
    }
 
    if (checksum != 0)
@@ -7481,9 +7528,9 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
-   u8    checksum;
-   int   i;
+ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+   u_int8_t checksum;
+   int      i;
 
    METHOD_TRACE("ips_verify_bios_memio", 1);
 
@@ -7504,11 +7551,11 @@
    checksum = 0xff;
    for (i = 2; i < buffersize; i++) {
 
-      writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
+      writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
          udelay(5); /* 5 us */
 
-      checksum = (u8) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
+      checksum = (u_int8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
    }
 
    if (checksum != 0)
@@ -7521,7 +7568,6 @@
 
 static Scsi_Host_Template driver_template = IPS;
 #include "scsi_module.c"
-
 
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ips.h linux/drivers/scsi/ips.h
--- v2.4.10/linux/drivers/scsi/ips.h	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/ips.h	Sun Sep 30 12:26:08 2001
@@ -50,6 +50,12 @@
    #include <asm/uaccess.h>
    #include <asm/io.h>
 
+   /* type definitions */
+   #define u_int8_t  uint8_t
+   #define u_int16_t uint16_t
+   #define u_int32_t uint32_t
+   #define u_int64_t uint64_t
+
    /* Prototypes */
    extern int ips_detect(Scsi_Host_Template *);
    extern int ips_release(struct Scsi_Host *);
@@ -99,11 +105,11 @@
    #ifndef verify_area_20
       #define verify_area_20(t,a,sz)   (0) /* success */
    #endif
-   
+
    #ifndef DECLARE_MUTEX_LOCKED
       #define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED;
    #endif
-
+   
    /*
     * Lock macros
     */
@@ -326,6 +332,53 @@
    #define IPS_TIMEOUT20M               0x30
 
    /*
+    * SCSI Inquiry Data Flags
+    */
+   #define IPS_SCSI_INQ_TYPE_DASD       0x00
+   #define IPS_SCSI_INQ_TYPE_PROCESSOR  0x03
+   #define IPS_SCSI_INQ_LU_CONNECTED    0x00
+   #define IPS_SCSI_INQ_RD_REV2         0x02
+   #define IPS_SCSI_INQ_REV2            0x02
+   #define IPS_SCSI_INQ_REV3            0x03
+   #define IPS_SCSI_INQ_Address16       0x01
+   #define IPS_SCSI_INQ_Address32       0x02
+   #define IPS_SCSI_INQ_MedChanger      0x08
+   #define IPS_SCSI_INQ_MultiPort       0x10
+   #define IPS_SCSI_INQ_EncServ         0x40
+   #define IPS_SCSI_INQ_SoftReset       0x01
+   #define IPS_SCSI_INQ_CmdQue          0x02
+   #define IPS_SCSI_INQ_Linked          0x08
+   #define IPS_SCSI_INQ_Sync            0x10
+   #define IPS_SCSI_INQ_WBus16          0x20
+   #define IPS_SCSI_INQ_WBus32          0x40
+   #define IPS_SCSI_INQ_RelAdr          0x80
+
+   /*
+    * SCSI Request Sense Data Flags
+    */
+   #define IPS_SCSI_REQSEN_VALID        0x80
+   #define IPS_SCSI_REQSEN_CURRENT_ERR  0x70
+   #define IPS_SCSI_REQSEN_NO_SENSE     0x00
+
+   /*
+    * SCSI Mode Page Equates
+    */
+   #define IPS_SCSI_MP3_SoftSector      0x01
+   #define IPS_SCSI_MP3_HardSector      0x02
+   #define IPS_SCSI_MP3_Removeable      0x04
+   #define IPS_SCSI_MP3_AllocateSurface 0x08
+
+   /*
+    * Configuration Structure Flags
+    */
+   #define IPS_CFG_USEROPT_UPDATECOUNT(cfg)   (((cfg)->UserOpt & 0xffff000) >> 16)
+   #define IPS_CFG_USEROPT_CONCURSTART(cfg)   (((cfg)->UserOpt & 0xf000) >> 12)
+   #define IPS_CFG_USEROPT_STARTUPDELAY(cfg)  (((cfg)->UserOpt & 0xf00) >> 8)
+   #define IPS_CFG_USEROPT_REARRANGE(cfg)     ((cfg)->UserOpt & 0x80)
+   #define IPS_CFG_USEROPT_CDBOOT(cfg)        ((cfg)->UserOpt & 0x40)
+   #define IPS_CFG_USEROPT_CLUSTER(cfg)       ((cfg)->UserOpt & 0x20)
+
+   /*
     * Host adapter Flags (bit numbers)
     */
    #define IPS_IN_INTR                  0
@@ -427,201 +480,201 @@
  * IBM PCI Raid Command Formats
  */
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u8        log_drv;
-   u8        sg_count;
-   u32       lba;
-   u32       sg_addr;
-   u16       sector_count;
-   u16       reserved;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  log_drv;
+   u_int8_t  sg_count;
+   u_int32_t lba;
+   u_int32_t sg_addr;
+   u_int16_t sector_count;
+   u_int16_t reserved;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_IO_CMD, *PIPS_IO_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u16       reserved;
-   u32       reserved2;
-   u32       buffer_addr;
-   u32       reserved3;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int16_t reserved;
+   u_int32_t reserved2;
+   u_int32_t buffer_addr;
+   u_int32_t reserved3;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_LD_CMD, *PIPS_LD_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u8        reserved;
-   u8        reserved2;
-   u32       reserved3;
-   u32       buffer_addr;
-   u32       reserved4;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  reserved;
+   u_int8_t  reserved2;
+   u_int32_t reserved3;
+   u_int32_t buffer_addr;
+   u_int32_t reserved4;
 } IPS_IOCTL_CMD, *PIPS_IOCTL_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u16       reserved;
-   u32       reserved2;
-   u32       dcdb_address;
-   u32       reserved3;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int16_t reserved;
+   u_int32_t reserved2;
+   u_int32_t dcdb_address;
+   u_int32_t reserved3;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_DCDB_CMD, *PIPS_DCDB_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u8        channel;
-   u8        source_target;
-   u32       reserved;
-   u32       reserved2;
-   u32       reserved3;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  channel;
+   u_int8_t  source_target;
+   u_int32_t reserved;
+   u_int32_t reserved2;
+   u_int32_t reserved3;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_CS_CMD, *PIPS_CS_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u8        log_drv;
-   u8        control;
-   u32       reserved;
-   u32       reserved2;
-   u32       reserved3;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  log_drv;
+   u_int8_t  control;
+   u_int32_t reserved;
+   u_int32_t reserved2;
+   u_int32_t reserved3;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_US_CMD, *PIPS_US_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u8        reserved;
-   u8        state;
-   u32       reserved2;
-   u32       reserved3;
-   u32       reserved4;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  reserved;
+   u_int8_t  state;
+   u_int32_t reserved2;
+   u_int32_t reserved3;
+   u_int32_t reserved4;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_FC_CMD, *PIPS_FC_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u8        reserved;
-   u8        desc;
-   u32       reserved2;
-   u32       buffer_addr;
-   u32       reserved3;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  reserved;
+   u_int8_t  desc;
+   u_int32_t reserved2;
+   u_int32_t buffer_addr;
+   u_int32_t reserved3;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_STATUS_CMD, *PIPS_STATUS_CMD;
 
 typedef struct {
-   u8        op_code;
-   u8        command_id;
-   u8        page;
-   u8        write;
-   u32       reserved;
-   u32       buffer_addr;
-   u32       reserved2;
-   u32       ccsar;
-   u32       cccr;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  page;
+   u_int8_t  write;
+   u_int32_t reserved;
+   u_int32_t buffer_addr;
+   u_int32_t reserved2;
+   u_int32_t ccsar;
+   u_int32_t cccr;
 } IPS_NVRAM_CMD, *PIPS_NVRAM_CMD;
 
 typedef struct {
-   u8     op_code;
-   u8     command_id;
-   u8     reset_count;
-   u8     reset_type;
-   u8     second;
-   u8     minute;
-   u8     hour;
-   u8     day;
-   u8     reserved1[4];
-   u8     month;
-   u8     yearH;
-   u8     yearL;
-   u8     reserved2;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  reset_count;
+   u_int8_t  reset_type;
+   u_int8_t  second;
+   u_int8_t  minute;
+   u_int8_t  hour;
+   u_int8_t  day;
+   u_int8_t  reserved1[4];
+   u_int8_t  month;
+   u_int8_t  yearH;
+   u_int8_t  yearL;
+   u_int8_t  reserved2;
 } IPS_FFDC_CMD, *PIPS_FFDC_CMD;
 
 typedef struct {
-   u8     op_code;
-   u8     command_id;
-   u8     type;
-   u8     direction;
-   u32    count;
-   u32    buffer_addr;
-   u8     total_packets;
-   u8     packet_num;
-   u16    reserved;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  type;
+   u_int8_t  direction;
+   u_int32_t count;
+   u_int32_t buffer_addr;
+   u_int8_t  total_packets;
+   u_int8_t  packet_num;
+   u_int16_t reserved;
 } IPS_FLASHFW_CMD, *PIPS_FLASHFW_CMD;
 
 typedef struct {
-   u8     op_code;
-   u8     command_id;
-   u8     type;
-   u8     direction;
-   u32    count;
-   u32    buffer_addr;
-   u32    offset;
+   u_int8_t  op_code;
+   u_int8_t  command_id;
+   u_int8_t  type;
+   u_int8_t  direction;
+   u_int32_t count;
+   u_int32_t buffer_addr;
+   u_int32_t offset;
 } IPS_FLASHBIOS_CMD, *PIPS_FLASHBIOS_CMD;
 
 typedef union {
-   IPS_IO_CMD         basic_io;
-   IPS_LD_CMD         logical_info;
-   IPS_IOCTL_CMD      ioctl_info;
-   IPS_DCDB_CMD       dcdb;
-   IPS_CS_CMD         config_sync;
-   IPS_US_CMD         unlock_stripe;
-   IPS_FC_CMD         flush_cache;
-   IPS_STATUS_CMD     status;
-   IPS_NVRAM_CMD      nvram;
-   IPS_FFDC_CMD       ffdc;
+   IPS_IO_CMD        basic_io;
+   IPS_LD_CMD        logical_info;
+   IPS_IOCTL_CMD     ioctl_info;
+   IPS_DCDB_CMD      dcdb;
+   IPS_CS_CMD        config_sync;
+   IPS_US_CMD        unlock_stripe;
+   IPS_FC_CMD        flush_cache;
+   IPS_STATUS_CMD    status;
+   IPS_NVRAM_CMD     nvram;
+   IPS_FFDC_CMD      ffdc;
    IPS_FLASHFW_CMD    flashfw;
    IPS_FLASHBIOS_CMD  flashbios;
 } IPS_HOST_COMMAND, *PIPS_HOST_COMMAND;
 
 typedef struct {
-   u8         logical_id;
-   u8         reserved;
-   u8         raid_level;
-   u8         state;
-   u32        sector_count;
+   u_int8_t  logical_id;
+   u_int8_t  reserved;
+   u_int8_t  raid_level;
+   u_int8_t  state;
+   u_int32_t sector_count;
 } IPS_DRIVE_INFO, *PIPS_DRIVE_INFO;
 
 typedef struct {
-   u8             no_of_log_drive;
-   u8             reserved[3];
+   u_int8_t       no_of_log_drive;
+   u_int8_t       reserved[3];
    IPS_DRIVE_INFO drive_info[IPS_MAX_LD];
 } IPS_LD_INFO, *PIPS_LD_INFO;
 
 typedef struct {
-   u8         device_address;
-   u8         cmd_attribute;
-   u16        transfer_length;
-   u32        buffer_pointer;
-   u8         cdb_length;
-   u8         sense_length;
-   u8         sg_count;
-   u8         reserved;
-   u8         scsi_cdb[12];
-   u8         sense_info[64];
-   u8         scsi_status;
-   u8         reserved2[3];
+   u_int8_t   device_address;
+   u_int8_t   cmd_attribute;
+   u_int16_t  transfer_length;
+   u_int32_t  buffer_pointer;
+   u_int8_t   cdb_length;
+   u_int8_t   sense_length;
+   u_int8_t   sg_count;
+   u_int8_t   reserved;
+   u_int8_t   scsi_cdb[12];
+   u_int8_t   sense_info[64];
+   u_int8_t   scsi_status;
+   u_int8_t   reserved2[3];
 } IPS_DCDB_TABLE, *PIPS_DCDB_TABLE;
 
 typedef union {
    struct {
-      volatile u8  reserved;
-      volatile u8  command_id;
-      volatile u8  basic_status;
-      volatile u8  extended_status;
+      volatile u_int8_t  reserved;
+      volatile u_int8_t  command_id;
+      volatile u_int8_t  basic_status;
+      volatile u_int8_t  extended_status;
    } fields;
 
-   volatile u32    value;
+   volatile u_int32_t    value;
 } IPS_STATUS, *PIPS_STATUS;
 
 typedef struct {
@@ -629,233 +682,234 @@
    volatile PIPS_STATUS p_status_start;
    volatile PIPS_STATUS p_status_end;
    volatile PIPS_STATUS p_status_tail;
-   volatile u32         hw_status_start;
-   volatile u32         hw_status_tail;
+   volatile u_int32_t   hw_status_start;
+   volatile u_int32_t   hw_status_tail;
    IPS_LD_INFO          logical_drive_info;
 } IPS_ADAPTER, *PIPS_ADAPTER;
 
 typedef struct {
-   u8        ucLogDriveCount;
-   u8        ucMiscFlag;
-   u8        ucSLTFlag;
-   u8        ucBSTFlag;
-   u8        ucPwrChgCnt;
-   u8        ucWrongAdrCnt;
-   u8        ucUnidentCnt;
-   u8        ucNVramDevChgCnt;
-   u8        CodeBlkVersion[8];
-   u8        BootBlkVersion[8];
-   u32       ulDriveSize[IPS_MAX_LD];
-   u8        ucConcurrentCmdCount;
-   u8        ucMaxPhysicalDevices;
-   u16       usFlashRepgmCount;
-   u8        ucDefunctDiskCount;
-   u8        ucRebuildFlag;
-   u8        ucOfflineLogDrvCount;
-   u8        ucCriticalDrvCount;
-   u16       usConfigUpdateCount;
-   u8        ucBlkFlag;
-   u8        reserved;
-   u16       usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
+   u_int8_t  ucLogDriveCount;
+   u_int8_t  ucMiscFlag;
+   u_int8_t  ucSLTFlag;
+   u_int8_t  ucBSTFlag;
+   u_int8_t  ucPwrChgCnt;
+   u_int8_t  ucWrongAdrCnt;
+   u_int8_t  ucUnidentCnt;
+   u_int8_t  ucNVramDevChgCnt;
+   u_int8_t  CodeBlkVersion[8];
+   u_int8_t  BootBlkVersion[8];
+   u_int32_t ulDriveSize[IPS_MAX_LD];
+   u_int8_t  ucConcurrentCmdCount;
+   u_int8_t  ucMaxPhysicalDevices;
+   u_int16_t usFlashRepgmCount;
+   u_int8_t  ucDefunctDiskCount;
+   u_int8_t  ucRebuildFlag;
+   u_int8_t  ucOfflineLogDrvCount;
+   u_int8_t  ucCriticalDrvCount;
+   u_int16_t usConfigUpdateCount;
+   u_int8_t  ucBlkFlag;
+   u_int8_t  reserved;
+   u_int16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
 } IPS_ENQ, *PIPS_ENQ;
 
 typedef struct {
-   u8        ucInitiator;
-   u8        ucParameters;
-   u8        ucMiscFlag;
-   u8        ucState;
-   u32       ulBlockCount;
-   u8        ucDeviceId[28];
+   u_int8_t  ucInitiator;
+   u_int8_t  ucParameters;
+   u_int8_t  ucMiscFlag;
+   u_int8_t  ucState;
+   u_int32_t ulBlockCount;
+   u_int8_t  ucDeviceId[28];
 } IPS_DEVSTATE, *PIPS_DEVSTATE;
 
 typedef struct {
-   u8        ucChn;
-   u8        ucTgt;
-   u16       ucReserved;
-   u32       ulStartSect;
-   u32       ulNoOfSects;
+   u_int8_t  ucChn;
+   u_int8_t  ucTgt;
+   u_int16_t ucReserved;
+   u_int32_t ulStartSect;
+   u_int32_t ulNoOfSects;
 } IPS_CHUNK, *PIPS_CHUNK;
 
 typedef struct {
-   u16       ucUserField;
-   u8        ucState;
-   u8        ucRaidCacheParam;
-   u8        ucNoOfChunkUnits;
-   u8        ucStripeSize;
-   u8        ucParams;
-   u8        ucReserved;
-   u32       ulLogDrvSize;
+   u_int16_t ucUserField;
+   u_int8_t  ucState;
+   u_int8_t  ucRaidCacheParam;
+   u_int8_t  ucNoOfChunkUnits;
+   u_int8_t  ucStripeSize;
+   u_int8_t  ucParams;
+   u_int8_t  ucReserved;
+   u_int32_t ulLogDrvSize;
    IPS_CHUNK chunk[IPS_MAX_CHUNKS];
 } IPS_LD, *PIPS_LD;
 
 typedef struct {
-   u8        board_disc[8];
-   u8        processor[8];
-   u8        ucNoChanType;
-   u8        ucNoHostIntType;
-   u8        ucCompression;
-   u8        ucNvramType;
-   u32       ulNvramSize;
+   u_int8_t  board_disc[8];
+   u_int8_t  processor[8];
+   u_int8_t  ucNoChanType;
+   u_int8_t  ucNoHostIntType;
+   u_int8_t  ucCompression;
+   u_int8_t  ucNvramType;
+   u_int32_t ulNvramSize;
 } IPS_HARDWARE, *PIPS_HARDWARE;
 
 typedef struct {
-   u8             ucLogDriveCount;
-   u8             ucDateD;
-   u8             ucDateM;
-   u8             ucDateY;
-   u8             init_id[4];
-   u8             host_id[12];
-   u8             time_sign[8];
-
-   struct {
-      u32         usCfgDrvUpdateCnt:16;
-      u32         ConcurDrvStartCnt:4;
-      u32         StartupDelay:4;
-      u32         auto_rearrange:1;
-      u32         cd_boot:1;
-      u32         cluster:1;
-      u32         reserved:5;
-   } UserOpt;
-
-   u16            user_field;
-   u8             ucRebuildRate;
-   u8             ucReserve;
+   u_int8_t       ucLogDriveCount;
+   u_int8_t       ucDateD;
+   u_int8_t       ucDateM;
+   u_int8_t       ucDateY;
+   u_int8_t       init_id[4];
+   u_int8_t       host_id[12];
+   u_int8_t       time_sign[8];
+   u_int32_t      UserOpt;
+   u_int16_t      user_field;
+   u_int8_t       ucRebuildRate;
+   u_int8_t       ucReserve;
    IPS_HARDWARE   hardware_disc;
    IPS_LD         logical_drive[IPS_MAX_LD];
    IPS_DEVSTATE   dev[IPS_MAX_CHANNELS][IPS_MAX_TARGETS+1];
-   u8             reserved[512];
-
+   u_int8_t       reserved[512];
 } IPS_CONF, *PIPS_CONF;
 
 typedef struct {
-   u32        signature;
-   u8         reserved;
-   u8         adapter_slot;
-   u16        adapter_type;
-   u8         bios_high[4];
-   u8         bios_low[4];
-   u16        reserved2;
-   u8         reserved3;
-   u8         operating_system;
-   u8         driver_high[4];
-   u8         driver_low[4];
-   u8         reserved4[100];
+   u_int32_t  signature;
+   u_int8_t   reserved;
+   u_int8_t   adapter_slot;
+   u_int16_t  adapter_type;
+   u_int8_t   bios_high[4];
+   u_int8_t   bios_low[4];
+   u_int16_t  reserved2;
+   u_int8_t   reserved3;
+   u_int8_t   operating_system;
+   u_int8_t   driver_high[4];
+   u_int8_t   driver_low[4];
+   u_int8_t   reserved4[100];
 } IPS_NVRAM_P5, *PIPS_NVRAM_P5;
 
 typedef struct _IPS_SUBSYS {
-   u32        param[128];
+   u_int32_t  param[128];
 } IPS_SUBSYS, *PIPS_SUBSYS;
 
+/**
+ ** SCSI Structures
+ **/
+
 /*
  * Inquiry Data Format
  */
 typedef struct {
-   u8        DeviceType:5;
-   u8        DeviceTypeQualifier:3;
-   u8        DeviceTypeModifier:7;
-   u8        RemoveableMedia:1;
-   u8        Versions;
-   u8        ResponseDataFormat;
-   u8        AdditionalLength;
-   u16       Reserved;
-   u8        SoftReset:1;
-   u8        CommandQueue:1;
-   u8        Reserved2:1;
-   u8        LinkedCommands:1;
-   u8        Synchronous:1;
-   u8        Wide16Bit:1;
-   u8        Wide32Bit:1;
-   u8        RelativeAddressing:1;
-   u8        VendorId[8];
-   u8        ProductId[16];
-   u8        ProductRevisionLevel[4];
-   u8        VendorSpecific[20];
-   u8        Reserved3[40];
-} IPS_INQ_DATA, *PIPS_INQ_DATA;
+   u_int8_t  DeviceType;
+   u_int8_t  DeviceTypeQualifier;
+   u_int8_t  Version;
+   u_int8_t  ResponseDataFormat;
+   u_int8_t  AdditionalLength;
+   u_int8_t  Reserved;
+   u_int8_t  Flags[2];
+   char      VendorId[8];
+   char      ProductId[16];
+   char      ProductRevisionLevel[4];
+} IPS_SCSI_INQ_DATA, *PIPS_SCSI_INQ_DATA;
 
 /*
  * Read Capacity Data Format
  */
 typedef struct {
-   u32       lba;
-   u32       len;
-} IPS_CAPACITY;
-
-/*
- * Sense Data Format
- */
-typedef struct {
-   u8        pg_pc:6;       /* Page Code                    */
-   u8        pg_res1:2;     /* Reserved                     */
-   u8        pg_len;        /* Page Length                  */
-   u16       pg_trk_z;      /* Tracks per zone              */
-   u16       pg_asec_z;     /* Alternate sectors per zone   */
-   u16       pg_atrk_z;     /* Alternate tracks per zone    */
-   u16       pg_atrk_v;     /* Alternate tracks per volume  */
-   u16       pg_sec_t;      /* Sectors per track            */
-   u16       pg_bytes_s;    /* Bytes per physical sectors   */
-   u16       pg_intl;       /* Interleave                   */
-   u16       pg_trkskew;    /* Track skew factor            */
-   u16       pg_cylskew;    /* Cylinder Skew Factor         */
-   u32       pg_res2:27;    /* Reserved                     */
-   u32       pg_ins:1;      /* Inhibit Slave                */
-   u32       pg_surf:1;     /* Allocate Surface Sectors     */
-   u32       pg_rmb:1;      /* Removeable                   */
-   u32       pg_hsec:1;     /* Hard sector formatting       */
-   u32       pg_ssec:1;     /* Soft sector formatting       */
-} IPS_DADF;
-
-typedef struct {
-   u8        pg_pc:6;        /* Page Code                     */
-   u8        pg_res1:2;      /* Reserved                      */
-   u8        pg_len;         /* Page Length                   */
-   u16       pg_cylu;        /* Number of cylinders (upper)   */
-   u8        pg_cyll;        /* Number of cylinders (lower)   */
-   u8        pg_head;        /* Number of heads               */
-   u16       pg_wrpcompu;    /* Write precomp (upper)         */
-   u32       pg_wrpcompl:8;  /* Write precomp (lower)         */
-   u32       pg_redwrcur:24; /* Reduced write current         */
-   u32       pg_drstep:16;   /* Drive step rate               */
-   u32       pg_landu:16;    /* Landing zone cylinder (upper) */
-   u32       pg_landl:8;     /* Landing zone cylinder (lower) */
-   u32       pg_res2:24;     /* Reserved                      */
-} IPS_RDDG;
-
-struct ips_blk_desc {
-   u8       bd_dencode;
-   u8       bd_nblks1;
-   u8       bd_nblks2;
-   u8       bd_nblks3;
-   u8       bd_res;
-   u8       bd_blen1;
-   u8       bd_blen2;
-   u8       bd_blen3;
-};
-
-typedef struct {
-   u8       plh_len;   /* Data length             */
-   u8       plh_type;  /* Medium type             */
-   u8       plh_res:7; /* Reserved                */
-   u8       plh_wp:1;  /* Write protect           */
-   u8       plh_bdl;   /* Block descriptor length */
-} ips_sense_plh_t;
+   u_int32_t lba;
+   u_int32_t len;
+} IPS_SCSI_CAPACITY;
+
+/*
+ * Request Sense Data Format
+ */
+typedef struct {
+   u_int8_t  ResponseCode;
+   u_int8_t  SegmentNumber;
+   u_int8_t  Flags;
+   u_int8_t  Information[4];
+   u_int8_t  AdditionalLength;
+   u_int8_t  CommandSpecific[4];
+   u_int8_t  AdditionalSenseCode;
+   u_int8_t  AdditionalSenseCodeQual;
+   u_int8_t  FRUCode;
+   u_int8_t  SenseKeySpecific[3];
+} IPS_SCSI_REQSEN;
+
+/*
+ * Sense Data Format - Page 3
+ */
+typedef struct {
+   u_int8_t  PageCode;
+   u_int8_t  PageLength;
+   u_int16_t TracksPerZone;
+   u_int16_t AltSectorsPerZone;
+   u_int16_t AltTracksPerZone;
+   u_int16_t AltTracksPerVolume;
+   u_int16_t SectorsPerTrack;
+   u_int16_t BytesPerSector;
+   u_int16_t Interleave;
+   u_int16_t TrackSkew;
+   u_int16_t CylinderSkew;
+   u_int8_t  flags;
+   u_int8_t  reserved[3];
+} IPS_SCSI_MODE_PAGE3;
+
+/*
+ * Sense Data Format - Page 4
+ */
+typedef struct {
+   u_int8_t  PageCode;
+   u_int8_t  PageLength;
+   u_int16_t CylindersHigh;
+   u_int8_t  CylindersLow;
+   u_int8_t  Heads;
+   u_int16_t WritePrecompHigh;
+   u_int8_t  WritePrecompLow;
+   u_int16_t ReducedWriteCurrentHigh;
+   u_int8_t  ReducedWriteCurrentLow;
+   u_int16_t StepRate;
+   u_int16_t LandingZoneHigh;
+   u_int8_t  LandingZoneLow;
+   u_int8_t  flags;
+   u_int8_t  RotationalOffset;
+   u_int8_t  Reserved;
+   u_int16_t MediumRotationRate;
+   u_int8_t  Reserved2[2];
+} IPS_SCSI_MODE_PAGE4;
+
+/*
+ * Sense Data Format - Block Descriptor (DASD)
+ */
+typedef struct {
+   u_int32_t NumberOfBlocks;
+   u_int8_t  DensityCode;
+   u_int16_t BlockLengthHigh;
+   u_int8_t  BlockLengthLow;
+} IPS_SCSI_MODE_PAGE_BLKDESC;
+
+/*
+ * Sense Data Format - Mode Page Header
+ */
+typedef struct {
+   u_int8_t  DataLength;
+   u_int8_t  MediumType;
+   u_int8_t  Reserved;
+   u_int8_t  BlockDescLength;
+} IPS_SCSI_MODE_PAGE_HEADER;
 
 typedef struct {
-   ips_sense_plh_t     plh;
-   struct ips_blk_desc blk_desc;
+   IPS_SCSI_MODE_PAGE_HEADER  hdr;
+   IPS_SCSI_MODE_PAGE_BLKDESC blkdesc;
 
    union {
-      IPS_DADF      pg3;
-      IPS_RDDG      pg4;
+      IPS_SCSI_MODE_PAGE3 pg3;
+      IPS_SCSI_MODE_PAGE4 pg4;
    } pdata;
-} ips_mdata_t;
+} IPS_SCSI_MODE_PAGE_DATA;
 
 /*
  * Scatter Gather list format
  */
 typedef struct ips_sglist {
-   u32       address;
-   u32       length;
+   u_int32_t address;
+   u_int32_t length;
 } IPS_SG_LIST, *PIPS_SG_LIST;
 
 typedef struct _IPS_INFOSTR {
@@ -874,23 +928,24 @@
 
 typedef struct {
    void             *userbuffer;
-   u32               usersize;
+   u_int32_t         usersize;
    void             *kernbuffer;
-   u32               kernsize;
+   u_int32_t         kernsize;
    void             *ha;
    void             *SC;
    void             *pt;
    struct semaphore *sem;
-   u32               offset;
-   u32               retcode;
+   u_int32_t         offset;
+   u_int32_t         retcode;
 } IPS_FLASH_DATA;
 
 /*
  * Status Info
  */
 typedef struct ips_stat {
-   u32       residue_len;
-   u32       scb_addr;
+   u_int32_t residue_len;
+   void     *scb_addr;
+   u_int8_t  padding[12 - sizeof(void *)];
 } ips_stat_t;
 
 /*
@@ -899,8 +954,8 @@
 typedef struct ips_scb_queue {
    struct ips_scb *head;
    struct ips_scb *tail;
-   u32             count;
-   u32             cpu_flags;
+   u_int32_t       count;
+   u_int32_t       cpu_flags;
    spinlock_t      lock;
 } ips_scb_queue_t;
 
@@ -910,8 +965,8 @@
 typedef struct ips_wait_queue {
    Scsi_Cmnd      *head;
    Scsi_Cmnd      *tail;
-   u32             count;
-   u32             cpu_flags;
+   u_int32_t       count;
+   u_int32_t       cpu_flags;
    spinlock_t      lock;
 } ips_wait_queue_t;
 
@@ -924,8 +979,8 @@
 typedef struct ips_copp_queue {
    struct ips_copp_wait_item *head;
    struct ips_copp_wait_item *tail;
-   u32                        count;
-   u32                        cpu_flags;
+   u_int32_t                  count;
+   u_int32_t                  cpu_flags;
    spinlock_t                 lock;
 } ips_copp_queue_t;
 
@@ -933,33 +988,33 @@
 struct ips_ha;
 
 typedef struct {
-   int  (*reset)(struct ips_ha *);
-   int  (*issue)(struct ips_ha *, struct ips_scb *);
-   int  (*isinit)(struct ips_ha *);
-   int  (*isintr)(struct ips_ha *);
-   int  (*init)(struct ips_ha *);
-   int  (*erasebios)(struct ips_ha *);
-   int  (*programbios)(struct ips_ha *, char *, u32, u32);
-   int  (*verifybios)(struct ips_ha *, char *, u32, u32);
-   u32  (*statupd)(struct ips_ha *);
-   void (*statinit)(struct ips_ha *);
-   void (*intr)(struct ips_ha *);
-   void (*enableint)(struct ips_ha *);
+   int       (*reset)(struct ips_ha *);
+   int       (*issue)(struct ips_ha *, struct ips_scb *);
+   int       (*isinit)(struct ips_ha *);
+   int       (*isintr)(struct ips_ha *);
+   int       (*init)(struct ips_ha *);
+   int       (*erasebios)(struct ips_ha *);
+   int       (*programbios)(struct ips_ha *, char *, u_int32_t, u_int32_t);
+   int       (*verifybios)(struct ips_ha *, char *, u_int32_t, u_int32_t);
+   void      (*statinit)(struct ips_ha *);
+   void      (*intr)(struct ips_ha *);
+   void      (*enableint)(struct ips_ha *);
+   u_int32_t (*statupd)(struct ips_ha *);
 } ips_hw_func_t;
 
 typedef struct ips_ha {
-   u8                 ha_id[IPS_MAX_CHANNELS+1];
-   u32                dcdb_active[IPS_MAX_CHANNELS];
-   u32                io_addr;            /* Base I/O address           */
-   u8                 irq;                /* IRQ for adapter            */
-   u8                 ntargets;           /* Number of targets          */
-   u8                 nbus;               /* Number of buses            */
-   u8                 nlun;               /* Number of Luns             */
-   u16                ad_type;            /* Adapter type               */
-   u16                host_num;           /* Adapter number             */
-   u32                max_xfer;           /* Maximum Xfer size          */
-   u32                max_cmds;           /* Max concurrent commands    */
-   u32                num_ioctl;          /* Number of Ioctls           */
+   u_int8_t           ha_id[IPS_MAX_CHANNELS+1];
+   u_int32_t          dcdb_active[IPS_MAX_CHANNELS];
+   u_int32_t          io_addr;            /* Base I/O address           */
+   u_int8_t           irq;                /* IRQ for adapter            */
+   u_int8_t           ntargets;           /* Number of targets          */
+   u_int8_t           nbus;               /* Number of buses            */
+   u_int8_t           nlun;               /* Number of Luns             */
+   u_int16_t          ad_type;            /* Adapter type               */
+   u_int16_t          host_num;           /* Adapter number             */
+   u_int32_t          max_xfer;           /* Maximum Xfer size          */
+   u_int32_t          max_cmds;           /* Max concurrent commands    */
+   u_int32_t          num_ioctl;          /* Number of Ioctls           */
    ips_stat_t         sp;                 /* Status packer pointer      */
    struct ips_scb    *scbs;               /* Array of all CCBS          */
    struct ips_scb    *scb_freelist;       /* SCB free list              */
@@ -973,23 +1028,23 @@
    IPS_NVRAM_P5      *nvram;              /* NVRAM page 5 data          */
    IPS_SUBSYS        *subsys;             /* Subsystem parameters       */
    char              *ioctl_data;         /* IOCTL data area            */
-   u32                ioctl_datasize;     /* IOCTL data size            */
-   u32                cmd_in_progress;    /* Current command in progress*/
-   long               flags;              /* HA flags                   */
-   u8                 waitflag;           /* are we waiting for cmd     */
-   u8                 active;
-   u16                reset_count;        /* number of resets           */
-   u32                last_ffdc;          /* last time we sent ffdc info*/
-   u8                 revision_id;        /* Revision level             */
-   u16                device_id;          /* PCI device ID              */
-   u8                 slot_num;           /* PCI Slot Number            */
-   u16                subdevice_id;       /* Subsystem device ID        */
-   u8                 ioctl_order;        /* Number of pages in ioctl   */
-   u8                 reserved2;          /* Empty                      */
-   u8                 bios_version[8];    /* BIOS Revision              */
-   u32                mem_addr;           /* Memory mapped address      */
-   u32                io_len;             /* Size of IO Address         */
-   u32                mem_len;            /* Size of memory address     */
+   u_int32_t          ioctl_datasize;     /* IOCTL data size            */
+   u_int32_t          cmd_in_progress;    /* Current command in progress*/
+   unsigned long      flags;              /* HA flags                   */
+   u_int8_t           waitflag;           /* are we waiting for cmd     */
+   u_int8_t           active;
+   u_int16_t          reset_count;        /* number of resets           */
+   u_int32_t          last_ffdc;          /* last time we sent ffdc info*/
+   u_int8_t           revision_id;        /* Revision level             */
+   u_int16_t          device_id;          /* PCI device ID              */
+   u_int8_t           slot_num;           /* PCI Slot Number            */
+   u_int16_t          subdevice_id;       /* Subsystem device ID        */
+   u_int8_t           ioctl_order;        /* Number of pages in ioctl   */
+   u_int8_t           reserved2;          /* Empty                      */
+   u_int8_t           bios_version[8];    /* BIOS Revision              */
+   u_int32_t          mem_addr;           /* Memory mapped address      */
+   u_int32_t          io_len;             /* Size of IO Address         */
+   u_int32_t          mem_len;            /* Size of memory address     */
    char              *mem_ptr;            /* Memory mapped Ptr          */
    char              *ioremap_ptr;        /* ioremapped memory pointer  */
    ips_hw_func_t      func;               /* hw function pointers       */
@@ -997,6 +1052,8 @@
    spinlock_t         scb_lock;
    spinlock_t         copp_lock;
    spinlock_t         ips_lock;
+   struct semaphore   ioctl_sem;          /* Semaphore for new IOCTL's  */
+   struct semaphore   flash_ioctl_sem;    /* Semaphore for Flashing     */
    char              *save_ioctl_data;    /* Save Area for ioctl_data   */
    u8                 save_ioctl_order;   /* Save Area for ioctl_order  */
    u32                save_ioctl_datasize;/* Save Area for ioctl_datasize */
@@ -1010,21 +1067,21 @@
 typedef struct ips_scb {
    IPS_HOST_COMMAND  cmd;
    IPS_DCDB_TABLE    dcdb;
-   u8                target_id;
-   u8                bus;
-   u8                lun;
-   u8                cdb[12];
-   u32               scb_busaddr;
-   u32               data_busaddr;
-   u32               timeout;
-   u8                basic_status;
-   u8                extended_status;
-   u8                breakup;
-   u8                sg_break;
-   u32               data_len;
-   u32               sg_len;
-   u32               flags;
-   u32               op_code;
+   u_int8_t          target_id;
+   u_int8_t          bus;
+   u_int8_t          lun;
+   u_int8_t          cdb[12];
+   u_int32_t         scb_busaddr;
+   u_int32_t         data_busaddr;
+   u_int32_t         timeout;
+   u_int8_t          basic_status;
+   u_int8_t          extended_status;
+   u_int8_t          breakup;
+   u_int8_t          sg_break;
+   u_int32_t         data_len;
+   u_int32_t         sg_len;
+   u_int32_t         flags;
+   u_int32_t         op_code;
    IPS_SG_LIST      *sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
@@ -1035,20 +1092,20 @@
 typedef struct ips_scb_pt {
    IPS_HOST_COMMAND  cmd;
    IPS_DCDB_TABLE    dcdb;
-   u8                target_id;
-   u8                bus;
-   u8                lun;
-   u8                cdb[12];
-   u32               scb_busaddr;
-   u32               data_busaddr;
-   u32               timeout;
-   u8                basic_status;
-   u8                extended_status;
-   u16               breakup;
-   u32               data_len;
-   u32               sg_len;
-   u32               flags;
-   u32               op_code;
+   u_int8_t          target_id;
+   u_int8_t          bus;
+   u_int8_t          lun;
+   u_int8_t          cdb[12];
+   u_int32_t         scb_busaddr;
+   u_int32_t         data_busaddr;
+   u_int32_t         timeout;
+   u_int8_t          basic_status;
+   u_int8_t          extended_status;
+   u_int16_t         breakup;
+   u_int32_t         data_len;
+   u_int32_t         sg_len;
+   u_int32_t         flags;
+   u_int32_t         op_code;
    IPS_SG_LIST      *sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
@@ -1059,16 +1116,16 @@
  * Passthru Command Format
  */
 typedef struct {
-   u8            CoppID[4];
-   u32           CoppCmd;
-   u32           PtBuffer;
-   u8           *CmdBuffer;
-   u32           CmdBSize;
+   u_int8_t      CoppID[4];
+   u_int32_t     CoppCmd;
+   u_int32_t     PtBuffer;
+   u_int8_t     *CmdBuffer;
+   u_int32_t     CmdBSize;
    ips_scb_pt_t  CoppCP;
-   u32           TimeOut;
-   u8            BasicStatus;
-   u8            ExtendedStatus;
-   u16           reserved;
+   u_int32_t     TimeOut;
+   u_int8_t      BasicStatus;
+   u_int8_t      ExtendedStatus;
+   u_int16_t     reserved;
 } ips_passthru_t;
 
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/lasi700.c linux/drivers/scsi/lasi700.c
--- v2.4.10/linux/drivers/scsi/lasi700.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/lasi700.c	Sun Sep 30 12:26:08 2001
@@ -109,6 +109,7 @@
 static int __initdata host_count = 0;
 static struct parisc_device_id lasi700_scsi_tbl[] = {
 	LASI700_ID_TABLE,
+	LASI710_ID_TABLE,
 	{ 0 }
 };
 
@@ -136,32 +137,48 @@
 {
 	unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
 	int irq = busdevice_alloc_irq(dev);
+	char *driver_name;
 	struct Scsi_Host *host;
 	struct NCR_700_Host_Parameters *hostdata =
 		kmalloc(sizeof(struct NCR_700_Host_Parameters),
 			GFP_KERNEL);
+	if(dev->id.sversion == LASI_700_SVERSION) {
+		driver_name = "lasi700";
+	} else {
+		driver_name = "lasi710";
+	}
 	if(hostdata == NULL) {
-		printk(KERN_ERR "lasi700: Failed to allocate host data\n");
+		printk(KERN_ERR "%s: Failed to allocate host data\n",
+		       driver_name);
 		return 1;
 	}
 	memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
-	if(request_mem_region(base, 64, "lasi700") == NULL) {
-		printk(KERN_ERR "lasi700: Failed to claim memory region\n");
+	if(request_mem_region(base, 64, driver_name) == NULL) {
+		printk(KERN_ERR "%s: Failed to claim memory region\n",
+		       driver_name);
 		kfree(hostdata);
 		return 1;
 	}
 	hostdata->base = base;
 	hostdata->differential = 0;
-	hostdata->clock = LASI700_CLOCK;
-	hostdata->force_le_on_be = 1;
+	if(dev->id.sversion == LASI_700_SVERSION) {
+		hostdata->clock = LASI700_CLOCK;
+		hostdata->force_le_on_be = 1;
+	} else {
+		hostdata->clock = LASI710_CLOCK;
+		hostdata->force_le_on_be = 0;
+		hostdata->chip710 = 1;
+		hostdata->dmode_extra = DMODE_FC2;
+	}
 	if((host = NCR_700_detect(host_tpnt, hostdata)) == NULL) {
 		kfree(hostdata);
 		release_mem_region(host->base, 64);
 		return 1;
 	}
 	host->irq = irq;
-	if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "lasi700", host)) {
-		printk(KERN_ERR "lasi700: irq problem, detatching\n");
+	if(request_irq(irq, NCR_700_intr, SA_SHIRQ, driver_name, host)) {
+		printk(KERN_ERR "%s: irq problem, detatching\n",
+		       driver_name);
 		scsi_unregister(host);
 		NCR_700_release(host);
 		return 1;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/lasi700.h linux/drivers/scsi/lasi700.h
--- v2.4.10/linux/drivers/scsi/lasi700.h	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/lasi700.h	Sun Sep 30 12:26:08 2001
@@ -38,9 +38,19 @@
 	this_id:	7,			\
 }
 
+#define LASI_710_SVERSION	0x082
+#define LASI_700_SVERSION	0x071
+
 #define LASI700_ID_TABLE {			\
 	hw_type:	HPHW_FIO,		\
-	sversion:	0x071,			\
+	sversion:	LASI_700_SVERSION,	\
+	hversion:	HVERSION_ANY_ID,	\
+	hversion_rev:	HVERSION_REV_ANY_ID,	\
+}
+
+#define LASI710_ID_TABLE {			\
+	hw_type:	HPHW_FIO,		\
+	sversion:	LASI_710_SVERSION,	\
 	hversion:	HVERSION_ANY_ID,	\
 	hversion_rev:	HVERSION_REV_ANY_ID,	\
 }
@@ -52,6 +62,7 @@
 }
 
 #define LASI700_CLOCK	25
+#define LASI710_CLOCK	40
 #define LASI_SCSI_CORE_OFFSET 0x100
 
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
--- v2.4.10/linux/drivers/scsi/megaraid.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/megaraid.c	Sun Sep 30 12:26:07 2001
@@ -552,6 +552,8 @@
 
 MODULE_AUTHOR ("American Megatrends Inc.");
 MODULE_DESCRIPTION ("AMI MegaRAID driver");
+MODULE_LICENSE("GPL");
+
 
 #define DRIVER_LOCK_T
 #define DRIVER_LOCK_INIT(p)
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- v2.4.10/linux/drivers/scsi/ncr53c8xx.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/ncr53c8xx.c	Sun Sep 30 12:26:07 2001
@@ -116,10 +116,7 @@
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
-
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/system.h>
@@ -9270,6 +9267,7 @@
 /*
 **	Module stuff
 */
+MODULE_LICENSE("GPL");
 
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
 static
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/osst.c linux/drivers/scsi/osst.c
--- v2.4.10/linux/drivers/scsi/osst.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/osst.c	Sun Sep 30 12:26:07 2001
@@ -83,6 +83,8 @@
 #ifdef MODULE
 MODULE_AUTHOR("Willem Riede");
 MODULE_DESCRIPTION("OnStream SCSI Tape Driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(buffer_kbs, "i");
 MODULE_PARM(write_threshold_kbs, "i");
 MODULE_PARM(max_buffers, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c
--- v2.4.10/linux/drivers/scsi/pas16.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/pas16.c	Sun Sep 30 12:26:07 2001
@@ -110,9 +110,7 @@
  *   (IRQ_AUTO == 254, IRQ_NONE == 255 in NCR5380.h)
  */
  
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <asm/system.h>
 #include <linux/signal.h>
@@ -609,3 +607,4 @@
 MODULE_PARM(pas16_addr, "h");
 MODULE_PARM(pas16_irq, "i");
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c
--- v2.4.10/linux/drivers/scsi/pci2000.c	Fri Apr 27 14:06:02 2001
+++ linux/drivers/scsi/pci2000.c	Sun Sep 30 12:26:07 2001
@@ -858,6 +858,7 @@
 	}
 
 
+MODULE_LICENSE("BSD without advertisement clause");
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = PCI2000;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/pci2220i.c linux/drivers/scsi/pci2220i.c
--- v2.4.10/linux/drivers/scsi/pci2220i.c	Mon Apr 30 17:13:07 2001
+++ linux/drivers/scsi/pci2220i.c	Sun Sep 30 12:26:07 2001
@@ -2924,6 +2924,7 @@
 	return 0;
 	}
 
+MODULE_LICENSE("BSD without advertising clause");
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = PCI2220I;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/pcmcia/aha152x_stub.c linux/drivers/scsi/pcmcia/aha152x_stub.c
--- v2.4.10/linux/drivers/scsi/pcmcia/aha152x_stub.c	Fri Mar  2 18:38:39 2001
+++ linux/drivers/scsi/pcmcia/aha152x_stub.c	Sun Sep 30 12:26:07 2001
@@ -92,6 +92,8 @@
 MODULE_PARM(reset_delay, "i");
 MODULE_PARM(ext_trans, "i");
 
+MODULE_LICENSE("Dual MPL/GPL");
+
 /*====================================================================*/
 
 typedef struct scsi_info_t {
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c
--- v2.4.10/linux/drivers/scsi/pcmcia/nsp_cs.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/pcmcia/nsp_cs.c	Sun Sep 30 12:26:07 2001
@@ -66,6 +66,8 @@
 
 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
+MODULE_LICENSE("GPL");
+
 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
 
 #ifdef PCMCIA_DEBUG
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
--- v2.4.10/linux/drivers/scsi/ppa.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/ppa.c	Sun Sep 30 12:26:07 2001
@@ -1145,3 +1145,4 @@
     printk("ppa: No devices found, aborting driver load.\n");
     return 1;
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/psi240i.c linux/drivers/scsi/psi240i.c
--- v2.4.10/linux/drivers/scsi/psi240i.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/psi240i.c	Sun Sep 30 12:26:07 2001
@@ -714,6 +714,7 @@
 	return 0;
 	}
 
+MODULE_LICENSE("GPL");
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = PSI240I;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/qla1280.c linux/drivers/scsi/qla1280.c
--- v2.4.10/linux/drivers/scsi/qla1280.c	Tue Jul  3 17:08:20 2001
+++ linux/drivers/scsi/qla1280.c	Sun Sep 30 12:26:07 2001
@@ -6812,6 +6812,7 @@
         *cp = '\0';
         return( cp );
 }
+MODULE_LICENSE("GPL");
 
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c
--- v2.4.10/linux/drivers/scsi/qlogicfas.c	Tue May 22 10:23:16 2001
+++ linux/drivers/scsi/qlogicfas.c	Sun Sep 30 12:26:07 2001
@@ -685,6 +685,7 @@
 {
 	return qinfo;
 }
+MODULE_LICENSE("GPL");
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = QLOGICFAS;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- v2.4.10/linux/drivers/scsi/qlogicfc.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/qlogicfc.c	Sun Sep 30 12:26:07 2001
@@ -2259,6 +2259,7 @@
 
 #endif				/* DEBUG_ISP2x00 */
 
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = QLOGICFC;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- v2.4.10/linux/drivers/scsi/qlogicisp.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/qlogicisp.c	Sun Sep 30 12:26:07 2001
@@ -1994,6 +1994,7 @@
 
 #endif /* DEBUG_ISP1020 */
 
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = QLOGICISP;
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.4.10/linux/drivers/scsi/scsi.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/scsi.c	Fri Oct  5 11:19:50 2001
@@ -629,6 +629,7 @@
 	if (++serial_number == 0)
 		serial_number = 1;
 	SCpnt->serial_number = serial_number;
+	SCpnt->pid = scsi_pid++;
 
 	/*
 	 * We will wait MIN_RESET_DELAY clock ticks after the last reset so
@@ -968,6 +969,7 @@
 
 	ASSERT_LOCK(&io_request_lock, 0);
 
+	SCpnt->pid = scsi_pid++;
 	SCpnt->owner = SCSI_OWNER_MIDLEVEL;
 
 	SCSI_LOG_MLQUEUE(4,
@@ -2515,6 +2517,7 @@
 
 MODULE_PARM(scsihosts, "s");
 MODULE_DESCRIPTION("SCSI core");
+MODULE_LICENSE("GPL");
 
 #ifndef MODULE
 int __init scsi_setup(char *str)
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- v2.4.10/linux/drivers/scsi/scsi_debug.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/scsi_debug.c	Sun Sep 30 12:26:07 2001
@@ -805,3 +805,4 @@
  * tab-width: 8
  * End:
  */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- v2.4.10/linux/drivers/scsi/scsi_scan.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/scsi_scan.c	Fri Oct  5 11:23:28 2001
@@ -795,19 +795,7 @@
 	 * other settings, and scan all of them.
 	 */
 	if (bflags & BLIST_SPARSELUN) {
-		/*
-		 * Scanning MAX_SCSI_LUNS units would be a bad idea.
-		 * Any better idea?
-		 * I think we need REPORT LUNS in future to avoid scanning
-		 * of unused LUNs. But, that is another item.
-		 *
-		 * FIXME(eric) - perhaps this should be a kernel configurable?
-		 */
-		if (*max_dev_lun < shpnt->max_lun)
-			*max_dev_lun = shpnt->max_lun;
-		else 	if ((max_scsi_luns >> 1) >= *max_dev_lun)
-				*max_dev_lun += shpnt->max_lun;
-			else	*max_dev_lun = max_scsi_luns;
+		*max_dev_lun = shpnt->max_lun;
 		*sparse_lun = 1;
 		return 1;
 	}
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.4.10/linux/drivers/scsi/sd.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/sd.c	Sun Sep 30 12:26:07 2001
@@ -1409,3 +1409,4 @@
 
 module_init(init_sd);
 module_exit(exit_sd);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- v2.4.10/linux/drivers/scsi/seagate.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/seagate.c	Sun Sep 30 12:26:07 2001
@@ -257,6 +257,8 @@
 MODULE_PARM (base_address, "i");
 MODULE_PARM (controller_type, "b");
 MODULE_PARM (irq, "i");
+MODULE_LICENSE("GPL");
+
 
 #define retcode(result) (((result) << 16) | (message << 8) | status)
 #define STATUS ((u8) isa_readb(st0x_cr_sr))
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v2.4.10/linux/drivers/scsi/sg.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/sg.c	Sun Sep 30 12:26:07 2001
@@ -1373,6 +1373,8 @@
 
 MODULE_AUTHOR("Douglas Gilbert");
 MODULE_DESCRIPTION("SCSI generic (sg) driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(def_reserved_size, "i");
 MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/sim710.c linux/drivers/scsi/sim710.c
--- v2.4.10/linux/drivers/scsi/sim710.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/scsi/sim710.c	Sun Sep 30 12:26:07 2001
@@ -187,6 +187,8 @@
 
 MODULE_AUTHOR("Richard Hirst");
 MODULE_DESCRIPTION("Simple NCR53C710 driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(sim710, "s");
 
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.4.10/linux/drivers/scsi/sr.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/scsi/sr.c	Sun Sep 30 12:26:07 2001
@@ -940,3 +940,4 @@
 
 module_init(init_sr);
 module_exit(exit_sr);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v2.4.10/linux/drivers/scsi/st.c	Mon Aug 27 12:41:44 2001
+++ linux/drivers/scsi/st.c	Wed Oct  3 14:28:50 2001
@@ -12,7 +12,7 @@
    Copyright 1992 - 2001 Kai Makisara
    email Kai.Makisara@metla.fi
 
-   Last modified: Sun Aug 12 12:34:28 2001 by makisara@kai.makisara.local
+   Last modified: Wed Oct  3 22:17:59 2001 by makisara@kai.makisara.local
    Some small formal changes - aeb, 950809
 
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
@@ -21,7 +21,7 @@
    error handling will be discarded.
  */
 
-static char *verstr = "20010812";
+static char *verstr = "20011003";
 
 #include <linux/module.h>
 
@@ -78,6 +78,8 @@
 
 MODULE_AUTHOR("Kai Makisara");
 MODULE_DESCRIPTION("SCSI Tape Driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(buffer_kbs, "i");
 MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size (KB; 32)");
 MODULE_PARM(write_threshold_kbs, "i");
@@ -87,6 +89,8 @@
 MODULE_PARM(max_sg_segs, "i");
 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (32)");
 
+EXPORT_NO_SYMBOLS;
+
 #ifndef MODULE
 static struct st_dev_parm {
 	char *name;
@@ -667,6 +671,7 @@
 
 	if (STp->device->host->hostt->module)
 		__MOD_INC_USE_COUNT(STp->device->host->hostt->module);
+	STp->device->access_count++;
 
 	if (!scsi_block_when_processing_errors(STp->device)) {
 		retval = (-ENXIO);
@@ -907,6 +912,7 @@
 		STp->buffer = NULL;
 	}
 	STp->in_use = 0;
+	STp->device->access_count--;
 	if (STp->device->host->hostt->module)
 	    __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
 	return retval;
@@ -1064,6 +1070,7 @@
 
 	STp->in_use = 0;
 	write_unlock_irqrestore(&st_dev_arr_lock, flags);
+	STp->device->access_count--;
 	if (STp->device->host->hostt->module)
 		__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c
--- v2.4.10/linux/drivers/scsi/sym53c416.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/scsi/sym53c416.c	Sun Sep 30 12:26:07 2001
@@ -847,6 +847,8 @@
 #ifdef MODULE
 
 MODULE_AUTHOR("Lieven Willems");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(sym53c416, "1-2i");
 MODULE_PARM(sym53c416_1, "1-2i");
 MODULE_PARM(sym53c416_2, "1-2i");
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- v2.4.10/linux/drivers/scsi/sym53c8xx.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/scsi/sym53c8xx.c	Sun Sep 30 12:26:08 2001
@@ -101,9 +101,7 @@
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -14701,6 +14699,8 @@
 /*
 **	Module stuff
 */
+
+MODULE_LICENSE("GPL");
 
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
 static
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c
--- v2.4.10/linux/drivers/scsi/t128.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/t128.c	Sun Sep 30 12:26:08 2001
@@ -120,6 +120,7 @@
 #include "sd.h"
 #include <linux/stat.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 static struct override {
     unsigned long address;
@@ -393,6 +394,8 @@
     } else 
 	return 0;
 }
+
+MODULE_LICENSE("GPL");
 
 #include "NCR5380.c"
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/tmscsim.c linux/drivers/scsi/tmscsim.c
--- v2.4.10/linux/drivers/scsi/tmscsim.c	Fri Apr 27 14:07:19 2001
+++ linux/drivers/scsi/tmscsim.c	Sun Sep 30 12:26:08 2001
@@ -492,6 +492,8 @@
 #if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
 MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
 MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
+MODULE_LICENSE("GPL");
+
 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
 #endif
 
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v2.4.10/linux/drivers/scsi/u14-34f.c	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/u14-34f.c	Sun Sep 30 12:26:08 2001
@@ -1756,6 +1756,7 @@
    return FALSE;
 }
 
+MODULE_LICENSE("BSD without advertisement clause");
 static Scsi_Host_Template driver_template = ULTRASTOR_14_34F;
 
 #include "scsi_module.c"
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- v2.4.10/linux/drivers/scsi/ultrastor.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/scsi/ultrastor.c	Sun Sep 30 12:26:08 2001
@@ -124,9 +124,7 @@
  * Release ICM slot by clearing first byte on 24F.
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <linux/stddef.h>
 #include <linux/string.h>
@@ -1166,6 +1164,8 @@
     ultrastor_interrupt(irq, dev_id, regs);
     spin_unlock_irqrestore(&io_request_lock, flags);
 }
+
+MODULE_LICENSE("GPL");
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = ULTRASTOR_14F;
diff -u --recursive --new-file v2.4.10/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c
--- v2.4.10/linux/drivers/scsi/wd7000.c	Wed Apr 11 19:02:37 2001
+++ linux/drivers/scsi/wd7000.c	Sun Sep 30 12:26:08 2001
@@ -142,9 +142,7 @@
  *  WD7000 driver now work on kernels >= 2.1.x
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <stdarg.h>
 #include <linux/kernel.h>
@@ -1779,6 +1777,8 @@
 
     return (0);
 }
+
+MODULE_LICENSE("GPL");
 
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = WD7000;
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/ac97.c linux/drivers/sound/ac97.c
--- v2.4.10/linux/drivers/sound/ac97.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/sound/ac97.c	Sun Sep 30 12:26:08 2001
@@ -445,6 +445,8 @@
 EXPORT_SYMBOL(ac97_get_mixer_scaled);
 EXPORT_SYMBOL(ac97_mixer_ioctl);
 EXPORT_SYMBOL(ac97_reset);
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- v2.4.10/linux/drivers/sound/ac97_codec.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/ac97_codec.c	Sun Sep 30 12:26:08 2001
@@ -1020,3 +1020,4 @@
 }
 
 EXPORT_SYMBOL(ac97_set_adc_rate);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/aci.c linux/drivers/sound/aci.c
--- v2.4.10/linux/drivers/sound/aci.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/sound/aci.c	Sun Sep 30 12:26:08 2001
@@ -706,3 +706,4 @@
 
 module_init(attach_aci);
 module_exit(unload_aci);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/ad1816.c linux/drivers/sound/ad1816.c
--- v2.4.10/linux/drivers/sound/ad1816.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/ad1816.c	Sun Sep 30 12:26:08 2001
@@ -1471,3 +1471,4 @@
 
 __setup("ad1816=", setup_ad1816);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.4.10/linux/drivers/sound/ad1848.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/ad1848.c	Sun Sep 30 12:26:08 2001
@@ -3064,3 +3064,4 @@
 
 __setup("ad1848=", setup_ad1848);	
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/adlib_card.c linux/drivers/sound/adlib_card.c
--- v2.4.10/linux/drivers/sound/adlib_card.c	Sat May 19 12:50:28 2001
+++ linux/drivers/sound/adlib_card.c	Sun Sep 30 12:26:08 2001
@@ -70,3 +70,4 @@
 }
 __setup("adlib=", setup_adlib);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/aedsp16.c linux/drivers/sound/aedsp16.c
--- v2.4.10/linux/drivers/sound/aedsp16.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/sound/aedsp16.c	Sun Sep 30 12:26:08 2001
@@ -1325,6 +1325,7 @@
 MODULE_PARM_DESC(mpu_base,"MPU-401 I/O base address (0x300 0x310 0x320 0x330)");
 MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>");
 MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION);
+MODULE_LICENSE("GPL");
 
 static int __init do_init_aedsp16(void) {
 	printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/awe_wave.c linux/drivers/sound/awe_wave.c
--- v2.4.10/linux/drivers/sound/awe_wave.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/awe_wave.c	Sun Sep 30 12:26:08 2001
@@ -213,6 +213,8 @@
 
 MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
 MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "base i/o port of Emu8000");
 MODULE_PARM(memsize, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.4.10/linux/drivers/sound/cmpci.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/cmpci.c	Sun Sep 30 12:26:08 2001
@@ -3140,6 +3140,8 @@
 
 MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw");
 MODULE_DESCRIPTION("CM8x38 Audio Driver");
+MODULE_LICENSE("GPL");
+
 
 static void __exit cleanup_cmpci(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/cs4232.c linux/drivers/sound/cs4232.c
--- v2.4.10/linux/drivers/sound/cs4232.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/sound/cs4232.c	Sun Sep 30 12:26:08 2001
@@ -329,6 +329,8 @@
 
 MODULE_DESCRIPTION("CS4232 based soundcard driver"); 
 MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); 
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(io,"i");
 MODULE_PARM_DESC(io,"base I/O port for AD1848");
 MODULE_PARM(irq,"i");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/cs4281/cs4281m.c linux/drivers/sound/cs4281/cs4281m.c
--- v2.4.10/linux/drivers/sound/cs4281/cs4281m.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/cs4281/cs4281m.c	Sun Sep 30 12:26:08 2001
@@ -4512,6 +4512,7 @@
 
 MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com");
 MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
+MODULE_LICENSE("GPL");
 
 // --------------------------------------------------------------------- 
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- v2.4.10/linux/drivers/sound/cs46xx.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/cs46xx.c	Sun Sep 30 12:26:08 2001
@@ -5259,6 +5259,8 @@
 
 MODULE_AUTHOR("Alan Cox <alan@redhat.com>, Jaroslav Kysela, <pcaudio@crystal.cirrus.com>");
 MODULE_DESCRIPTION("Crystal SoundFusion Audio Support");
+MODULE_LICENSE("GPL");
+
 
 static const char cs46xx_banner[] = KERN_INFO "Crystal 4280/46xx + AC97 Audio, version " CS46XX_MAJOR_VERSION "." CS46XX_MINOR_VERSION "." CS46XX_ARCH ", " __TIME__ " " __DATE__ "\n";
 static const char fndmsg[] = KERN_INFO "cs46xx: Found %d audio device(s).\n";
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/audio.c linux/drivers/sound/emu10k1/audio.c
--- v2.4.10/linux/drivers/sound/emu10k1/audio.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/emu10k1/audio.c	Tue Oct  9 10:53:17 2001
@@ -49,7 +49,6 @@
 #include "irqmgr.h"
 #include "audio.h"
 #include "8010.h"
-#include "passthrough.h"
 
 static void calculate_ofrag(struct woinst *);
 static void calculate_ifrag(struct wiinst *);
@@ -984,6 +983,9 @@
 	unsigned long pgoff;
 	int rd, wr;
 
+	DPF(4, "emu10k1_mm_nopage()\n");
+	DPD(4, "addr: %#lx\n", address);
+
 	if (address > vma->vm_end) {
 		DPF(2, "EXIT, returning NOPAGE_SIGBUS\n");
 		return NOPAGE_SIGBUS; /* Disallow mremap */
@@ -1013,6 +1015,8 @@
 	}
 
 	get_page (dmapage);
+
+	DPD(4, "page: %#lx\n", dmapage);
 	return dmapage;
 }
 
@@ -1023,14 +1027,14 @@
 static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
-	unsigned long maxsize, size, offset, pgoffset;
+	unsigned long max_pages, n_pages, pgoffset;
 	struct woinst *woinst = NULL;
 	struct wiinst *wiinst = NULL;
 	unsigned long flags;
 
 	DPF(2, "emu10k1_audio_mmap()\n");
 
-	maxsize = 0;
+	max_pages = 0;
 	if (vma->vm_flags & VM_WRITE) {
 		woinst = wave_dev->woinst;
 
@@ -1053,7 +1057,7 @@
 		}
 
 		woinst->mmapped = 1;
-		maxsize += woinst->buffer.pages * PAGE_SIZE;
+		max_pages += woinst->buffer.pages;
 		spin_unlock_irqrestore(&woinst->lock, flags);
 	}
 
@@ -1072,21 +1076,23 @@
 		}
 
 		wiinst->mmapped = 1;
-		maxsize += wiinst->buffer.pages * PAGE_SIZE;
+		max_pages += wiinst->buffer.pages;
 		spin_unlock_irqrestore(&wiinst->lock, flags);
 	}
 
-	size = vma->vm_end - vma->vm_start;
+	n_pages = ((vma->vm_end - vma->vm_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	pgoffset = vma->vm_pgoff;
-	offset = pgoffset << PAGE_SHIFT;
 
-	if (offset + size > maxsize)
+	DPD(3, "vma_start: %#lx, vma_end: %#lx, vma_offset: %d\n", vma->vm_start, vma->vm_end, pgoffset);
+	DPD(3, "n_pages: %d, max_pages: %d\n", n_pages, max_pages);
+
+	if (pgoffset + n_pages > max_pages)
 		return -EINVAL;
 
 	vma->vm_flags |= VM_RESERVED;
 	vma->vm_ops = &emu10k1_mm_ops;
 	vma->vm_private_data = wave_dev;
-	
+
 	return 0;
 }
 
@@ -1240,9 +1246,11 @@
 
 		spin_lock_irqsave(&woinst->lock, flags);
 
-		if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE)
+		if (woinst->format.passthrough && card->pt.state != PT_STATE_INACTIVE) {
+			spin_lock(&card->pt.lock);
                         emu10k1_pt_stop(card);
-
+			spin_unlock(&card->pt.lock);
+		}
 		if (woinst->state & WAVE_STATE_OPEN) {
 			if (woinst->state & WAVE_STATE_STARTED) {
 				if (!(file->f_flags & O_NONBLOCK)) {
@@ -1259,7 +1267,7 @@
 		}
 
 		spin_unlock_irqrestore(&woinst->lock, flags);
-		/* wait for the tasklet (bottom-half) to finish */
+		/* remove the tasklet */
 		tasklet_kill(&woinst->timer.tasklet);
 		kfree(wave_dev->woinst);
 	}
@@ -1505,9 +1513,10 @@
 
 	spin_unlock_irqrestore(&wiinst->lock, flags);
 
-	if (bytestocopy >= wiinst->buffer.fragment_size && waitqueue_active(&wiinst->wait_queue))
-		wake_up_interruptible(&wiinst->wait_queue);
-	else
+	if (bytestocopy >= wiinst->buffer.fragment_size) {
+	 	if (waitqueue_active(&wiinst->wait_queue))
+			wake_up_interruptible(&wiinst->wait_queue);
+	} else
 		DPD(3, "Not enough transfer size, %d\n", bytestocopy);
 
 	return;
@@ -1539,9 +1548,10 @@
 	} else
 		spin_unlock_irqrestore(&woinst->lock, flags);
 
-	if (bytestocopy >= woinst->buffer.fragment_size && waitqueue_active(&woinst->wait_queue))
-		wake_up_interruptible(&woinst->wait_queue);
-	else
+	if (bytestocopy >= woinst->buffer.fragment_size) {
+		if (waitqueue_active(&woinst->wait_queue))
+			wake_up_interruptible(&woinst->wait_queue);
+	} else
 		DPD(3, "Not enough transfer size -> %d\n", bytestocopy);
 
 	return;
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/efxmgr.c linux/drivers/sound/emu10k1/efxmgr.c
--- v2.4.10/linux/drivers/sound/emu10k1/efxmgr.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/sound/emu10k1/efxmgr.c	Tue Oct  9 10:53:18 2001
@@ -1,4 +1,4 @@
-/*     
+/*
  **********************************************************************
  *     efxmgr.c
  *     Copyright 1999, 2000 Creative Labs, Inc. 
@@ -49,7 +49,7 @@
 		goto match;
 	}
 
-	for(i = 0; i < mgr->current_pages * PATCHES_PER_PAGE; i++) {
+	for (i = 0; i < mgr->current_pages * PATCHES_PER_PAGE; i++) {
 		patch = PATCH(mgr, i);
 			sprintf(s,"%s", patch->name);
 
@@ -97,77 +97,81 @@
 
 //An internal function for setting OSS mixer controls.
 void emu10k1_set_oss_vol(struct emu10k1_card *card, int oss_mixer,
-			 unsigned int left, unsigned int right){
-
-	extern struct oss_scaling volume_params[SOUND_MIXER_NRDEVICES];
+			 unsigned int left, unsigned int right)
+{
+	extern char volume_params[SOUND_MIXER_NRDEVICES];
 
 	card->ac97.mixer_state[oss_mixer] = (right << 8) | left;
 
 	if (!card->isaps)
 		card->ac97.write_mixer(&card->ac97, oss_mixer, left, right);
-
 	
 	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left,
-			       volume_params[oss_mixer].scale,
-			       volume_params[oss_mixer].muting);
-	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right,
-			       volume_params[oss_mixer].scale,
-			       volume_params[oss_mixer].muting);
+			       volume_params[oss_mixer]);
 
+	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right,
+			       volume_params[oss_mixer]);
 }
 
-
 //FIXME: mute should unmute when pressed a second time
 void emu10k1_mute_irqhandler(struct emu10k1_card *card)
 {
-	struct patch_manager *mgr = &card->mgr;
-	unsigned long  flags;
+	int oss_channel = VOLCTRL_CHANNEL;
+	int left, right;
+	static int val = 0;
+
+	if (val) {
+		left = val & 0xff;
+		right = (val >> 8) & 0xff;
+		val = 0;
+	} else {
+		val = card->ac97.mixer_state[oss_channel];
+		left = 0;
+		right = 0;
+	}
 
-	spin_lock_irqsave(&mgr->lock, flags);
-	emu10k1_set_oss_vol(card,VOLCTRL_CHANNEL,0,0);
-	spin_unlock_irqrestore(&mgr->lock, flags);
+	emu10k1_set_oss_vol(card, oss_channel, left, right);
 }
 
 void emu10k1_volincr_irqhandler(struct emu10k1_card *card)
 {
-	struct patch_manager *mgr = &card->mgr;
-	unsigned long  flags;
-	unsigned int oss_channel=VOLCTRL_CHANNEL, left=0,right=0;
+	int oss_channel = VOLCTRL_CHANNEL;
+	int left, right;
 
-	spin_lock_irqsave(&mgr->lock, flags);
 	left = card->ac97.mixer_state[oss_channel] & 0xff;
 	right = (card->ac97.mixer_state[oss_channel] >> 8) & 0xff;
 
-	if((left+=VOLCTRL_STEP_SIZE )>100)
-		left=100;
-	if((right+=VOLCTRL_STEP_SIZE )>100)
-		right=100;
-	emu10k1_set_oss_vol(card,oss_channel,left,right);
-	spin_unlock_irqrestore(&mgr->lock, flags);	
+	if ((left += VOLCTRL_STEP_SIZE) > 100)
+		left = 100;
+
+	if ((right += VOLCTRL_STEP_SIZE) > 100)
+		right = 100;
+
+	emu10k1_set_oss_vol(card, oss_channel, left, right);
 }
+
 void emu10k1_voldecr_irqhandler(struct emu10k1_card *card)
 {
-	struct patch_manager *mgr = &card->mgr;
-	unsigned long  flags;
-	int oss_channel=VOLCTRL_CHANNEL, left=0,right=0;
+	int oss_channel = VOLCTRL_CHANNEL;
+	int left, right;
 
-	spin_lock_irqsave(&mgr->lock, flags);
 	left = card->ac97.mixer_state[oss_channel] & 0xff;
 	right = (card->ac97.mixer_state[oss_channel] >> 8) & 0xff;
 
-	if((left-=VOLCTRL_STEP_SIZE )<0)
-		left=0;
-	if((right-=VOLCTRL_STEP_SIZE )<0)
-		right=0;
-	emu10k1_set_oss_vol(card,oss_channel,left,right);
-	spin_unlock_irqrestore(&mgr->lock, flags);
-}
+	if ((left -= VOLCTRL_STEP_SIZE) < 0)
+		left = 0;
 
+	if ((right -= VOLCTRL_STEP_SIZE) < 0)
+		right = 0;
 
-void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int scale, int muting)
+	emu10k1_set_oss_vol(card, oss_channel, left, right);
+}
+
+void emu10k1_set_volume_gpr(struct emu10k1_card *card, int addr, s32 vol, int scale)
 {
 	struct patch_manager *mgr = &card->mgr;
 	unsigned long flags;
+	int muting;
 
 	const s32 log2lin[5] ={                  //  attenuation (dB)
 		0x7fffffff,                      //       0.0         
@@ -179,10 +183,12 @@
 	if (addr < 0)
 		return;
 
+	muting = (scale == 0x10) ? 0x7f: scale;
+	
 	vol = (100 - vol ) * scale / 100;
 
 	// Thanks to the comp.dsp newsgroup for this neat trick:
-	vol = vol >= muting ? 0: log2lin[vol&3]>>(vol>>2);
+	vol = (vol >= muting) ? 0 : (log2lin[vol & 3] >> (vol >> 2));
 
 	spin_lock_irqsave(&mgr->lock, flags);
 	emu10k1_set_control_gpr(card, addr, vol, 0);
@@ -197,15 +203,16 @@
 		u32 bc;
 		bc = sblive_readptr(card, GPR_BASE + card->pt.intr_gpr, 0);
 		if (bc != 0) {
-			spin_lock_irqsave(&card->lock, flags);
+			DPD(3, "pt interrupt, bc = %d\n", bc);
+			spin_lock_irqsave(&card->pt.lock, flags);
 			card->pt.blocks_played = bc;
 			if (card->pt.blocks_played >= card->pt.blocks_copied) {
 				DPF(1, "buffer underrun in passthrough playback\n");
 				emu10k1_pt_stop(card);
 			}
 			wake_up_interruptible(&card->pt.wait);
-			spin_unlock_irqrestore(&card->lock, flags);
-			DPD(3, "pt interrupt, bc = %d\n", bc);
+			spin_unlock_irqrestore(&card->pt.lock, flags);
 		}
 	}
 }
+
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/efxmgr.h linux/drivers/sound/emu10k1/efxmgr.h
--- v2.4.10/linux/drivers/sound/emu10k1/efxmgr.h	Sun Aug 12 13:28:00 2001
+++ linux/drivers/sound/emu10k1/efxmgr.h	Tue Oct  9 10:53:18 2001
@@ -66,7 +66,8 @@
 
         u32 gpr_used[NUM_GPRS / 32];    /* bitmap of used gprs */
         u32 gpr_input[NUM_GPRS / 32];
-        u8 traml_istart;  /* starting address of the internal tram lines used */        u8 traml_isize;   /* number of internal tram lines used */
+        u8 traml_istart;  /* starting address of the internal tram lines used */
+        u8 traml_isize;   /* number of internal tram lines used */
 
         u8 traml_estart;
         u8 traml_esize;
@@ -97,10 +98,6 @@
 #define GPR_BASE 0x100
 #define OUTPUT_BASE 0x20
 
-//We can get this info by looking at the code start
-//#define PATCH_TYPE_INPUT        0x1
-//#define PATCH_TYPE_OUTPUT       0x2
-
 #define MAX_PATCHES_PAGES 32
 
 struct patch_manager {
@@ -139,6 +136,14 @@
 
 #define PCM1_IN_L        0x04
 #define PCM1_IN_R        0x05
+//mutilchannel playback stream appear here:
+
+#define MULTI_FRONT_L	0x08
+#define MULTI_FRONT_R	0x09
+#define MULTI_REAR_L	0x0a
+#define MULTI_REAR_R	0x0b
+#define MULTI_CENTER	0x0c
+#define MULTI_LFE	0x0d
 
 #define AC97_IN_L	0x10
 #define AC97_IN_R	0x11
@@ -150,10 +155,17 @@
 #define AC97_FRONT_R	0x21
 #define DIGITAL_OUT_L	0x22
 #define DIGITAL_OUT_R	0x23
+#define DIGITAL_CENTER	0x24
+#define DIGITAL_LFE	0x25
+
 #define ANALOG_REAR_L	0x28
 #define ANALOG_REAR_R	0x29
 #define ADC_REC_L	0x2a
 #define ADC_REC_R	0x2b
+
+#define ANALOG_CENTER	0x31
+#define ANALOG_LFE	0x32
+
 
 #define INPUT_PATCH_START(patch, nm, ln, i)		\
 do {							\
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/hwaccess.h linux/drivers/sound/emu10k1/hwaccess.h
--- v2.4.10/linux/drivers/sound/emu10k1/hwaccess.h	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/emu10k1/hwaccess.h	Tue Oct  9 10:53:18 2001
@@ -38,8 +38,8 @@
 #include <linux/ac97_codec.h>
 #include <linux/pci.h>
 
-#include "passthrough.h"
 #include "efxmgr.h"
+#include "passthrough.h"
 #include "midi.h"
 
 #define EMUPAGESIZE     4096            /* don't change */
@@ -122,10 +122,10 @@
 #define CMD_SETGPR2OSS		_IOW('D', 16, struct mixer_private_ioctl)
 #define CMD_SETMCH_FX		_IOW('D', 17, struct mixer_private_ioctl)
 #define CMD_SETPASSTHROUGH	_IOW('D', 18, struct mixer_private_ioctl)
+#define CMD_PRIVATE3_VERSION	_IOW('D', 19, struct mixer_private_ioctl)
 
-struct oss_scaling {
-	char scale, muting;
-}; 
+//up this number when breaking compatibility
+#define PRIVATE3_VERSION 1
 
 struct emu10k1_card 
 {
@@ -192,12 +192,12 @@
 int emu10k1_find_control_gpr(struct patch_manager *, const char *, const char *);
 void emu10k1_set_control_gpr(struct emu10k1_card *, int , s32, int );
 
-void emu10k1_set_volume_gpr(struct emu10k1_card *, int, s32, int, int);
+void emu10k1_set_volume_gpr(struct emu10k1_card *, int, s32, int);
 
 
-#define VOL_6BIT 0x40,0x40
-#define VOL_5BIT 0x20,0x20
-#define VOL_4BIT 0x10,0x7f
+#define VOL_6BIT 0x40
+#define VOL_5BIT 0x20
+#define VOL_4BIT 0x10
 
 #define TIMEOUT 		    16384
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/main.c linux/drivers/sound/emu10k1/main.c
--- v2.4.10/linux/drivers/sound/emu10k1/main.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/emu10k1/main.c	Tue Oct  9 10:53:18 2001
@@ -66,7 +66,10 @@
  *          Added Support for 5.1 cards (digital out and the third analog out)
  *     0.15 Added Sequencer Support (Daniel Mack)
  *          Support for multichannel pcm playback (Eduard Hasenleithner)
- *          
+ *     0.16 Mixer improvements, added old treble/bass support (Daniel Bertrand)
+ *          Small code format cleanup.
+ *          Deadlock bug fix for emu10k1_volxxx_irqhandler().
+ *
  *********************************************************************/
 
 /* These are only included once per module */
@@ -99,7 +102,7 @@
 #define SNDCARD_EMU10K1 46
 #endif
  
-#define DRIVER_VERSION "0.15"
+#define DRIVER_VERSION "0.16"
 
 /* FIXME: is this right? */
 /* does the card support 32 bit bus master?*/
@@ -216,7 +219,7 @@
 
 	card->ac97.private_data = card;
 
-	if(!card->isaps) {
+	if (!card->isaps) {
 		card->ac97.id = 0;
 		card->ac97.codec_read = emu10k1_ac97_read;
         	card->ac97.codec_write = emu10k1_ac97_write;
@@ -227,8 +230,10 @@
 		}
 		/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
 			does not support this, it shouldn't do any harm */
-		sblive_writeptr(card, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
-		
+		sblive_writeptr(card, AC97SLOT, 0, AC97SLOT_CNTR | AC97SLOT_LFE);
+
+		// Force 5bit
+		//card->ac97.bit_resolution=5;
 
 		if (!proc_mkdir ("driver/emu10k1", 0)) {
 			printk(KERN_ERR "emu10k1: unable to create proc directory driver/emu10k1\n");
@@ -247,6 +252,7 @@
 			goto err_ac97_proc;
 		}
 
+		/* these will store the original values and never be modified */
 		card->ac97_supported_mixers = card->ac97.supported_mixers;
 		card->ac97_stereo_mixers = card->ac97.stereo_mixers;
 	}
@@ -268,7 +274,7 @@
 {
 	char s[32];
 
-	if(!card->isaps) {
+	if (!card->isaps) {
 		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
 		remove_proc_entry(s, NULL);
 
@@ -333,7 +339,7 @@
 
 #ifdef EMU10K1_SEQUENCER
 	card->seq_dev = sound_alloc_mididev();
-	if(card->seq_dev == -1)
+	if (card->seq_dev == -1)
 			printk(KERN_WARNING "emu10k1: unable to register sequencer device!");
 	else {
 			std_midi_synth.midi_dev = card->seq_dev;
@@ -341,22 +347,21 @@
 					(struct midi_operations *)
 					kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
 			
-			if(midi_devs[card->seq_dev] == NULL) {
-					printk(KERN_ERR "emu10k1: unable to allocate memory!");
-					sound_unload_mididev(card->seq_dev);
-					card->seq_dev = -1;
-					return 0;
+			if (midi_devs[card->seq_dev] == NULL) {
+				printk(KERN_ERR "emu10k1: unable to allocate memory!");
+				sound_unload_mididev(card->seq_dev);
+				card->seq_dev = -1;
+				return 0;
 			} else {
-					memcpy((char *)midi_devs[card->seq_dev], 
-						   (char *)&emu10k1_midi_operations, 
-						   sizeof(struct midi_operations));
-					midi_devs[card->seq_dev]->devc = card;
-					sequencer_init();
+				memcpy((char *)midi_devs[card->seq_dev], 
+					(char *)&emu10k1_midi_operations, 
+					sizeof(struct midi_operations));
+				midi_devs[card->seq_dev]->devc = card;
+				sequencer_init();
 			}
 	}
 	card->seq_mididev = 0;
 #endif
-
 	return 0;
 
 err_out3:
@@ -370,19 +375,19 @@
 
 static void __devinit emu10k1_midi_cleanup(struct emu10k1_card *card)
 {
-    tasklet_kill(&card->mpuout->tasklet);
-    kfree(card->mpuout);
+	tasklet_kill(&card->mpuout->tasklet);
+	kfree(card->mpuout);
 
-    tasklet_kill(&card->mpuin->tasklet);
-    kfree(card->mpuin);
+	tasklet_kill(&card->mpuin->tasklet);
+	kfree(card->mpuin);
 
 #ifdef EMU10K1_SEQUENCER
-    if(card->seq_dev > -1) {
-	        kfree(midi_devs[card->seq_dev]);
-			midi_devs[card->seq_dev] = NULL;
-            sound_unload_mididev(card->seq_dev);
-			card->seq_dev = -1;
-    }
+	if (card->seq_dev > -1) {
+		kfree(midi_devs[card->seq_dev]);
+		midi_devs[card->seq_dev] = NULL;
+		sound_unload_mididev(card->seq_dev);
+		card->seq_dev = -1;
+	}
 #endif
 
 	unregister_sound_midi(card->midi_dev);
@@ -447,91 +452,152 @@
 				    TANKMEMADDRREGBASE + i, 0,
 				    TAGLIST_END);
 
-	mgr->current_pages = 5 / PATCHES_PER_PAGE + 1;
-        for(i = 0; i < mgr->current_pages; i++) {
-                mgr->patch[i] = (void *)__get_free_pages(GFP_KERNEL, 1);
-                if (mgr->patch[i] == NULL) {
-                        mgr->current_pages = i;
-                        fx_cleanup(mgr);
-                        return -ENOMEM;
-                }
-                memset(mgr->patch[i], 0, PAGE_SIZE);
-        }
+	/* !! The number bellow must equal the number of patches, currently 11 !! */
+	mgr->current_pages = (11 + PATCHES_PER_PAGE - 1) / PATCHES_PER_PAGE;
+	for (i = 0; i < mgr->current_pages; i++) {
+		mgr->patch[i] = (void *)__get_free_page(GFP_KERNEL);
+		if (mgr->patch[i] == NULL) {
+			mgr->current_pages = i;
+			fx_cleanup(mgr);
+			return -ENOMEM;
+		}
+		memset(mgr->patch[i], 0, PAGE_SIZE);
+	}
 
 	pc = 0;
 	patch_n = 0;
+	//first free GPR = 0x11b
 
-	/* FX volume correction */
-	INPUT_PATCH_START(patch, "Pcm L vol correction", 0x0, 0);
+	/* FX volume correction and Volume control*/
+	INPUT_PATCH_START(patch, "Pcm L vol", 0x0, 0);
 	GET_OUTPUT_GPR(patch, 0x100, 0x0);
-	
-	OP(4, 0x100, 0x40, PCM_IN_L, 0x44);
+	GET_CONTROL_GPR(patch, 0x106, "Vol", 0, 0x7fffffff);
+	GET_DYNAMIC_GPR(patch, 0x112);
+
+	OP(4, 0x112, 0x40, PCM_IN_L, 0x44); //*4
+	OP(0, 0x100, 0x040, 0x112, 0x106);  //*vol
 	INPUT_PATCH_END(patch);
 
 
-	INPUT_PATCH_START(patch, "Pcm R vol correction", 0x1, 0);
+	INPUT_PATCH_START(patch, "Pcm R vol", 0x1, 0);
 	GET_OUTPUT_GPR(patch, 0x101, 0x1);
+	GET_CONTROL_GPR(patch, 0x107, "Vol", 0, 0x7fffffff);
+	GET_DYNAMIC_GPR(patch, 0x112);
+
+	OP(4, 0x112, 0x40, PCM_IN_R, 0x44); 
+	OP(0, 0x101, 0x040, 0x112, 0x107);
 
-	OP(4, 0x101, 0x40, PCM_IN_R, 0x44);
 	INPUT_PATCH_END(patch);
 
 
+	// CD-Digital In Volume control
+	INPUT_PATCH_START(patch, "CD-Digital Vol L", 0x12, 0);
+	GET_OUTPUT_GPR(patch, 0x10c, 0x12);
+	GET_CONTROL_GPR(patch, 0x10d, "Vol", 0, 0x7fffffff);
+
+	OP(0, 0x10c, 0x040, SPDIF_CD_L, 0x10d);
+	INPUT_PATCH_END(patch);
+
+	INPUT_PATCH_START(patch, "CD-Digital Vol R", 0x13, 0);
+	GET_OUTPUT_GPR(patch, 0x10e, 0x13);
+	GET_CONTROL_GPR(patch, 0x10f, "Vol", 0, 0x7fffffff);
+
+	OP(0, 0x10e, 0x040, SPDIF_CD_R, 0x10f);
+	INPUT_PATCH_END(patch);
+
+	//Volume Correction for Multi-channel Inputs
+	INPUT_PATCH_START(patch, "Multi-Channel Gain", 0x08, 0);
+	patch->input=patch->output=0x3F00;
+
+	GET_OUTPUT_GPR(patch, 0x113, MULTI_FRONT_L);
+	GET_OUTPUT_GPR(patch, 0x114, MULTI_FRONT_R);
+	GET_OUTPUT_GPR(patch, 0x115, MULTI_REAR_L);
+	GET_OUTPUT_GPR(patch, 0x116, MULTI_REAR_R);
+	GET_OUTPUT_GPR(patch, 0x117, MULTI_CENTER);
+	GET_OUTPUT_GPR(patch, 0x118, MULTI_LFE);
+
+	OP(4, 0x113, 0x40, MULTI_FRONT_L, 0x44);
+	OP(4, 0x114, 0x40, MULTI_FRONT_R, 0x44);
+	OP(4, 0x115, 0x40, MULTI_REAR_L, 0x44);
+	OP(4, 0x116, 0x40, MULTI_REAR_R, 0x44);
+	OP(4, 0x117, 0x40, MULTI_CENTER, 0x44);
+	OP(4, 0x118, 0x40, MULTI_LFE, 0x44);
+	
+	INPUT_PATCH_END(patch);
+
+
+	//Routing patch start
 	ROUTING_PATCH_START(rpatch, "Routing");
 	GET_INPUT_GPR(rpatch, 0x100, 0x0);
 	GET_INPUT_GPR(rpatch, 0x101, 0x1);
+	GET_INPUT_GPR(rpatch, 0x10c, 0x12);
+	GET_INPUT_GPR(rpatch, 0x10e, 0x13);
+	GET_INPUT_GPR(rpatch, 0x113, MULTI_FRONT_L);
+	GET_INPUT_GPR(rpatch, 0x114, MULTI_FRONT_R);
+	GET_INPUT_GPR(rpatch, 0x115, MULTI_REAR_L);
+	GET_INPUT_GPR(rpatch, 0x116, MULTI_REAR_R);
+	GET_INPUT_GPR(rpatch, 0x117, MULTI_CENTER);
+	GET_INPUT_GPR(rpatch, 0x118, MULTI_LFE);
 
-        GET_DYNAMIC_GPR(rpatch, 0x102);
-        GET_DYNAMIC_GPR(rpatch, 0x103);
+	GET_DYNAMIC_GPR(rpatch, 0x102);
+	GET_DYNAMIC_GPR(rpatch, 0x103);
 
 	GET_OUTPUT_GPR(rpatch, 0x104, 0x8);
 	GET_OUTPUT_GPR(rpatch, 0x105, 0x9);
 	GET_OUTPUT_GPR(rpatch, 0x10a, 0x2);
 	GET_OUTPUT_GPR(rpatch, 0x10b, 0x3);
 
-	GET_CONTROL_GPR(rpatch, 0x106, "Vol Pcm L:Rear L", 0, 0x7fffffff);
-        GET_CONTROL_GPR(rpatch, 0x107, "Vol Pcm R:Rear R", 0, 0x7fffffff);
 
 	/* input buffer */
 	OP(6, 0x102, AC97_IN_L, 0x40, 0x40);
 	OP(6, 0x103, AC97_IN_R, 0x40, 0x40);
 
-	/* Digital In + PCM --> AC97 out (front speakers)*/
-	OP(6, AC97_FRONT_L, 0x100, SPDIF_CD_L, 0x40);
 
+	/* Digital In + PCM + MULTI_FRONT-> AC97 out (front speakers)*/
+	OP(6, AC97_FRONT_L, 0x100, 0x10c, 0x113);
+
+	CONNECT(MULTI_FRONT_L, AC97_FRONT_L);
 	CONNECT(PCM_IN_L, AC97_FRONT_L);
-        CONNECT(SPDIF_CD_L, AC97_FRONT_L);
+	CONNECT(SPDIF_CD_L, AC97_FRONT_L);
 
-	OP(6, AC97_FRONT_R, 0x101, SPDIF_CD_R, 0x40);
+	OP(6, AC97_FRONT_R, 0x101, 0x10e, 0x114);
 
+	CONNECT(MULTI_FRONT_R, AC97_FRONT_R);
 	CONNECT(PCM_IN_R, AC97_FRONT_R);
 	CONNECT(SPDIF_CD_R, AC97_FRONT_R);
 
-	/* Digital In + PCM + AC97 In + PCM1 --> Rear Channel */ 
-	OP(0, 0x104, PCM1_IN_L, 0x100, 0x106);
-	OP(6, 0x104, 0x104, SPDIF_CD_L, 0x102);
+	/* Digital In + PCM + AC97 In + PCM1 + MULTI_REAR --> Rear Channel */ 
+	OP(6, 0x104, PCM1_IN_L, 0x100, 0x115);
+	OP(6, 0x104, 0x104, 0x10c, 0x102);
 
+	CONNECT(MULTI_REAR_L, ANALOG_REAR_L);
 	CONNECT(AC97_IN_L, ANALOG_REAR_L);
-	CONNECT_V(PCM_IN_L, ANALOG_REAR_L);
+	CONNECT(PCM_IN_L, ANALOG_REAR_L);
 	CONNECT(SPDIF_CD_L, ANALOG_REAR_L);
 	CONNECT(PCM1_IN_L, ANALOG_REAR_L);
 
-	OP(0, 0x105, PCM1_IN_R, 0x101, 0x107);
-	OP(6, 0x105, 0x105, SPDIF_CD_R, 0x103);
+	OP(6, 0x105, PCM1_IN_R, 0x101, 0x116);
+	OP(6, 0x105, 0x105, 0x10e, 0x103);
 
+	CONNECT(MULTI_REAR_R, ANALOG_REAR_R);
 	CONNECT(AC97_IN_R, ANALOG_REAR_R);
-        CONNECT_V(PCM_IN_R, ANALOG_REAR_R);
-        CONNECT(SPDIF_CD_R, ANALOG_REAR_R);
+	CONNECT(PCM_IN_R, ANALOG_REAR_R);
+	CONNECT(SPDIF_CD_R, ANALOG_REAR_R);
 	CONNECT(PCM1_IN_R, ANALOG_REAR_R);
 
-	/* Digital In + PCM + AC97 In --> Digital out */
-	OP(6, 0x10b, 0x100, 0x102, SPDIF_CD_L);
+	/* Digital In + PCM + AC97 In + MULTI_FRONT --> Digital out */
+	OP(6, 0x10b, 0x100, 0x102, 0x10c);
+	OP(6, 0x10b, 0x10b, 0x113, 0x40);
 
+	CONNECT(MULTI_FRONT_L, DIGITAL_OUT_L);
 	CONNECT(PCM_IN_L, DIGITAL_OUT_L);
-        CONNECT(AC97_IN_L, DIGITAL_OUT_L);
-        CONNECT(SPDIF_CD_L, DIGITAL_OUT_L);
+	CONNECT(AC97_IN_L, DIGITAL_OUT_L);
+	CONNECT(SPDIF_CD_L, DIGITAL_OUT_L);
 
-	OP(6, 0x10a, 0x101, 0x103, SPDIF_CD_R);
+	OP(6, 0x10a, 0x101, 0x103, 0x10e);
+	OP(6, 0x10b, 0x10b, 0x114, 0x40);
 
+	CONNECT(MULTI_FRONT_R, DIGITAL_OUT_R);
 	CONNECT(PCM_IN_R, DIGITAL_OUT_R);
 	CONNECT(AC97_IN_R, DIGITAL_OUT_R);
 	CONNECT(SPDIF_CD_R, DIGITAL_OUT_R);
@@ -545,23 +611,40 @@
 
 	CONNECT(AC97_IN_R, ADC_REC_R);
 
+
+	/* fx12:Analog-Center */
+	OP(6, ANALOG_CENTER, 0x117, 0x40, 0x40);
+	CONNECT(MULTI_CENTER, ANALOG_CENTER);
+
+	/* fx11:Analog-LFE */
+	OP(6, ANALOG_LFE, 0x118, 0x40, 0x40);
+	CONNECT(MULTI_LFE, ANALOG_LFE);
+
+	/* fx12:Digital-Center */
+	OP(6, DIGITAL_CENTER, 0x117, 0x40, 0x40);
+	CONNECT(MULTI_CENTER, DIGITAL_CENTER);
+
+	/* fx11:Analog-LFE */
+	OP(6, DIGITAL_LFE, 0x118, 0x40, 0x40);
+	CONNECT(MULTI_LFE, DIGITAL_LFE);
+	
 	ROUTING_PATCH_END(rpatch);
 
 
-	// Master volume control on rear
-	OUTPUT_PATCH_START(patch, "Vol Master L", 0x8, 0);
+	// Rear volume control
+	OUTPUT_PATCH_START(patch, "Vol Rear L", 0x8, 0);
 	GET_INPUT_GPR(patch, 0x104, 0x8);
-	GET_CONTROL_GPR(patch, 0x108, "Vol", 0, 0x7fffffff);
+	GET_CONTROL_GPR(patch, 0x119, "Vol", 0, 0x7fffffff);
 
-	OP(0, ANALOG_REAR_L, 0x040, 0x104, 0x108);
+	OP(0, ANALOG_REAR_L, 0x040, 0x104, 0x119);
 	OUTPUT_PATCH_END(patch);
 
 
-	OUTPUT_PATCH_START(patch, "Vol Master R", 0x9, 0);
+	OUTPUT_PATCH_START(patch, "Vol Rear R", 0x9, 0);
 	GET_INPUT_GPR(patch, 0x105, 0x9);
-	GET_CONTROL_GPR(patch, 0x109, "Vol", 0, 0x7fffffff);
+	GET_CONTROL_GPR(patch, 0x11a, "Vol", 0, 0x7fffffff);
 
-	OP(0, ANALOG_REAR_R, 0x040, 0x105, 0x109);
+	OP(0, ANALOG_REAR_R, 0x040, 0x105, 0x11a);
 	OUTPUT_PATCH_END(patch);
 
 
@@ -573,7 +656,7 @@
 	OP(0, DIGITAL_OUT_L, 0x040, 0x10a, 0x108);
 	OUTPUT_PATCH_END(patch);
 
-	
+
 	OUTPUT_PATCH_START(patch, "Vol Master R", 0x3, 1);
 	GET_INPUT_GPR(patch, 0x10b, 0x3);
 	GET_CONTROL_GPR(patch, 0x109, "Vol", 0, 0x7fffffff);
@@ -590,24 +673,62 @@
 
 	mgr->lock = SPIN_LOCK_UNLOCKED;
 
+
+	//Master volume
 	mgr->ctrl_gpr[SOUND_MIXER_VOLUME][0] = 8;
 	mgr->ctrl_gpr[SOUND_MIXER_VOLUME][1] = 9;
 
 	left = card->ac97.mixer_state[SOUND_MIXER_VOLUME] & 0xff;
 	right = (card->ac97.mixer_state[SOUND_MIXER_VOLUME] >> 8) & 0xff;
 
-	emu10k1_set_volume_gpr(card, 8, left,  VOL_6BIT);
-	emu10k1_set_volume_gpr(card, 9, right, VOL_6BIT);
+	emu10k1_set_volume_gpr(card, 8, left, 1 << card->ac97.bit_resolution);
+	emu10k1_set_volume_gpr(card, 9, right, 1 << card->ac97.bit_resolution);
+
+	//Rear volume
+	mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][0] = 0x19;
+	mgr->ctrl_gpr[ SOUND_MIXER_OGAIN ][1] = 0x1a;
+
+	left = right = 67;
+	card->ac97.mixer_state[SOUND_MIXER_OGAIN] = (right << 8) | left;
 
+	card->ac97.supported_mixers |= SOUND_MASK_OGAIN;
+	card->ac97.stereo_mixers |= SOUND_MASK_OGAIN;
+
+	emu10k1_set_volume_gpr(card, 0x19, left, VOL_5BIT);
+	emu10k1_set_volume_gpr(card, 0x1a, right, VOL_5BIT);
+
+	//PCM Volume
 	mgr->ctrl_gpr[SOUND_MIXER_PCM][0] = 6;
 	mgr->ctrl_gpr[SOUND_MIXER_PCM][1] = 7;
 
 	left = card->ac97.mixer_state[SOUND_MIXER_PCM] & 0xff;
 	right = (card->ac97.mixer_state[SOUND_MIXER_PCM] >> 8) & 0xff;
 
-	emu10k1_set_volume_gpr(card, 6, left,  VOL_5BIT);
+	emu10k1_set_volume_gpr(card, 6, left, VOL_5BIT);
 	emu10k1_set_volume_gpr(card, 7, right, VOL_5BIT);
 
+	//CD-Digital Volume
+	mgr->ctrl_gpr[SOUND_MIXER_DIGITAL1][0] = 0xd;
+	mgr->ctrl_gpr[SOUND_MIXER_DIGITAL1][1] = 0xf;
+
+	left = right = 67;
+	card->ac97.mixer_state[SOUND_MIXER_DIGITAL1] = (right << 8) | left; 
+
+	card->ac97.supported_mixers |= SOUND_MASK_DIGITAL1;
+	card->ac97.stereo_mixers |= SOUND_MASK_DIGITAL1;
+
+	emu10k1_set_volume_gpr(card, 0xd, left, VOL_5BIT);
+	emu10k1_set_volume_gpr(card, 0xf, right, VOL_5BIT);
+
+	//hard wire the ac97's pcm, we'll do that in dsp code instead.
+	emu10k1_ac97_write(&card->ac97, 0x18, 0x0);
+	card->ac97_supported_mixers &= ~SOUND_MASK_PCM;
+	card->ac97_stereo_mixers &= ~SOUND_MASK_PCM;
+
+	//set Igain to 0dB by default, maybe consider hardwiring it here.
+	emu10k1_ac97_write(&card->ac97, AC97_RECORD_GAIN, 0x0000);
+	card->ac97.mixer_state[SOUND_MIXER_IGAIN] = 0x101; 
+
 	return 0;
 }
 
@@ -775,6 +896,7 @@
 	card->pt.intr_gpr_name = "count";
 	card->pt.enable_gpr_name = "enable";
 	card->pt.pos_gpr_name = "ptr";
+	spin_lock_init(&card->pt.lock);
 	init_waitqueue_head(&card->pt.wait);
 
 /*	tmp = sblive_readfn0(card, HCFG);
@@ -999,6 +1121,7 @@
 
 MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@opensource.creative.com)");
 MODULE_DESCRIPTION("Creative EMU10K1 PCI Audio Driver v" DRIVER_VERSION "\nCopyright (C) 1999 Creative Technology Ltd.");
+MODULE_LICENSE("GPL");
 
 static struct pci_driver emu10k1_pci_driver = {
 	name:		"emu10k1",
@@ -1039,8 +1162,8 @@
 
 static struct midi_operations emu10k1_midi_operations =
 {
-    THIS_MODULE,
-    {"EMU10K1 MIDI", 0, 0, SNDCARD_EMU10K1},
+	THIS_MODULE,
+	{"EMU10K1 MIDI", 0, 0, SNDCARD_EMU10K1},
 	&std_midi_synth,
 	{0},
 	emu10k1_seq_midi_open,
@@ -1056,4 +1179,3 @@
 };
 
 #endif
-
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/midi.c linux/drivers/sound/emu10k1/midi.c
--- v2.4.10/linux/drivers/sound/emu10k1/midi.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/emu10k1/midi.c	Tue Oct  9 10:53:18 2001
@@ -94,7 +94,6 @@
 
 	DPF(2, "emu10k1_midi_open()\n");
 
-	
 	/* Check for correct device to open */
 	list_for_each(entry, &emu10k1_devs) {
 		card = list_entry(entry, struct emu10k1_card, list);
@@ -107,10 +106,9 @@
 
 match:
 #ifdef EMU10K1_SEQUENCER
-	if(card->seq_mididev)	/* card is opened by sequencer */
-			return -EBUSY;
+	if (card->seq_mididev)	/* card is opened by sequencer */
+		return -EBUSY;
 #endif
-	
 
 	/* Wait for device to become free */
 	down(&card->open_sem);
@@ -130,9 +128,8 @@
 		down(&card->open_sem);
 	}
 
-	if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
+	if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
 		return -EINVAL;
-	}
 
 	midi_dev->card = card;
 	midi_dev->mistate = MIDIIN_STATE_STOPPED;
@@ -244,7 +241,6 @@
 	wake_up_interruptible(&card->open_wait);
 
 	unlock_kernel();
-	
 
 	return 0;
 }
@@ -462,24 +458,22 @@
 				void (*input) (int dev, unsigned char data),
 				void (*output) (int dev))
 {
-    struct emu10k1_card *card;
-    struct midi_openinfo dsCardMidiOpenInfo;
+	struct emu10k1_card *card;
+	struct midi_openinfo dsCardMidiOpenInfo;
 	struct emu10k1_mididevice *midi_dev;
-		
-	if(    midi_devs[dev] == NULL
-		|| midi_devs[dev]->devc == NULL)
-			return -EINVAL;
+
+	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
+		return -EINVAL;
 
 	card = midi_devs[dev]->devc;
 
-	if(card->open_mode)		/* card is opened native */
-			return -EBUSY;
+	if (card->open_mode)		/* card is opened native */
+		return -EBUSY;
 			
 	DPF(2, "emu10k1_seq_midi_open()\n");
 	
-	if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
+	if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
 		return -EINVAL;
-	}
 
 	midi_dev->card = card;
 	midi_dev->mistate = MIDIIN_STATE_STOPPED;
@@ -492,10 +486,10 @@
 
 	dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
 
-    if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
-        ERROR();
-        return -ENODEV;
-    }
+	if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
+		ERROR();
+		return -ENODEV;
+	}
 
 	card->seq_mididev = midi_dev;
 		
@@ -507,29 +501,26 @@
 	struct emu10k1_card *card;
 
 	DPF(2, "emu10k1_seq_midi_close()\n");
-    if(    midi_devs[dev] == NULL
-        || midi_devs[dev]->devc == NULL)
-			return;
+	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
+		return;
 
 	card = midi_devs[dev]->devc;
 	emu10k1_mpuout_close(card);
 
-	if(card->seq_mididev) {
-			kfree(card->seq_mididev);
-			card->seq_mididev = 0;
+	if (card->seq_mididev) {
+		kfree(card->seq_mididev);
+		card->seq_mididev = 0;
 	}
 }
 
 int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
 {
-
 	struct emu10k1_card *card;
 	struct midi_hdr *midihdr;
 	unsigned long flags;
 
-	if(    midi_devs[dev] == NULL
-        || midi_devs[dev]->devc == NULL)
-			return -EINVAL;
+	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
+		return -EINVAL;
 
 	card = midi_devs[dev]->devc;
 
@@ -583,21 +574,22 @@
 	struct midi_queue *queue;
 	struct emu10k1_card *card;
 
-	if(    midi_devs[dev] == NULL
-        || midi_devs[dev]->devc == NULL)
-			return -EINVAL;
+	if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
+		return -EINVAL;
 
 	count = 0;
-	
+
 	card = midi_devs[dev]->devc;
 	queue = card->mpuout->firstmidiq;
 
-	while(queue != NULL) {
-			count++;
-			if(queue == card->mpuout->lastmidiq)
-					break;
-			queue = queue->next;
+	while (queue != NULL) {
+		count++;
+		if (queue == card->mpuout->lastmidiq)
+			break;
+
+		queue = queue->next;
 	}
+
 	return count;
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/mixer.c linux/drivers/sound/emu10k1/mixer.c
--- v2.4.10/linux/drivers/sound/emu10k1/mixer.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/sound/emu10k1/mixer.c	Tue Oct  9 10:53:18 2001
@@ -40,44 +40,149 @@
 #include "8010.h"
 #include "recmgr.h"
 
-//FIXME: SOUND_MIXER_VOLUME should be selectable 5 or 6 bit
-const struct oss_scaling volume_params[SOUND_MIXER_NRDEVICES]= {
-/* Used by the ac97 driver */
-	[SOUND_MIXER_VOLUME]	=	{VOL_6BIT},
-	[SOUND_MIXER_BASS]	=	{VOL_4BIT},
-	[SOUND_MIXER_TREBLE]	=	{VOL_4BIT},
-	[SOUND_MIXER_PCM]	=	{VOL_5BIT},
-	[SOUND_MIXER_SPEAKER]	=	{VOL_4BIT},
-	[SOUND_MIXER_LINE]	=	{VOL_5BIT},
-	[SOUND_MIXER_MIC]	=	{VOL_5BIT},
-	[SOUND_MIXER_CD]	=	{VOL_5BIT},
-	[SOUND_MIXER_ALTPCM]	=	{VOL_6BIT},
-	[SOUND_MIXER_IGAIN]	=	{VOL_4BIT},
-	[SOUND_MIXER_LINE1]	=	{VOL_5BIT},
-	[SOUND_MIXER_PHONEIN]	= 	{VOL_5BIT},
-	[SOUND_MIXER_PHONEOUT]	= 	{VOL_6BIT},
-	[SOUND_MIXER_VIDEO]	=	{VOL_5BIT},
-/* Not used by the ac97 driver */
-	[SOUND_MIXER_SYNTH]	=	{VOL_5BIT},
-	[SOUND_MIXER_IMIX]	=	{VOL_5BIT},
-	[SOUND_MIXER_RECLEV]	=	{VOL_5BIT},
-	[SOUND_MIXER_OGAIN]	=	{VOL_5BIT},
-	[SOUND_MIXER_LINE2]	=	{VOL_5BIT},
-	[SOUND_MIXER_LINE3]	=	{VOL_5BIT},
-	[SOUND_MIXER_DIGITAL1]	=	{VOL_5BIT},
-	[SOUND_MIXER_DIGITAL2]	=	{VOL_5BIT},
-	[SOUND_MIXER_DIGITAL3]	=	{VOL_5BIT},
-	[SOUND_MIXER_RADIO]	=	{VOL_5BIT},
-	[SOUND_MIXER_MONITOR]	=	{VOL_5BIT}
+
+static const u32 bass_table[41][5] = {
+	{ 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
+	{ 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
+	{ 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
+	{ 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
+	{ 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
+	{ 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
+	{ 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
+	{ 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
+	{ 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
+	{ 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
+	{ 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
+	{ 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
+	{ 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
+	{ 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
+	{ 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
+	{ 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
+	{ 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
+	{ 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
+	{ 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
+	{ 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
+	{ 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
+	{ 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
+	{ 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
+	{ 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
+	{ 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
+	{ 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
+	{ 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
+	{ 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
+	{ 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
+	{ 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
+	{ 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
+	{ 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
+	{ 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
+	{ 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
+	{ 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
+	{ 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
+	{ 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
+	{ 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
+	{ 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
+	{ 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
+	{ 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
+};
+
+static const u32 treble_table[41][5] = {
+	{ 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
+	{ 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
+	{ 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
+	{ 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
+	{ 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
+	{ 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
+	{ 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
+	{ 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
+	{ 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
+	{ 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
+	{ 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
+	{ 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
+	{ 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
+	{ 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
+	{ 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
+	{ 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
+	{ 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
+	{ 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
+	{ 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
+	{ 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
+	{ 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
+	{ 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
+	{ 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
+	{ 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
+	{ 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
+	{ 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
+	{ 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
+	{ 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
+	{ 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
+	{ 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
+	{ 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
+	{ 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
+	{ 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
+	{ 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
+	{ 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
+	{ 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
+	{ 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
+	{ 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
+	{ 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
+	{ 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
+	{ 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
 };
-static loff_t emu10k1_mixer_llseek(struct file *file, loff_t offset, int origin)
+
+
+static void set_bass(struct emu10k1_card *card, int l, int r)
 {
-	DPF(2, "sblive_mixer_llseek() called\n");
-	return -ESPIPE;
+	int i;
+
+	l = (l * 40 + 50) / 100;
+	r = (r * 40 + 50) / 100;
+
+	for (i = 0; i < 5; i++)
+		sblive_writeptr(card, GPR_BASE + card->mgr.ctrl_gpr[SOUND_MIXER_BASS][0] + i, 0, bass_table[l][i]);
 }
 
-/* Mixer file operations */
+static void set_treble(struct emu10k1_card *card, int l, int r)
+{
+	int i;
+
+	l = (l * 40 + 50) / 100;
+	r = (r * 40 + 50) / 100;
+
+	for (i = 0; i < 5; i++)
+		sblive_writeptr(card, GPR_BASE + card->mgr.ctrl_gpr[SOUND_MIXER_TREBLE][0] + i , 0, treble_table[l][i]);
+}
+
+const char volume_params[SOUND_MIXER_NRDEVICES]= {
+/* Used by the ac97 driver */
+	[SOUND_MIXER_VOLUME]	=	VOL_6BIT,
+	[SOUND_MIXER_BASS]	=	VOL_4BIT,
+	[SOUND_MIXER_TREBLE]	=	VOL_4BIT,
+	[SOUND_MIXER_PCM]	=	VOL_5BIT,
+	[SOUND_MIXER_SPEAKER]	=	VOL_4BIT,
+	[SOUND_MIXER_LINE]	=	VOL_5BIT,
+	[SOUND_MIXER_MIC]	=	VOL_5BIT,
+	[SOUND_MIXER_CD]	=	VOL_5BIT,
+	[SOUND_MIXER_ALTPCM]	=	VOL_6BIT,
+	[SOUND_MIXER_IGAIN]	=	VOL_4BIT,
+	[SOUND_MIXER_LINE1]	=	VOL_5BIT,
+	[SOUND_MIXER_PHONEIN]	= 	VOL_5BIT,
+	[SOUND_MIXER_PHONEOUT]	= 	VOL_6BIT,
+	[SOUND_MIXER_VIDEO]	=	VOL_5BIT,
+/* Not used by the ac97 driver */
+	[SOUND_MIXER_SYNTH]	=	VOL_5BIT,
+	[SOUND_MIXER_IMIX]	=	VOL_5BIT,
+	[SOUND_MIXER_RECLEV]	=	VOL_5BIT,
+	[SOUND_MIXER_OGAIN]	=	VOL_5BIT,
+	[SOUND_MIXER_LINE2]	=	VOL_5BIT,
+	[SOUND_MIXER_LINE3]	=	VOL_5BIT,
+	[SOUND_MIXER_DIGITAL1]	=	VOL_5BIT,
+	[SOUND_MIXER_DIGITAL2]	=	VOL_5BIT,
+	[SOUND_MIXER_DIGITAL3]	=	VOL_5BIT,
+	[SOUND_MIXER_RADIO]	=	VOL_5BIT,
+	[SOUND_MIXER_MONITOR]	=	VOL_5BIT
+};
 
+/* Mixer file operations */
 static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, unsigned long arg)
 {
 	struct mixer_private_ioctl *ctl;
@@ -150,17 +255,23 @@
 					ret = -EINVAL;
 					break;
 				}
+
 				card->wavein.recsrc = WAVERECORD_AC97;
 				break;
+
 			case WAVERECORD_MIC:
 				card->wavein.recsrc = WAVERECORD_MIC;
 				break;
+
 			case WAVERECORD_FX:
 				card->wavein.recsrc = WAVERECORD_FX;
 				card->wavein.fxwc = ctl->val[1] & 0xffff;
+
 				if (!card->wavein.fxwc)
 					ret = -EINVAL;
+
 				break;
+
 			default:
 				ret = -EINVAL;
 				break;
@@ -267,8 +378,8 @@
 				}
 
 				if (page >= card->mgr.current_pages) {
-					for(i = card->mgr.current_pages; i < page + 1; i++) {
-				                card->mgr.patch[i] = (void *)__get_free_pages(GFP_KERNEL, 1);
+					for (i = card->mgr.current_pages; i < page + 1; i++) {
+				                card->mgr.patch[i] = (void *)__get_free_page(GFP_KERNEL);
 						if(card->mgr.patch[i] == NULL) {
 							card->mgr.current_pages = i;
 							ret = -ENOMEM;
@@ -283,7 +394,7 @@
 
 				memcpy(patch, &ctl->val[1], sizeof(struct dsp_patch));
 
-				if(patch->code_size == 0) {
+				if (patch->code_size == 0) {
 					for(i = page + 1; i < card->mgr.current_pages; i++)
                                                 free_page((unsigned long) card->mgr.patch[i]);
 
@@ -306,13 +417,13 @@
 			emu10k1_set_control_gpr(card, addr, *((s32 *)((char *) ctl->val + 2 * PATCH_NAME_SIZE)), 0);
 			break;
 
-
 		case CMD_SETGPOUT:
-			if( ctl->val[0]>2 || ctl->val[1]>1){
+			if (ctl->val[0] > 2 || ctl->val[1] > 1) {
 				ret= -EINVAL;
 				break;
 			}
-			emu10k1_writefn0(card, (1<<24)| (((ctl->val[0])+10)<<16 ) | HCFG ,ctl->val[1]);
+
+			emu10k1_writefn0(card, (1 << 24) | (((ctl->val[0]) + 10) << 16) | HCFG, ctl->val[1]);
 			break;
 
 		case CMD_GETGPR2OSS:
@@ -328,6 +439,7 @@
 
 			if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
 				ret = -EFAULT;
+
 			break;
 
 		case CMD_SETGPR2OSS:
@@ -350,30 +462,43 @@
 
 				if (ch) {
 					state >>= 8;
-					card->ac97.stereo_mixers |= (1<<id);
+					card->ac97.stereo_mixers |= (1 << id);
 				} else {
-					card->ac97.supported_mixers |= (1<<id);
+					card->ac97.supported_mixers |= (1 << id);
 				}
 
-				emu10k1_set_volume_gpr(card, addr, state & 0xff,
-						       volume_params[id].scale,
-						       volume_params[id].muting);
+				if (id == SOUND_MIXER_TREBLE) {
+					set_treble(card, card->ac97.mixer_state[id] & 0xff, (card->ac97.mixer_state[id] >> 8) & 0xff);
+				} else if (id == SOUND_MIXER_BASS) {
+					set_bass(card, card->ac97.mixer_state[id] & 0xff, (card->ac97.mixer_state[id] >> 8) & 0xff);
+				} else
+					emu10k1_set_volume_gpr(card, addr, state & 0xff,
+							       volume_params[id]);
 			} else {
 				if (ch) {
-					card->ac97.stereo_mixers &= ~(1<<id);
+					card->ac97.stereo_mixers &= ~(1 << id);
 					card->ac97.stereo_mixers |= card->ac97_stereo_mixers;
 				} else {
-					card->ac97.supported_mixers &= ~(1<<id);
+					card->ac97.supported_mixers &= ~(1 << id);
 					card->ac97.supported_mixers |= card->ac97_supported_mixers;
 				}
 			}
 			break;
+
 		case CMD_SETPASSTHROUGH:
 			card->pt.selected = ctl->val[0] ? 1 : 0;
 			if (card->pt.state != PT_STATE_INACTIVE)
 				break;
+
 			card->pt.spcs_to_use = ctl->val[0] & 0x07;
 			break;
+
+		case CMD_PRIVATE3_VERSION:
+			ctl->val[0]=PRIVATE3_VERSION;
+			if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+				ret = -EFAULT;
+			break;
+
 		default:
 			ret = -EINVAL;
 			break;
@@ -441,42 +566,75 @@
 	return -EINVAL;
 }
 
+static int emu10k1_dsp_mixer(struct emu10k1_card *card, unsigned int oss_mixer, unsigned long arg)
+{
+	unsigned int left, right;
+	int val;
+	int scale;
+
+	if (get_user(val, (int *)arg))
+		return -EFAULT;
+
+	/* cleanse input a little */
+	right = ((val >> 8)  & 0xff);
+	left = (val  & 0xff);
+
+	if (right > 100) right = 100;
+	if (left > 100) left = 100;
+
+	card->ac97.mixer_state[oss_mixer] = (right << 8) | left;
+	if (oss_mixer == SOUND_MIXER_TREBLE) {
+		set_treble(card, left, right);
+		return 0;
+	} if (oss_mixer == SOUND_MIXER_BASS) {
+		set_bass(card, left, right);
+		return 0;
+	}
+
+	if (oss_mixer == SOUND_MIXER_VOLUME)
+		scale = 1 << card->ac97.bit_resolution;
+	else
+		scale = volume_params[oss_mixer];
+
+	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left, scale);
+	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right, scale);
+
+	if (card->ac97_supported_mixers & (1 << oss_mixer))
+		card->ac97.write_mixer(&card->ac97, oss_mixer, left, right);
+
+	return 0;
+}
 
-	
 static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int ret;
 	struct emu10k1_card *card = file->private_data;
-
+	unsigned int oss_mixer = _IOC_NR(cmd);
+	
 	ret = -EINVAL;
-	if (!card->isaps)
-		ret = card->ac97.mixer_ioctl(&card->ac97, cmd, arg);
-
-	if (ret < 0)
-		ret = emu10k1_private_mixer(card, cmd, arg);
-	else{
-		unsigned int oss_mixer, left, right;
-
-		oss_mixer = _IOC_NR(cmd);
+	if (!card->isaps) {
+		if (cmd == SOUND_MIXER_INFO) {
+			mixer_info info;
+
+			strncpy(info.id, card->ac97.name, sizeof(info.id));
+			strncpy(info.name, "Creative SBLive - Emu10k1", sizeof(info.name));
+			info.modify_counter = card->ac97.modcnt;
 
-		if ((_IOC_DIR(cmd) == (_IOC_WRITE|_IOC_READ)) && oss_mixer<=SOUND_MIXER_NRDEVICES ) {
+			if (copy_to_user((void *)arg, &info, sizeof(info)))
+				return -EFAULT;
 
-			left = card->ac97.mixer_state[oss_mixer] & 0xff;
-			right = (card->ac97.mixer_state[oss_mixer] >> 8) & 0xff;
-			if(card->ac97.supported_mixers|(1<<oss_mixer))
-				emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left,
-						       volume_params[oss_mixer].scale,
-						       volume_params[oss_mixer].muting);
-			if(card->ac97.stereo_mixers |(1<<oss_mixer))
-				emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][1], right,
-						       volume_params[oss_mixer].scale,
-						       volume_params[oss_mixer].muting);
+			return 0;
 		}
-		
+
+		if ((_IOC_DIR(cmd) == (_IOC_WRITE|_IOC_READ)) && oss_mixer <= SOUND_MIXER_NRDEVICES)
+			ret = emu10k1_dsp_mixer(card, oss_mixer, arg);
+		else
+			ret = card->ac97.mixer_ioctl(&card->ac97, cmd, arg);
 	}
 	
-	
-		
+	if (ret < 0)
+		ret = emu10k1_private_mixer(card, cmd, arg);
+
 	return ret;
 }
 
@@ -510,7 +668,7 @@
 
 struct file_operations emu10k1_mixer_fops = {
 	owner:		THIS_MODULE,
-	llseek:		emu10k1_mixer_llseek,
+	llseek:		no_llseek,
 	ioctl:		emu10k1_mixer_ioctl,
 	open:		emu10k1_mixer_open,
 	release:	emu10k1_mixer_release,
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/passthrough.c linux/drivers/sound/emu10k1/passthrough.c
--- v2.4.10/linux/drivers/sound/emu10k1/passthrough.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/emu10k1/passthrough.c	Tue Oct  9 10:53:18 2001
@@ -47,7 +47,6 @@
 #include "irqmgr.h"
 #include "audio.h"
 #include "8010.h"
-#include "passthrough.h"
 
 static void pt_putsamples(struct pt_data *pt, u16 *ptr, u16 left, u16 right)
 {
@@ -209,9 +208,7 @@
 {
 	struct pt_data *pt = &card->pt;
 	int i;
-	unsigned long flags;
 
-	spin_lock_irqsave(&card->pt.lock, flags);
 	if (pt->state != PT_STATE_INACTIVE) {
 		DPF(2, "digital pass-through stopped\n");
 		sblive_writeptr(card, GPR_BASE + pt->enable_gpr, 0, 0);
@@ -222,7 +219,6 @@
 		pt->state = PT_STATE_INACTIVE;
 		kfree(pt->buf);
 	}
-	spin_unlock_irqrestore(&card->pt.lock, flags);
 }
 
 void emu10k1_pt_waveout_update(struct emu10k1_wavedevice *wave_dev)
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/emu10k1/passthrough.h linux/drivers/sound/emu10k1/passthrough.h
--- v2.4.10/linux/drivers/sound/emu10k1/passthrough.h	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/emu10k1/passthrough.h	Tue Oct  9 10:53:18 2001
@@ -32,7 +32,6 @@
 #ifndef _PASSTHROUGH_H
 #define _PASSTHROUGH_H
 
-#include "hwaccess.h"
 #include "audio.h"
 
 /* number of 16-bit stereo samples in XTRAM buffer */
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- v2.4.10/linux/drivers/sound/es1370.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/es1370.c	Sun Sep 30 12:26:08 2001
@@ -2541,6 +2541,8 @@
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
 MODULE_DESCRIPTION("ES1370 AudioPCI Driver");
+MODULE_LICENSE("GPL");
+
 
 /* --------------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- v2.4.10/linux/drivers/sound/es1371.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/es1371.c	Sun Sep 30 12:26:08 2001
@@ -2757,6 +2757,8 @@
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
 MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
+MODULE_LICENSE("GPL");
+
 
 /* --------------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c
--- v2.4.10/linux/drivers/sound/esssolo1.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/esssolo1.c	Sun Sep 30 12:26:08 2001
@@ -2468,6 +2468,8 @@
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
 MODULE_DESCRIPTION("ESS Solo1 Driver");
+MODULE_LICENSE("GPL");
+
 
 static void __exit cleanup_solo1(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/gus_card.c linux/drivers/sound/gus_card.c
--- v2.4.10/linux/drivers/sound/gus_card.c	Sun Sep 17 09:45:05 2000
+++ linux/drivers/sound/gus_card.c	Sun Sep 30 12:26:08 2001
@@ -232,6 +232,7 @@
 MODULE_PARM(db16, "i");
 MODULE_PARM(gus16, "i");
 #endif
+MODULE_LICENSE("GPL");
 
 static int __init init_gus(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- v2.4.10/linux/drivers/sound/i810_audio.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/i810_audio.c	Sun Sep 30 12:26:08 2001
@@ -2700,6 +2700,7 @@
 
 MODULE_AUTHOR("");
 MODULE_DESCRIPTION("Intel 810 audio support");
+MODULE_LICENSE("GPL");
 MODULE_PARM(ftsodell, "i");
 MODULE_PARM(clocking, "i");
 MODULE_PARM(strict_clocking, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c
--- v2.4.10/linux/drivers/sound/mad16.c	Fri Apr  6 10:51:19 2001
+++ linux/drivers/sound/mad16.c	Sun Sep 30 12:26:08 2001
@@ -1071,3 +1071,4 @@
 
 __setup("mad16=", setup_mad16);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/maestro.c linux/drivers/sound/maestro.c
--- v2.4.10/linux/drivers/sound/maestro.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/maestro.c	Sun Sep 30 12:26:08 2001
@@ -257,6 +257,8 @@
 
 MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>");
 MODULE_DESCRIPTION("ESS Maestro Driver");
+MODULE_LICENSE("GPL");
+
 #ifdef M_DEBUG
 MODULE_PARM(debug,"i");
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- v2.4.10/linux/drivers/sound/maestro3.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/maestro3.c	Sun Sep 30 12:26:08 2001
@@ -2905,6 +2905,8 @@
 
 MODULE_AUTHOR("Zach Brown <zab@zabbo.net>");
 MODULE_DESCRIPTION("ESS Maestro3/Allegro Driver");
+MODULE_LICENSE("GPL");
+
 #ifdef M_DEBUG
 MODULE_PARM(debug,"i");
 #endif
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/maui.c linux/drivers/sound/maui.c
--- v2.4.10/linux/drivers/sound/maui.c	Sat Nov 11 18:33:13 2000
+++ linux/drivers/sound/maui.c	Sun Sep 30 12:26:08 2001
@@ -474,3 +474,4 @@
 
 __setup("maui=", setup_maui);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/midibuf.c linux/drivers/sound/midibuf.c
--- v2.4.10/linux/drivers/sound/midibuf.c	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/midibuf.c	Sun Sep 30 12:26:08 2001
@@ -253,13 +253,13 @@
 
 	midi_devs[dev]->close(dev);
 
+	open_devs--;
+	if (open_devs == 0)
+		del_timer_sync(&poll_timer);
 	vfree(midi_in_buf[dev]);
 	vfree(midi_out_buf[dev]);
 	midi_in_buf[dev] = NULL;
 	midi_out_buf[dev] = NULL;
-	if (open_devs < 2)
-		del_timer(&poll_timer);;
-	open_devs--;
 
 	if (midi_devs[dev]->owner)
 		__MOD_DEC_USE_COUNT (midi_devs[dev]->owner);
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/mpu401.c linux/drivers/sound/mpu401.c
--- v2.4.10/linux/drivers/sound/mpu401.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/mpu401.c	Sun Sep 30 12:26:08 2001
@@ -1794,3 +1794,4 @@
 
 __setup("mpu401=", setup_mpu401);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/msnd.c linux/drivers/sound/msnd.c
--- v2.4.10/linux/drivers/sound/msnd.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/sound/msnd.c	Sun Sep 30 12:26:08 2001
@@ -392,6 +392,8 @@
 #ifdef MODULE
 MODULE_AUTHOR				("Andrew Veliath <andrewtv@usa.net>");
 MODULE_DESCRIPTION			("Turtle Beach MultiSound Driver Base");
+MODULE_LICENSE("GPL");
+
 
 int init_module(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- v2.4.10/linux/drivers/sound/msnd_pinnacle.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/msnd_pinnacle.c	Sun Sep 30 12:26:08 2001
@@ -1571,6 +1571,8 @@
 #ifdef MODULE
 MODULE_AUTHOR				("Andrew Veliath <andrewtv@usa.net>");
 MODULE_DESCRIPTION			("Turtle Beach " LONGNAME " Linux Driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM				(io, "i");
 MODULE_PARM				(irq, "i");
 MODULE_PARM				(mem, "i");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/nm256_audio.c linux/drivers/sound/nm256_audio.c
--- v2.4.10/linux/drivers/sound/nm256_audio.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/sound/nm256_audio.c	Sun Sep 30 12:26:08 2001
@@ -1653,6 +1653,8 @@
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, nm256_pci_tbl);
+MODULE_LICENSE("GPL");
+
 
 struct pci_driver nm256_pci_driver = {
 	name:"nm256_audio",
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/opl3.c linux/drivers/sound/opl3.c
--- v2.4.10/linux/drivers/sound/opl3.c	Sun Sep 17 09:45:06 2000
+++ linux/drivers/sound/opl3.c	Sun Sep 30 12:26:08 2001
@@ -1250,3 +1250,4 @@
 
 __setup("opl3=", setup_opl3);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/opl3sa.c linux/drivers/sound/opl3sa.c
--- v2.4.10/linux/drivers/sound/opl3sa.c	Wed Sep 27 13:53:56 2000
+++ linux/drivers/sound/opl3sa.c	Sun Sep 30 12:26:08 2001
@@ -334,3 +334,4 @@
 
 __setup("opl3sa=", setup_opl3sa);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.4.10/linux/drivers/sound/opl3sa2.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/opl3sa2.c	Sun Sep 30 12:26:08 2001
@@ -164,6 +164,8 @@
 
 MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
 MODULE_AUTHOR("Scott Murray <scott@spiteful.org>");
+MODULE_LICENSE("GPL");
+
 
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "Set I/O base of OPL3-SA2 or SA3 card (usually 0x370.  Address must be even and must be from 0x100 to 0xFFE)");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/pas2_card.c linux/drivers/sound/pas2_card.c
--- v2.4.10/linux/drivers/sound/pas2_card.c	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/pas2_card.c	Sun Sep 30 12:26:08 2001
@@ -403,6 +403,8 @@
 MODULE_PARM(symphony,"i");
 MODULE_PARM(broken_bus_clock,"i");
 
+MODULE_LICENSE("GPL");
+
 static int __init init_pas2(void)
 {
 	printk(KERN_INFO "Pro Audio Spectrum driver Copyright (C) by Hannu Savolainen 1993-1996\n");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/pss.c linux/drivers/sound/pss.c
--- v2.4.10/linux/drivers/sound/pss.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/sound/pss.c	Sun Sep 30 12:26:08 2001
@@ -1132,6 +1132,8 @@
 MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble, synth volume). The mixer is not available on all PSS cards.");
 MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
 MODULE_DESCRIPTION("Module for PSS sound cards (based on AD1848, ADSP-2115 and ESC614). This module includes control of output amplifier and synth volume of the Beethoven ADSP-16 card (this may work with other PSS cards).\n");
+MODULE_LICENSE("GPL");
+
 
 static int fw_load = 0;
 static int pssmpu = 0, pssmss = 0;
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/rme96xx.c linux/drivers/sound/rme96xx.c
--- v2.4.10/linux/drivers/sound/rme96xx.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/rme96xx.c	Sun Sep 30 12:26:08 2001
@@ -52,6 +52,8 @@
 
 MODULE_AUTHOR("Guenter Geiger, geiger@debian.org");
 MODULE_DESCRIPTION("RME9652/36 \"Hammerfall\" Driver");
+MODULE_LICENSE("GPL");
+
 
 #ifdef DEBUG
 #define DBG(x) printk("RME_DEBUG:");x
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.4.10/linux/drivers/sound/sb_card.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/sb_card.c	Sun Sep 30 12:26:08 2001
@@ -211,6 +211,7 @@
 #endif
 
 MODULE_DESCRIPTION("Soundblaster driver");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(io,		"i");
 MODULE_PARM(irq,	"i");
@@ -365,11 +366,6 @@
 		0,1,1,-1},
         {"Sound Blaster AWE 32",
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0045),
-		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
-		0,0,0,0,
-		0,1,1,-1},
-	{"Sound Blaster AWE 32",
-		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0047),
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
 		0,0,0,0,
 		0,1,1,-1},
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- v2.4.10/linux/drivers/sound/sb_common.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/sound/sb_common.c	Sun Sep 30 12:26:08 2001
@@ -1292,3 +1292,4 @@
 EXPORT_SYMBOL(probe_sbmpu);
 EXPORT_SYMBOL(unload_sbmpu);
 EXPORT_SYMBOL(smw_free);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c
--- v2.4.10/linux/drivers/sound/sb_mixer.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/sound/sb_mixer.c	Sun Sep 30 12:26:08 2001
@@ -748,6 +748,9 @@
 
 void sb_mixer_unload(sb_devc *devc)
 {
+	if (devc->my_mixerdev == -1)
+		return;
+
 	kfree(mixer_devs[devc->my_mixerdev]);
 	sound_unload_mixerdev(devc->my_mixerdev);
 	sbmixnum--;
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/sgalaxy.c linux/drivers/sound/sgalaxy.c
--- v2.4.10/linux/drivers/sound/sgalaxy.c	Sat Nov 11 18:33:14 2000
+++ linux/drivers/sound/sgalaxy.c	Sun Sep 30 12:26:08 2001
@@ -194,3 +194,4 @@
 
 __setup("sgalaxy=", setup_sgalaxy);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- v2.4.10/linux/drivers/sound/sonicvibes.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/sonicvibes.c	Sun Sep 30 12:26:08 2001
@@ -2458,6 +2458,8 @@
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
 MODULE_DESCRIPTION("S3 SonicVibes Driver");
+MODULE_LICENSE("GPL");
+
 
 /* --------------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- v2.4.10/linux/drivers/sound/sound_core.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/sound_core.c	Sun Sep 30 12:26:08 2001
@@ -547,6 +547,7 @@
 
 MODULE_DESCRIPTION("Core sound module");
 MODULE_AUTHOR("Alan Cox");
+MODULE_LICENSE("GPL");
 
 static void __exit cleanup_soundcore(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v2.4.10/linux/drivers/sound/soundcard.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sound/soundcard.c	Sun Sep 30 12:26:08 2001
@@ -44,6 +44,7 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
+#include <linux/module.h>
 
 /*
  * This ought to be moved into include/asm/dma.h
@@ -645,6 +646,7 @@
 
 module_init(oss_init);
 module_exit(oss_cleanup);
+MODULE_LICENSE("GPL");
 
 
 int sound_alloc_dma(int chn, char *deviceID)
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/sscape.c linux/drivers/sound/sscape.c
--- v2.4.10/linux/drivers/sound/sscape.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/sound/sscape.c	Sun Sep 30 12:26:08 2001
@@ -1528,3 +1528,4 @@
 
 __setup("sscape=", setup_sscape);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.4.10/linux/drivers/sound/trident.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/trident.c	Sun Sep 30 12:26:08 2001
@@ -4165,6 +4165,8 @@
 
 MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee");
 MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 and Tvia/IGST CyberPro5050 PCI Audio Driver");
+MODULE_LICENSE("GPL");
+
 
 #define TRIDENT_MODULE_NAME "trident"
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/trix.c linux/drivers/sound/trix.c
--- v2.4.10/linux/drivers/sound/trix.c	Sun Jan 28 13:30:07 2001
+++ linux/drivers/sound/trix.c	Sun Sep 30 12:26:08 2001
@@ -543,3 +543,4 @@
 
 __setup("trix=", setup_trix);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/uart401.c linux/drivers/sound/uart401.c
--- v2.4.10/linux/drivers/sound/uart401.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/uart401.c	Sun Sep 30 12:26:08 2001
@@ -478,3 +478,4 @@
 
 __setup("uart401=", setup_uart401);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/uart6850.c linux/drivers/sound/uart6850.c
--- v2.4.10/linux/drivers/sound/uart6850.c	Sun Sep 17 09:45:07 2000
+++ linux/drivers/sound/uart6850.c	Sun Sep 30 12:26:08 2001
@@ -361,3 +361,4 @@
 }
 __setup("uart6850=", setup_uart6850);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/v_midi.c linux/drivers/sound/v_midi.c
--- v2.4.10/linux/drivers/sound/v_midi.c	Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/v_midi.c	Sun Sep 30 12:26:08 2001
@@ -287,3 +287,4 @@
 
 module_init(init_vmidi);
 module_exit(cleanup_vmidi);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c
--- v2.4.10/linux/drivers/sound/via82cxxx_audio.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/via82cxxx_audio.c	Sun Sep 30 12:26:08 2001
@@ -3254,6 +3254,8 @@
 
 MODULE_AUTHOR("Jeff Garzik <jgarzik@mandrakesoft.com>");
 MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices");
+MODULE_LICENSE("GPL");
+
 EXPORT_NO_SYMBOLS;
 
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c
--- v2.4.10/linux/drivers/sound/wavfront.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/wavfront.c	Sun Sep 30 12:26:08 2001
@@ -3486,6 +3486,7 @@
 
 MODULE_AUTHOR      ("Paul Barton-Davis <pbd@op.net>");
 MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM        (io,"i");
 MODULE_PARM        (irq,"i");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- v2.4.10/linux/drivers/sound/ymfpci.c	Sun Sep 23 11:40:59 2001
+++ linux/drivers/sound/ymfpci.c	Sun Sep 30 12:26:08 2001
@@ -2525,6 +2525,7 @@
 
 MODULE_AUTHOR("Jaroslav Kysela");
 MODULE_DESCRIPTION("Yamaha YMF7xx PCI Audio");
+MODULE_LICENSE("GPL");
 
 static struct pci_driver ymfpci_driver = {
 	name:		"ymfpci",
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/CDCEther.c linux/drivers/usb/CDCEther.c
--- v2.4.10/linux/drivers/usb/CDCEther.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/CDCEther.c	Fri Oct  5 12:06:08 2001
@@ -31,12 +31,10 @@
 
 static const char *version = __FILE__ ": v0.98.5 22 Sep 2001 Brad Hards and another";
 
-/* We need to be selective about what we try to match on, to avoiding loading for a CDC
- * ACM (ISDN or PSTN) modem */
+/* Take any CDC device, and sort it out in probe() */
 static struct usb_device_id CDCEther_ids[] = {
-        { match_flags: (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
-          bInterfaceClass: USB_CLASS_COMM, bInterfaceSubClass: 6},
-        { } /* Terminating null entry */
+	{ USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
+	{ } /* Terminating null entry */
 };
 
 /* 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.4.10/linux/drivers/usb/Config.in	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/Config.in	Fri Oct  5 12:04:51 2001
@@ -59,6 +59,7 @@
    dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
    dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
    dep_tristate '  Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
+   dep_tristate '  HP53xx USB scanner support (EXPERIMENTAL)' CONFIG_USB_HPUSBSCSI $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
 
    comment 'USB Multimedia devices'
    dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/Makefile linux/drivers/usb/Makefile
--- v2.4.10/linux/drivers/usb/Makefile	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/Makefile	Fri Oct  5 12:04:51 2001
@@ -59,7 +59,7 @@
 obj-$(CONFIG_USB_ACM)		+= acm.o
 obj-$(CONFIG_USB_PRINTER)	+= printer.o
 obj-$(CONFIG_USB_AUDIO)		+= audio.o
-obj-$(CONFIG_USB_IBMCAM)	+= ibmcam.o
+obj-$(CONFIG_USB_IBMCAM)	+= ibmcam.o usbvideo.o ultracam.o
 obj-$(CONFIG_USB_PWC)		+= pwc.o
 obj-$(CONFIG_USB_DC2XX)		+= dc2xx.o
 obj-$(CONFIG_USB_MDC800)	+= mdc800.o
@@ -74,6 +74,7 @@
 obj-$(CONFIG_USB_RIO500)	+= rio500.o
 obj-$(CONFIG_USB_DSBR)		+= dsbr100.o
 obj-$(CONFIG_USB_MICROTEK)	+= microtek.o
+obj-$(CONFIG_USB_HPUSBSCSI)	+= hpusbscsi.o
 obj-$(CONFIG_USB_BLUETOOTH)	+= bluetooth.o
 obj-$(CONFIG_USB_USBNET)	+= usbnet.o
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
--- v2.4.10/linux/drivers/usb/acm.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/acm.c	Fri Oct  5 12:06:08 2001
@@ -1,9 +1,9 @@
 /*
- * acm.c  Version 0.20
+ * acm.c  Version 0.21
  *
  * Copyright (c) 1999 Armin Fuerst	<fuerst@in.tum.de>
  * Copyright (c) 1999 Pavel Machek	<pavel@suse.cz>
- * Copyright (c) 1999 Johannes Erdfelt	<jerdfelt@valinux.com>
+ * Copyright (c) 1999 Johannes Erdfelt	<johannes@erdfelt.com>
  * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
  *
  * USB Abstract Control Model driver for USB modems and ISDN adapters
@@ -22,7 +22,8 @@
  *	v0.17 - added new style probing
  *	v0.18 - fixed new style probing for devices with more configurations
  *	v0.19 - fixed CLOCAL handling (thanks to Richard Shih-Ping Chan)
- *      v0.20 - switched to probing on interface (rather than device) class
+ *	v0.20 - switched to probing on interface (rather than device) class
+ *	v0.21 - revert to probing on device for devices with multiple configs
  */
 
 /*
@@ -60,7 +61,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.20"
+#define DRIVER_VERSION "v0.21"
 #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
 
@@ -648,8 +649,7 @@
  */
 
 static struct usb_device_id acm_ids[] = {
-	{match_flags: (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
-	bInterfaceClass: USB_CLASS_COMM, bInterfaceSubClass: 2},
+	{ USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
 	{ }
 };
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/audio.c linux/drivers/usb/audio.c
--- v2.4.10/linux/drivers/usb/audio.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/usb/audio.c	Fri Oct  5 12:04:50 2001
@@ -3,7 +3,7 @@
 /*
  *	audio.c  --  USB Audio Class driver
  *
- *	Copyright (C) 1999, 2000
+ *	Copyright (C) 1999, 2000, 2001
  *	    Alan Cox (alan@lxorguk.ukuu.org.uk)
  *	    Thomas Sailer (sailer@ife.ee.ethz.ch)
  *
@@ -12,6 +12,8 @@
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
  *
+ * Debugging:
+ * 	Use the 'lsusb' utility to dump the descriptors.
  *
  * 1999-09-07:  Alan Cox
  *		Parsing Audio descriptor patch
@@ -92,9 +94,11 @@
  * 2000-11-26:  Thomas Sailer
  *              Workaround for Dallas DS4201. The DS4201 uses PCM8 as format tag for
  *              its 8 bit modes, but expects signed data (and should therefore have used PCM).
- * 2001-04-08:  gb
- *              Identify version on module load.
- *
+ * 2001-03-10:  Thomas Sailer
+ *              provide abs function, prevent picking up a bogus kernel macro
+ *              for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
+ * 2001-06-16:  Bryce Nesbitt <bryce@obviously.com>
+ *              Fix SNDCTL_DSP_STEREO API violation
  */
 
 /*
@@ -205,6 +209,9 @@
 
 #define dprintk(x)
 
+#undef abs
+extern int abs(int __x) __attribute__ ((__const__)); /* Shut up warning */
+
 /* --------------------------------------------------------------------- */
 
 /*
@@ -390,6 +397,17 @@
 
 /* --------------------------------------------------------------------- */
 
+/* prevent picking up a bogus abs macro */
+#undef abs
+extern inline int abs(int x)
+{
+        if (x < 0)
+		return -x;
+	return x;
+}
+                                
+/* --------------------------------------------------------------------- */
+
 extern inline unsigned ld2(unsigned int x)
 {
 	unsigned r = 0;
@@ -485,10 +503,10 @@
 	}
 	db->bufsize = nr << PAGE_SHIFT;
 	db->ready = 1;
-	dprintk((KERN_DEBUG "dmabuf_init: bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d "
-	         "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d fmt 0x%x\n",
+	dprintk((KERN_DEBUG "usbaudio: dmabuf_init bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d "
+	         "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d fmt 0x%x srate %d\n",
 	         bytepersec, bufs, db->ossfragshift, db->ossmaxfrags, db->fragshift, db->fragsize,
-	         db->numfrag, db->dmasize, db->bufsize, db->format));
+	         db->numfrag, db->dmasize, db->bufsize, db->format, db->srate));
 	return 0;
 }
 
@@ -860,9 +878,11 @@
 		u->dma.count += cnt;
 		if (u->format == u->dma.format) {
 			/* we do not need format conversion */
+			dprintk((KERN_DEBUG "usbaudio: no sample format conversion\n"));
 			dmabuf_copyin(&u->dma, cp, cnt);
 		} else {
 			/* we need sampling format conversion */
+			dprintk((KERN_DEBUG "usbaudio: sample format conversion %x != %x\n", u->format, u->dma.format));
 			usbin_convert(u, cp, scnt);
 		}
 	}
@@ -1533,7 +1553,7 @@
 		d->srate = fmt->sratelo;
 	if (d->srate > fmt->sratehi)
 		d->srate = fmt->sratehi;
-	dprintk((KERN_DEBUG "usb_audio: set_format_in: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
+	dprintk((KERN_DEBUG "usbaudio: set_format_in: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
 	if (usb_set_interface(dev, alts->bInterfaceNumber, fmt->altsetting) < 0) {
 		printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",
 		       dev->devnum, u->interface, fmt->altsetting);
@@ -1628,7 +1648,7 @@
 		d->srate = fmt->sratelo;
 	if (d->srate > fmt->sratehi)
 		d->srate = fmt->sratehi;
-	dprintk((KERN_DEBUG "usb_audio: set_format_out: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
+	dprintk((KERN_DEBUG "usbaudio: set_format_out: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
 	if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) {
 		printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",
 		       dev->devnum, u->interface, fmt->altsetting);
@@ -1925,13 +1945,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static loff_t usb_audio_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-/* --------------------------------------------------------------------- */
-
 static int usb_audio_open_mixdev(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
@@ -2071,7 +2084,7 @@
 
 static /*const*/ struct file_operations usb_mixer_fops = {
 	owner:		THIS_MODULE,
-	llseek:		usb_audio_llseek,
+	llseek:		no_llseek,
 	ioctl:		usb_audio_ioctl_mixdev,
 	open:		usb_audio_open_mixdev,
 	release:	usb_audio_release_mixdev,
@@ -2341,12 +2354,18 @@
 	unsigned long flags;
 	audio_buf_info abinfo;
 	count_info cinfo;
-	int val, val2, mapped, ret;
+	int val = 0;
+	int val2, mapped, ret;
 
 	if (!s->usbdev)
 		return -EIO;
 	mapped = ((file->f_mode & FMODE_WRITE) && as->usbout.dma.mapped) ||
 		((file->f_mode & FMODE_READ) && as->usbin.dma.mapped);
+#if 0
+	if (arg)
+		get_user(val, (int *)arg);
+	printk(KERN_DEBUG "usbaudio: usb_audio_ioctl cmd=%x arg=%lx *arg=%d\n", cmd, arg, val)
+#endif
 	switch (cmd) {
 	case OSS_GETVERSION:
 		return put_user(SOUND_VERSION, (int *)arg);
@@ -2388,8 +2407,14 @@
 		return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg);
 
 	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *)arg))
+			return -EFAULT;
 		val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
-		if (set_format(as, file->f_mode, val2 | AFMT_STEREO, 0))
+		if (val)
+			val2 |= AFMT_STEREO;
+		else
+			val2 &= ~AFMT_STEREO;
+		if (set_format(as, file->f_mode, val2, 0))
 			return -EIO;
 		return 0;
 
@@ -2590,6 +2615,7 @@
 	case SOUND_PCM_READ_FILTER:
 		return -EINVAL;
 	}
+	dprintk((KERN_DEBUG "usbaudio: usb_audio_ioctl - no command found\n"));
 	return -ENOIOCTLCMD;
 }
 
@@ -2690,7 +2716,7 @@
 
 static /*const*/ struct file_operations usb_audio_fops = {
 	owner:		THIS_MODULE,
-	llseek:		usb_audio_llseek,
+	llseek:		no_llseek,
 	read:		usb_audio_read,
 	write:		usb_audio_write,
 	poll:		usb_audio_poll,
@@ -2815,8 +2841,10 @@
 			if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2)
 				continue;
 			if (alts->bNumEndpoints < 1) {
-				printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", 
-				       dev->devnum, asifin, i);
+				if (i != 0) {  /* altsetting 0 has no endpoints (Section B.3.4.1) */
+					printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", 
+					       dev->devnum, asifin, i);
+				}
 				continue;
 			}
 			if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 ||
@@ -2871,8 +2899,10 @@
 			fp->format = format;
 			fp->altsetting = i;
 			fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16);
+			printk(KERN_INFO "usbaudio: valid input sample rate %u\n", fp->sratelo);
 			for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) {
 				k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16);
+				printk(KERN_INFO "usbaudio: valid input sample rate %u\n", k);
 				if (k > fp->sratehi)
 					fp->sratehi = k;
 				if (k < fp->sratelo)
@@ -2902,6 +2932,7 @@
 				       dev->devnum, asifout, i);
 				continue;
 			}
+			/* See USB audio formats manual, section 2 */
 			fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifout, i);
 			if (!fmt) {
 				printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", 
@@ -2951,8 +2982,10 @@
 			fp->format = format;
 			fp->altsetting = i;
 			fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16);
+			printk(KERN_INFO "usbaudio: valid output sample rate %u\n", fp->sratelo);
 			for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) {
 				k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16);
+				printk(KERN_INFO "usbaudio: valid output sample rate %u\n", k);
 				if (k > fp->sratehi)
 					fp->sratehi = k;
 				if (k < fp->sratelo)
@@ -2972,6 +3005,7 @@
 		kfree(as);
 		return;
 	}
+	printk(KERN_INFO "usbaudio: registered dsp 14,%d\n", as->dev_audio);
 	/* everything successful */
 	list_add_tail(&as->list, &s->audiolist);
 }
@@ -3318,6 +3352,8 @@
 	state->chconfig = proc[8+proc[6]] | (proc[9+proc[6]] << 8);
 }
 
+
+/* See Audio Class Spec, section 4.3.2.5 */
 static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr)
 {
 	struct mixerchannel *ch;
@@ -3335,7 +3371,7 @@
 	if (state->nrchannels > 2)
 		printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
 	if (state->nrchannels == 1 && ftr[0] == 7+ftr[5]) {
-		printk(KERN_WARNING "usbaudio: workaround for broken Philips Camera Microphone descriptor enabled\n");
+		printk(KERN_DEBUG "usbaudio: workaround for Philips camera microphone descriptor enabled\n");
 		mchftr = ftr[6];
 		chftr = 0;
 	} else {
@@ -3465,7 +3501,7 @@
 		usb_audio_selectorunit(state, p1);
 		return;
 
-	case FEATURE_UNIT:
+	case FEATURE_UNIT: /* See USB Audio Class Spec 4.3.2.5 */
 		if (p1[0] < 7 || p1[0] < 7+p1[5]) {
 			printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid);
 			return;
@@ -3517,7 +3553,7 @@
 	state.buflen = buflen;
 	state.ctrlif = ctrlif;
 	set_bit(oterm[3], &state.unitbitmap);  /* mark terminal ID as visited */
-	printk(KERN_INFO "usbaudio: constructing mixer for Terminal %u type 0x%04x\n",
+	printk(KERN_DEBUG "usbaudio: constructing mixer for Terminal %u type 0x%04x\n",
 	       oterm[3], oterm[4] | (oterm[5] << 8));
 	usb_audio_recurseunit(&state, oterm[7]);
 	if (!state.nrmixch) {
@@ -3536,6 +3572,7 @@
 		kfree(ms);
 		return;
 	}
+	printk(KERN_INFO "usbaudio: registered mixer 14,%d\n", ms->dev_mixer);
 	list_add_tail(&ms->list, &s->mixerlist);
 }
 
@@ -3688,8 +3725,8 @@
 		return NULL;
 	}
 	ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8);
-	if (ret<0) {
-		printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum);
+	if (ret < 0) {
+		printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
 		return NULL;
 	}
 	if (buf[1] != USB_DT_CONFIG || buf[0] < 9) {
@@ -3702,7 +3739,7 @@
 	ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen);
 	if (ret < 0) {
 		kfree(buffer);
-		printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d\n", i, dev->devnum);
+		printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
 		return NULL;
 	}
 	return usb_audio_parsecontrol(dev, buffer, buflen, ifnum);
@@ -3720,11 +3757,11 @@
 
 	/* we get called with -1 for every audiostreaming interface registered */
 	if (s == (struct usb_audio_state *)-1) {
-		dprintk((KERN_DEBUG "usb_audio_disconnect: called with -1\n"));
+		dprintk((KERN_DEBUG "usbaudio: note, usb_audio_disconnect called with -1\n"));
 		return;
 	}
 	if (!s->usbdev) {
-		dprintk((KERN_DEBUG "usb_audio_disconnect: already called for %p!\n", s));
+		dprintk((KERN_DEBUG "usbaudio: error,  usb_audio_disconnect already called for %p!\n", s));
 		return;
 	}
 	down(&open_sem);
@@ -3738,14 +3775,18 @@
 		usbout_disc(as);
 		wake_up(&as->usbin.dma.wait);
 		wake_up(&as->usbout.dma.wait);
-		if (as->dev_audio >= 0)
+		if (as->dev_audio >= 0) {
 			unregister_sound_dsp(as->dev_audio);
+			printk(KERN_INFO "usbaudio: unregister dsp 14,%d\n", as->dev_audio);
+		}
 		as->dev_audio = -1;
 	}
 	for(list = s->mixerlist.next; list != &s->mixerlist; list = list->next) {
 		ms = list_entry(list, struct usb_mixerdev, list);
-		if (ms->dev_mixer >= 0)
+		if (ms->dev_mixer >= 0) {
 			unregister_sound_mixer(ms->dev_mixer);
+			printk(KERN_INFO "usbaudio: unregister mixer 14,%d\n", ms->dev_mixer);
+		}
 		ms->dev_mixer = -1;
 	}
 	release(s);
@@ -3770,4 +3811,5 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/dsbr100.c linux/drivers/usb/dsbr100.c
--- v2.4.10/linux/drivers/usb/dsbr100.c	Wed Jul 25 17:10:23 2001
+++ linux/drivers/usb/dsbr100.c	Tue Oct  9 15:15:02 2001
@@ -64,6 +64,7 @@
 #include <linux/input.h>
 #include <linux/videodev.h>
 #include <linux/usb.h>
+#include <linux/smp_lock.h>
 
 /*
  * Version Information
@@ -194,10 +195,14 @@
 {
 	usb_dsbr100 *radio=ptr;
 
-	if (users)
+	lock_kernel();
+	if (users) {
+		unlock_kernel();
 		return;
+	}
 	kfree(radio);
 	usb_dsbr100_radio.priv = NULL;
+	unlock_kernel();
 }
 
 static int usb_dsbr100_ioctl(struct video_device *dev, unsigned int cmd, 
@@ -362,6 +367,7 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
 
 /*
 vi: ts=8
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/hpusbscsi.c linux/drivers/usb/hpusbscsi.c
--- v2.4.10/linux/drivers/usb/hpusbscsi.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/hpusbscsi.c	Tue Oct  9 15:15:02 2001
@@ -0,0 +1,519 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/usb.h>
+#include <asm/atomic.h>
+#include <linux/blk.h>
+#include "../scsi/scsi.h"
+#include "../scsi/hosts.h"
+#include "../scsi/sd.h"
+
+#include "hpusbscsi.h"
+
+#define DEBUG(x...) \
+	printk( KERN_DEBUG x )
+
+static char *states[]={"FREE", "BEGINNING", "WORKING", "ERROR", "WAIT", "PREMATURE"};
+
+#define TRACE_STATE printk(KERN_DEBUG"hpusbscsi->state = %s at line %d\n", states[hpusbscsi->state], __LINE__)
+
+/* global variables */
+
+struct list_head hpusbscsi_devices;
+//LIST_HEAD(hpusbscsi_devices);
+
+/* USB related parts */
+
+static void *
+hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface,
+		     const struct usb_device_id *id)
+{
+	struct hpusbscsi *new;
+	struct usb_interface_descriptor *altsetting =
+		&(dev->actconfig->interface[interface].altsetting[0]);
+
+	int i, result;
+
+	/* basic check */
+
+	if (altsetting->bNumEndpoints != 3) {
+		printk (KERN_ERR "Wrong number of endpoints\n");
+		return NULL;
+	}
+
+	/* descriptor allocation */
+
+	new =
+		(struct hpusbscsi *) kmalloc (sizeof (struct hpusbscsi),
+					      GFP_KERNEL);
+	if (new == NULL)
+		return NULL;
+	DEBUG ("Allocated memory\n");
+	memset (new, 0, sizeof (struct hpusbscsi));
+	spin_lock_init (&new->dataurb.lock);
+	spin_lock_init (&new->controlurb.lock);
+	new->dev = dev;
+	init_waitqueue_head (&new->pending);
+	init_waitqueue_head (&new->deathrow);
+	INIT_LIST_HEAD (&new->lh);
+
+
+
+	/* finding endpoints */
+
+	for (i = 0; i < altsetting->bNumEndpoints; i++) {
+		if (
+		    (altsetting->endpoint[i].
+		     bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		    USB_ENDPOINT_XFER_BULK) {
+			if (altsetting->endpoint[i].
+			    bEndpointAddress & USB_DIR_IN) {
+				new->ep_in =
+					altsetting->endpoint[i].
+					bEndpointAddress &
+					USB_ENDPOINT_NUMBER_MASK;
+			} else {
+				new->ep_out =
+					altsetting->endpoint[i].
+					bEndpointAddress &
+					USB_ENDPOINT_NUMBER_MASK;
+			}
+		} else {
+			new->ep_int =
+				altsetting->endpoint[i].
+				bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+			new->interrupt_interval= altsetting->endpoint[i].bInterval;
+		}
+	}
+
+	/* USB initialisation magic for the simple case */
+
+	result = usb_set_interface (dev, altsetting->bInterfaceNumber, 0);
+
+	switch (result) {
+	case 0:		/* no error */
+		break;
+
+	case -EPIPE:
+		usb_clear_halt (dev, usb_sndctrlpipe (dev, 0));
+		break;
+
+	default:
+		printk (KERN_ERR "unknown error %d from usb_set_interface\n",
+			 result);
+		goto err_out;
+	}
+
+	/* making a template for the scsi layer to fake detection of a scsi device */
+
+	memcpy (&(new->ctempl), &hpusbscsi_scsi_host_template,
+		sizeof (hpusbscsi_scsi_host_template));
+	(struct hpusbscsi *) new->ctempl.proc_dir = new;
+	new->ctempl.module = THIS_MODULE;
+
+	if (scsi_register_module (MODULE_SCSI_HA, &(new->ctempl)))
+		goto err_out;
+
+	/* adding to list for module unload */
+	list_add (&hpusbscsi_devices, &new->lh);
+
+	return new;
+
+      err_out:
+	kfree (new);
+	return NULL;
+}
+
+static void
+hpusbscsi_usb_disconnect (struct usb_device *dev, void *ptr)
+{
+                 usb_unlink_urb(&(((struct hpusbscsi *) ptr)->controlurb));
+	((struct hpusbscsi *) ptr)->dev = NULL;
+}
+
+static struct usb_device_id hpusbscsi_usb_ids[] = {
+	{USB_DEVICE (0x03f0, 0x0701)},	/* HP 53xx */
+	{USB_DEVICE (0x03f0, 0x0801)},	/* HP 7400 */
+	{USB_DEVICE (0x0638, 0x026a)},	/*Scan Dual II */
+	{}			/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, hpusbscsi_usb_ids);
+MODULE_LICENSE("GPL");
+
+
+static struct usb_driver hpusbscsi_usb_driver = {
+	name:"hpusbscsi",
+	probe:hpusbscsi_usb_probe,
+	disconnect:hpusbscsi_usb_disconnect,
+	id_table:hpusbscsi_usb_ids,
+};
+
+/* module initialisation */
+
+int __init
+hpusbscsi_init (void)
+{
+	int result;
+
+	INIT_LIST_HEAD (&hpusbscsi_devices);
+	DEBUG ("Driver loaded\n");
+
+	if ((result = usb_register (&hpusbscsi_usb_driver)) < 0) {
+		printk (KERN_ERR "hpusbscsi: driver registration failed\n");
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+void __exit
+hpusbscsi_exit (void)
+{
+	struct list_head *tmp;
+	struct list_head *old;
+	struct hpusbscsi * o;
+
+	for (tmp = hpusbscsi_devices.next; tmp != &hpusbscsi_devices;/*nothing */) {
+		old = tmp;
+		tmp = tmp->next;
+		o = (struct hpusbscsi *)old;
+		usb_unlink_urb(&o->controlurb);
+		scsi_unregister_module(MODULE_SCSI_HA,&o->ctempl);
+		kfree(old);
+	}
+
+	usb_deregister (&hpusbscsi_usb_driver);
+}
+
+module_init (hpusbscsi_init);
+module_exit (hpusbscsi_exit);
+
+/* interface to the scsi layer */
+
+static int
+hpusbscsi_scsi_detect (struct SHT *sht)
+{
+	/* Whole function stolen from usb-storage */
+
+	struct hpusbscsi *desc = (struct hpusbscsi *) sht->proc_dir;
+	/* What a hideous hack! */
+
+	char local_name[48];
+
+
+	/* set up the name of our subdirectory under /proc/scsi/ */
+	sprintf (local_name, "hpusbscsi-%d", desc->number);
+	sht->proc_name = kmalloc (strlen (local_name) + 1, GFP_KERNEL);
+	/* FIXME: where is this freed ? */
+
+	if (!sht->proc_name) {
+		return 0;
+	}
+
+	strcpy (sht->proc_name, local_name);
+
+	sht->proc_dir = NULL;
+
+	/* build and submit an interrupt URB for status byte handling */
+ 	FILL_INT_URB(&desc->controlurb,
+			desc->dev,
+			usb_rcvintpipe(desc->dev,desc->ep_int),
+			&desc->scsi_state_byte,
+			1,
+			control_interrupt_callback,
+			desc,
+			desc->interrupt_interval
+	);
+
+	if ( 0  >  usb_submit_urb(&desc->controlurb)) {
+		kfree(sht->proc_name);
+		return 0;
+	}
+
+	/* In host->hostdata we store a pointer to desc */
+	desc->host = scsi_register (sht, sizeof (desc));
+	if (desc->host == NULL) {
+		kfree (sht->proc_name);
+		usb_unlink_urb(&desc->controlurb);
+		return 0;
+	}
+	desc->host->hostdata[0] = (unsigned long) desc;
+
+
+	return 1;
+}
+
+static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
+{
+	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
+	usb_urb_callback usb_callback;
+	int res;
+
+	hpusbscsi->use_count++;
+
+	/* we don't answer for anything but our single device on any faked host controller */
+	if ( srb->device->lun || srb->device->id || srb->device->channel ) {
+		if (callback) {
+			srb->result = DID_BAD_TARGET;
+			callback(srb);
+		}
+                	goto out;
+	}
+
+	/* Now we need to decide which callback to give to the urb we send the command with */
+
+	if (!srb->bufflen) {
+		usb_callback = simple_command_callback;
+	} else {
+        	if (srb->use_sg) {
+			usb_callback = scatter_gather_callback;
+			hpusbscsi->fragment = 0;
+		} else {
+                	usb_callback = simple_payload_callback;
+		}
+		/* Now we find out which direction data is to be transfered in */
+		hpusbscsi->current_data_pipe = DIRECTION_IS_IN(srb->cmnd[0]) ?
+			usb_rcvbulkpipe(hpusbscsi->dev, hpusbscsi->ep_in)
+		:
+			usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out)
+		;
+	}
+
+
+	TRACE_STATE;
+	if (hpusbscsi->state != HP_STATE_FREE) {
+		printk(KERN_CRIT"hpusbscsi - Ouch: queueing violation!\n");
+		return 1; /* This must not happen */
+	}
+
+        /* We zero the sense buffer to avoid confusing user space */
+        memset(srb->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+
+	hpusbscsi->state = HP_STATE_BEGINNING;
+	TRACE_STATE;
+
+	/* We prepare the urb for writing out the scsi command */
+	FILL_BULK_URB(
+		&hpusbscsi->dataurb,
+		hpusbscsi->dev,
+		usb_sndbulkpipe(hpusbscsi->dev,hpusbscsi->ep_out),
+		srb->cmnd,
+		srb->cmd_len,
+		usb_callback,
+		hpusbscsi
+	);
+	hpusbscsi->scallback = callback;
+	hpusbscsi->srb = srb;
+
+	res = usb_submit_urb(&hpusbscsi->dataurb);
+	if (res) {
+		hpusbscsi->state = HP_STATE_FREE;
+		TRACE_STATE;
+		if (callback) {
+			srb->result = DID_ERROR;
+			callback(srb);
+		}
+	}
+
+out:
+	hpusbscsi->use_count--;
+	return 0;
+}
+
+static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb)
+{
+	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
+
+	printk(KERN_DEBUG"SCSI reset requested.\n");
+	usb_reset_device(hpusbscsi->dev);
+	printk(KERN_DEBUG"SCSI reset completed.\n");
+	hpusbscsi->state = HP_STATE_FREE;
+
+	return 0;
+}
+
+static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
+{
+	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
+	printk(KERN_DEBUG"Requested is canceled.\n");
+
+	usb_unlink_urb(&hpusbscsi->dataurb);
+	usb_unlink_urb(&hpusbscsi->controlurb);
+	hpusbscsi->state = HP_STATE_FREE;
+
+	return SCSI_ABORT_PENDING;
+}
+
+/* usb interrupt handlers - they are all running IN INTERRUPT ! */
+
+static void handle_usb_error (struct hpusbscsi *hpusbscsi)
+{
+	if (hpusbscsi->scallback != NULL) {
+		hpusbscsi->srb->result = DID_ERROR;
+		hpusbscsi->scallback(hpusbscsi->srb);
+	}
+	hpusbscsi->state = HP_STATE_FREE;
+}
+
+static void  control_interrupt_callback (struct urb *u)
+{
+	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+
+DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte);
+	if(u->status < 0) {
+                if (hpusbscsi->state != HP_STATE_FREE)
+                        handle_usb_error(hpusbscsi);
+		return;
+	}
+	hpusbscsi->srb->result &= SCSI_ERR_MASK;
+	hpusbscsi->srb->result |= hpusbscsi->scsi_state_byte<<1;
+
+	if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT)
+		/* we do a callback to the scsi layer if and only if all data has been transfered */
+		hpusbscsi->scallback(hpusbscsi->srb);
+
+	TRACE_STATE;
+	switch (hpusbscsi->state) {
+	case HP_STATE_WAIT:
+		hpusbscsi->state = HP_STATE_FREE;
+	TRACE_STATE;
+		break;
+	case HP_STATE_WORKING:
+	case HP_STATE_BEGINNING:
+		hpusbscsi->state = HP_STATE_PREMATURE;
+	TRACE_STATE;
+		break;
+	default:
+		printk(KERN_ERR"hpusbscsi: Unexpected status report.\n");
+	TRACE_STATE;
+		hpusbscsi->state = HP_STATE_FREE;
+	TRACE_STATE;
+		break;
+	}
+}
+
+static void simple_command_callback(struct urb *u)
+{
+	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+	if (u->status<0) {
+		handle_usb_error(hpusbscsi);
+		return;
+        }
+	TRACE_STATE;
+	if (hpusbscsi->state != HP_STATE_PREMATURE) {
+	        TRACE_STATE;
+		hpusbscsi->state = HP_STATE_WAIT;
+	} else {
+		if (hpusbscsi->scallback != NULL)
+			hpusbscsi->scallback(hpusbscsi->srb);
+		hpusbscsi->state = HP_STATE_FREE;
+	TRACE_STATE;
+	}
+}
+
+static void scatter_gather_callback(struct urb *u)
+{
+	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+        struct scatterlist *sg = hpusbscsi->srb->buffer;
+        usb_urb_callback callback;
+        int res;
+
+        DEBUG("Going through scatter/gather\n");
+        if (u->status < 0) {
+                handle_usb_error(hpusbscsi);
+                return;
+        }
+
+        if (hpusbscsi->fragment + 1 != hpusbscsi->srb->use_sg)
+                callback = scatter_gather_callback;
+        else
+                callback = simple_done;
+
+	TRACE_STATE;
+        if (hpusbscsi->state != HP_STATE_PREMATURE)
+		hpusbscsi->state = HP_STATE_WORKING;
+	TRACE_STATE;
+
+        FILL_BULK_URB(
+                u,
+                hpusbscsi->dev,
+                hpusbscsi->current_data_pipe,
+                sg[hpusbscsi->fragment].address,
+                sg[hpusbscsi->fragment++].length,
+                callback,
+                hpusbscsi
+        );
+
+        res = usb_submit_urb(u);
+        if (res)
+                hpusbscsi->state = HP_STATE_ERROR;
+	TRACE_STATE;
+}
+
+static void simple_done (struct urb *u)
+{
+	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+
+        if (u->status < 0) {
+                handle_usb_error(hpusbscsi);
+                return;
+        }
+        DEBUG("Data transfer done\n");
+	TRACE_STATE;
+	if (hpusbscsi->state != HP_STATE_PREMATURE) {
+		if (u->status < 0)
+			hpusbscsi->state = HP_STATE_ERROR;
+		else
+			hpusbscsi->state = HP_STATE_WAIT;
+		TRACE_STATE;
+	} else {
+		if (hpusbscsi->scallback != NULL)
+			hpusbscsi->scallback(hpusbscsi->srb);
+		hpusbscsi->state = HP_STATE_FREE;
+	}
+}
+
+static void simple_payload_callback (struct urb *u)
+{
+	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+	int res;
+
+	if (u->status<0) {
+                handle_usb_error(hpusbscsi);
+		return;
+        }
+
+	FILL_BULK_URB(
+		u,
+		hpusbscsi->dev,
+		hpusbscsi->current_data_pipe,
+		hpusbscsi->srb->buffer,
+		hpusbscsi->srb->bufflen,
+		simple_done,
+		hpusbscsi
+	);
+
+	res = usb_submit_urb(u);
+	if (res) {
+                handle_usb_error(hpusbscsi);
+		return;
+        }
+	TRACE_STATE;
+	if (hpusbscsi->state != HP_STATE_PREMATURE) {
+		hpusbscsi->state = HP_STATE_WORKING;
+	TRACE_STATE;
+	} else {
+		if (hpusbscsi->scallback != NULL)
+			hpusbscsi->scallback(hpusbscsi->srb);
+		hpusbscsi->state = HP_STATE_FREE;
+	TRACE_STATE;
+	}
+}
+
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/hpusbscsi.h linux/drivers/usb/hpusbscsi.h
--- v2.4.10/linux/drivers/usb/hpusbscsi.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/hpusbscsi.h	Fri Oct  5 12:04:51 2001
@@ -0,0 +1,88 @@
+/* Header file for the hpusbscsi driver */
+/* (C) Copyright 2001 Oliver Neukum */
+/* sponsored by the Linux Usb Project */
+/* large parts based on or taken from code by John Fremlin and Matt Dharm */
+/* this file is licensed under the GPL */
+
+typedef void (*usb_urb_callback) (struct urb *);
+typedef void (*scsi_callback)(Scsi_Cmnd *);
+
+struct hpusbscsi
+{
+        struct list_head lh;
+        struct usb_device *dev; /* NULL indicates unplugged device */
+        int ep_out;
+        int ep_in;
+        int ep_int;
+        int interrupt_interval;
+
+        struct Scsi_Host *host;
+        Scsi_Host_Template ctempl;
+        int number;
+       scsi_callback scallback;
+       Scsi_Cmnd *srb;
+
+        int use_count;
+        wait_queue_head_t pending;
+        wait_queue_head_t deathrow;
+
+        struct urb dataurb;
+        struct urb controlurb;
+        int fragment;
+
+        int state;
+        int current_data_pipe;
+
+        u8 scsi_state_byte;
+};
+
+#define SCSI_ERR_MASK ~0x3fu
+
+static const unsigned char scsi_command_direction[256/8] = {
+	0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
+	0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#define DIRECTION_IS_IN(x) ((scsi_command_direction[x>>3] >> (x & 7)) & 1)
+
+static int hpusbscsi_scsi_detect (struct SHT * sht);
+static void simple_command_callback(struct urb *u);
+static void scatter_gather_callback(struct urb *u);
+static void simple_payload_callback (struct urb *u);
+static void  control_interrupt_callback (struct urb *u);
+static void simple_done (struct urb *u);
+static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
+static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);
+static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
+
+static Scsi_Host_Template hpusbscsi_scsi_host_template = {
+	name:           "hpusbscsi",
+	detect:		hpusbscsi_scsi_detect,
+//	release:	hpusbscsi_scsi_release,
+	queuecommand:	hpusbscsi_scsi_queuecommand,
+
+	eh_abort_handler:	hpusbscsi_scsi_abort,
+	eh_host_reset_handler:	hpusbscsi_scsi_host_reset,
+
+	sg_tablesize:		SG_ALL,
+	can_queue:		1,
+	this_id:		-1,
+	cmd_per_lun:		1,
+	present:		0,
+	unchecked_isa_dma:	FALSE,
+	use_clustering:		TRUE,
+	use_new_eh_code:	TRUE,
+	emulated:		TRUE
+};
+
+/* defines for internal driver state */
+#define HP_STATE_FREE                 0  /*ready for next request */
+#define HP_STATE_BEGINNING      1  /*command being transfered */
+#define HP_STATE_WORKING         2  /* data transfer stage */
+#define HP_STATE_ERROR             3  /* error has been reported */
+#define HP_STATE_WAIT                 4  /* waiting for status transfer */
+#define HP_STATE_PREMATURE              5 /* status prematurely reported */
+
+
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/hub.c linux/drivers/usb/hub.c
--- v2.4.10/linux/drivers/usb/hub.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/hub.c	Tue Oct  9 15:15:02 2001
@@ -4,6 +4,8 @@
  * (C) Copyright 1999 Linus Torvalds
  * (C) Copyright 1999 Johannes Erdfelt
  * (C) Copyright 1999 Gregory P. Smith
+ * (C) Copyright 2001 Brad Hards (bhards@bigpond.net.au)
+ *
  */
 
 #include <linux/config.h>
@@ -51,6 +53,7 @@
 }
 #endif
 
+/* USB 2.0 spec Section 11.24.4.5 */
 static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
@@ -58,24 +61,38 @@
 		USB_DT_HUB << 8, 0, data, size, HZ);
 }
 
+/*
+ * USB 2.0 spec Section 11.24.2.1
+ */
 static int usb_clear_hub_feature(struct usb_device *dev, int feature)
 {
 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature, 0, NULL, 0, HZ);
 }
 
+/*
+ * USB 2.0 spec Section 11.24.2.2
+ * BUG: doesn't handle port indicator selector in high byte of wIndex
+ */
 static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
 {
 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
 }
 
+/*
+ * USB 2.0 spec Section 11.24.2.13
+ * BUG: doesn't handle port indicator selector in high byte of wIndex
+ */
 static int usb_set_port_feature(struct usb_device *dev, int port, int feature)
 {
 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, HZ);
 }
 
+/*
+ * USB 2.0 spec Section 11.24.2.6
+ */
 static int usb_get_hub_status(struct usb_device *dev, void *data)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
@@ -83,6 +100,9 @@
 		data, sizeof(struct usb_hub_status), HZ);
 }
 
+/*
+ * USB 2.0 spec Section 11.24.2.7
+ */
 static int usb_get_port_status(struct usb_device *dev, int port, void *data)
 {
 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
@@ -230,7 +250,7 @@
 	dbg("hub controller current requirement: %dmA", hub->descriptor->bHubContrCurrent);
 
 	for (i = 0; i < dev->maxchild; i++)
-		portstr[i] = hub->descriptor->bitmap[((i + 1) / 8)] & (1 << ((i + 1) % 8)) ? 'F' : 'R';
+		portstr[i] = hub->descriptor->DeviceRemovable[((i + 1) / 8)] & (1 << ((i + 1) % 8)) ? 'F' : 'R';
 	portstr[dev->maxchild] = 0;
 
 	dbg("port removable status: %s", portstr);
@@ -838,6 +858,7 @@
 
 	dbg("usb_hub_thread exiting");
 
+	unlock_kernel();
 	complete_and_exit(&khubd_exited, 0);
 }
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/hub.h linux/drivers/usb/hub.h
--- v2.4.10/linux/drivers/usb/hub.h	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/hub.h	Tue Oct  9 15:25:52 2001
@@ -12,12 +12,14 @@
 
 /*
  * Hub Class feature numbers
+ * See USB 2.0 spec Table 11-17
  */
 #define C_HUB_LOCAL_POWER	0
 #define C_HUB_OVER_CURRENT	1
 
 /*
  * Port feature numbers
+ * See USB 2.0 spec Table 11-17
  */
 #define USB_PORT_FEAT_CONNECTION	0
 #define USB_PORT_FEAT_ENABLE		1
@@ -99,7 +101,10 @@
 #define HUB_CHANGE_OVERCURRENT	0x0002
 
 
-/* Hub descriptor */
+/* 
+ * Hub descriptor 
+ * See USB 2.0 spec Table 11-13
+ */
 struct usb_hub_descriptor {
 	__u8  bDescLength;
 	__u8  bDescriptorType;
@@ -107,9 +112,9 @@
 	__u16 wHubCharacteristics;
 	__u8  bPwrOn2PwrGood;
 	__u8  bHubContrCurrent;
-	/* DeviceRemovable and PortPwrCtrlMask want to be variable-length 
-	   bitmaps that hold max 256 entries, but for now they're ignored */
-	__u8  bitmap[2 * ((USB_MAXCHILDREN + 1 + 7) / 8)];
+	    	/* add 1 bit for hub status change; round to bytes */
+	__u8  DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
+	__u8  PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
 } __attribute__ ((packed));
 
 struct usb_device;
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/ibmcam.c linux/drivers/usb/ibmcam.c
--- v2.4.10/linux/drivers/usb/ibmcam.c	Sun Aug 12 13:28:00 2001
+++ linux/drivers/usb/ibmcam.c	Fri Oct  5 12:04:51 2001
@@ -27,58 +27,71 @@
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-#include <linux/videodev.h>
-#include <linux/vmalloc.h>
 #include <linux/wrapper.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/usb.h>
 
-#include <asm/io.h>
+#include "usbvideo.h"
 
-#include "ibmcam.h"
+#define	IBMCAM_VENDOR_ID	0x0545
+#define	IBMCAM_PRODUCT_ID	0x8080
+#define NETCAM_PRODUCT_ID	0x8002	/* IBM NetCamera, close to model 2 */
+
+#define MAX_IBMCAM		4	/* How many devices we allow to connect */
+#define USES_IBMCAM_PUTPIXEL    0       /* 0=Fast/oops 1=Slow/secure */
+
+/* Header signatures */
+
+/* Model 1 header: 00 FF 00 xx */
+#define HDRSIG_MODEL1_128x96	0x06	/* U Y V Y ... */
+#define HDRSIG_MODEL1_176x144	0x0e	/* U Y V Y ... */
+#define HDRSIG_MODEL1_352x288	0x00	/* V Y U Y ... */
+
+#define	IBMCAM_MODEL_1	1	/* XVP-501, 3 interfaces, rev. 0.02 */
+#define IBMCAM_MODEL_2	2	/* KSX-X9903, 2 interfaces, rev. 3.0a */
+#define IBMCAM_MODEL_3	3	/* KSX-X9902, 2 interfaces, rev. 3.01 */
+#define	IBMCAM_MODEL_4	4	/* IBM NetCamera, 0545/8002/3.0a */
+
+/* Video sizes supported */
+#define	VIDEOSIZE_128x96	VIDEOSIZE(128, 96)
+#define	VIDEOSIZE_176x144	VIDEOSIZE(176,144)
+#define	VIDEOSIZE_352x288	VIDEOSIZE(352,288)
+#define	VIDEOSIZE_320x240	VIDEOSIZE(320,240)
+#define	VIDEOSIZE_352x240	VIDEOSIZE(352,240)
+#define	VIDEOSIZE_640x480	VIDEOSIZE(640,480)
+#define	VIDEOSIZE_160x120	VIDEOSIZE(160,120)
+
+/* Video sizes supported */
+enum {
+	SIZE_128x96 = 0,
+	SIZE_160x120,
+	SIZE_176x144,
+	SIZE_320x240,
+	SIZE_352x240,
+	SIZE_352x288,
+	SIZE_640x480,
+	/* Add/remove/rearrange items before this line */
+	SIZE_LastItem
+};
 
 /*
- * Version Information
+ * This structure lives in uvd_t->user field.
  */
-#define DRIVER_VERSION "v1.0.0"
-#define DRIVER_AUTHOR "http://www.linux-usb.org/ibmcam/"
-#define DRIVER_DESC "IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000"
-
-#define	ENABLE_HEXDUMP	0	/* Enable if you need it */
-static int debug = 0;
+typedef struct {
+	int initialized;	/* Had we already sent init sequence? */
+	int camera_model;	/* What type of IBM camera we got? */
+	int has_hdr;
+} ibmcam_t;
+#define	IBMCAM_T(uvd)	((ibmcam_t *)((uvd)->user_data))
 
-static int video_nr = -1;
+usbvideo_t *cams = NULL;
 
-/* Completion states of the data parser */
-typedef enum {
-	scan_Continue,		/* Just parse next item */
-	scan_NextFrame,		/* Frame done, send it to V4L */
-	scan_Out,		/* Not enough data for frame */
-	scan_EndParse		/* End parsing */
-} scan_state_t;
-
-/* Bit flags (options) */
-#define FLAGS_RETRY_VIDIOCSYNC		(1 << 0)
-#define	FLAGS_MONOCHROME		(1 << 1)
-#define FLAGS_DISPLAY_HINTS		(1 << 2)
-#define FLAGS_OVERLAY_STATS		(1 << 3)
-#define FLAGS_FORCE_TESTPATTERN		(1 << 4)
-#define FLAGS_SEPARATE_FRAMES		(1 << 5)
-#define FLAGS_CLEAN_FRAMES		(1 << 6)
+static int debug = 0;
 
 static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
 
-/* This is the size of V4L frame that we provide */
-static const int imgwidth = V4L_FRAME_WIDTH_USED;
-static const int imgheight = V4L_FRAME_HEIGHT;
-static const int min_imgwidth  = 8;
-static const int min_imgheight = 4;
+static const int min_canvasWidth  = 8;
+static const int min_canvasHeight = 4;
 
 static int lighting = 1; /* Medium */
 
@@ -88,27 +101,9 @@
 
 #define FRAMERATE_MIN	0
 #define FRAMERATE_MAX	6
-static int framerate = 2; /* Lower, reliable frame rate (8-12 fps) */
-
-enum {
-	VIDEOSIZE_128x96 = 0,
-	VIDEOSIZE_176x144,
-	VIDEOSIZE_352x288,
-	VIDEOSIZE_320x240,
-	VIDEOSIZE_352x240,
-};
-
-static int videosize = VIDEOSIZE_352x288;
+static int framerate = -1;
 
-/*
- * The value of 'scratchbufsize' affects quality of the picture
- * in many ways. Shorter buffers may cause loss of data when client
- * is too slow. Larger buffers are memory-consuming and take longer
- * to work with. This setting can be adjusted, but the default value
- * should be OK for most desktop users.
- */
-#define DEFAULT_SCRATCH_BUF_SIZE	(0x10000)	/* 64 KB */
-static const int scratchbufsize = DEFAULT_SCRATCH_BUF_SIZE;
+static int size = SIZE_352x288;
 
 /*
  * Here we define several initialization variables. They may
@@ -131,36 +126,37 @@
 static int hue_correction = 128;
 
 /* Settings for camera model 2 */
-static int init_model2_rg = -1;
 static int init_model2_rg2 = -1;
 static int init_model2_sat = -1;
 static int init_model2_yb = -1;
 
+/* 01.01.08 - Added for RCA video in support -LO */
+/* Settings for camera model 3 */
+static int init_model3_input = 0;
+
 MODULE_PARM(debug, "i");
 MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
 MODULE_PARM(flags, "i");
-MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, 1=B/W, 2=show hints, 3=show stats, 4=test pattern, 5=seperate frames, 6=clean frames");
+MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, 1=B/W, 2=show hints, 3=show stats, 4=test pattern, 5=separate frames, 6=clean frames");
 MODULE_PARM(framerate, "i");
 MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
 MODULE_PARM(lighting, "i");
 MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light");
 MODULE_PARM(sharpness, "i");
 MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)");
-MODULE_PARM(videosize, "i");
-MODULE_PARM_DESC(videosize, "Image size: 0=128x96, 1=176x144, 2=352x288, 3=320x240, 4=352x240 (default=1)");
+MODULE_PARM(size, "i");
+MODULE_PARM_DESC(size, "Image size: 0=128x96 1=160x120 2=176x144 3=320x240 4=352x240 5=352x288 6=640x480  (default=5)");
 MODULE_PARM(init_brightness, "i");
 MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
 MODULE_PARM(init_contrast, "i");
 MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
 MODULE_PARM(init_color, "i");
-MODULE_PARM_DESC(init_color, "Dolor preconfiguration: 0-255 (default=128)");
+MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
 MODULE_PARM(init_hue, "i");
 MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
 MODULE_PARM(hue_correction, "i");
 MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
 
-MODULE_PARM(init_model2_rg, "i");
-MODULE_PARM_DESC(init_model2_rg, "Model2 preconfiguration: 0-255 (default=112)");
 MODULE_PARM(init_model2_rg2, "i");
 MODULE_PARM_DESC(init_model2_rg2, "Model2 preconfiguration: 0-255 (default=47)");
 MODULE_PARM(init_model2_sat, "i");
@@ -168,6 +164,14 @@
 MODULE_PARM(init_model2_yb, "i");
 MODULE_PARM_DESC(init_model2_yb, "Model2 preconfiguration: 0-255 (default=160)");
 
+/* 01.01.08 - Added for RCA video in support -LO */
+MODULE_PARM(init_model3_input, "i");
+MODULE_PARM_DESC(init_model3_input, "Model3 input: 0=CCD 1=RCA");
+
+MODULE_AUTHOR ("Dmitri");
+MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000");
+MODULE_LICENSE("GPL");
+
 /* Still mysterious i2c commands */
 static const unsigned short unknown_88 = 0x0088;
 static const unsigned short unknown_89 = 0x0089;
@@ -182,594 +186,326 @@
 static const unsigned short mod2_color_balance_rg2 = 0x001e;	/* 0 (red) .. $7F (green) */
 static const unsigned short mod2_saturation = 0x0020;		/* 0 (b/w) - $7F (full color) */
 static const unsigned short mod2_color_balance_yb = 0x0022;	/* 0..$7F, $50 is about right */
-static const unsigned short mod2_color_balance_rg = 0x0024;	/* 0..$7F, $70 is about right */
+static const unsigned short mod2_hue = 0x0024;			/* 0..$7F, $70 is about right */
 static const unsigned short mod2_sensitivity = 0x0028;		/* 0 (min) .. $1F (max) */
 
-#define MAX_IBMCAM	4
-
-struct usb_ibmcam cams[MAX_IBMCAM];
-
-/*******************************/
-/* Memory management functions */
-/*******************************/
-
-#define MDEBUG(x)	do { } while(0)		/* Debug memory management */
-
-static struct usb_driver ibmcam_driver;
-static void usb_ibmcam_release(struct usb_ibmcam *ibmcam);
-
-/* Given PGD from the address space's page table, return the kernel
- * virtual mapping of the physical memory mapped at ADR.
- */
-static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
-{
-	unsigned long ret = 0UL;
-	pmd_t *pmd;
-	pte_t *ptep, pte;
-
-	if (!pgd_none(*pgd)) {
-		pmd = pmd_offset(pgd, adr);
-		if (!pmd_none(*pmd)) {
-			ptep = pte_offset(pmd, adr);
-			pte = *ptep;
-			if (pte_present(pte)) {
-				ret = (unsigned long) page_address(pte_page(pte));
-				ret |= (adr & (PAGE_SIZE - 1));
-			}
-		}
-	}
-	MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
-	return ret;
-}
-
-static inline unsigned long uvirt_to_bus(unsigned long adr)
-{
-	unsigned long kva, ret;
-
-	kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
-	ret = virt_to_bus((void *)kva);
-	MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
-	return ret;
-}
-
-static inline unsigned long kvirt_to_bus(unsigned long adr)
-{
-	unsigned long va, kva, ret;
-
-	va = VMALLOC_VMADDR(adr);
-	kva = uvirt_to_kva(pgd_offset_k(va), va);
-	ret = virt_to_bus((void *)kva);
-	MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
-	return ret;
-}
-
-/* Here we want the physical address of the memory.
- * This is used when initializing the contents of the
- * area and marking the pages as reserved.
- */
-static inline unsigned long kvirt_to_pa(unsigned long adr)
-{
-	unsigned long va, kva, ret;
-
-	va = VMALLOC_VMADDR(adr);
-	kva = uvirt_to_kva(pgd_offset_k(va), va);
-	ret = __pa(kva);
-	MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
-	return ret;
-}
-
-static void *rvmalloc(unsigned long size)
-{
-	void *mem;
-	unsigned long adr, page;
-
-	/* Round it off to PAGE_SIZE */
-	size += (PAGE_SIZE - 1);
-	size &= ~(PAGE_SIZE - 1);
-
-	mem = vmalloc_32(size);
-	if (!mem)
-		return NULL;
-
-	memset(mem, 0, size); /* Clear the ram out, no junk to the user */
-	adr = (unsigned long) mem;
-	while (size > 0) {
-		page = kvirt_to_pa(adr);
-		mem_map_reserve(virt_to_page(__va(page)));
-		adr += PAGE_SIZE;
-		if (size > PAGE_SIZE)
-			size -= PAGE_SIZE;
-		else
-			size = 0;
-	}
-
-	return mem;
-}
-
-static void rvfree(void *mem, unsigned long size)
-{
-	unsigned long adr, page;
-
-	if (!mem)
-		return;
-
-	size += (PAGE_SIZE - 1);
-	size &= ~(PAGE_SIZE - 1);
-
-	adr=(unsigned long) mem;
-	while (size > 0) {
-		page = kvirt_to_pa(adr);
-		mem_map_unreserve(virt_to_page(__va(page)));
-		adr += PAGE_SIZE;
-		if (size > PAGE_SIZE)
-			size -= PAGE_SIZE;
-		else
-			size = 0;
-	}
-	vfree(mem);
-}
-
-#if ENABLE_HEXDUMP
-static void ibmcam_hexdump(const unsigned char *data, int len)
-{
-	char tmp[80];
-	int i, k;
-
-	for (i=k=0; len > 0; i++, len--) {
-		if (i > 0 && (i%16 == 0)) {
-			printk("%s\n", tmp);
-			k=0;
-		}
-		k += sprintf(&tmp[k], "%02x ", data[i]);
-	}
-	if (k > 0)
-		printk("%s\n", tmp);
-}
-#endif
-
-/*
- * usb_ibmcam_overlaychar()
- *
- * History:
- * 1/2/00   Created.
- */
-void usb_ibmcam_overlaychar(
-	struct usb_ibmcam *ibmcam,
-	struct ibmcam_frame *frame,
-	int x, int y, int ch)
-{
-	static const unsigned short digits[16] = {
-		0xF6DE, /* 0 */
-		0x2492, /* 1 */
-		0xE7CE, /* 2 */
-		0xE79E, /* 3 */
-		0xB792, /* 4 */
-		0xF39E, /* 5 */
-		0xF3DE, /* 6 */
-		0xF492, /* 7 */
-		0xF7DE, /* 8 */
-		0xF79E, /* 9 */
-		0x77DA, /* a */
-		0xD75C, /* b */
-		0xF24E, /* c */
-		0xD6DC, /* d */
-		0xF34E, /* e */
-		0xF348  /* f */
-	};
-	unsigned short digit;
-	int ix, iy;
-
-	if ((ibmcam == NULL) || (frame == NULL))
-		return;
-
-	if (ch >= '0' && ch <= '9')
-		ch -= '0';
-	else if (ch >= 'A' && ch <= 'F')
-		ch = 10 + (ch - 'A');
-	else if (ch >= 'a' && ch <= 'f')
-		ch = 10 + (ch - 'a');
-	else
-		return;
-	digit = digits[ch];
-
-	for (iy=0; iy < 5; iy++) {
-		for (ix=0; ix < 3; ix++) {
-			if (digit & 0x8000) {
-				IBMCAM_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
-			}
-			digit = digit << 1;
-		}
-	}
-}
+struct struct_initData {
+	unsigned char req;
+	unsigned short value;
+	unsigned short index;
+};
 
 /*
- * usb_ibmcam_overlaystring()
+ * ibmcam_size_to_videosize()
  *
- * History:
- * 1/2/00   Created.
+ * This procedure converts module option 'size' into the actual
+ * videosize_t that defines the image size in pixels. We need
+ * simplified 'size' because user wants a simple enumerated list
+ * of choices, not an infinite set of possibilities.
  */
-void usb_ibmcam_overlaystring(
-	struct usb_ibmcam *ibmcam,
-	struct ibmcam_frame *frame,
-	int x, int y, const char *str)
+static videosize_t ibmcam_size_to_videosize(int size)
 {
-	while (*str) {
-		usb_ibmcam_overlaychar(ibmcam, frame, x, y, *str);
-		str++;
-		x += 4; /* 3 pixels character + 1 space */
+	videosize_t vs = VIDEOSIZE_352x288;
+	RESTRICT_TO_RANGE(size, 0, (SIZE_LastItem-1));
+	switch (size) {
+	case SIZE_128x96:
+		vs = VIDEOSIZE_128x96;
+		break;
+	case SIZE_160x120:
+		vs = VIDEOSIZE_160x120;
+		break;
+	case SIZE_176x144:
+		vs = VIDEOSIZE_176x144;
+		break;
+	case SIZE_320x240:
+		vs = VIDEOSIZE_320x240;
+		break;
+	case SIZE_352x240:
+		vs = VIDEOSIZE_352x240;
+		break;
+	case SIZE_352x288:
+		vs = VIDEOSIZE_352x288;
+		break;
+	case SIZE_640x480:
+		vs = VIDEOSIZE_640x480;
+		break;
+	default:
+		err("size=%d. is not valid", size);
+		break;
 	}
+	return vs;
 }
 
 /*
- * usb_ibmcam_overlaystats()
- *
- * Overlays important debugging information.
- *
- * History:
- * 1/2/00   Created.
- */
-void usb_ibmcam_overlaystats(struct usb_ibmcam *ibmcam, struct ibmcam_frame *frame)
-{
-	const int y_diff = 8;
-	char tmp[16];
-	int x = 10;
-	int y = 10;
-
-	sprintf(tmp, "%8x", ibmcam->frame_num);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8lx", ibmcam->urb_count);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8lx", ibmcam->urb_length);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8lx", ibmcam->data_count);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8lx", ibmcam->header_count);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8lx", ibmcam->scratch_ovf_count);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8lx", ibmcam->iso_skip_count);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8lx", ibmcam->iso_err_count);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8x", ibmcam->vpic.colour);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8x", ibmcam->vpic.hue);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8x", ibmcam->vpic.brightness >> 8);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8x", ibmcam->vpic.contrast >> 12);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-
-	sprintf(tmp, "%8d", ibmcam->vpic.whiteness >> 8);
-	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
-	y += y_diff;
-}
-
-/*
- * usb_ibmcam_testpattern()
+ * ibmcam_find_header()
  *
- * Procedure forms a test pattern (yellow grid on blue background).
- *
- * Parameters:
- * fullframe:   if TRUE then entire frame is filled, otherwise the procedure
- *	      continues from the current scanline.
- * pmode	0: fill the frame with solid blue color (like on VCR or TV)
- *	      1: Draw a colored grid
+ * Locate one of supported header markers in the queue.
+ * Once found, remove all preceding bytes AND the marker (4 bytes)
+ * from the data pump queue. Whatever follows must be video lines.
  *
  * History:
- * 1/2/00   Created.
+ * 1/21/00  Created.
  */
-void usb_ibmcam_testpattern(struct usb_ibmcam *ibmcam, int fullframe, int pmode)
+static ParseState_t ibmcam_find_header(uvd_t *uvd) /* FIXME: Add frame here */
 {
-	static const char proc[] = "usb_ibmcam_testpattern";
-	struct ibmcam_frame *frame;
-	unsigned char *f;
-	int num_cell = 0;
-	int scan_length = 0;
-	static int num_pass = 0;
-
-	if (ibmcam == NULL) {
-		printk(KERN_ERR "%s: ibmcam == NULL\n", proc);
-		return;
-	}
-	if ((ibmcam->curframe < 0) || (ibmcam->curframe >= IBMCAM_NUMFRAMES)) {
-		printk(KERN_ERR "%s: ibmcam->curframe=%d.\n", proc, ibmcam->curframe);
-		return;
-	}
+	usbvideo_frame_t *frame;
+	ibmcam_t *icam;
 
-	/* Grab the current frame */
-	frame = &ibmcam->frame[ibmcam->curframe];
-
-	/* Optionally start at the beginning */
-	if (fullframe) {
-		frame->curline = 0;
-		frame->scanlength = 0;
+	if ((uvd->curframe) < 0 || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
+		err("ibmcam_find_header: Illegal frame %d.", uvd->curframe);
+		return scan_EndParse;
 	}
-
-	/* Form every scan line */
-	for (; frame->curline < imgheight; frame->curline++) {
-		int i;
-
-		f = frame->data + (imgwidth * 3 * frame->curline);
-		for (i=0; i < imgwidth; i++) {
-			unsigned char cb=0x80;
-			unsigned char cg = 0;
-			unsigned char cr = 0;
-
-			if (pmode == 1) {
-				if (frame->curline % 32 == 0)
-					cb = 0, cg = cr = 0xFF;
-				else if (i % 32 == 0) {
-					if (frame->curline % 32 == 1)
-						num_cell++;
-					cb = 0, cg = cr = 0xFF;
-				} else {
-					cb = ((num_cell*7) + num_pass) & 0xFF;
-					cg = ((num_cell*5) + num_pass*2) & 0xFF;
-					cr = ((num_cell*3) + num_pass*3) & 0xFF;
+	icam = IBMCAM_T(uvd);
+	assert(icam != NULL);
+	frame = &uvd->frame[uvd->curframe];
+	icam->has_hdr = 0;
+	switch (icam->camera_model) {
+	case IBMCAM_MODEL_1:
+	{
+		const int marker_len = 4;
+		while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
+			if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00))
+			{
+#if 0				/* This code helps to detect new frame markers */
+				info("Header sig: 00 FF 00 %02X", RING_QUEUE_PEEK(&uvd->dp, 3));
+#endif
+				frame->header = RING_QUEUE_PEEK(&uvd->dp, 3);
+				if ((frame->header == HDRSIG_MODEL1_128x96) ||
+				    (frame->header == HDRSIG_MODEL1_176x144) ||
+				    (frame->header == HDRSIG_MODEL1_352x288))
+				{
+#if 0
+					info("Header found.");
+#endif
+					RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
+					icam->has_hdr = 1;
+					break;
 				}
-			} else {
-				/* Just the blue screen */
 			}
-				
-			*f++ = cb;
-			*f++ = cg;
-			*f++ = cr;
-			scan_length += 3;
+			/* If we are still here then this doesn't look like a header */
+			RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
 		}
+		break;
 	}
-
-	frame->grabstate = FRAME_DONE;
-	frame->scanlength += scan_length;
-	++num_pass;
-
-	/* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
-	usb_ibmcam_overlaystats(ibmcam, frame);
-}
-
-static unsigned char *ibmcam_model1_find_header(unsigned char hdr_sig, unsigned char *data, int len)
-{
-	while (len >= 4)
+	case IBMCAM_MODEL_2:
+case IBMCAM_MODEL_4:
 	{
-		if ((data[0] == 0x00) && (data[1] == 0xFF) && (data[2] == 0x00))
-		{
+		int marker_len = 0;
+		switch (uvd->videosize) {
+		case VIDEOSIZE_176x144:
+			marker_len = 10;
+			break;
+		default:
+			marker_len = 2;
+			break;
+		}
+		while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
+			if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF))
+			{
 #if 0
-			/* This code helps to detect new frame markers */
-			printk(KERN_DEBUG "Header sig: 00 FF 00 %02X\n", data[3]);
+				info("Header found.");
 #endif
-			if (data[3] == hdr_sig) {
-				if (debug > 2)
-					printk(KERN_DEBUG "Header found.\n");
-				return data+4;
+				RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
+				icam->has_hdr = 1;
+				frame->header = HDRSIG_MODEL1_176x144;
+				break;
 			}
+			/* If we are still here then this doesn't look like a header */
+			RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
 		}
-		++data;
-		--len;
-	}
-	return NULL;
-}
-
-static unsigned char *ibmcam_model2_find_header(unsigned char hdr_sig, unsigned char *data, int len)
-{
-	int marker_len = 0;
-
-	switch (videosize) {
-	case VIDEOSIZE_176x144:
-		marker_len = 10;
-		break;
-	default:
-		marker_len = 2;
 		break;
 	}
-	while (len >= marker_len)
-	{
-		if ((data[0] == 0x00) && (data[1] == 0xFF))
-		{
+	case IBMCAM_MODEL_3:
+	{	/*
+		 * Headers: (one precedes every frame). nc=no compression,
+		 * bq=best quality bf=best frame rate.
+		 *
+		 * 176x144: 00 FF 02 { 0A=nc CA=bq EA=bf }
+		 * 320x240: 00 FF 02 { 08=nc 28=bq 68=bf }
+		 * 640x480: 00 FF 03 { 08=nc 28=bq 68=bf }
+		 *
+		 * Bytes '00 FF' seem to indicate header. Other two bytes
+		 * encode the frame type. This is a set of bit fields that
+		 * encode image size, compression type etc. These fields
+		 * do NOT contain frame number because all frames carry
+		 * the same header.
+		 */
+		const int marker_len = 4;
+		while (RingQueue_GetLength(&uvd->dp) >= marker_len) {
+			if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xFF) &&
+			    (RING_QUEUE_PEEK(&uvd->dp, 2) != 0xFF))
+			{
+				/*
+				 * Combine 2 bytes of frame type into one
+				 * easy to use value
+				 */
+				unsigned long byte3, byte4;
+
+				byte3 = RING_QUEUE_PEEK(&uvd->dp, 2);
+				byte4 = RING_QUEUE_PEEK(&uvd->dp, 3);
+				frame->header = (byte3 << 8) | byte4;
 #if 0
-			/* This code helps to detect new frame markers */
-			static int pass = 0;
-			if (pass++ == 0)
-				ibmcam_hexdump(data, (len > 16) ? 16 : len);
+				info("Header found.");
 #endif
-			if (debug > 2)
-				printk(KERN_DEBUG "Header found.\n");
-			return data+marker_len;
+				RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, marker_len);
+				icam->has_hdr = 1;
+				break;
+			}
+			/* If we are still here then this doesn't look like a header */
+			RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
 		}
-		++data;
-		--len;
+		break;
 	}
-	return NULL;
-}
-
-/* How much data is left in the scratch buf? */
-#define scratch_left(x)	(ibmcam->scratchlen - (int)((char *)x - (char *)ibmcam->scratch))
-
-/* Grab the remaining */
-static void usb_ibmcam_align_scratch(struct usb_ibmcam *ibmcam, unsigned char *data)
-{
-	unsigned long left;
-
-	left = scratch_left(data);
-	memmove(ibmcam->scratch, data, left);
-	ibmcam->scratchlen = left;
-}
-
-/*
- * usb_ibmcam_find_header()
- *
- * Locate one of supported header markers in the scratch buffer.
- * Once found, remove all preceding bytes AND the marker (4 bytes)
- * from the scratch buffer. Whatever follows must be video lines.
- *
- * History:
- * 1/21/00  Created.
- */
-static scan_state_t usb_ibmcam_find_header(struct usb_ibmcam *ibmcam)
-{
-	struct ibmcam_frame *frame;
-	unsigned char *data, *tmp;
-
-	data = ibmcam->scratch;
-	frame = &ibmcam->frame[ibmcam->curframe];
-
-	if (ibmcam->camera_model == IBMCAM_MODEL_1)
-		tmp = ibmcam_model1_find_header(frame->hdr_sig, data, scratch_left(data));
-	else if (ibmcam->camera_model == IBMCAM_MODEL_2)
-		tmp = ibmcam_model2_find_header(frame->hdr_sig, data, scratch_left(data));
-	else
-		tmp = NULL;
-
-	if (tmp == NULL) {
-		/* No header - entire scratch buffer is useless! */
-		if (debug > 2)
-			printk(KERN_DEBUG "Skipping frame, no header\n");
-		ibmcam->scratchlen = 0;
+	default:
+		break;
+	}
+	if (!icam->has_hdr) {
+		if (uvd->debug > 2)
+			info("Skipping frame, no header");
 		return scan_EndParse;
 	}
-	/* Header found */
-	data = tmp;
 
-	ibmcam->has_hdr = 1;
-	ibmcam->header_count++;
-	frame->scanstate = STATE_LINES;
+	/* Header found */
+	icam->has_hdr = 1;
+	uvd->stats.header_count++;
+	frame->scanstate = ScanState_Lines;
 	frame->curline = 0;
 
 	if (flags & FLAGS_FORCE_TESTPATTERN) {
-		usb_ibmcam_testpattern(ibmcam, 1, 1);
+		usbvideo_TestPattern(uvd, 1, 1);
 		return scan_NextFrame;
 	}
-	usb_ibmcam_align_scratch(ibmcam, data);
 	return scan_Continue;
 }
 
 /*
- * usb_ibmcam_parse_lines()
+ * ibmcam_parse_lines()
  *
- * Parse one line (TODO: more than one!) from the scratch buffer, put
- * decoded RGB value into the current frame buffer and add the written
- * number of bytes (RGB) to the *pcopylen.
+ * Parse one line (interlaced) from the buffer, put
+ * decoded RGB value into the current frame buffer
+ * and add the written number of bytes (RGB) to
+ * the *pcopylen.
  *
  * History:
- * 1/21/00  Created.
+ * 21-Jan-2000 Created.
+ * 12-Oct-2000 Reworked to reflect interlaced nature of the data.
  */
-static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcopylen)
+static ParseState_t ibmcam_parse_lines(
+	uvd_t *uvd,
+	usbvideo_frame_t *frame,
+	long *pcopylen)
 {
-	struct ibmcam_frame *frame;
-	unsigned char *data, *f, *chromaLine;
-	unsigned int len;
-	const int v4l_linesize = imgwidth * V4L_BYTES_PER_PIXEL;	/* V4L line offset */
-	const int hue_corr  = (ibmcam->vpic.hue - 0x8000) >> 10;	/* -32..+31 */
+	unsigned char *f;
+	ibmcam_t *icam;
+	unsigned int len, scanLength, scanHeight, order_uv, order_yc;
+	int v4l_linesize; /* V4L line offset */
+	const int hue_corr  = (uvd->vpic.hue - 0x8000) >> 10;	/* -32..+31 */
 	const int hue2_corr = (hue_correction - 128) / 4;		/* -32..+31 */
 	const int ccm = 128; /* Color correction median - see below */
-	int y, u, v, i, frame_done=0, mono_plane, color_corr;
-
-	color_corr = (ibmcam->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
+	int y, u, v, i, frame_done=0, color_corr;
+	static unsigned char lineBuffer[640*3];
+	unsigned const char *chromaLine, *lumaLine;
+
+	assert(uvd != NULL);
+	assert(frame != NULL);
+	icam = IBMCAM_T(uvd);
+	assert(icam != NULL);
+	color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
 	RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
-	data = ibmcam->scratch;
-	frame = &ibmcam->frame[ibmcam->curframe];
 
-	len = frame->frmwidth * 3; /* 1 line of mono + 1 line of color */
-	/*printk(KERN_DEBUG "len=%d. left=%d.\n",len,scratch_left(data));*/
+	v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
+
+	if (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_4) {
+		/* Model 4 frame markers do not carry image size identification */
+		switch (uvd->videosize) {
+		case VIDEOSIZE_128x96:
+		case VIDEOSIZE_160x120:
+		case VIDEOSIZE_176x144:
+			scanLength = VIDEOSIZE_X(uvd->videosize);
+			scanHeight = VIDEOSIZE_Y(uvd->videosize);
+			break;
+		default:
+			err("ibmcam_parse_lines: Wrong mode.");
+			return scan_Out;
+		}
+		order_yc = 1;	/* order_yc: true=Yc false=cY ('c'=either U or V) */
+		order_uv = 1;	/* Always true in this algorithm */
+	} else {
+		switch (frame->header) {
+		case HDRSIG_MODEL1_128x96:
+			scanLength = 128;
+			scanHeight = 96;
+			order_uv = 1;	/* U Y V Y ... */
+			break;
+		case HDRSIG_MODEL1_176x144:
+			scanLength = 176;
+			scanHeight = 144;
+			order_uv = 1;	/* U Y V Y ... */
+			break;
+		case HDRSIG_MODEL1_352x288:
+			scanLength = 352;
+			scanHeight = 288;
+			order_uv = 0;	/* Y V Y V ... */
+			break;
+		default:
+			err("Unknown header signature 00 FF 00 %02lX", frame->header);
+			return scan_NextFrame;
+		}
+		/* order_yc: true=Yc false=cY ('c'=either U or V) */
+		order_yc = (IBMCAM_T(uvd)->camera_model == IBMCAM_MODEL_2);
+	}
 
-	mono_plane = ((frame->curline & 1) == 0);
+	len = scanLength * 3;
+	assert(len <= sizeof(lineBuffer));
 
 	/*
-	 * Lines are organized this way (or are they?)
+	 * Lines are organized this way:
 	 *
 	 * I420:
 	 * ~~~~
+	 * <scanLength->
 	 * ___________________________________
 	 * |-----Y-----|---UVUVUV...UVUV-----| \
 	 * |-----------+---------------------|  \
-	 * |<-- 176 -->|<------ 176*2 ------>|  Total 72. pairs of lines
-	 * |...	   ...	     ...|  /
-	 * |___________|_____________________| /
-	 *  - odd line- ------- even line ---
-	 *
-	 * another format:
-	 * ~~~~~~~~~~~~~~
-	 * ___________________________________
-	 * |-----Y-----|---UVUVUV...UVUV-----| \
-	 * |-----------+---------------------|  \
-	 * |<-- 352 -->|<------ 352*2 ------>|  Total 144. pairs of lines
-	 * |...	   ...	     ...|  /
+	 * |<-- 176 -->|<------ 176*2 ------>|  Total 72. lines (interlaced)
+	 * |...	   ... |        ...          |  /
+	 * |<-- 352 -->|<------ 352*2 ------>|  Total 144. lines (interlaced)
 	 * |___________|_____________________| /
-	 *  - odd line- ------- even line ---
+	 *  \           \
+	 *   lumaLine    chromaLine
 	 */
 
 	/* Make sure there's enough data for the entire line */
-	if (scratch_left(data) < (len+1024)) {
-		/*printk(KERN_DEBUG "out of data, need %u.\n", len);*/
+	if (RingQueue_GetLength(&uvd->dp) < len)
 		return scan_Out;
-	}
 
-#if 0
-	{	/* This code prints beginning of the source frame */
-		static int pass = 0;
-		if ((pass++ % 3000) == 0)
-			ibmcam_hexdump(data, 16);
-	}
-#endif
+	/* Suck one line out of the ring queue */
+	RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
 
-#if 0
-	if (frame->curline == 10 || frame->curline == 11) {
-		/* This code prints beginning of 10th (mono), 11th (chroma) line */
-		static int pass = 0;
-		if ((pass % 100) == 0)
-			ibmcam_hexdump(data, 16);
-		if (frame->curline == 11)
-			pass++;
-	}
-#endif
 	/*
 	 * Make sure that our writing into output buffer
 	 * will not exceed the buffer. Mind that we may write
 	 * not into current output scanline but in several after
 	 * it as well (if we enlarge image vertically.)
 	 */
-	if ((frame->curline + 1) >= V4L_FRAME_HEIGHT)
+	if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
 		return scan_NextFrame;
 
 	/*
-	 * Now we are sure that entire line (representing all 'frame->frmwidth'
-	 * pixels from the camera) is available in the scratch buffer. We
-	 * start copying the line left-aligned to the V4L buffer (which
-	 * might be larger - not smaller, hopefully). If the camera
-	 * line is shorter then we should pad the V4L buffer with something
-	 * (black in this case) to complete the line.
+	 * Now we are sure that entire line (representing all 'scanLength'
+	 * pixels from the camera) is available in the buffer. We
+	 * start copying the line left-aligned to the V4L buffer.
+	 * If the camera line is shorter then we should pad the V4L
+	 * buffer with something (black) to complete the line.
 	 */
+	assert(frame->data != NULL);
 	f = frame->data + (v4l_linesize * frame->curline);
 
 	/*
-	 * chromaLine points to 1st pixel of the line with chrominance.
-	 * If current line is monochrome then chromaLine points to next
-	 * line after monochrome one. If current line has chrominance
-	 * then chromaLine points to this very line. Such method allows
-	 * to access chrominance data uniformly.
-	 *
 	 * To obtain chrominance data from the 'chromaLine' use this:
 	 *   v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]...
 	 *   u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]...
@@ -778,40 +514,16 @@
 	 * v_index = (i >> 1) << 2;
 	 * u_index = (i >> 1) << 2 + 2;
 	 *
-	 * where 'i' is the column number [0..frame->frmwidth-1]
+	 * where 'i' is the column number [0..VIDEOSIZE_X(frame->request)-1]
 	 */
-	chromaLine = data;
-	if (mono_plane)
-		chromaLine += frame->frmwidth;
-
-	for (i = 0; i < frame->frmwidth; i++, data += (mono_plane ? 1 : 2))
+	lumaLine = lineBuffer;
+	chromaLine = lineBuffer + scanLength;
+	for (i = 0; i < VIDEOSIZE_X(frame->request); i++)
 	{
 		unsigned char rv, gv, bv;	/* RGB components */
 
-		/*
-		 * Search for potential Start-Of-Frame marker. It should
-		 * not be here, of course, but if your formats don't match
-		 * you might exceed the frame. We must match the marker to
-		 * each byte of multi-byte data element if it is multi-byte.
-		 */
-#if 1
-		if ((ibmcam->camera_model == IBMCAM_MODEL_1) && (scratch_left(data) >= (4+2))) {
-			unsigned char *dp;
-			int j;
-
-			for (j=0, dp=data; j < 2; j++, dp++) {
-				if ((dp[0] == 0x00) && (dp[1] == 0xFF) &&
-				    (dp[2] == 0x00) && (dp[3] == frame->hdr_sig)) {
-					ibmcam->has_hdr = 2;
-					frame_done++;
-					break;
-				}
-			}
-		}
-#endif
-
 		/* Check for various visual debugging hints (colorized pixels) */
-		if ((flags & FLAGS_DISPLAY_HINTS) && (ibmcam->has_hdr)) {
+		if ((flags & FLAGS_DISPLAY_HINTS) && (icam->has_hdr)) {
 			/*
 			 * This is bad and should not happen. This means that
 			 * we somehow overshoot the line and encountered new
@@ -819,7 +531,7 @@
 			 * of whack. This cyan dot will help you to figure
 			 * out where exactly the new frame arrived.
 			 */
-			if (ibmcam->has_hdr == 1) {
+			if (icam->has_hdr == 1) {
 				bv = 0; /* Yellow marker */
 				gv = 0xFF;
 				rv = 0xFF;
@@ -828,15 +540,27 @@
 				gv = 0xFF;
 				rv = 0;
 			}
-			ibmcam->has_hdr = 0;
+			icam->has_hdr = 0;
 			goto make_pixel;
 		}
 
-		if (mono_plane || frame->order_yc)
-			y = data[0];
-		else
-			y = data[1];
+		/*
+		 * Check if we are still in range. We may be out of range if our
+		 * V4L canvas is wider or taller than the camera "native" image.
+		 * Then we quickly fill the remainder of the line with zeros to
+		 * make black color and quit the horizontal scanning loop.
+		 */
+		if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
+			const int j = i * V4L_BYTES_PER_PIXEL;
+#if USES_IBMCAM_PUTPIXEL
+			/* Refresh 'f' because we don't use it much with PUTPIXEL */
+			f = frame->data + (v4l_linesize * frame->curline) + j;
+#endif
+			memset(f, 0, v4l_linesize - j);
+			break;
+		}
 
+		y = lumaLine[i];
 		if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
 			rv = gv = bv = y;
 		else {
@@ -845,11 +569,11 @@
 			off_0 = (i >> 1) << 2;
 			off_2 = off_0 + 2;
 
-			if (frame->order_yc) {
+			if (order_yc) {
 				off_0++;
 				off_2++;
 			}
-			if (!frame->order_uv) {
+			if (!order_uv) {
 				off_0 += 2;
 				off_2 -= 2;
 			}
@@ -877,7 +601,7 @@
 		 * (in this order).
 		 */
 #if USES_IBMCAM_PUTPIXEL
-		IBMCAM_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
+		RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
 #else
 		*f++ = bv;
 		*f++ = gv;
@@ -899,18 +623,19 @@
 	 * may fill more than one output scanline if we do vertical
 	 * enlargement.
 	 */
-	frame->curline++;
-	*pcopylen += v4l_linesize;
-	usb_ibmcam_align_scratch(ibmcam, data);
+	frame->curline += 2;
+	if (pcopylen != NULL)
+		*pcopylen += 2 * v4l_linesize;
+	frame->deinterlace = Deinterlace_FillOddLines;
 
-	if (frame_done || (frame->curline >= frame->frmheight))
+	if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
 		return scan_NextFrame;
 	else
 		return scan_Continue;
 }
 
 /*
- * usb_ibmcam_model2_parse_lines()
+ * ibmcam_model2_320x240_parse_lines()
  *
  * This procedure deals with a weird RGB format that is produced by IBM
  * camera model 2 in modes 320x240 and above; 'x' below is 159 or 175,
@@ -918,15 +643,15 @@
  *
  * <--- 160 or 176 pairs of RA,RB bytes ----->
  * *-----------------------------------------* \
- * | RA0 | RB0 | RA1 | RB1 | ... | RAx | RBx |  \
- * |-----+-----+-----+-----+ ... +-----+-----|   *- This is pair of horizontal lines,
- * | B0  | G0  | B1  | G1  | ... | Bx  | Gx  |  /   total 240 or 288 lines (120 or 144
- * |=====+=====+=====+=====+ ... +=====+=====| /    such pairs).
+ * | RA0 | RB0 | RA1 | RB1 | ... | RAx | RBx |  \   This is pair of horizontal lines,
+ * |-----+-----+-----+-----+ ... +-----+-----|   *- or one interlaced line, total
+ * | B0  | G0  | B1  | G1  | ... | Bx  | Gx  |  /   120 or 144 such pairs which yield
+ * |=====+=====+=====+=====+ ... +=====+=====| /    240 or 288 lines after deinterlacing.
  *
  * Each group of FOUR bytes (RAi, RBi, Bi, Gi) where i=0..frame_width/2-1
  * defines ONE pixel. Therefore this format yields 176x144 "decoded"
  * resolution at best. I do not know why camera sends such format - the
- * previous model just used I420 and everyone was happy.
+ * previous model (1) just used interlaced I420 and everyone was happy.
  *
  * I do not know what is the difference between RAi and RBi bytes. Both
  * seemingly represent R component, but slightly vary in value (so that
@@ -934,29 +659,42 @@
  * them both as R component in attempt to at least partially recover the
  * lost resolution.
  */
-static scan_state_t usb_ibmcam_model2_parse_lines(struct usb_ibmcam *ibmcam, long *pcopylen)
+static ParseState_t ibmcam_model2_320x240_parse_lines(
+	uvd_t *uvd,
+	usbvideo_frame_t *frame,
+	long *pcopylen)
 {
-	struct ibmcam_frame *frame;
-	unsigned char *data, *f, *la, *lb;
+	unsigned char *f, *la, *lb;
 	unsigned int len;
-	const int v4l_linesize = imgwidth * V4L_BYTES_PER_PIXEL;	/* V4L line offset */
+	int v4l_linesize; /* V4L line offset */
 	int i, j, frame_done=0, color_corr;
+	int scanLength, scanHeight;
+	static unsigned char lineBuffer[352*2];
 
-	color_corr = (ibmcam->vpic.colour) >> 8; /* 0..+255 */
+	switch (uvd->videosize) {
+	case VIDEOSIZE_320x240:
+	case VIDEOSIZE_352x240:
+	case VIDEOSIZE_352x288:
+		scanLength = VIDEOSIZE_X(uvd->videosize);
+		scanHeight = VIDEOSIZE_Y(uvd->videosize);
+		break;
+	default:
+		err("ibmcam_model2_320x240_parse_lines: Wrong mode.");
+		return scan_Out;
+	}
 
-	data = ibmcam->scratch;
-	frame = &ibmcam->frame[ibmcam->curframe];
+	color_corr = (uvd->vpic.colour) >> 8; /* 0..+255 */
+	v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
 
-	/* Here we deal with pairs of horizontal lines */
-
-	len = frame->frmwidth * 2; /* 2 lines */
-	/*printk(KERN_DEBUG "len=%d. left=%d.\n",len,scratch_left(data));*/
+	len = scanLength * 2; /* See explanation above */
+	assert(len <= sizeof(lineBuffer));
 
 	/* Make sure there's enough data for the entire line */
-	if (scratch_left(data) < (len+32)) {
-		/*printk(KERN_DEBUG "out of data, need %u.\n", len);*/
+	if (RingQueue_GetLength(&uvd->dp) < len)
 		return scan_Out;
-	}
+
+	/* Suck one line out of the ring queue */
+	RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
 
 	/*
 	 * Make sure that our writing into output buffer
@@ -964,19 +702,15 @@
 	 * not into current output scanline but in several after
 	 * it as well (if we enlarge image vertically.)
 	 */
-	if ((frame->curline + 1) >= V4L_FRAME_HEIGHT)
+	if ((frame->curline + 2) >= VIDEOSIZE_Y(frame->request))
 		return scan_NextFrame;
 
-	if ((frame->curline & 1) == 0) {
-		la = data;
-		lb = data + frame->frmwidth;
-	} else {
-		la = data + frame->frmwidth;
-		lb = data;
-	}
+	la = lineBuffer;
+	lb = lineBuffer + scanLength;
 
 	/*
-	 * Now we are sure that entire line (representing all 'frame->frmwidth'
+	 * Now we are sure that entire line (representing all
+	 *         VIDEOSIZE_X(frame->request)
 	 * pixels from the camera) is available in the scratch buffer. We
 	 * start copying the line left-aligned to the V4L buffer (which
 	 * might be larger - not smaller, hopefully). If the camera
@@ -986,14 +720,14 @@
 	f = frame->data + (v4l_linesize * frame->curline);
 
 	/* Fill the 2-line strip */
-	for (i = 0; i < frame->frmwidth; i++) {
+	for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
 		int y, rv, gv, bv;	/* RGB components */
 
 		j = i & (~1);
 
 		/* Check for various visual debugging hints (colorized pixels) */
-		if ((flags & FLAGS_DISPLAY_HINTS) && (ibmcam->has_hdr)) {
-			if (ibmcam->has_hdr == 1) {
+		if ((flags & FLAGS_DISPLAY_HINTS) && (IBMCAM_T(uvd)->has_hdr)) {
+			if (IBMCAM_T(uvd)->has_hdr == 1) {
 				bv = 0; /* Yellow marker */
 				gv = 0xFF;
 				rv = 0xFF;
@@ -1002,11 +736,27 @@
 				gv = 0xFF;
 				rv = 0;
 			}
-			ibmcam->has_hdr = 0;
+			IBMCAM_T(uvd)->has_hdr = 0;
 			goto make_pixel;
 		}
 
 		/*
+		 * Check if we are still in range. We may be out of range if our
+		 * V4L canvas is wider or taller than the camera "native" image.
+		 * Then we quickly fill the remainder of the line with zeros to
+		 * make black color and quit the horizontal scanning loop.
+		 */
+		if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
+			const int j = i * V4L_BYTES_PER_PIXEL;
+#if USES_IBMCAM_PUTPIXEL
+			/* Refresh 'f' because we don't use it much with PUTPIXEL */
+			f = frame->data + (v4l_linesize * frame->curline) + j;
+#endif
+			memset(f, 0, v4l_linesize - j);
+			break;
+		}
+
+		/*
 		 * Here I use RA and RB components, one per physical pixel.
 		 * This causes fine vertical grid on the picture but may improve
 		 * horizontal resolution. If you prefer replicating, use this:
@@ -1045,8 +795,7 @@
 		}
 
 	make_pixel:
-		IBMCAM_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
-		IBMCAM_PUTPIXEL(frame, i, frame->curline+1, rv, gv, bv);
+		RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
 	}
 	/*
 	 * Account for number of bytes that we wrote into output V4L frame.
@@ -1056,257 +805,342 @@
 	 */
 	frame->curline += 2;
 	*pcopylen += v4l_linesize * 2;
-	data += frame->frmwidth * 2;
-	usb_ibmcam_align_scratch(ibmcam, data);
+	frame->deinterlace = Deinterlace_FillOddLines;
 
-	if (frame_done || (frame->curline >= frame->frmheight))
+	if (frame_done || (frame->curline >= VIDEOSIZE_Y(frame->request)))
 		return scan_NextFrame;
 	else
 		return scan_Continue;
 }
 
-/*
- * ibmcam_parse_data()
- *
- * Generic routine to parse the scratch buffer. It employs either
- * usb_ibmcam_find_header() or usb_ibmcam_parse_lines() to do most
- * of work.
- *
- * History:
- * 1/21/00  Created.
- */
-static void ibmcam_parse_data(struct usb_ibmcam *ibmcam)
+static ParseState_t ibmcam_model3_parse_lines(
+	uvd_t *uvd,
+	usbvideo_frame_t *frame,
+	long *pcopylen)
 {
-	struct ibmcam_frame *frame;
-	unsigned char *data = ibmcam->scratch;
-	scan_state_t newstate;
-	long copylen = 0;
-
-	/* Grab the current frame and the previous frame */
-	frame = &ibmcam->frame[ibmcam->curframe];
+	unsigned char *data;
+	const unsigned char *color;
+	unsigned int len;
+	int v4l_linesize; /* V4L line offset */
+	const int hue_corr  = (uvd->vpic.hue - 0x8000) >> 10;	/* -32..+31 */
+	const int hue2_corr = (hue_correction - 128) / 4;		/* -32..+31 */
+	const int ccm = 128; /* Color correction median - see below */
+	int i, u, v, rw, data_w=0, data_h=0, color_corr;
+	static unsigned char lineBuffer[640*3];
 
-	/* printk(KERN_DEBUG "parsing %u.\n", ibmcam->scratchlen); */
+	color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
+	RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);
 
-	while (1) {
+	v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
 
-		newstate = scan_Out;
-		if (scratch_left(data)) {
-			if (frame->scanstate == STATE_SCANNING)
-				newstate = usb_ibmcam_find_header(ibmcam);
-			else if (frame->scanstate == STATE_LINES) {
-				if ((ibmcam->camera_model == IBMCAM_MODEL_2) &&
-				    (videosize >= VIDEOSIZE_352x288)) {
-					newstate = usb_ibmcam_model2_parse_lines(ibmcam, &copylen);
-				}
-				else {
-					newstate = usb_ibmcam_parse_lines(ibmcam, &copylen);
-				}
-			}
-		}
-		if (newstate == scan_Continue)
-			continue;
-		else if ((newstate == scan_NextFrame) || (newstate == scan_Out))
-			break;
-		else
-			return; /* scan_EndParse */
+	/* The header tells us what sort of data is in this frame */
+	switch (frame->header) {
+		/*
+		 * Uncompressed modes (that are easy to decode).
+		 */
+	case 0x0308:
+		data_w = 640;
+		data_h = 480;
+		break;
+	case 0x0208:
+		data_w = 320;
+		data_h = 240;
+		break;
+	case 0x020A:
+		data_w = 160;
+		data_h = 120;
+		break;
+		/*
+		 * Compressed modes (ViCE - that I don't know how to decode).
+		 */
+	case 0x0328:	/* 640x480, best quality compression */
+	case 0x0368:	/* 640x480, best frame rate compression */
+	case 0x0228:	/* 320x240, best quality compression */
+	case 0x0268:	/* 320x240, best frame rate compression */
+	case 0x02CA:	/* 160x120, best quality compression */
+	case 0x02EA:	/* 160x120, best frame rate compression */
+		/* Do nothing with this - not supported */
+		err("Unsupported mode $%04lx", frame->header);
+		return scan_NextFrame;
+	default:
+		/* Catch unknown headers, may help in learning new headers */
+		err("Strange frame->header=$%08lx", frame->header);
+		return scan_NextFrame;
 	}
 
-	if (newstate == scan_NextFrame) {
-		frame->grabstate = FRAME_DONE;
-		ibmcam->curframe = -1;
-		ibmcam->frame_num++;
-
-		/* Optionally display statistics on the screen */
-		if (flags & FLAGS_OVERLAY_STATS)
-			usb_ibmcam_overlaystats(ibmcam, frame);
-
-		/* This will cause the process to request another frame. */
-		if (waitqueue_active(&frame->wq))
-			wake_up_interruptible(&frame->wq);
+	/*
+	 * Make sure that our writing into output buffer
+	 * will not exceed the buffer. Note that we may write
+	 * not into current output scanline but in several after
+	 * it as well (if we enlarge image vertically.)
+	 */
+	if ((frame->curline + 1) >= data_h) {
+		if (uvd->debug >= 3)
+			info("Reached line %d. (frame is done)", frame->curline);
+		return scan_NextFrame;
 	}
 
-	/* Update the frame's uncompressed length. */
-	frame->scanlength += copylen;
-}
+	/* Make sure there's enough data for the entire line */
+	len = 3 * data_w; /* <y-data> <uv-data> */
+	assert(len <= sizeof(lineBuffer));
 
-/*
- * Make all of the blocks of data contiguous
- */
-static int ibmcam_compress_isochronous(struct usb_ibmcam *ibmcam, urb_t *urb)
-{
-	unsigned char *cdata, *data, *data0;
-	int i, totlen = 0;
+	/* Make sure there's enough data for the entire line */
+	if (RingQueue_GetLength(&uvd->dp) < len)
+		return scan_Out;
 
-	data = data0 = ibmcam->scratch + ibmcam->scratchlen;
-	for (i = 0; i < urb->number_of_packets; i++) {
-		int n = urb->iso_frame_desc[i].actual_length;
-		int st = urb->iso_frame_desc[i].status;
-		
-		cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+	/* Suck one line out of the ring queue */
+	RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
 
-		/* Detect and ignore errored packets */
-		if (st < 0) {
-			if (debug >= 1) {
-				printk(KERN_ERR "ibmcam data error: [%d] len=%d, status=%X\n",
-				       i, n, st);
-			}
-			ibmcam->iso_err_count++;
-			continue;
-		}
+	data = lineBuffer;
+	color = data + data_w;		/* Point to where color planes begin */
 
-		/* Detect and ignore empty packets */
-		if (n <= 0) {
-			ibmcam->iso_skip_count++;
-			continue;
-		}
+	/* Bottom-to-top scanning */
+	rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1;
+	RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1);
 
-		/*
-		 * If camera continues to feed us with data but there is no
-		 * consumption (if, for example, V4L client fell asleep) we
-		 * may overflow the buffer. We have to move old data over to
-		 * free room for new data. This is bad for old data. If we
-		 * just drop new data then it's bad for new data... choose
-		 * your favorite evil here.
-		 */
-		if ((ibmcam->scratchlen + n) > scratchbufsize) {
-#if 0
-			ibmcam->scratch_ovf_count++;
-			if (debug >= 3)
-				printk(KERN_ERR "ibmcam: scratch buf overflow! "
-				       "scr_len: %d, n: %d\n", ibmcam->scratchlen, n );
-			return totlen;
-#else
-			int mv;
+	for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
+		int y, rv, gv, bv;	/* RGB components */
 
-			ibmcam->scratch_ovf_count++;
-			if (debug >= 3) {
-				printk(KERN_ERR "ibmcam: scratch buf overflow! "
-				       "scr_len: %d, n: %d\n", ibmcam->scratchlen, n );
-			}
-			mv  = (ibmcam->scratchlen + n) - scratchbufsize;
-			if (ibmcam->scratchlen >= mv) {
-				int newslen = ibmcam->scratchlen - mv;
-				memmove(ibmcam->scratch, ibmcam->scratch + mv, newslen);
-				ibmcam->scratchlen = newslen;
-				data = data0 = ibmcam->scratch + ibmcam->scratchlen;
-			} else {
-				printk(KERN_ERR "ibmcam: scratch buf too small\n");
-				return totlen;
+		if (i < data_w) {
+			y = data[i];	/* Luminosity is the first line */
+
+			/* Apply static color correction */
+			u = color[i*2] + hue_corr;
+			v = color[i*2 + 1] + hue2_corr;
+
+			/* Apply color correction */
+			if (color_corr != 0) {
+				/* Magnify up to 2 times, reduce down to zero saturation */
+				u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;
+				v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;
 			}
-#endif
-		}
+		} else
+			y = 0, u = v = 128;
 
-		/* Now we know that there is enough room in scratch buffer */
-		memmove(data, cdata, n);
-		data += n;
-		totlen += n;
-		ibmcam->scratchlen += n;
+		YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
+		RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* Done by deinterlacing now */
 	}
-#if 0
-	if (totlen > 0) {
-		static int foo=0;
-		if (foo < 1) {
-			printk(KERN_DEBUG "+%d.\n", totlen);
-			ibmcam_hexdump(data0, (totlen > 64) ? 64:totlen);
-			++foo;
+	frame->deinterlace = Deinterlace_FillEvenLines;
+
+	/*
+	 * Account for number of bytes that we wrote into output V4L frame.
+	 * We do it here, after we are done with the scanline, because we
+	 * may fill more than one output scanline if we do vertical
+	 * enlargement.
+	 */
+	frame->curline += 2;
+	*pcopylen += 2 * v4l_linesize;
+
+	if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
+		if (uvd->debug >= 3) {
+			info("All requested lines (%ld.) done.",
+			     VIDEOSIZE_Y(frame->request));
 		}
-	}
-#endif
-	return totlen;
+		return scan_NextFrame;
+	} else
+		return scan_Continue;
 }
 
-static void ibmcam_isoc_irq(struct urb *urb)
+/*
+ * ibmcam_model4_128x96_parse_lines()
+ *
+ * This decoder is for one strange data format that is produced by Model 4
+ * camera only in 128x96 mode. This is RGB format and here is its description.
+ * First of all, this is non-interlaced stream, meaning that all scan lines
+ * are present in the datastream. There are 96 consecutive blocks of data
+ * that describe all 96 lines of the image. Each block is 5*128 bytes long
+ * and carries R, G, B components. The format of the block is shown in the
+ * code below. First 128*2 bytes are interleaved R and G components. Then
+ * we have a gap (junk data) 64 bytes long. Then follow B and something
+ * else, also interleaved (this makes another 128*2 bytes). After that
+ * probably another 64 bytes of junk follow.
+ *
+ * History:
+ * 10-Feb-2001 Created.
+ */
+static ParseState_t ibmcam_model4_128x96_parse_lines(
+	uvd_t *uvd,
+	usbvideo_frame_t *frame,
+	long *pcopylen)
 {
-	int len;
-	struct usb_ibmcam *ibmcam = urb->context;
-	struct ibmcam_sbuf *sbuf;
-	int i;
+	const unsigned char *data_rv, *data_gv, *data_bv;
+	unsigned int len;
+	int i, v4l_linesize; /* V4L line offset */
+	const int data_w=128, data_h=96;
+	static unsigned char lineBuffer[128*5];
 
-	/* We don't want to do anything if we are about to be removed! */
-	if (!IBMCAM_IS_OPERATIONAL(ibmcam))
-		return;
+	v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
 
-#if 0
-	if (urb->actual_length > 0) {
-		printk(KERN_DEBUG "ibmcam_isoc_irq: %p status %d, "
-		       " errcount = %d, length = %d\n", urb, urb->status,
-		       urb->error_count, urb->actual_length);
-	} else {
-		static int c = 0;
-		if (c++ % 100 == 0)
-			printk(KERN_DEBUG "ibmcam_isoc_irq: no data\n");
+	/*
+	 * Make sure that our writing into output buffer
+	 * will not exceed the buffer. Note that we may write
+	 * not into current output scanline but in several after
+	 * it as well (if we enlarge image vertically.)
+	 */
+	if ((frame->curline + 1) >= data_h) {
+		if (uvd->debug >= 3)
+			info("Reached line %d. (frame is done)", frame->curline);
+		return scan_NextFrame;
 	}
-#endif
 
-	if (!ibmcam->streaming) {
-		if (debug >= 1)
-			printk(KERN_DEBUG "ibmcam: oops, not streaming, but interrupt\n");
-		return;
-	}
-	
-	sbuf = &ibmcam->sbuf[ibmcam->cursbuf];
+	/*
+	 * RGRGRG .... RGRG_____________B?B?B? ... B?B?____________
+	 * <---- 128*2 ---><---- 64 ---><--- 128*2 ---><--- 64 --->
+	 */
+
+	/* Make sure there's enough data for the entire line */
+	len = 5 * data_w;
+	assert(len <= sizeof(lineBuffer));
 
-	/* Copy the data received into our scratch buffer */
-	len = ibmcam_compress_isochronous(ibmcam, urb);
+	/* Make sure there's enough data for the entire line */
+	if (RingQueue_GetLength(&uvd->dp) < len)
+		return scan_Out;
 
-	ibmcam->urb_count++;
-	ibmcam->urb_length = len;
-	ibmcam->data_count += len;
-
-#if 0   /* This code prints few initial bytes of ISO data: used to decode markers */
-	if (ibmcam->urb_count % 64 == 1) {
-		if (ibmcam->urb_count == 1) {
-			ibmcam_hexdump(ibmcam->scratch,
-				       (ibmcam->scratchlen > 32) ? 32 : ibmcam->scratchlen);
+	/* Suck one line out of the ring queue */
+	RingQueue_Dequeue(&uvd->dp, lineBuffer, len);
+
+	data_rv = lineBuffer;
+	data_gv = lineBuffer + 1;
+	data_bv = lineBuffer + data_w*2 + data_w/2;
+	for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
+		int rv, gv, bv;	/* RGB components */
+		if (i < data_w) {
+			const int j = i * 2;
+			gv = data_rv[j];
+			rv = data_gv[j];
+			bv = data_bv[j];
+			if (flags & FLAGS_MONOCHROME) {
+				unsigned long y;
+				y = rv + gv + bv;
+				y /= 3;
+				if (y > 0xFF)
+					y = 0xFF;
+				rv = gv = bv = (unsigned char) y;
+			}
+		} else {
+			rv = gv = bv = 0;
 		}
+		RGB24_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
 	}
-#endif
+	frame->deinterlace = Deinterlace_None;
+	frame->curline++;
+	*pcopylen += v4l_linesize;
 
-	/* If we collected enough data let's parse! */
-	if (ibmcam->scratchlen) {
-		/* If we don't have a frame we're current working on, complain */
-		if (ibmcam->curframe >= 0)
-			ibmcam_parse_data(ibmcam);
-		else {
-			if (debug >= 1)
-				printk(KERN_DEBUG "ibmcam: received data, but no frame available\n");
+	if (frame->curline >= VIDEOSIZE_Y(frame->request)) {
+		if (uvd->debug >= 3) {
+			info("All requested lines (%ld.) done.",
+			     VIDEOSIZE_Y(frame->request));
+		}
+		return scan_NextFrame;
+	} else
+		return scan_Continue;
+}
+
+/*
+ * ibmcam_ProcessIsocData()
+ *
+ * Generic routine to parse the ring queue data. It employs either
+ * ibmcam_find_header() or ibmcam_parse_lines() to do most
+ * of work.
+ *
+ * History:
+ * 1/21/00  Created.
+ */
+void ibmcam_ProcessIsocData(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+	ParseState_t newstate;
+	long copylen = 0;
+	int mod = IBMCAM_T(uvd)->camera_model;
+
+	while (1) {
+		newstate = scan_Out;
+		if (RingQueue_GetLength(&uvd->dp) > 0) {
+			if (frame->scanstate == ScanState_Scanning) {
+				newstate = ibmcam_find_header(uvd);
+			} else if (frame->scanstate == ScanState_Lines) {
+				if ((mod == IBMCAM_MODEL_2) &&
+				    ((uvd->videosize == VIDEOSIZE_352x288) ||
+				     (uvd->videosize == VIDEOSIZE_320x240) ||
+				     (uvd->videosize == VIDEOSIZE_352x240)))
+				{
+					newstate = ibmcam_model2_320x240_parse_lines(
+						uvd, frame, &copylen);
+				} else if (mod == IBMCAM_MODEL_4) {
+					/*
+					 * Model 4 cameras (IBM NetCamera) use Model 2 decoder (RGB)
+					 * for 320x240 and above; 160x120 and 176x144 uses Model 1
+					 * decoder (YUV), and 128x96 mode uses ???
+					 */
+					if ((uvd->videosize == VIDEOSIZE_352x288) ||
+					    (uvd->videosize == VIDEOSIZE_320x240) ||
+					    (uvd->videosize == VIDEOSIZE_352x240))
+					{
+						newstate = ibmcam_model2_320x240_parse_lines(uvd, frame, &copylen);
+					} else if (uvd->videosize == VIDEOSIZE_128x96) {
+						newstate = ibmcam_model4_128x96_parse_lines(uvd, frame, &copylen);
+					} else {
+						newstate = ibmcam_parse_lines(uvd, frame, &copylen);
+					}
+				} else if (mod == IBMCAM_MODEL_3) {
+					newstate = ibmcam_model3_parse_lines(uvd, frame, &copylen);
+				} else {
+					newstate = ibmcam_parse_lines(uvd, frame, &copylen);
+				}
+			}
 		}
+		if (newstate == scan_Continue)
+			continue;
+		else if ((newstate == scan_NextFrame) || (newstate == scan_Out))
+			break;
+		else
+			return; /* scan_EndParse */
 	}
 
-	for (i = 0; i < FRAMES_PER_DESC; i++) {
-		sbuf->urb->iso_frame_desc[i].status = 0;
-		sbuf->urb->iso_frame_desc[i].actual_length = 0;
+	if (newstate == scan_NextFrame) {
+		frame->frameState = FrameState_Done;
+		uvd->curframe = -1;
+		uvd->stats.frame_num++;
+		if ((mod == IBMCAM_MODEL_2) || (mod == IBMCAM_MODEL_4)) {
+			/* Need software contrast adjustment for those cameras */
+			frame->flags |= USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST;
+		}
 	}
 
-	/* Move to the next sbuf */
-	ibmcam->cursbuf = (ibmcam->cursbuf + 1) % IBMCAM_NUMSBUF;
+	/* Update the frame's uncompressed length. */
+	frame->seqRead_Length += copylen;
 
-	return;
+#if 0
+	{
+		static unsigned char j=0;
+		memset(frame->data, j++, uvd->max_frame_size);
+		frame->frameState = FrameState_Ready;
+	}
+#endif
 }
 
 /*
- * usb_ibmcam_veio()
+ * ibmcam_veio()
  *
  * History:
  * 1/27/00  Added check for dev == NULL; this happens if camera is unplugged.
  */
-static int usb_ibmcam_veio(
-	struct usb_ibmcam *ibmcam,
+static int ibmcam_veio(
+	uvd_t *uvd,
 	unsigned char req,
 	unsigned short value,
 	unsigned short index)
 {
-	static const char proc[] = "usb_ibmcam_veio";
+	static const char proc[] = "ibmcam_veio";
 	unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
 	int i;
 
-	if (!IBMCAM_IS_OPERATIONAL(ibmcam))
+	if (!CAMERA_IS_OPERATIONAL(uvd))
 		return 0;
 
 	if (req == 1) {
 		i = usb_control_msg(
-			ibmcam->dev,
-			usb_rcvctrlpipe(ibmcam->dev, 0),
+			uvd->dev,
+			usb_rcvctrlpipe(uvd->dev, 0),
 			req,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
 			value,
@@ -1315,15 +1149,15 @@
 			sizeof(cp),
 			HZ);
 #if 0
-		printk(KERN_DEBUG "USB => %02x%02x%02x%02x%02x%02x%02x%02x "
-		       "(req=$%02x val=$%04x ind=$%04x)\n",
+		info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "
+		       "(req=$%02x val=$%04x ind=$%04x)",
 		       cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
 		       req, value, index);
 #endif
 	} else {
 		i = usb_control_msg(
-			ibmcam->dev,
-			usb_sndctrlpipe(ibmcam->dev, 0),
+			uvd->dev,
+			usb_sndctrlpipe(uvd->dev, 0),
 			req,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
 			value,
@@ -1333,15 +1167,15 @@
 			HZ);
 	}
 	if (i < 0) {
-		printk(KERN_ERR "%s: ERROR=%d. Camera stopped - "
-		       "reconnect or reload driver.\n", proc, i);
-		ibmcam->last_error = i;
+		err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
+		    proc, i);
+		uvd->last_error = i;
 	}
 	return i;
 }
 
 /*
- * usb_ibmcam_calculate_fps()
+ * ibmcam_calculate_fps()
  *
  * This procedure roughly calculates the real frame rate based
  * on FPS code (framerate=NNN option). Actual FPS differs
@@ -1358,13 +1192,13 @@
  * History:
  * 1/18/00  Created.
  */
-static int usb_ibmcam_calculate_fps(void)
+static int ibmcam_calculate_fps(uvd_t *uvd)
 {
 	return 3 + framerate*4 + framerate/2;
 }
 
 /*
- * usb_ibmcam_send_FF_04_02()
+ * ibmcam_send_FF_04_02()
  *
  * This procedure sends magic 3-command prefix to the camera.
  * The purpose of this prefix is not known.
@@ -1372,108 +1206,140 @@
  * History:
  * 1/2/00   Created.
  */
-static void usb_ibmcam_send_FF_04_02(struct usb_ibmcam *ibmcam)
+static void ibmcam_send_FF_04_02(uvd_t *uvd)
 {
-	usb_ibmcam_veio(ibmcam, 0, 0x00FF, 0x0127);
-	usb_ibmcam_veio(ibmcam, 0, 0x0004, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0002, 0x0124);
+	ibmcam_veio(uvd, 0, 0x00FF, 0x0127);
+	ibmcam_veio(uvd, 0, 0x0004, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0002, 0x0124);
 }
 
-static void usb_ibmcam_send_00_04_06(struct usb_ibmcam *ibmcam)
+static void ibmcam_send_00_04_06(uvd_t *uvd)
 {
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0127);
-	usb_ibmcam_veio(ibmcam, 0, 0x0004, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0006, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+	ibmcam_veio(uvd, 0, 0x0004, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0006, 0x0124);
 }
 
-static void usb_ibmcam_send_x_00(struct usb_ibmcam *ibmcam, unsigned short x)
+static void ibmcam_send_x_00(uvd_t *uvd, unsigned short x)
 {
-	usb_ibmcam_veio(ibmcam, 0, x,      0x0127);
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0124);
+	ibmcam_veio(uvd, 0, x,      0x0127);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0124);
 }
 
-static void usb_ibmcam_send_x_00_05(struct usb_ibmcam *ibmcam, unsigned short x)
+static void ibmcam_send_x_00_05(uvd_t *uvd, unsigned short x)
 {
-	usb_ibmcam_send_x_00(ibmcam, x);
-	usb_ibmcam_veio(ibmcam, 0, 0x0005, 0x0124);
+	ibmcam_send_x_00(uvd, x);
+	ibmcam_veio(uvd, 0, 0x0005, 0x0124);
 }
 
-static void usb_ibmcam_send_x_00_05_02(struct usb_ibmcam *ibmcam, unsigned short x)
+static void ibmcam_send_x_00_05_02(uvd_t *uvd, unsigned short x)
 {
-	usb_ibmcam_veio(ibmcam, 0, x,      0x0127);
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0005, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0002, 0x0124);
+	ibmcam_veio(uvd, 0, x,      0x0127);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0005, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0002, 0x0124);
 }
 
-static void usb_ibmcam_send_x_01_00_05(struct usb_ibmcam *ibmcam, unsigned short x)
+static void ibmcam_send_x_01_00_05(uvd_t *uvd, unsigned short x)
 {
-	usb_ibmcam_veio(ibmcam, 0, x,      0x0127);
-	usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0005, 0x0124);
+	ibmcam_veio(uvd, 0, x,      0x0127);
+	ibmcam_veio(uvd, 0, 0x0001, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0005, 0x0124);
 }
 
-static void usb_ibmcam_send_x_00_05_02_01(struct usb_ibmcam *ibmcam, unsigned short x)
+static void ibmcam_send_x_00_05_02_01(uvd_t *uvd, unsigned short x)
 {
-	usb_ibmcam_veio(ibmcam, 0, x,      0x0127);
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0005, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0002, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0124);
+	ibmcam_veio(uvd, 0, x,      0x0127);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0005, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0002, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0001, 0x0124);
 }
 
-static void usb_ibmcam_send_x_00_05_02_08_01(struct usb_ibmcam *ibmcam, unsigned short x)
+static void ibmcam_send_x_00_05_02_08_01(uvd_t *uvd, unsigned short x)
 {
-	usb_ibmcam_veio(ibmcam, 0, x,      0x0127);
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0005, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0002, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0008, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0124);
+	ibmcam_veio(uvd, 0, x,      0x0127);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0005, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0002, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0008, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0001, 0x0124);
 }
 
-static void usb_ibmcam_Packet_Format1(struct usb_ibmcam *ibmcam, unsigned char fkey, unsigned char val)
+static void ibmcam_Packet_Format1(uvd_t *uvd, unsigned char fkey, unsigned char val)
 {
-	usb_ibmcam_send_x_01_00_05	(ibmcam, unknown_88);
-	usb_ibmcam_send_x_00_05		(ibmcam, fkey);
-	usb_ibmcam_send_x_00_05_02_08_01(ibmcam, val);
-	usb_ibmcam_send_x_00_05		(ibmcam, unknown_88);
-	usb_ibmcam_send_x_00_05_02_01	(ibmcam, fkey);
-	usb_ibmcam_send_x_00_05		(ibmcam, unknown_89);
-	usb_ibmcam_send_x_00		(ibmcam, fkey);
-	usb_ibmcam_send_00_04_06	(ibmcam);
-	usb_ibmcam_veio			(ibmcam, 1, 0x0000, 0x0126);
-	usb_ibmcam_send_FF_04_02	(ibmcam);
+	ibmcam_send_x_01_00_05(uvd, unknown_88);
+	ibmcam_send_x_00_05(uvd, fkey);
+	ibmcam_send_x_00_05_02_08_01(uvd, val);
+	ibmcam_send_x_00_05(uvd, unknown_88);
+	ibmcam_send_x_00_05_02_01(uvd, fkey);
+	ibmcam_send_x_00_05(uvd, unknown_89);
+	ibmcam_send_x_00(uvd, fkey);
+	ibmcam_send_00_04_06(uvd);
+	ibmcam_veio(uvd, 1, 0x0000, 0x0126);
+	ibmcam_send_FF_04_02(uvd);
 }
 
-static void usb_ibmcam_PacketFormat2(struct usb_ibmcam *ibmcam, unsigned char fkey, unsigned char val)
+static void ibmcam_PacketFormat2(uvd_t *uvd, unsigned char fkey, unsigned char val)
 {
-	usb_ibmcam_send_x_01_00_05	(ibmcam, unknown_88);
-	usb_ibmcam_send_x_00_05		(ibmcam, fkey);
-	usb_ibmcam_send_x_00_05_02	(ibmcam, val);
+	ibmcam_send_x_01_00_05	(uvd, unknown_88);
+	ibmcam_send_x_00_05	(uvd, fkey);
+	ibmcam_send_x_00_05_02	(uvd, val);
 }
 
-static void usb_ibmcam_model2_Packet2(struct usb_ibmcam *ibmcam)
+static void ibmcam_model2_Packet2(uvd_t *uvd)
 {
-	usb_ibmcam_veio(ibmcam, 0, 0x00ff, 0x012d);
-	usb_ibmcam_veio(ibmcam, 0, 0xfea3, 0x0124);
+	ibmcam_veio(uvd, 0, 0x00ff, 0x012d);
+	ibmcam_veio(uvd, 0, 0xfea3, 0x0124);
 }
 
-static void usb_ibmcam_model2_Packet1(struct usb_ibmcam *ibmcam, unsigned short v1, unsigned short v2)
+static void ibmcam_model2_Packet1(uvd_t *uvd, unsigned short v1, unsigned short v2)
 {
-	usb_ibmcam_veio(ibmcam, 0, 0x00aa, 0x012d);
-	usb_ibmcam_veio(ibmcam, 0, 0x00ff, 0x012e);
-	usb_ibmcam_veio(ibmcam, 0, v1, 	   0x012f);
-	usb_ibmcam_veio(ibmcam, 0, 0x00ff, 0x0130);
-	usb_ibmcam_veio(ibmcam, 0, 0xc719, 0x0124);
-	usb_ibmcam_veio(ibmcam, 0, v2,     0x0127);
+	ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+	ibmcam_veio(uvd, 0, 0x00ff, 0x012e);
+	ibmcam_veio(uvd, 0, v1,     0x012f);
+	ibmcam_veio(uvd, 0, 0x00ff, 0x0130);
+	ibmcam_veio(uvd, 0, 0xc719, 0x0124);
+	ibmcam_veio(uvd, 0, v2,     0x0127);
 
-	usb_ibmcam_model2_Packet2(ibmcam);
+	ibmcam_model2_Packet2(uvd);
 }
 
 /*
- * usb_ibmcam_adjust_contrast()
+ * ibmcam_model3_Packet1()
+ *
+ * 00_0078_012d	
+ * 00_0097_012f
+ * 00_d141_0124	
+ * 00_0096_0127
+ * 00_fea8_0124	
+*/
+static void ibmcam_model3_Packet1(uvd_t *uvd, unsigned short v1, unsigned short v2)
+{
+	ibmcam_veio(uvd, 0, 0x0078, 0x012d);
+	ibmcam_veio(uvd, 0, v1,     0x012f);
+	ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+	ibmcam_veio(uvd, 0, v2,     0x0127);
+	ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+}
+
+static void ibmcam_model4_BrightnessPacket(uvd_t *uvd, int i)
+{
+	ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+	ibmcam_veio(uvd, 0, 0x0026, 0x012f);
+	ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+	ibmcam_veio(uvd, 0, i,      0x0127);
+	ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+	ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+	ibmcam_veio(uvd, 0, 0x0038, 0x012d);
+	ibmcam_veio(uvd, 0, 0x0004, 0x012f);
+	ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+	ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+}
+
+/*
+ * ibmcam_adjust_contrast()
  *
  * The contrast value changes from 0 (high contrast) to 15 (low contrast).
  * This is in reverse to usual order of things (such as TV controls), so
@@ -1484,30 +1350,65 @@
  * History:
  * 1/2/00   Created.
  */
-static void usb_ibmcam_adjust_contrast(struct usb_ibmcam *ibmcam)
+static void ibmcam_adjust_contrast(uvd_t *uvd)
 {
-	unsigned char new_contrast = ibmcam->vpic.contrast >> 12;
-	const int ntries = 5;
+	unsigned char a_contrast = uvd->vpic.contrast >> 12;
+	unsigned char new_contrast;
 
-	if (new_contrast >= 16)
-		new_contrast = 15;
-	new_contrast = 15 - new_contrast;
-	if (new_contrast != ibmcam->vpic_old.contrast) {
-		ibmcam->vpic_old.contrast = new_contrast;
-		if (ibmcam->camera_model == IBMCAM_MODEL_1) {
-			int i;
-			for (i=0; i < ntries; i++) {
-				usb_ibmcam_Packet_Format1(ibmcam, contrast_14, new_contrast);
-				usb_ibmcam_send_FF_04_02(ibmcam);
-			}
-		} else {
-			/* Camera model 2 does not have this control; implemented in software. */
+	if (a_contrast >= 16)
+		a_contrast = 15;
+	new_contrast = 15 - a_contrast;
+	if (new_contrast == uvd->vpic_old.contrast)
+		return;
+	uvd->vpic_old.contrast = new_contrast;
+	switch (IBMCAM_T(uvd)->camera_model) {
+	case IBMCAM_MODEL_1:
+	{
+		const int ntries = 5;
+		int i;
+		for (i=0; i < ntries; i++) {
+			ibmcam_Packet_Format1(uvd, contrast_14, new_contrast);
+			ibmcam_send_FF_04_02(uvd);
 		}
+		break;
+	}
+	case IBMCAM_MODEL_2:
+	case IBMCAM_MODEL_4:
+		/* Models 2, 4 do not have this control; implemented in software. */
+		break;
+	case IBMCAM_MODEL_3:
+	{	/* Preset hardware values */
+		static const struct {
+			unsigned short cv1;
+			unsigned short cv2;
+			unsigned short cv3;
+		} cv[7] = {
+			{ 0x05, 0x05, 0x0f },	/* Minimum */
+			{ 0x04, 0x04, 0x16 },
+			{ 0x02, 0x03, 0x16 },
+			{ 0x02, 0x08, 0x16 },
+			{ 0x01, 0x0c, 0x16 },
+			{ 0x01, 0x0e, 0x16 },
+			{ 0x01, 0x10, 0x16 }	/* Maximum */
+		};
+		int i = a_contrast / 2;
+		RESTRICT_TO_RANGE(i, 0, 6);
+		ibmcam_veio(uvd, 0, 0x0000, 0x010c);	/* Stop */
+		ibmcam_model3_Packet1(uvd, 0x0067, cv[i].cv1);
+		ibmcam_model3_Packet1(uvd, 0x005b, cv[i].cv2);
+		ibmcam_model3_Packet1(uvd, 0x005c, cv[i].cv3);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0114);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);	/* Go! */
+		usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
+		break;
+	}
+	default:
+		break;
 	}
 }
 
 /*
- * usb_ibmcam_change_lighting_conditions()
+ * ibmcam_change_lighting_conditions()
  *
  * Camera model 1:
  * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
@@ -1524,19 +1425,24 @@
  * 1/5/00   Created.
  * 2/20/00  Added support for Model 2 cameras.
  */
-static void usb_ibmcam_change_lighting_conditions(struct usb_ibmcam *ibmcam)
+static void ibmcam_change_lighting_conditions(uvd_t *uvd)
 {
-	static const char proc[] = "usb_ibmcam_change_lighting_conditions";
+	static const char proc[] = "ibmcam_change_lighting_conditions";
 
 	if (debug > 0)
-		printk(KERN_INFO "%s: Set lighting to %hu.\n", proc, lighting);
+		info("%s: Set lighting to %hu.", proc, lighting);
 
-	if (ibmcam->camera_model == IBMCAM_MODEL_1) {
+	switch (IBMCAM_T(uvd)->camera_model) {
+	case IBMCAM_MODEL_1:
+	{
 		const int ntries = 5;
 		int i;
 		for (i=0; i < ntries; i++)
-			usb_ibmcam_Packet_Format1(ibmcam, light_27, (unsigned short) lighting);
-	} else {
+			ibmcam_Packet_Format1(uvd, light_27, (unsigned short) lighting);
+		break;
+	}
+	case IBMCAM_MODEL_2:
+#if 0
 		/*
 		 * This command apparently requires camera to be stopped. My
 		 * experiments showed that it -is- possible to alter the lighting
@@ -1546,385 +1452,549 @@
 		 * is commented out because it does not work at -any- moment, so its
 		 * presence makes no sense. You may use it for experiments.
 		 */
-#if 0
-		usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x010c);	/* Stop camera */
-		usb_ibmcam_model2_Packet1(ibmcam, mod2_sensitivity, lighting);
-		usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c);	/* Start camera */
+		ibmcam_veio(uvd, 0, 0x0000, 0x010c);	/* Stop camera */
+		ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);	/* Start camera */
 #endif
+		break;
+	case IBMCAM_MODEL_3:
+	case IBMCAM_MODEL_4:
+	default:
+		break;
 	}
 }
 
 /*
- * usb_ibmcam_set_sharpness()
+ * ibmcam_set_sharpness()
  *
  * Cameras model 1 have internal smoothing feature. It is controlled by value in
  * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess).
  * Recommended value is 4. Cameras model 2 do not have this feature at all.
  */
-static void usb_ibmcam_set_sharpness(struct usb_ibmcam *ibmcam)
+static void ibmcam_set_sharpness(uvd_t *uvd)
 {
-	static const char proc[] = "usb_ibmcam_set_sharpness";
+	static const char proc[] = "ibmcam_set_sharpness";
 
-	if (ibmcam->camera_model == IBMCAM_MODEL_1) {
+	switch (IBMCAM_T(uvd)->camera_model) {
+	case IBMCAM_MODEL_1:
+	{
 		static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
 		unsigned short i, sv;
 
 		RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
 		if (debug > 0)
-			printk(KERN_INFO "%s: Set sharpness to %hu.\n", proc, sharpness);
+			info("%s: Set sharpness to %hu.", proc, sharpness);
 
 		sv = sa[sharpness - SHARPNESS_MIN];
 		for (i=0; i < 2; i++) {
-			usb_ibmcam_send_x_01_00_05	(ibmcam, unknown_88);
-			usb_ibmcam_send_x_00_05		(ibmcam, sharp_13);
-			usb_ibmcam_send_x_00_05_02	(ibmcam, sv);
+			ibmcam_send_x_01_00_05	(uvd, unknown_88);
+			ibmcam_send_x_00_05		(uvd, sharp_13);
+			ibmcam_send_x_00_05_02	(uvd, sv);
 		}
-	} else {
-		/* Camera model 2 does not have this control */
+		break;
+	}
+	case IBMCAM_MODEL_2:
+	case IBMCAM_MODEL_4:
+		/* Models 2, 4 do not have this control */
+		break;
+	case IBMCAM_MODEL_3:
+	{	/*
+		 * "Use a table of magic numbers.
+		 *  This setting doesn't really change much.
+		 *  But that's how Windows does it."
+		 */
+		static const struct {
+			unsigned short sv1;
+			unsigned short sv2;
+			unsigned short sv3;
+			unsigned short sv4;
+		} sv[7] = {
+			{ 0x00, 0x00, 0x05, 0x14 },	/* Smoothest */
+			{ 0x01, 0x04, 0x05, 0x14 },
+			{ 0x02, 0x04, 0x05, 0x14 },
+			{ 0x03, 0x04, 0x05, 0x14 },
+			{ 0x03, 0x05, 0x05, 0x14 },
+			{ 0x03, 0x06, 0x05, 0x14 },
+			{ 0x03, 0x07, 0x05, 0x14 }	/* Sharpest */
+		};
+		RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
+		RESTRICT_TO_RANGE(sharpness, 0, 6);
+		ibmcam_veio(uvd, 0, 0x0000, 0x010c);	/* Stop */
+		ibmcam_model3_Packet1(uvd, 0x0060, sv[sharpness].sv1);
+		ibmcam_model3_Packet1(uvd, 0x0061, sv[sharpness].sv2);
+		ibmcam_model3_Packet1(uvd, 0x0062, sv[sharpness].sv3);
+		ibmcam_model3_Packet1(uvd, 0x0063, sv[sharpness].sv4);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0114);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);	/* Go! */
+		usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
+		ibmcam_veio(uvd, 0, 0x0001, 0x0113);
+		break;
+	}
+	default:
+		break;
 	}
 }
 
 /*
- * usb_ibmcam_set_brightness()
+ * ibmcam_set_brightness()
  *
  * This procedure changes brightness of the picture.
  */
-static void usb_ibmcam_set_brightness(struct usb_ibmcam *ibmcam)
+static void ibmcam_set_brightness(uvd_t *uvd)
 {
-	static const char proc[] = "usb_ibmcam_set_brightness";
+	static const char proc[] = "ibmcam_set_brightness";
 	static const unsigned short n = 1;
-	unsigned short i, j, bv[3];
-
-	bv[0] = bv[1] = bv[2] = ibmcam->vpic.brightness >> 10;
-	if (bv[0] == (ibmcam->vpic_old.brightness >> 10))
-		return;
-	ibmcam->vpic_old.brightness = ibmcam->vpic.brightness;
 
 	if (debug > 0)
-		printk(KERN_INFO "%s: Set brightness to (%hu,%hu,%hu)\n",
-		       proc, bv[0], bv[1], bv[2]);
+		info("%s: Set brightness to %hu.", proc, uvd->vpic.brightness);
 
-	if (ibmcam->camera_model == IBMCAM_MODEL_1) {
+	switch (IBMCAM_T(uvd)->camera_model) {
+	case IBMCAM_MODEL_1:
+	{
+		unsigned short i, j, bv[3];
+		bv[0] = bv[1] = bv[2] = uvd->vpic.brightness >> 10;
+		if (bv[0] == (uvd->vpic_old.brightness >> 10))
+			return;
+		uvd->vpic_old.brightness = bv[0];
 		for (j=0; j < 3; j++)
 			for (i=0; i < n; i++)
-				usb_ibmcam_Packet_Format1(ibmcam, bright_3x[j], bv[j]);
-	} else {
-		i = ibmcam->vpic.brightness >> 12;	/* 0 .. 15 */
+				ibmcam_Packet_Format1(uvd, bright_3x[j], bv[j]);
+		break;
+	}
+	case IBMCAM_MODEL_2:
+	{
+		unsigned short i, j;
+		i = uvd->vpic.brightness >> 12;	/* 0 .. 15 */
 		j = 0x60 + i * ((0xee - 0x60) / 16);	/* 0x60 .. 0xee or so */
-		usb_ibmcam_model2_Packet1(ibmcam, mod2_brightness, j);
+		if (uvd->vpic_old.brightness == j)
+			break;
+		uvd->vpic_old.brightness = j;
+		ibmcam_model2_Packet1(uvd, mod2_brightness, j);
+		break;
+	}
+	case IBMCAM_MODEL_3:
+	{
+		/* Model 3: Brightness range 'i' in [0x0C..0x3F] */
+		unsigned short i =
+			0x0C + (uvd->vpic.brightness / (0xFFFF / (0x3F - 0x0C + 1)));
+		RESTRICT_TO_RANGE(i, 0x0C, 0x3F);
+		if (uvd->vpic_old.brightness == i)
+			break;
+		uvd->vpic_old.brightness = i;
+		ibmcam_veio(uvd, 0, 0x0000, 0x010c);	/* Stop */
+		ibmcam_model3_Packet1(uvd, 0x0036, i);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0114);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);	/* Go! */
+		usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
+		ibmcam_veio(uvd, 0, 0x0001, 0x0113);
+		break;
+	}
+	case IBMCAM_MODEL_4:
+	{
+		/* Model 4: Brightness range 'i' in [0x04..0xb4] */
+		unsigned short i = 0x04 + (uvd->vpic.brightness / (0xFFFF / (0xb4 - 0x04 + 1)));
+		RESTRICT_TO_RANGE(i, 0x04, 0xb4);
+		if (uvd->vpic_old.brightness == i)
+			break;
+		uvd->vpic_old.brightness = i;
+		ibmcam_model4_BrightnessPacket(uvd, i);
+		break;
+	}
+	default:
+		break;
 	}
 }
 
-static void usb_ibmcam_model2_set_hue(struct usb_ibmcam *ibmcam)
+static void ibmcam_set_hue(uvd_t *uvd)
 {
-	unsigned short hue = ibmcam->vpic.hue >> 9; /* 0 .. 7F */
+	switch (IBMCAM_T(uvd)->camera_model) {
+	case IBMCAM_MODEL_2:
+	{
+		unsigned short hue = uvd->vpic.hue >> 9; /* 0 .. 7F */
+		if (uvd->vpic_old.hue == hue)
+			return;
+		uvd->vpic_old.hue = hue;
+		ibmcam_model2_Packet1(uvd, mod2_hue, hue);
+		/* ibmcam_model2_Packet1(uvd, mod2_saturation, sat); */
+		break;
+	}
+	case IBMCAM_MODEL_3:
+	{
+#if 0 /* This seems not to work. No problem, will fix programmatically */
+		unsigned short hue = 0x05 + (uvd->vpic.hue / (0xFFFF / (0x37 - 0x05 + 1)));
+		RESTRICT_TO_RANGE(hue, 0x05, 0x37);
+		if (uvd->vpic_old.hue == hue)
+			return;
+		uvd->vpic_old.hue = hue;
+		ibmcam_veio(uvd, 0, 0x0000, 0x010c);	/* Stop */
+		ibmcam_model3_Packet1(uvd, 0x007e, hue);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0114);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);	/* Go! */
+		usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
+		ibmcam_veio(uvd, 0, 0x0001, 0x0113);
+#endif
+		break;
+	}
+	case IBMCAM_MODEL_4:
+	{
+		unsigned short r_gain, g_gain, b_gain, hue;
+
+		/*
+		 * I am not sure r/g/b_gain variables exactly control gain
+		 * of those channels. Most likely they subtly change some
+		 * very internal image processing settings in the camera.
+		 * In any case, here is what they do, and feel free to tweak:
+		 *
+		 * r_gain: seriously affects red gain
+		 * g_gain: seriously affects green gain
+		 * b_gain: seriously affects blue gain
+		 * hue: changes average color from violet (0) to red (0xFF)
+		 *
+		 * These settings are preset for a decent white balance in
+		 * 320x240, 352x288 modes. Low-res modes exhibit higher contrast
+		 * and therefore may need different values here.
+		 */
+		hue = 20 + (uvd->vpic.hue >> 9);
+		switch (uvd->videosize) {
+		case VIDEOSIZE_128x96:
+			r_gain = 90;
+			g_gain = 166;
+			b_gain = 175;
+			break;
+		case VIDEOSIZE_160x120:
+			r_gain = 70;
+			g_gain = 166;
+			b_gain = 185;
+			break;
+		case VIDEOSIZE_176x144:
+			r_gain = 160;
+			g_gain = 175;
+			b_gain = 185;
+			break;
+		default:
+			r_gain = 120;
+			g_gain = 166;
+			b_gain = 175;
+			break;
+		}
+		RESTRICT_TO_RANGE(hue, 1, 0x7f);
 
-	usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg, hue);
-	/* usb_ibmcam_model2_Packet1(ibmcam, mod2_saturation, sat); */
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x001e, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, g_gain, 0x0127);	/* Green gain */
+		ibmcam_veio(uvd, 0, r_gain, 0x012e);	/* Red gain */
+		ibmcam_veio(uvd, 0, b_gain, 0x0130);	/* Blue gain */
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, hue,    0x012d);	/* Hue */
+		ibmcam_veio(uvd, 0, 0xf545, 0x0124);
+		break;
+	}
+	default:
+		break;
+	}
 }
 
 /*
- * usb_ibmcam_adjust_picture()
+ * ibmcam_adjust_picture()
  *
  * This procedure gets called from V4L interface to update picture settings.
  * Here we change brightness and contrast.
  */
-static void usb_ibmcam_adjust_picture(struct usb_ibmcam *ibmcam)
+static void ibmcam_adjust_picture(uvd_t *uvd)
 {
-	usb_ibmcam_adjust_contrast(ibmcam);
-	usb_ibmcam_set_brightness(ibmcam);
-	if (ibmcam->camera_model == IBMCAM_MODEL_2) {
-		usb_ibmcam_model2_set_hue(ibmcam);
-	}
+	ibmcam_adjust_contrast(uvd);
+	ibmcam_set_brightness(uvd);
+	ibmcam_set_hue(uvd);
 }
 
-static int usb_ibmcam_model1_setup(struct usb_ibmcam *ibmcam)
+static int ibmcam_model1_setup(uvd_t *uvd)
 {
 	const int ntries = 5;
 	int i;
 
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0128);
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100);
-	usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0100);	/* LED On  */
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100);
-	usb_ibmcam_veio(ibmcam, 0, 0x81, 0x0100);	/* LED Off */
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100);
-	usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0100);	/* LED On  */
-	usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0108);
-
-	usb_ibmcam_veio(ibmcam, 0, 0x03, 0x0112);
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0115);
-	usb_ibmcam_veio(ibmcam, 0, 0x06, 0x0115);
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0116);
-	usb_ibmcam_veio(ibmcam, 0, 0x44, 0x0116);
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0116);
-	usb_ibmcam_veio(ibmcam, 0, 0x40, 0x0116);
-	usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0115);
-	usb_ibmcam_veio(ibmcam, 0, 0x0e, 0x0115);
-	usb_ibmcam_veio(ibmcam, 0, 0x19, 0x012c);
-
-	usb_ibmcam_Packet_Format1(ibmcam, 0x00, 0x1e);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x39, 0x0d);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x39, 0x09);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x3b, 0x00);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x28, 0x22);
-	usb_ibmcam_Packet_Format1(ibmcam, light_27, 0);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x2b, 0x1f);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x39, 0x08);
+	ibmcam_veio(uvd, 1, 0x00, 0x0128);
+	ibmcam_veio(uvd, 1, 0x00, 0x0100);
+	ibmcam_veio(uvd, 0, 0x01, 0x0100);	/* LED On  */
+	ibmcam_veio(uvd, 1, 0x00, 0x0100);
+	ibmcam_veio(uvd, 0, 0x81, 0x0100);	/* LED Off */
+	ibmcam_veio(uvd, 1, 0x00, 0x0100);
+	ibmcam_veio(uvd, 0, 0x01, 0x0100);	/* LED On  */
+	ibmcam_veio(uvd, 0, 0x01, 0x0108);
+
+	ibmcam_veio(uvd, 0, 0x03, 0x0112);
+	ibmcam_veio(uvd, 1, 0x00, 0x0115);
+	ibmcam_veio(uvd, 0, 0x06, 0x0115);
+	ibmcam_veio(uvd, 1, 0x00, 0x0116);
+	ibmcam_veio(uvd, 0, 0x44, 0x0116);
+	ibmcam_veio(uvd, 1, 0x00, 0x0116);
+	ibmcam_veio(uvd, 0, 0x40, 0x0116);
+	ibmcam_veio(uvd, 1, 0x00, 0x0115);
+	ibmcam_veio(uvd, 0, 0x0e, 0x0115);
+	ibmcam_veio(uvd, 0, 0x19, 0x012c);
+
+	ibmcam_Packet_Format1(uvd, 0x00, 0x1e);
+	ibmcam_Packet_Format1(uvd, 0x39, 0x0d);
+	ibmcam_Packet_Format1(uvd, 0x39, 0x09);
+	ibmcam_Packet_Format1(uvd, 0x3b, 0x00);
+	ibmcam_Packet_Format1(uvd, 0x28, 0x22);
+	ibmcam_Packet_Format1(uvd, light_27, 0);
+	ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
+	ibmcam_Packet_Format1(uvd, 0x39, 0x08);
 
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x2c, 0x00);
+		ibmcam_Packet_Format1(uvd, 0x2c, 0x00);
 
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x30, 0x14);
+		ibmcam_Packet_Format1(uvd, 0x30, 0x14);
 
-	usb_ibmcam_PacketFormat2(ibmcam, 0x39, 0x02);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x01, 0xe1);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x02, 0xcd);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x03, 0xcd);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x04, 0xfa);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x3f, 0xff);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x39, 0x00);
-
-	usb_ibmcam_PacketFormat2(ibmcam, 0x39, 0x02);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x0a, 0x37);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x0b, 0xb8);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x0c, 0xf3);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x0d, 0xe3);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x0e, 0x0d);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x0f, 0xf2);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x10, 0xd5);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x11, 0xba);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x12, 0x53);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x3f, 0xff);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x39, 0x00);
-
-	usb_ibmcam_PacketFormat2(ibmcam, 0x39, 0x02);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x16, 0x00);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x17, 0x28);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x18, 0x7d);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x19, 0xbe);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x3f, 0xff);
-	usb_ibmcam_PacketFormat2(ibmcam, 0x39, 0x00);
+	ibmcam_PacketFormat2(uvd, 0x39, 0x02);
+	ibmcam_PacketFormat2(uvd, 0x01, 0xe1);
+	ibmcam_PacketFormat2(uvd, 0x02, 0xcd);
+	ibmcam_PacketFormat2(uvd, 0x03, 0xcd);
+	ibmcam_PacketFormat2(uvd, 0x04, 0xfa);
+	ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
+	ibmcam_PacketFormat2(uvd, 0x39, 0x00);
+
+	ibmcam_PacketFormat2(uvd, 0x39, 0x02);
+	ibmcam_PacketFormat2(uvd, 0x0a, 0x37);
+	ibmcam_PacketFormat2(uvd, 0x0b, 0xb8);
+	ibmcam_PacketFormat2(uvd, 0x0c, 0xf3);
+	ibmcam_PacketFormat2(uvd, 0x0d, 0xe3);
+	ibmcam_PacketFormat2(uvd, 0x0e, 0x0d);
+	ibmcam_PacketFormat2(uvd, 0x0f, 0xf2);
+	ibmcam_PacketFormat2(uvd, 0x10, 0xd5);
+	ibmcam_PacketFormat2(uvd, 0x11, 0xba);
+	ibmcam_PacketFormat2(uvd, 0x12, 0x53);
+	ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
+	ibmcam_PacketFormat2(uvd, 0x39, 0x00);
+
+	ibmcam_PacketFormat2(uvd, 0x39, 0x02);
+	ibmcam_PacketFormat2(uvd, 0x16, 0x00);
+	ibmcam_PacketFormat2(uvd, 0x17, 0x28);
+	ibmcam_PacketFormat2(uvd, 0x18, 0x7d);
+	ibmcam_PacketFormat2(uvd, 0x19, 0xbe);
+	ibmcam_PacketFormat2(uvd, 0x3f, 0xff);
+	ibmcam_PacketFormat2(uvd, 0x39, 0x00);
 
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x00, 0x18);
+		ibmcam_Packet_Format1(uvd, 0x00, 0x18);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x13, 0x18);
+		ibmcam_Packet_Format1(uvd, 0x13, 0x18);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x14, 0x06);
+		ibmcam_Packet_Format1(uvd, 0x14, 0x06);
 
 	/* This is default brightness */
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x31, 0x37);
+		ibmcam_Packet_Format1(uvd, 0x31, 0x37);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x32, 0x46);
+		ibmcam_Packet_Format1(uvd, 0x32, 0x46);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x33, 0x55);
+		ibmcam_Packet_Format1(uvd, 0x33, 0x55);
 
-	usb_ibmcam_Packet_Format1(ibmcam, 0x2e, 0x04);
+	ibmcam_Packet_Format1(uvd, 0x2e, 0x04);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x2d, 0x04);
+		ibmcam_Packet_Format1(uvd, 0x2d, 0x04);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x29, 0x80);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x2c, 0x01);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x30, 0x17);
-	usb_ibmcam_Packet_Format1(ibmcam, 0x39, 0x08);
+		ibmcam_Packet_Format1(uvd, 0x29, 0x80);
+	ibmcam_Packet_Format1(uvd, 0x2c, 0x01);
+	ibmcam_Packet_Format1(uvd, 0x30, 0x17);
+	ibmcam_Packet_Format1(uvd, 0x39, 0x08);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x34, 0x00);
+		ibmcam_Packet_Format1(uvd, 0x34, 0x00);
 
-	usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0101);
-	usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010a);
+	ibmcam_veio(uvd, 0, 0x00, 0x0101);
+	ibmcam_veio(uvd, 0, 0x00, 0x010a);
 
-	switch (videosize) {
+	switch (uvd->videosize) {
 	case VIDEOSIZE_128x96:
-		usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0103);
-		usb_ibmcam_veio(ibmcam, 0, 0x60, 0x0105);
-		usb_ibmcam_veio(ibmcam, 0, 0x0c, 0x010b);
-		usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011b);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x0b, 0x011d);
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x011e);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0129);
+		ibmcam_veio(uvd, 0, 0x80, 0x0103);
+		ibmcam_veio(uvd, 0, 0x60, 0x0105);
+		ibmcam_veio(uvd, 0, 0x0c, 0x010b);
+		ibmcam_veio(uvd, 0, 0x04, 0x011b);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x0b, 0x011d);
+		ibmcam_veio(uvd, 0, 0x00, 0x011e);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x00, 0x0129);
 		break;
 	case VIDEOSIZE_176x144:
-		usb_ibmcam_veio(ibmcam, 0, 0xb0, 0x0103);
-		usb_ibmcam_veio(ibmcam, 0, 0x8f, 0x0105);
-		usb_ibmcam_veio(ibmcam, 0, 0x06, 0x010b);
-		usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011b);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x0d, 0x011d);
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x011e);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x03, 0x0129);
+		ibmcam_veio(uvd, 0, 0xb0, 0x0103);
+		ibmcam_veio(uvd, 0, 0x8f, 0x0105);
+		ibmcam_veio(uvd, 0, 0x06, 0x010b);
+		ibmcam_veio(uvd, 0, 0x04, 0x011b);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x0d, 0x011d);
+		ibmcam_veio(uvd, 0, 0x00, 0x011e);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x03, 0x0129);
 		break;
 	case VIDEOSIZE_352x288:
-		usb_ibmcam_veio(ibmcam, 0, 0xb0, 0x0103);
-		usb_ibmcam_veio(ibmcam, 0, 0x90, 0x0105);
-		usb_ibmcam_veio(ibmcam, 0, 0x02, 0x010b);
-		usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011b);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x05, 0x011d);
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x011e);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0129);
+		ibmcam_veio(uvd, 0, 0xb0, 0x0103);
+		ibmcam_veio(uvd, 0, 0x90, 0x0105);
+		ibmcam_veio(uvd, 0, 0x02, 0x010b);
+		ibmcam_veio(uvd, 0, 0x04, 0x011b);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x05, 0x011d);
+		ibmcam_veio(uvd, 0, 0x00, 0x011e);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x00, 0x0129);
 		break;
 	}
 
-	usb_ibmcam_veio(ibmcam, 0, 0xff, 0x012b);
+	ibmcam_veio(uvd, 0, 0xff, 0x012b);
 
 	/* This is another brightness - don't know why */
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x31, 0xc3);
+		ibmcam_Packet_Format1(uvd, 0x31, 0xc3);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x32, 0xd2);
+		ibmcam_Packet_Format1(uvd, 0x32, 0xd2);
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, 0x33, 0xe1);
+		ibmcam_Packet_Format1(uvd, 0x33, 0xe1);
 
 	/* Default contrast */
 	for (i=0; i < ntries; i++)
-		usb_ibmcam_Packet_Format1(ibmcam, contrast_14, 0x0a);
+		ibmcam_Packet_Format1(uvd, contrast_14, 0x0a);
 
 	/* Default sharpness */
 	for (i=0; i < 2; i++)
-		usb_ibmcam_PacketFormat2(ibmcam, sharp_13, 0x1a);	/* Level 4 FIXME */
+		ibmcam_PacketFormat2(uvd, sharp_13, 0x1a);	/* Level 4 FIXME */
 
 	/* Default lighting conditions */
-	usb_ibmcam_Packet_Format1(ibmcam, light_27, lighting); /* 0=Bright 2=Low */
+	ibmcam_Packet_Format1(uvd, light_27, lighting); /* 0=Bright 2=Low */
 
 	/* Assorted init */
 
-	switch (videosize) {
+	switch (uvd->videosize) {
 	case VIDEOSIZE_128x96:
-		usb_ibmcam_Packet_Format1(ibmcam, 0x2b, 0x1e);
-		usb_ibmcam_veio(ibmcam, 0, 0xc9, 0x0119);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0109);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x36, 0x0102);
-		usb_ibmcam_veio(ibmcam, 0, 0x1a, 0x0104);
-		usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011a);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x2b, 0x011c);
-		usb_ibmcam_veio(ibmcam, 0, 0x23, 0x012a);	/* Same everywhere */
+		ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
+		ibmcam_veio(uvd, 0, 0xc9, 0x0119);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x80, 0x0109);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x36, 0x0102);
+		ibmcam_veio(uvd, 0, 0x1a, 0x0104);
+		ibmcam_veio(uvd, 0, 0x04, 0x011a);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x2b, 0x011c);
+		ibmcam_veio(uvd, 0, 0x23, 0x012a);	/* Same everywhere */
 #if 0
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x0106);
-		usb_ibmcam_veio(ibmcam, 0, 0x38, 0x0107);
+		ibmcam_veio(uvd, 0, 0x00, 0x0106);
+		ibmcam_veio(uvd, 0, 0x38, 0x0107);
 #else
-		usb_ibmcam_veio(ibmcam, 0, 0x02, 0x0106);
-		usb_ibmcam_veio(ibmcam, 0, 0x2a, 0x0107);
+		ibmcam_veio(uvd, 0, 0x02, 0x0106);
+		ibmcam_veio(uvd, 0, 0x2a, 0x0107);
 #endif
 		break;
 	case VIDEOSIZE_176x144:
-		usb_ibmcam_Packet_Format1(ibmcam, 0x2b, 0x1e);
-		usb_ibmcam_veio(ibmcam, 0, 0xc9, 0x0119);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0109);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x04, 0x0102);
-		usb_ibmcam_veio(ibmcam, 0, 0x02, 0x0104);
-		usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011a);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x2b, 0x011c);
-		usb_ibmcam_veio(ibmcam, 0, 0x23, 0x012a);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0106);
-		usb_ibmcam_veio(ibmcam, 0, 0xca, 0x0107);
+		ibmcam_Packet_Format1(uvd, 0x2b, 0x1e);
+		ibmcam_veio(uvd, 0, 0xc9, 0x0119);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x80, 0x0109);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x04, 0x0102);
+		ibmcam_veio(uvd, 0, 0x02, 0x0104);
+		ibmcam_veio(uvd, 0, 0x04, 0x011a);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x2b, 0x011c);
+		ibmcam_veio(uvd, 0, 0x23, 0x012a);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x01, 0x0106);
+		ibmcam_veio(uvd, 0, 0xca, 0x0107);
 		break;
 	case VIDEOSIZE_352x288:
-		usb_ibmcam_Packet_Format1(ibmcam, 0x2b, 0x1f);
-		usb_ibmcam_veio(ibmcam, 0, 0xc9, 0x0119);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x80, 0x0109);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x08, 0x0102);
-		usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0104);
-		usb_ibmcam_veio(ibmcam, 0, 0x04, 0x011a);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x2f, 0x011c);
-		usb_ibmcam_veio(ibmcam, 0, 0x23, 0x012a);	/* Same everywhere */
-		usb_ibmcam_veio(ibmcam, 0, 0x03, 0x0106);
-		usb_ibmcam_veio(ibmcam, 0, 0xf6, 0x0107);
-		break;
-	}
-	return IBMCAM_IS_OPERATIONAL(ibmcam);
-}
-
-static int usb_ibmcam_model2_setup(struct usb_ibmcam *ibmcam)
-{
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0100);	/* LED on */
-	usb_ibmcam_veio(ibmcam, 1, 0x0000, 0x0116);
-	usb_ibmcam_veio(ibmcam, 0, 0x0060, 0x0116);
-	usb_ibmcam_veio(ibmcam, 0, 0x0002, 0x0112);
-	usb_ibmcam_veio(ibmcam, 0, 0x00bc, 0x012c);
-	usb_ibmcam_veio(ibmcam, 0, 0x0008, 0x012b);
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0108);
-	usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0133);
-	usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0102);
-	switch (videosize) {
+		ibmcam_Packet_Format1(uvd, 0x2b, 0x1f);
+		ibmcam_veio(uvd, 0, 0xc9, 0x0119);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x80, 0x0109);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x08, 0x0102);
+		ibmcam_veio(uvd, 0, 0x01, 0x0104);
+		ibmcam_veio(uvd, 0, 0x04, 0x011a);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x2f, 0x011c);
+		ibmcam_veio(uvd, 0, 0x23, 0x012a);	/* Same everywhere */
+		ibmcam_veio(uvd, 0, 0x03, 0x0106);
+		ibmcam_veio(uvd, 0, 0xf6, 0x0107);
+		break;
+	}
+	return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
+}
+
+static int ibmcam_model2_setup(uvd_t *uvd)
+{
+	ibmcam_veio(uvd, 0, 0x0000, 0x0100);	/* LED on */
+	ibmcam_veio(uvd, 1, 0x0000, 0x0116);
+	ibmcam_veio(uvd, 0, 0x0060, 0x0116);
+	ibmcam_veio(uvd, 0, 0x0002, 0x0112);
+	ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
+	ibmcam_veio(uvd, 0, 0x0008, 0x012b);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0108);
+	ibmcam_veio(uvd, 0, 0x0001, 0x0133);
+	ibmcam_veio(uvd, 0, 0x0001, 0x0102);
+	switch (uvd->videosize) {
 	case VIDEOSIZE_176x144:
-		usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103);	/* All except 320x240 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x0024, 0x0105);	/* 176x144, 352x288 */
-		usb_ibmcam_veio(ibmcam, 0, 0x00b9, 0x010a);	/* Unique to this mode */
-		usb_ibmcam_veio(ibmcam, 0, 0x0038, 0x0119);	/* Unique to this mode */
-		usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x0090, 0x0107);	/* Unique to every mode*/
+		ibmcam_veio(uvd, 0, 0x002c, 0x0103);	/* All except 320x240 */
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);	/* Same */
+		ibmcam_veio(uvd, 0, 0x0024, 0x0105);	/* 176x144, 352x288 */
+		ibmcam_veio(uvd, 0, 0x00b9, 0x010a);	/* Unique to this mode */
+		ibmcam_veio(uvd, 0, 0x0038, 0x0119);	/* Unique to this mode */
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);	/* Same */
+		ibmcam_veio(uvd, 0, 0x0090, 0x0107);	/* Unique to every mode*/
 		break;
 	case VIDEOSIZE_320x240:
-		usb_ibmcam_veio(ibmcam, 0, 0x0028, 0x0103);	/* Unique to this mode */
-		usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x001e, 0x0105);	/* 320x240, 352x240 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a);	/* All except 176x144 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119);	/* All except 176x144 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x0098, 0x0107);	/* Unique to every mode*/
+		ibmcam_veio(uvd, 0, 0x0028, 0x0103);	/* Unique to this mode */
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);	/* Same */
+		ibmcam_veio(uvd, 0, 0x001e, 0x0105);	/* 320x240, 352x240 */
+		ibmcam_veio(uvd, 0, 0x0039, 0x010a);	/* All except 176x144 */
+		ibmcam_veio(uvd, 0, 0x0070, 0x0119);	/* All except 176x144 */
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);	/* Same */
+		ibmcam_veio(uvd, 0, 0x0098, 0x0107);	/* Unique to every mode*/
 		break;
 	case VIDEOSIZE_352x240:
-		usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103);	/* All except 320x240 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x001e, 0x0105);	/* 320x240, 352x240 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a);	/* All except 176x144 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119);	/* All except 176x144 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x00da, 0x0107);	/* Unique to every mode*/
+		ibmcam_veio(uvd, 0, 0x002c, 0x0103);	/* All except 320x240 */
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);	/* Same */
+		ibmcam_veio(uvd, 0, 0x001e, 0x0105);	/* 320x240, 352x240 */
+		ibmcam_veio(uvd, 0, 0x0039, 0x010a);	/* All except 176x144 */
+		ibmcam_veio(uvd, 0, 0x0070, 0x0119);	/* All except 176x144 */
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);	/* Same */
+		ibmcam_veio(uvd, 0, 0x00da, 0x0107);	/* Unique to every mode*/
 		break;
 	case VIDEOSIZE_352x288:
-		usb_ibmcam_veio(ibmcam, 0, 0x002c, 0x0103);	/* All except 320x240 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0104);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x0024, 0x0105);	/* 176x144, 352x288 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0039, 0x010a);	/* All except 176x144 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0070, 0x0119);	/* All except 176x144 */
-		usb_ibmcam_veio(ibmcam, 0, 0x0003, 0x0106);	/* Same */
-		usb_ibmcam_veio(ibmcam, 0, 0x00fe, 0x0107);	/* Unique to every mode*/
+		ibmcam_veio(uvd, 0, 0x002c, 0x0103);	/* All except 320x240 */
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);	/* Same */
+		ibmcam_veio(uvd, 0, 0x0024, 0x0105);	/* 176x144, 352x288 */
+		ibmcam_veio(uvd, 0, 0x0039, 0x010a);	/* All except 176x144 */
+		ibmcam_veio(uvd, 0, 0x0070, 0x0119);	/* All except 176x144 */
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);	/* Same */
+		ibmcam_veio(uvd, 0, 0x00fe, 0x0107);	/* Unique to every mode*/
 		break;
 	}
-	return IBMCAM_IS_OPERATIONAL(ibmcam);
+	return (CAMERA_IS_OPERATIONAL(uvd) ? 0 : -EFAULT);
 }
 
 /*
- * usb_ibmcam_model1_setup_after_video_if()
+ * ibmcam_model1_setup_after_video_if()
  *
  * This code adds finishing touches to the video data interface.
  * Here we configure the frame rate and turn on the LED.
  */
-static void usb_ibmcam_model1_setup_after_video_if(struct usb_ibmcam *ibmcam)
+static void ibmcam_model1_setup_after_video_if(uvd_t *uvd)
 {
 	unsigned short internal_frame_rate;
 
 	RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
 	internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */
-	usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0100);	/* LED On  */
-	usb_ibmcam_veio(ibmcam, 0, internal_frame_rate, 0x0111);
-	usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0114);
-	usb_ibmcam_veio(ibmcam, 0, 0xc0, 0x010c);
+	ibmcam_veio(uvd, 0, 0x01, 0x0100);	/* LED On  */
+	ibmcam_veio(uvd, 0, internal_frame_rate, 0x0111);
+	ibmcam_veio(uvd, 0, 0x01, 0x0114);
+	ibmcam_veio(uvd, 0, 0xc0, 0x010c);
 }
 
-static void usb_ibmcam_model2_setup_after_video_if(struct usb_ibmcam *ibmcam)
+static void ibmcam_model2_setup_after_video_if(uvd_t *uvd)
 {
-	unsigned short setup_model2_rg, setup_model2_rg2, setup_model2_sat, setup_model2_yb;
+	unsigned short setup_model2_rg2, setup_model2_sat, setup_model2_yb;
 
-	usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0100);	/* LED on */
+	ibmcam_veio(uvd, 0, 0x0000, 0x0100);	/* LED on */
 
-	switch (videosize) {
+	switch (uvd->videosize) {
 	case VIDEOSIZE_176x144:
-		usb_ibmcam_veio(ibmcam, 0, 0x0050, 0x0111);
-		usb_ibmcam_veio(ibmcam, 0, 0x00d0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x0050, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
 		break;
 	case VIDEOSIZE_320x240:
 	case VIDEOSIZE_352x240:
 	case VIDEOSIZE_352x288:
-		usb_ibmcam_veio(ibmcam, 0, 0x0040, 0x0111);
-		usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x0040, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
 		break;
 	}
-	usb_ibmcam_veio(ibmcam, 0, 0x009b, 0x010f);
-	usb_ibmcam_veio(ibmcam, 0, 0x00bb, 0x010f);
+	ibmcam_veio(uvd, 0, 0x009b, 0x010f);
+	ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
 
 	/*
 	 * Hardware settings, may affect CMOS sensor; not user controls!
@@ -1939,52 +2009,52 @@
 	 * 0x002c: hardware setting (related to scan lines)
 	 * 0x002e: stops video stream, probably important h/w setting
 	 */
-	usb_ibmcam_model2_Packet1(ibmcam, 0x000a, 0x005c);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x0004, 0x0000);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x0006, 0x00fb);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x0008, 0x0000);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x000c, 0x0009);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x0012, 0x000a);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x002a, 0x0000);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x002c, 0x0000);
-	usb_ibmcam_model2_Packet1(ibmcam, 0x002e, 0x0008);
+	ibmcam_model2_Packet1(uvd, 0x000a, 0x005c);
+	ibmcam_model2_Packet1(uvd, 0x0004, 0x0000);
+	ibmcam_model2_Packet1(uvd, 0x0006, 0x00fb);
+	ibmcam_model2_Packet1(uvd, 0x0008, 0x0000);
+	ibmcam_model2_Packet1(uvd, 0x000c, 0x0009);
+	ibmcam_model2_Packet1(uvd, 0x0012, 0x000a);
+	ibmcam_model2_Packet1(uvd, 0x002a, 0x0000);
+	ibmcam_model2_Packet1(uvd, 0x002c, 0x0000);
+	ibmcam_model2_Packet1(uvd, 0x002e, 0x0008);
 
 	/*
 	 * Function 0x0030 pops up all over the place. Apparently
 	 * it is a hardware control register, with every bit assigned to
 	 * do something.
 	 */
-	usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0000);
+	ibmcam_model2_Packet1(uvd, 0x0030, 0x0000);
 
 	/*
 	 * Magic control of CMOS sensor. Only lower values like
 	 * 0-3 work, and picture shifts left or right. Don't change.
 	 */
-	switch (videosize) {
+	switch (uvd->videosize) {
 	case VIDEOSIZE_176x144:
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0002);
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0002); /* Horizontal shift */
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x004a); /* Another hardware setting */
+		ibmcam_model2_Packet1(uvd, 0x0014, 0x0002);
+		ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
+		ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
 		break;
 	case VIDEOSIZE_320x240:
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0009);
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0005); /* Horizontal shift */
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x0044); /* Another hardware setting */
+		ibmcam_model2_Packet1(uvd, 0x0014, 0x0009);
+		ibmcam_model2_Packet1(uvd, 0x0016, 0x0005); /* Horizontal shift */
+		ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Another hardware setting */
 		break;
 	case VIDEOSIZE_352x240:
 		/* This mode doesn't work as Windows programs it; changed to work */
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0009); /* Windows sets this to 8 */
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0003); /* Horizontal shift */
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
+		ibmcam_model2_Packet1(uvd, 0x0014, 0x0009); /* Windows sets this to 8 */
+		ibmcam_model2_Packet1(uvd, 0x0016, 0x0003); /* Horizontal shift */
+		ibmcam_model2_Packet1(uvd, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
 		break;
 	case VIDEOSIZE_352x288:
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0014, 0x0003);
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0016, 0x0002); /* Horizontal shift */
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0018, 0x004a); /* Another hardware setting */
+		ibmcam_model2_Packet1(uvd, 0x0014, 0x0003);
+		ibmcam_model2_Packet1(uvd, 0x0016, 0x0002); /* Horizontal shift */
+		ibmcam_model2_Packet1(uvd, 0x0018, 0x004a); /* Another hardware setting */
 		break;
 	}
 
-	usb_ibmcam_model2_Packet1(ibmcam, mod2_brightness, 0x005a);
+	ibmcam_model2_Packet1(uvd, mod2_brightness, 0x005a);
 
 	/*
 	 * We have our own frame rate setting varying from 0 (slowest) to 6 (fastest).
@@ -2008,7 +2078,7 @@
 
 		RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
 		i_framerate = FRAMERATE_MAX - framerate + FRAMERATE_MIN;
-		switch (videosize) {
+		switch (uvd->videosize) {
 		case VIDEOSIZE_176x144:
 			hw_fps = 6 + i_framerate*4;
 			break;
@@ -2022,10 +2092,10 @@
 			hw_fps = 28 + i_framerate/2;
 			break;
 		}
-		if (debug > 0)
-			printk(KERN_DEBUG "Framerate (hardware): %hd.\n", hw_fps);
+		if (uvd->debug > 0)
+			info("Framerate (hardware): %hd.", hw_fps);
 		RESTRICT_TO_RANGE(hw_fps, 0, 31);
-		usb_ibmcam_model2_Packet1(ibmcam, mod2_set_framerate, hw_fps);
+		ibmcam_model2_Packet1(uvd, mod2_set_framerate, hw_fps);
 	}
 
 	/*
@@ -2034,28 +2104,22 @@
 	 * does not allow arbitrary values and apparently is a bit mask, to
 	 * be activated only at appropriate time. Don't change it randomly!
 	 */
-	switch (videosize) {
+	switch (uvd->videosize) {
 	case VIDEOSIZE_176x144:
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x00c2);
+		ibmcam_model2_Packet1(uvd, 0x0026, 0x00c2);
 		break;
 	case VIDEOSIZE_320x240:
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0044);
+		ibmcam_model2_Packet1(uvd, 0x0026, 0x0044);
 		break;
 	case VIDEOSIZE_352x240:
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0046);
+		ibmcam_model2_Packet1(uvd, 0x0026, 0x0046);
 		break;
 	case VIDEOSIZE_352x288:
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0026, 0x0048);
+		ibmcam_model2_Packet1(uvd, 0x0026, 0x0048);
 		break;
 	}
 
-	usb_ibmcam_model2_Packet1(ibmcam, mod2_sensitivity, lighting);
-
-	if (init_model2_rg >= 0) {
-		RESTRICT_TO_RANGE(init_model2_rg, 0, 255);
-		setup_model2_rg = init_model2_rg;
-	} else
-		setup_model2_rg = 0x0070;
+	ibmcam_model2_Packet1(uvd, mod2_sensitivity, lighting);
 
 	if (init_model2_rg2 >= 0) {
 		RESTRICT_TO_RANGE(init_model2_rg2, 0, 255);
@@ -2075,806 +2139,1469 @@
 	} else
 		setup_model2_yb = 0x00a0;
 
-	usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg2, setup_model2_rg2);
-	usb_ibmcam_model2_Packet1(ibmcam, mod2_saturation, setup_model2_sat);
-	usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_yb, setup_model2_yb);
-	usb_ibmcam_model2_Packet1(ibmcam, mod2_color_balance_rg, setup_model2_rg);
+	ibmcam_model2_Packet1(uvd, mod2_color_balance_rg2, setup_model2_rg2);
+	ibmcam_model2_Packet1(uvd, mod2_saturation, setup_model2_sat);
+	ibmcam_model2_Packet1(uvd, mod2_color_balance_yb, setup_model2_yb);
+	ibmcam_model2_Packet1(uvd, mod2_hue, uvd->vpic.hue >> 9); /* 0 .. 7F */;
 
 	/* Hardware control command */
-	usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0004);
+	ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
 
-	usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c);	/* Go camera, go! */
-	usb_clear_halt(ibmcam->dev, ibmcam->video_endp);
+	ibmcam_veio(uvd, 0, 0x00c0, 0x010c);	/* Go camera, go! */
+	usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
 }
 
-/*
- * usb_ibmcam_setup_video_stop()
- *
- * This code tells camera to stop streaming. The interface remains
- * configured and bandwidth - claimed.
- */
-static void usb_ibmcam_setup_video_stop(struct usb_ibmcam *ibmcam)
+static void ibmcam_model4_setup_after_video_if(uvd_t *uvd)
 {
-	if (ibmcam->camera_model == IBMCAM_MODEL_1) {
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c);
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c);
-		usb_ibmcam_veio(ibmcam, 0, 0x01, 0x0114);
-		usb_ibmcam_veio(ibmcam, 0, 0xc0, 0x010c);
-		usb_ibmcam_veio(ibmcam, 0, 0x00, 0x010c);
-		usb_ibmcam_send_FF_04_02(ibmcam);
-		usb_ibmcam_veio(ibmcam, 1, 0x00, 0x0100);
-		usb_ibmcam_veio(ibmcam, 0, 0x81, 0x0100);	/* LED Off */
-	} else if (ibmcam->camera_model == IBMCAM_MODEL_2) {
-		usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x010c);	/* Stop the camera */
-
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0004);
-
-		usb_ibmcam_veio(ibmcam, 0, 0x0080, 0x0100);	/* LED Off */
-		usb_ibmcam_veio(ibmcam, 0, 0x0020, 0x0111);
-		usb_ibmcam_veio(ibmcam, 0, 0x00a0, 0x0111);
-
-		usb_ibmcam_model2_Packet1(ibmcam, 0x0030, 0x0002);
-
-		usb_ibmcam_veio(ibmcam, 0, 0x0020, 0x0111);
-		usb_ibmcam_veio(ibmcam, 0, 0x0000, 0x0112);
-	}
-}
-
-/*
- * usb_ibmcam_reinit_iso()
- *
- * This procedure sends couple of commands to the camera and then
- * resets the video pipe. This sequence was observed to reinit the
- * camera or, at least, to initiate ISO data stream.
- *
- * History:
- * 1/2/00   Created.
- */
-static void usb_ibmcam_reinit_iso(struct usb_ibmcam *ibmcam, int do_stop)
-{
-	if (ibmcam->camera_model == IBMCAM_MODEL_1) {
-		if (do_stop)
-			usb_ibmcam_setup_video_stop(ibmcam);
-		usb_ibmcam_veio(ibmcam, 0, 0x0001, 0x0114);
-		usb_ibmcam_veio(ibmcam, 0, 0x00c0, 0x010c);
-		usb_clear_halt(ibmcam->dev, ibmcam->video_endp);
-		usb_ibmcam_model1_setup_after_video_if(ibmcam);
-	} else if (ibmcam->camera_model == IBMCAM_MODEL_2) {
-		usb_ibmcam_model2_setup_after_video_if(ibmcam);
+	switch (uvd->videosize) {
+	case VIDEOSIZE_128x96:
+		ibmcam_veio(uvd, 0, 0x0000, 0x0100);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
+		ibmcam_veio(uvd, 0, 0x0080, 0x012b);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0108);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0133);
+		ibmcam_veio(uvd, 0, 0x009b, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x000a, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005c, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0004, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0009, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0012, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0008, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x002a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0000, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0034, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0070, 0x0119);
+		ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x005e, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x0039, 0x010a);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0102);
+		ibmcam_veio(uvd, 0, 0x0028, 0x0103);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);
+		ibmcam_veio(uvd, 0, 0x001e, 0x0105);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0016, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000a, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0014, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
+		ibmcam_veio(uvd, 0, 0x001a, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x9545, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0018, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0043, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x001c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0032, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0036, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x001e, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0017, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0013, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0031, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0017, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0078, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0004, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
+		break;
+	case VIDEOSIZE_160x120:
+		ibmcam_veio(uvd, 0, 0x0000, 0x0100);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
+		ibmcam_veio(uvd, 0, 0x0080, 0x012b);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0108);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0133);
+		ibmcam_veio(uvd, 0, 0x009b, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x000a, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005c, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0004, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0009, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0012, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0008, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x002a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0000, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0034, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0038, 0x0119);
+		ibmcam_veio(uvd, 0, 0x00d8, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0002, 0x0106);
+		ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0102);
+		ibmcam_veio(uvd, 0, 0x0028, 0x0103);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);
+		ibmcam_veio(uvd, 0, 0x001e, 0x0105);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0016, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000b, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0014, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
+		ibmcam_veio(uvd, 0, 0x001a, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x9545, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0018, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0043, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x001c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0032, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0025, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0036, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x001e, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0048, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0035, 0x012e);
+		ibmcam_veio(uvd, 0, 0x00d0, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0048, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0090, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0004, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
+		break;
+	case VIDEOSIZE_176x144:
+		ibmcam_veio(uvd, 0, 0x0000, 0x0100);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
+		ibmcam_veio(uvd, 0, 0x0080, 0x012b);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0108);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0133);
+		ibmcam_veio(uvd, 0, 0x009b, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x000a, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005c, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0004, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0009, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0012, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0008, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x002a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0000, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0034, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0038, 0x0119);
+		ibmcam_veio(uvd, 0, 0x00d6, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x0018, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00b9, 0x010a);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0102);
+		ibmcam_veio(uvd, 0, 0x002c, 0x0103);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);
+		ibmcam_veio(uvd, 0, 0x0024, 0x0105);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0016, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0007, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0014, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0001, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
+		ibmcam_veio(uvd, 0, 0x001a, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005e, 0x012d);
+		ibmcam_veio(uvd, 0, 0x9545, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0018, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0049, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x001c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00c7, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0032, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0028, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0036, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x001e, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0010, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0013, 0x012e);
+		ibmcam_veio(uvd, 0, 0x002a, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0010, 0x012d);
+		ibmcam_veio(uvd, 0, 0x006d, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0004, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
+		break;
+	case VIDEOSIZE_320x240:
+		ibmcam_veio(uvd, 0, 0x0000, 0x0100);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
+		ibmcam_veio(uvd, 0, 0x0080, 0x012b);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0108);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0133);
+		ibmcam_veio(uvd, 0, 0x009b, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x000a, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005c, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0004, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0009, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0012, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0008, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x002a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0000, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0034, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0070, 0x0119);
+		ibmcam_veio(uvd, 0, 0x00d2, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x005e, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x00d0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x0039, 0x010a);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0102);
+		ibmcam_veio(uvd, 0, 0x0028, 0x0103);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);
+		ibmcam_veio(uvd, 0, 0x001e, 0x0105);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0016, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000a, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0014, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
+		ibmcam_veio(uvd, 0, 0x001a, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x9545, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0018, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0043, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x001c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00eb, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0032, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0036, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x001e, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0017, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0013, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0031, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0017, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0078, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0004, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
+		break;
+	case VIDEOSIZE_352x288:
+		ibmcam_veio(uvd, 0, 0x0000, 0x0100);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00bc, 0x012c);
+		ibmcam_veio(uvd, 0, 0x0080, 0x012b);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0108);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0133);
+		ibmcam_veio(uvd, 0, 0x009b, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00bb, 0x010f);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x000a, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005c, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0004, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00fb, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x000c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0009, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0012, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0008, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x002a, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0000, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0034, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0070, 0x0119);
+		ibmcam_veio(uvd, 0, 0x00f2, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x008c, 0x0107);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x0111);
+		ibmcam_veio(uvd, 0, 0x0039, 0x010a);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0102);
+		ibmcam_veio(uvd, 0, 0x002c, 0x0103);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0104);
+		ibmcam_veio(uvd, 0, 0x0024, 0x0105);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0016, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0006, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0014, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0002, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012e);
+		ibmcam_veio(uvd, 0, 0x001a, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a0a, 0x0124);
+		ibmcam_veio(uvd, 0, 0x005e, 0x012d);
+		ibmcam_veio(uvd, 0, 0x9545, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0018, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0049, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd055, 0x0124);
+		ibmcam_veio(uvd, 0, 0x001c, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00cf, 0x012e);
+		ibmcam_veio(uvd, 0, 0xaa28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0032, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x0130);
+		ibmcam_veio(uvd, 0, 0x82a8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0036, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0008, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0xfffa, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x001e, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0010, 0x0127);
+		ibmcam_veio(uvd, 0, 0x0013, 0x012e);
+		ibmcam_veio(uvd, 0, 0x0025, 0x0130);
+		ibmcam_veio(uvd, 0, 0x8a28, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0010, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0048, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd145, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00aa, 0x012d);
+		ibmcam_veio(uvd, 0, 0x0038, 0x012f);
+		ibmcam_veio(uvd, 0, 0xd141, 0x0124);
+		ibmcam_veio(uvd, 0, 0x0004, 0x0127);
+		ibmcam_veio(uvd, 0, 0xfea8, 0x0124);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
+		break; 
 	}
+	usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
 }
 
-/*
- * ibmcam_init_isoc()
- *
- * History:
- * 1/27/00  Used ibmcam->iface, ibmcam->ifaceAltActive instead of hardcoded values.
- *          Simplified by using for loop, allowed any number of URBs.
- */
-static int ibmcam_init_isoc(struct usb_ibmcam *ibmcam)
+static void ibmcam_model3_setup_after_video_if(uvd_t *uvd)
 {
-	struct usb_device *dev = ibmcam->dev;
-	int i, err;
-
-	if (!IBMCAM_IS_OPERATIONAL(ibmcam))
-		return -EFAULT;
-
-	ibmcam->compress = 0;
-	ibmcam->curframe = -1;
-	ibmcam->cursbuf = 0;
-	ibmcam->scratchlen = 0;
-
-	/* Alternate interface 1 is is the biggest frame size */
-	i = usb_set_interface(dev, ibmcam->iface, ibmcam->ifaceAltActive);
-	if (i < 0) {
-		printk(KERN_ERR "usb_set_interface error\n");
-		ibmcam->last_error = i;
-		return -EBUSY;
-	}
-	usb_ibmcam_change_lighting_conditions(ibmcam);
-	usb_ibmcam_set_sharpness(ibmcam);
-	usb_ibmcam_reinit_iso(ibmcam, 0);
-
-	/* We double buffer the Iso lists */
-
-	for (i=0; i < IBMCAM_NUMSBUF; i++) {
-		int j, k;
-		urb_t *urb;
-
-		urb = usb_alloc_urb(FRAMES_PER_DESC);
-		if (urb == NULL) {
-			printk(KERN_ERR "ibmcam_init_isoc: usb_init_isoc() failed.\n");
-			return -ENOMEM;
-		}
-		ibmcam->sbuf[i].urb = urb;
-		urb->dev = dev;
-		urb->context = ibmcam;
-		urb->pipe = usb_rcvisocpipe(dev, ibmcam->video_endp);
-		urb->transfer_flags = USB_ISO_ASAP;
-		urb->transfer_buffer = ibmcam->sbuf[i].data;
-		urb->complete = ibmcam_isoc_irq;
-		urb->number_of_packets = FRAMES_PER_DESC;
-		urb->transfer_buffer_length = ibmcam->iso_packet_len * FRAMES_PER_DESC;
-		for (j=k=0; j < FRAMES_PER_DESC; j++, k += ibmcam->iso_packet_len) {
-			urb->iso_frame_desc[j].offset = k;
-			urb->iso_frame_desc[j].length = ibmcam->iso_packet_len;
-		}
-	}
-
-	/* Link URBs into a ring so that they invoke each other infinitely */
-	for (i=0; i < IBMCAM_NUMSBUF; i++) {
-		if ((i+1) < IBMCAM_NUMSBUF)
-			ibmcam->sbuf[i].urb->next = ibmcam->sbuf[i+1].urb;
-		else
-			ibmcam->sbuf[i].urb->next = ibmcam->sbuf[0].urb;
-	}
-
-	/* Submit all URBs */
-	for (i=0; i < IBMCAM_NUMSBUF; i++) {
-		err = usb_submit_urb(ibmcam->sbuf[i].urb);
-		if (err)
-			printk(KERN_ERR "ibmcam_init_isoc: usb_run_isoc(%d) ret %d\n",
-			       i, err);
-	}
-
-	ibmcam->streaming = 1;
-	/* printk(KERN_DEBUG "streaming=1 ibmcam->video_endp=$%02x\n", ibmcam->video_endp); */
-	return 0;
-}
+	int i;
+	/*
+	 * 01.01.08 - Added for RCA video in support -LO
+	 * This struct is used to init the Model3 cam to use the RCA video in port
+	 * instead of the CCD sensor.
+	 */
+	static const struct struct_initData initData[] = {
+		{0, 0x0000, 0x010c},
+		{0, 0x0006, 0x012c},
+		{0, 0x0078, 0x012d},
+		{0, 0x0046, 0x012f},
+		{0, 0xd141, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfea8, 0x0124},
+		{1, 0x0000, 0x0116},
+		{0, 0x0064, 0x0116},
+		{1, 0x0000, 0x0115},
+		{0, 0x0003, 0x0115},
+		{0, 0x0008, 0x0123},
+		{0, 0x0000, 0x0117},
+		{0, 0x0000, 0x0112},
+		{0, 0x0080, 0x0100},
+		{0, 0x0000, 0x0100},
+		{1, 0x0000, 0x0116},
+		{0, 0x0060, 0x0116},
+		{0, 0x0002, 0x0112},
+		{0, 0x0000, 0x0123},
+		{0, 0x0001, 0x0117},
+		{0, 0x0040, 0x0108},
+		{0, 0x0019, 0x012c},
+		{0, 0x0040, 0x0116},
+		{0, 0x000a, 0x0115},
+		{0, 0x000b, 0x0115},
+		{0, 0x0078, 0x012d},
+		{0, 0x0046, 0x012f},
+		{0, 0xd141, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfea8, 0x0124},
+		{0, 0x0064, 0x0116},
+		{0, 0x0000, 0x0115},
+		{0, 0x0001, 0x0115},
+		{0, 0xffff, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x00aa, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xffff, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x00f2, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x000f, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xffff, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x00f8, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x00fc, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xffff, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x00f9, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x003c, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xffff, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0027, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0019, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0021, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0006, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0045, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x002a, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x000e, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x002b, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x00f4, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x002c, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0004, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x002d, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0014, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x002e, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0003, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x002f, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0003, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0014, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0040, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0040, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0053, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0x0000, 0x0101},
+		{0, 0x00a0, 0x0103},
+		{0, 0x0078, 0x0105},
+		{0, 0x0000, 0x010a},
+		{0, 0x0024, 0x010b},
+		{0, 0x0028, 0x0119},
+		{0, 0x0088, 0x011b},
+		{0, 0x0002, 0x011d},
+		{0, 0x0003, 0x011e},
+		{0, 0x0000, 0x0129},
+		{0, 0x00fc, 0x012b},
+		{0, 0x0008, 0x0102},
+		{0, 0x0000, 0x0104},
+		{0, 0x0008, 0x011a},
+		{0, 0x0028, 0x011c},
+		{0, 0x0021, 0x012a},
+		{0, 0x0000, 0x0118},
+		{0, 0x0000, 0x0132},
+		{0, 0x0000, 0x0109},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0031, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0040, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0040, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x00dc, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0032, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0020, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0001, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0040, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0040, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0037, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0030, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0xfff9, 0x0124},
+		{0, 0x0086, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0038, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0008, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0x0000, 0x0127},
+		{0, 0xfff8, 0x0124},
+		{0, 0xfffd, 0x0124},
+		{0, 0xfffa, 0x0124},
+		{0, 0x0003, 0x0106},
+		{0, 0x0062, 0x0107},
+		{0, 0x0003, 0x0111},
+	};
+#define NUM_INIT_DATA 
 
-/*
- * ibmcam_stop_isoc()
- *
- * This procedure stops streaming and deallocates URBs. Then it
- * activates zero-bandwidth alt. setting of the video interface.
- *
- * History:
- * 1/22/00  Corrected order of actions to work after surprise removal.
- * 1/27/00  Used ibmcam->iface, ibmcam->ifaceAltInactive instead of hardcoded values.
- */
-static void ibmcam_stop_isoc(struct usb_ibmcam *ibmcam)
-{
-	static const char proc[] = "ibmcam_stop_isoc";
-	int i, j;
+	unsigned short compression = 0;	/* 0=none, 7=best frame rate  */
+	int f_rate; /* 0=Fastest 7=slowest */
 
-	if (!ibmcam->streaming || (ibmcam->dev == NULL))
+	if (IBMCAM_T(uvd)->initialized)
 		return;
 
-	/* Unschedule all of the iso td's */
-	for (i=0; i < IBMCAM_NUMSBUF; i++) {
-		j = usb_unlink_urb(ibmcam->sbuf[i].urb);
-		if (j < 0)
-			printk(KERN_ERR "%s: usb_unlink_urb() error %d.\n", proc, j);
-	}
-	/* printk(KERN_DEBUG "streaming=0\n"); */
-	ibmcam->streaming = 0;
-
-	/* Delete them all */
-	for (i=0; i < IBMCAM_NUMSBUF; i++)
-		usb_free_urb(ibmcam->sbuf[i].urb);
-
-	if (!ibmcam->remove_pending) {
-		usb_ibmcam_setup_video_stop(ibmcam);
-
-		/* Set packet size to 0 */
-		j = usb_set_interface(ibmcam->dev, ibmcam->iface, ibmcam->ifaceAltInactive);
-		if (j < 0) {
-			printk(KERN_ERR "%s: usb_set_interface() error %d.\n", proc, j);
-			ibmcam->last_error = j;
-		}
-	}
-}
-
-/*
- * ibmcam_new_frame()
- *
- * History:
- * 29-Mar-00 Added copying of previous frame into the current one.
- */
-static int ibmcam_new_frame(struct usb_ibmcam *ibmcam, int framenum)
-{
-	struct ibmcam_frame *frame;
-	int n, width, height;
-
-	/* If we're not grabbing a frame right now and the other frame is */
-	/*  ready to be grabbed into, then use it instead */
-	if (ibmcam->curframe != -1)
-		return 0;
-
-	n = (framenum - 1 + IBMCAM_NUMFRAMES) % IBMCAM_NUMFRAMES;
-	if (ibmcam->frame[n].grabstate == FRAME_READY)
-		framenum = n;
-
-	frame = &ibmcam->frame[framenum];
-
-	frame->grabstate = FRAME_GRABBING;
-	frame->scanstate = STATE_SCANNING;
-	frame->scanlength = 0;		/* Accumulated in ibmcam_parse_data() */
-	ibmcam->curframe = framenum;
-
-	/*
-	 * Normally we would want to copy previous frame into the current one
-	 * before we even start filling it with data; this allows us to stop
-	 * filling at any moment; top portion of the frame will be new and
-	 * bottom portion will stay as it was in previous frame. If we don't
-	 * do that then missing chunks of video stream will result in flickering
-	 * portions of old data whatever it was before.
-	 *
-	 * If we choose not to copy previous frame (to, for example, save few
-	 * bus cycles - the frame can be pretty large!) then we have an option
-	 * to clear the frame before using. If we experience losses in this
-	 * mode then missing picture will be black (no flickering).
-	 *
-	 * Finally, if user chooses not to clean the current frame before
-	 * filling it with data then the old data will be visible if we fail
-	 * to refill entire frame with new data.
-	 */
-	if (!(flags & FLAGS_SEPARATE_FRAMES)) {
-		/* This copies previous frame into this one to mask losses */
-		memmove(frame->data, ibmcam->frame[1-framenum].data,  MAX_FRAME_SIZE);
-	} else {
-		if (flags & FLAGS_CLEAN_FRAMES) {
-			/* This provides a "clean" frame but slows things down */
-			memset(frame->data, 0, MAX_FRAME_SIZE);
-		}
-	}
-	switch (videosize) {
-	case VIDEOSIZE_128x96:
-		frame->frmwidth = 128;
-		frame->frmheight = 96;
-		frame->order_uv = 1;	/* U Y V Y ... */
-		frame->hdr_sig = 0x06;	/* 00 FF 00 06 */
+	/* Internal frame rate is controlled by f_rate value */
+	f_rate = 7 - framerate;
+	RESTRICT_TO_RANGE(f_rate, 0, 7);
+
+	ibmcam_veio(uvd, 0, 0x0000, 0x0100);
+	ibmcam_veio(uvd, 1, 0x0000, 0x0116);
+	ibmcam_veio(uvd, 0, 0x0060, 0x0116);
+	ibmcam_veio(uvd, 0, 0x0002, 0x0112);
+	ibmcam_veio(uvd, 0, 0x0000, 0x0123);
+	ibmcam_veio(uvd, 0, 0x0001, 0x0117);
+	ibmcam_veio(uvd, 0, 0x0040, 0x0108);
+	ibmcam_veio(uvd, 0, 0x0019, 0x012c);
+	ibmcam_veio(uvd, 0, 0x0060, 0x0116);
+	ibmcam_veio(uvd, 0, 0x0002, 0x0115);
+	ibmcam_veio(uvd, 0, 0x0003, 0x0115);
+	ibmcam_veio(uvd, 1, 0x0000, 0x0115);
+	ibmcam_veio(uvd, 0, 0x000b, 0x0115);
+	ibmcam_model3_Packet1(uvd, 0x000a, 0x0040);
+	ibmcam_model3_Packet1(uvd, 0x000b, 0x00f6);
+	ibmcam_model3_Packet1(uvd, 0x000c, 0x0002);
+	ibmcam_model3_Packet1(uvd, 0x000d, 0x0020);
+	ibmcam_model3_Packet1(uvd, 0x000e, 0x0033);
+	ibmcam_model3_Packet1(uvd, 0x000f, 0x0007);
+	ibmcam_model3_Packet1(uvd, 0x0010, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0011, 0x0070);
+	ibmcam_model3_Packet1(uvd, 0x0012, 0x0030);
+	ibmcam_model3_Packet1(uvd, 0x0013, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0014, 0x0001);
+	ibmcam_model3_Packet1(uvd, 0x0015, 0x0001);
+	ibmcam_model3_Packet1(uvd, 0x0016, 0x0001);
+	ibmcam_model3_Packet1(uvd, 0x0017, 0x0001);
+	ibmcam_model3_Packet1(uvd, 0x0018, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x001e, 0x00c3);
+	ibmcam_model3_Packet1(uvd, 0x0020, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0028, 0x0010);
+	ibmcam_model3_Packet1(uvd, 0x0029, 0x0054);
+	ibmcam_model3_Packet1(uvd, 0x002a, 0x0013);
+	ibmcam_model3_Packet1(uvd, 0x002b, 0x0007);
+	ibmcam_model3_Packet1(uvd, 0x002d, 0x0028);
+	ibmcam_model3_Packet1(uvd, 0x002e, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0031, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0032, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0033, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0034, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0035, 0x0038);
+	ibmcam_model3_Packet1(uvd, 0x003a, 0x0001);
+	ibmcam_model3_Packet1(uvd, 0x003c, 0x001e);
+	ibmcam_model3_Packet1(uvd, 0x003f, 0x000a);
+	ibmcam_model3_Packet1(uvd, 0x0041, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0046, 0x003f);
+	ibmcam_model3_Packet1(uvd, 0x0047, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0050, 0x0005);
+	ibmcam_model3_Packet1(uvd, 0x0052, 0x001a);
+	ibmcam_model3_Packet1(uvd, 0x0053, 0x0003);
+	ibmcam_model3_Packet1(uvd, 0x005a, 0x006b);
+	ibmcam_model3_Packet1(uvd, 0x005d, 0x001e);
+	ibmcam_model3_Packet1(uvd, 0x005e, 0x0030);
+	ibmcam_model3_Packet1(uvd, 0x005f, 0x0041);
+	ibmcam_model3_Packet1(uvd, 0x0064, 0x0008);
+	ibmcam_model3_Packet1(uvd, 0x0065, 0x0015);
+	ibmcam_model3_Packet1(uvd, 0x0068, 0x000f);
+	ibmcam_model3_Packet1(uvd, 0x0079, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x007a, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x007c, 0x003f);
+	ibmcam_model3_Packet1(uvd, 0x0082, 0x000f);
+	ibmcam_model3_Packet1(uvd, 0x0085, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x0099, 0x0000);
+	ibmcam_model3_Packet1(uvd, 0x009b, 0x0023);
+	ibmcam_model3_Packet1(uvd, 0x009c, 0x0022);
+	ibmcam_model3_Packet1(uvd, 0x009d, 0x0096);
+	ibmcam_model3_Packet1(uvd, 0x009e, 0x0096);
+	ibmcam_model3_Packet1(uvd, 0x009f, 0x000a);
+
+	switch (uvd->videosize) {
+	case VIDEOSIZE_160x120:
+		ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
+		ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
+		ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
+		ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
+		ibmcam_veio(uvd, 0, 0x0024, 0x010b); /* Differs everywhere */
+		ibmcam_veio(uvd, 0, 0x00a9, 0x0119);
+		ibmcam_veio(uvd, 0, 0x0016, 0x011b);
+		ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same on 176x144, 320x240 */
+		ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
+		ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
+		ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
+		ibmcam_veio(uvd, 0, 0x0018, 0x0102);
+		ibmcam_veio(uvd, 0, 0x0004, 0x0104);
+		ibmcam_veio(uvd, 0, 0x0004, 0x011a);
+		ibmcam_veio(uvd, 0, 0x0028, 0x011c);
+		ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
+		ibmcam_veio(uvd, 0, 0x0000, 0x0118);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0132);
+		ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
+		ibmcam_veio(uvd, 0, compression, 0x0109);
 		break;
-	case VIDEOSIZE_176x144:
-		frame->frmwidth = 176;
-		frame->frmheight = 144;
-		frame->order_uv = 1;	/* U Y V Y ... */
-		frame->hdr_sig = 0x0E;	/* 00 FF 00 0E */
-		break;
-	case VIDEOSIZE_320x240:		/* For model 2 only */
-		frame->frmwidth = 320;
-		frame->frmheight = 240;
-		break;
-	case VIDEOSIZE_352x240:		/* For model 2 only */
-		frame->frmwidth = 352;
-		frame->frmheight = 240;
+	case VIDEOSIZE_320x240:
+		ibmcam_veio(uvd, 0, 0x0000, 0x0101); /* Same on 176x144, 320x240 */
+		ibmcam_veio(uvd, 0, 0x00a0, 0x0103); /* Same on 176x144, 320x240 */
+		ibmcam_veio(uvd, 0, 0x0078, 0x0105); /* Same on 176x144, 320x240 */
+		ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
+		ibmcam_veio(uvd, 0, 0x0028, 0x010b); /* Differs everywhere */
+		ibmcam_veio(uvd, 0, 0x0002, 0x011d); /* Same */
+		ibmcam_veio(uvd, 0, 0x0000, 0x011e);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
+		ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
+		/* 4 commands from 160x120 skipped */
+		ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
+		ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
+		ibmcam_veio(uvd, 0, compression, 0x0109);
+		ibmcam_veio(uvd, 0, 0x00d9, 0x0119);
+		ibmcam_veio(uvd, 0, 0x0006, 0x011b);
+		ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
+		ibmcam_veio(uvd, 0, 0x0010, 0x0104);
+		ibmcam_veio(uvd, 0, 0x0004, 0x011a);
+		ibmcam_veio(uvd, 0, 0x003f, 0x011c);
+		ibmcam_veio(uvd, 0, 0x001c, 0x0118);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0132);
+		break;
+	case VIDEOSIZE_640x480:
+		ibmcam_veio(uvd, 0, 0x00f0, 0x0105);
+		ibmcam_veio(uvd, 0, 0x0000, 0x010a); /* Same */
+		ibmcam_veio(uvd, 0, 0x0038, 0x010b); /* Differs everywhere */
+		ibmcam_veio(uvd, 0, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
+		ibmcam_veio(uvd, 0, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
+		ibmcam_veio(uvd, 0, 0x0004, 0x011d); /* NC */
+		ibmcam_veio(uvd, 0, 0x0003, 0x011e); /* Same on 176x144, 640x480 */
+		ibmcam_veio(uvd, 0, 0x0000, 0x0129); /* Same */
+		ibmcam_veio(uvd, 0, 0x00fc, 0x012b); /* Same */
+		ibmcam_veio(uvd, 0, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
+		ibmcam_veio(uvd, 0, 0x0016, 0x0104); /* NC */
+		ibmcam_veio(uvd, 0, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
+		ibmcam_veio(uvd, 0, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
+		ibmcam_veio(uvd, 0, 0x0022, 0x012a); /* Same */
+		ibmcam_veio(uvd, 0, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
+		ibmcam_model3_Packet1(uvd, 0x0021, 0x0001); /* Same */
+		ibmcam_veio(uvd, 0, compression, 0x0109);
+		ibmcam_veio(uvd, 0, 0x0040, 0x0101);
+		ibmcam_veio(uvd, 0, 0x0040, 0x0103);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
+		break;
+	}
+	ibmcam_model3_Packet1(uvd, 0x007e, 0x000e);	/* Hue */
+	ibmcam_model3_Packet1(uvd, 0x0036, 0x0011);	/* Brightness */
+	ibmcam_model3_Packet1(uvd, 0x0060, 0x0002);	/* Sharpness */
+	ibmcam_model3_Packet1(uvd, 0x0061, 0x0004);	/* Sharpness */
+	ibmcam_model3_Packet1(uvd, 0x0062, 0x0005);	/* Sharpness */
+	ibmcam_model3_Packet1(uvd, 0x0063, 0x0014);	/* Sharpness */
+	ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0);	/* Red gain */
+	ibmcam_model3_Packet1(uvd, 0x0097, 0x0096);	/* Blue gain */
+	ibmcam_model3_Packet1(uvd, 0x0067, 0x0001);	/* Contrast */
+	ibmcam_model3_Packet1(uvd, 0x005b, 0x000c);	/* Contrast */
+	ibmcam_model3_Packet1(uvd, 0x005c, 0x0016);	/* Contrast */
+	ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
+	ibmcam_model3_Packet1(uvd, 0x002c, 0x0003);	/* Was 1, broke 640x480 */
+	ibmcam_model3_Packet1(uvd, 0x002f, 0x002a);
+	ibmcam_model3_Packet1(uvd, 0x0030, 0x0029);
+	ibmcam_model3_Packet1(uvd, 0x0037, 0x0002);
+	ibmcam_model3_Packet1(uvd, 0x0038, 0x0059);
+	ibmcam_model3_Packet1(uvd, 0x003d, 0x002e);
+	ibmcam_model3_Packet1(uvd, 0x003e, 0x0028);
+	ibmcam_model3_Packet1(uvd, 0x0078, 0x0005);
+	ibmcam_model3_Packet1(uvd, 0x007b, 0x0011);
+	ibmcam_model3_Packet1(uvd, 0x007d, 0x004b);
+	ibmcam_model3_Packet1(uvd, 0x007f, 0x0022);
+	ibmcam_model3_Packet1(uvd, 0x0080, 0x000c);
+	ibmcam_model3_Packet1(uvd, 0x0081, 0x000b);
+	ibmcam_model3_Packet1(uvd, 0x0083, 0x00fd);
+	ibmcam_model3_Packet1(uvd, 0x0086, 0x000b);
+	ibmcam_model3_Packet1(uvd, 0x0087, 0x000b);
+	ibmcam_model3_Packet1(uvd, 0x007e, 0x000e);
+	ibmcam_model3_Packet1(uvd, 0x0096, 0x00a0);	/* Red gain */
+	ibmcam_model3_Packet1(uvd, 0x0097, 0x0096);	/* Blue gain */
+	ibmcam_model3_Packet1(uvd, 0x0098, 0x000b);
+
+	switch (uvd->videosize) {
+	case VIDEOSIZE_160x120:
+		ibmcam_veio(uvd, 0, 0x0002, 0x0106);
+		ibmcam_veio(uvd, 0, 0x0008, 0x0107);
+		ibmcam_veio(uvd, 0, f_rate, 0x0111);	/* Frame rate */
+		ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
+		ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
+		ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
+		ibmcam_model3_Packet1(uvd, 0x0040, 0x000a);
+		ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
 		break;
-	case VIDEOSIZE_352x288:
-		frame->frmwidth = 352;
-		frame->frmheight = 288;
-		frame->order_uv = 0;	/* V Y U Y ... */
-		frame->hdr_sig = 0x00;	/* 00 FF 00 00 */
+	case VIDEOSIZE_320x240:
+		ibmcam_veio(uvd, 0, 0x0003, 0x0106);
+		ibmcam_veio(uvd, 0, 0x0062, 0x0107);
+		ibmcam_veio(uvd, 0, f_rate, 0x0111);	/* Frame rate */
+		ibmcam_model3_Packet1(uvd, 0x001f, 0x0000); /* Same */
+		ibmcam_model3_Packet1(uvd, 0x0039, 0x001f); /* Same */
+		ibmcam_model3_Packet1(uvd, 0x003b, 0x003c); /* Same */
+		ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
+		ibmcam_model3_Packet1(uvd, 0x0051, 0x000b);
+		break;
+	case VIDEOSIZE_640x480:
+		ibmcam_veio(uvd, 0, 0x0002, 0x0106);	/* Adjustments */
+		ibmcam_veio(uvd, 0, 0x00b4, 0x0107);	/* Adjustments */
+		ibmcam_veio(uvd, 0, f_rate, 0x0111);	/* Frame rate */
+		ibmcam_model3_Packet1(uvd, 0x001f, 0x0002); /* !Same */
+		ibmcam_model3_Packet1(uvd, 0x0039, 0x003e); /* !Same */
+		ibmcam_model3_Packet1(uvd, 0x0040, 0x0008);
+		ibmcam_model3_Packet1(uvd, 0x0051, 0x000a);
 		break;
 	}
-	frame->order_yc = (ibmcam->camera_model == IBMCAM_MODEL_2);
-
-	width = frame->width;
-	RESTRICT_TO_RANGE(width, min_imgwidth, imgwidth);
-	width &= ~7;		/* Multiple of 8 */
-
-	height = frame->height;
-	RESTRICT_TO_RANGE(height, min_imgheight, imgheight);
-	height &= ~3;		/* Multiple of 4 */
-
-	return 0;
-}
-
-/*
- * ibmcam_open()
- *
- * This is part of Video 4 Linux API. The driver can be opened by one
- * client only (checks internal counter 'ibmcam->user'). The procedure
- * then allocates buffers needed for video processing.
- *
- * History:
- * 1/22/00  Rewrote, moved scratch buffer allocation here. Now the
- *          camera is also initialized here (once per connect), at
- *          expense of V4L client (it waits on open() call).
- * 1/27/00  Used IBMCAM_NUMSBUF as number of URB buffers.
- * 5/24/00  Corrected to prevent race condition (MOD_xxx_USE_COUNT).
- */
-static int ibmcam_open(struct video_device *dev, int flags)
-{
-	struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
-	const int sb_size = FRAMES_PER_DESC * ibmcam->iso_packet_len;
-	int i, err = 0;
-
-	MOD_INC_USE_COUNT;
-	down(&ibmcam->lock);
 
-	if (ibmcam->user)
-		err = -EBUSY;
-	else {
-		/* Clean pointers so we know if we allocated something */
-		for (i=0; i < IBMCAM_NUMSBUF; i++)
-			ibmcam->sbuf[i].data = NULL;
-
-		/* Allocate memory for the frame buffers */
-		ibmcam->fbuf_size = IBMCAM_NUMFRAMES * MAX_FRAME_SIZE;
-		ibmcam->fbuf = rvmalloc(ibmcam->fbuf_size);
-		ibmcam->scratch = kmalloc(scratchbufsize, GFP_KERNEL);
-		ibmcam->scratchlen = 0;
-		if ((ibmcam->fbuf == NULL) || (ibmcam->scratch == NULL))
-			err = -ENOMEM;
-		else {
-			/* Allocate all buffers */
-			for (i=0; i < IBMCAM_NUMFRAMES; i++) {
-				ibmcam->frame[i].grabstate = FRAME_UNUSED;
-				ibmcam->frame[i].data = ibmcam->fbuf + i*MAX_FRAME_SIZE;
-				/*
-				 * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
-				 * is not used (using read() instead).
-				 */
-				ibmcam->frame[i].width = imgwidth;
-				ibmcam->frame[i].height = imgheight;
-				ibmcam->frame[i].bytes_read = 0;
-			}
-			for (i=0; i < IBMCAM_NUMSBUF; i++) {
-				ibmcam->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
-				if (ibmcam->sbuf[i].data == NULL) {
-					err = -ENOMEM;
-					break;
-				}
-			}
-		}
-		if (err) {
-			/* Have to free all that memory */
-			if (ibmcam->fbuf != NULL) {
-				rvfree(ibmcam->fbuf, ibmcam->fbuf_size);
-				ibmcam->fbuf = NULL;
-			}
-			if (ibmcam->scratch != NULL) {
-				kfree(ibmcam->scratch);
-				ibmcam->scratch = NULL;
-			}
-			for (i=0; i < IBMCAM_NUMSBUF; i++) {
-				if (ibmcam->sbuf[i].data != NULL) {
-					kfree (ibmcam->sbuf[i].data);
-					ibmcam->sbuf[i].data = NULL;
-				}
-			}
+	/* 01.01.08 - Added for RCA video in support -LO */
+	if(init_model3_input) {
+		if (debug > 0)
+			info("Setting input to RCA.");
+		for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) {
+			ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index);
 		}
 	}
 
-	/* If so far no errors then we shall start the camera */
-	if (!err) {
-		err = ibmcam_init_isoc(ibmcam);
-		if (!err) {
-			/* Send init sequence only once, it's large! */
-			if (!ibmcam->initialized) {
-				int setup_ok = 0;
-				if (ibmcam->camera_model == IBMCAM_MODEL_1)
-					setup_ok = usb_ibmcam_model1_setup(ibmcam);
-				else if (ibmcam->camera_model == IBMCAM_MODEL_2)
-					setup_ok = usb_ibmcam_model2_setup(ibmcam);
-				if (setup_ok)
-					ibmcam->initialized = 1;
-				else
-					err = -EBUSY;
-			}
-			if (!err)
-				ibmcam->user++;
-		}
-	}
-	up(&ibmcam->lock);
-	if (err)
-		MOD_DEC_USE_COUNT;
-	return err;
+	ibmcam_veio(uvd, 0, 0x0001, 0x0114);
+	ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
+	usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
 }
 
 /*
- * ibmcam_close()
- *
- * This is part of Video 4 Linux API. The procedure
- * stops streaming and deallocates all buffers that were earlier
- * allocated in ibmcam_open().
+ * ibmcam_video_stop()
  *
- * History:
- * 1/22/00  Moved scratch buffer deallocation here.
- * 1/27/00  Used IBMCAM_NUMSBUF as number of URB buffers.
- * 5/24/00  Moved MOD_DEC_USE_COUNT outside of code that can sleep.
+ * This code tells camera to stop streaming. The interface remains
+ * configured and bandwidth - claimed.
  */
-static void ibmcam_close(struct video_device *dev)
+static void ibmcam_video_stop(uvd_t *uvd)
 {
-	struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
-	int i;
-
-	down(&ibmcam->lock);	
+	switch (IBMCAM_T(uvd)->camera_model) {
+	case IBMCAM_MODEL_1:
+		ibmcam_veio(uvd, 0, 0x00, 0x010c);
+		ibmcam_veio(uvd, 0, 0x00, 0x010c);
+		ibmcam_veio(uvd, 0, 0x01, 0x0114);
+		ibmcam_veio(uvd, 0, 0xc0, 0x010c);
+		ibmcam_veio(uvd, 0, 0x00, 0x010c);
+		ibmcam_send_FF_04_02(uvd);
+		ibmcam_veio(uvd, 1, 0x00, 0x0100);
+		ibmcam_veio(uvd, 0, 0x81, 0x0100);	/* LED Off */
+		break;
+	case IBMCAM_MODEL_2:
+case IBMCAM_MODEL_4:
+		ibmcam_veio(uvd, 0, 0x0000, 0x010c);	/* Stop the camera */
+
+		ibmcam_model2_Packet1(uvd, 0x0030, 0x0004);
+
+		ibmcam_veio(uvd, 0, 0x0080, 0x0100);	/* LED Off */
+		ibmcam_veio(uvd, 0, 0x0020, 0x0111);
+		ibmcam_veio(uvd, 0, 0x00a0, 0x0111);
 
-	ibmcam_stop_isoc(ibmcam);
+		ibmcam_model2_Packet1(uvd, 0x0030, 0x0002);
 
-	rvfree(ibmcam->fbuf, ibmcam->fbuf_size);
-	kfree(ibmcam->scratch);
-	for (i=0; i < IBMCAM_NUMSBUF; i++)
-		kfree(ibmcam->sbuf[i].data);
+		ibmcam_veio(uvd, 0, 0x0020, 0x0111);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0112);
+		break;
+	case IBMCAM_MODEL_3:
+#if 1
+		ibmcam_veio(uvd, 0, 0x0000, 0x010c);
 
-	ibmcam->user--;
+		/* Here we are supposed to select video interface alt. setting 0 */
+		ibmcam_veio(uvd, 0, 0x0006, 0x012c);
 
-	if (ibmcam->remove_pending) {
-		printk(KERN_INFO "ibmcam_close: Final disconnect.\n");
-		usb_ibmcam_release(ibmcam);
-	}
-	up(&ibmcam->lock);
-	MOD_DEC_USE_COUNT;
-}
+		ibmcam_model3_Packet1(uvd, 0x0046, 0x0000);
 
-static long ibmcam_write(struct video_device *dev, const char *buf, unsigned long count, int noblock)
-{
-	return -EINVAL;
+		ibmcam_veio(uvd, 1, 0x0000, 0x0116);
+		ibmcam_veio(uvd, 0, 0x0064, 0x0116);
+		ibmcam_veio(uvd, 1, 0x0000, 0x0115);
+		ibmcam_veio(uvd, 0, 0x0003, 0x0115);
+		ibmcam_veio(uvd, 0, 0x0008, 0x0123);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0117);
+		ibmcam_veio(uvd, 0, 0x0000, 0x0112);
+		ibmcam_veio(uvd, 0, 0x0080, 0x0100);
+		IBMCAM_T(uvd)->initialized = 0;
+#endif
+		break;
+	} /* switch */
 }
 
 /*
- * ibmcam_ioctl()
+ * ibmcam_reinit_iso()
  *
- * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
+ * This procedure sends couple of commands to the camera and then
+ * resets the video pipe. This sequence was observed to reinit the
+ * camera or, at least, to initiate ISO data stream.
  *
  * History:
- * 1/22/00  Corrected VIDIOCSPICT to reject unsupported settings.
+ * 1/2/00   Created.
  */
-static int ibmcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+static void ibmcam_reinit_iso(uvd_t *uvd, int do_stop)
 {
-	struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
-
-	if (!IBMCAM_IS_OPERATIONAL(ibmcam))
-		return -EFAULT;
-
-	switch (cmd) {
-		case VIDIOCGCAP:
-		{
-			if (copy_to_user(arg, &ibmcam->vcap, sizeof(ibmcam->vcap)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCGCHAN:
-		{
-			if (copy_to_user(arg, &ibmcam->vchan, sizeof(ibmcam->vchan)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCSCHAN:
-		{
-			int v;
-
-			if (copy_from_user(&v, arg, sizeof(v)))
-				return -EFAULT;
-			if ((v < 0) || (v >= 3)) /* 3 grades of lighting conditions */
-				return -EINVAL;
-			if (v != ibmcam->vchan.channel) {
-				ibmcam->vchan.channel = v;
-				usb_ibmcam_change_lighting_conditions(ibmcam);
-			}
-			return 0;
-		}
-		case VIDIOCGPICT:
-		{
-			if (copy_to_user(arg, &ibmcam->vpic, sizeof(ibmcam->vpic)))
-				return -EFAULT;
-			return 0;
-		}
-		case VIDIOCSPICT:
-		{
-			struct video_picture tmp;
-			/*
-			 * Use temporary 'video_picture' structure to preserve our
-			 * own settings (such as color depth, palette) that we
-			 * aren't allowing everyone (V4L client) to change.
-			 */
-			if (copy_from_user(&tmp, arg, sizeof(tmp)))
-				return -EFAULT;
-			ibmcam->vpic.brightness = tmp.brightness;
-			ibmcam->vpic.hue = tmp.hue;
-			ibmcam->vpic.colour = tmp.colour;
-			ibmcam->vpic.contrast = tmp.contrast;
-			usb_ibmcam_adjust_picture(ibmcam);
-			return 0;
-		}
-		case VIDIOCSWIN:
-		{
-			struct video_window vw;
-
-			if (copy_from_user(&vw, arg, sizeof(vw)))
-				return -EFAULT;
-			if (vw.flags)
-				return -EINVAL;
-			if (vw.clipcount)
-				return -EINVAL;
-			if (vw.height != imgheight)
-				return -EINVAL;
-			if (vw.width != imgwidth)
-				return -EINVAL;
-
-			ibmcam->compress = 0;
-
-			return 0;
-		}
-		case VIDIOCGWIN:
-		{
-			struct video_window vw;
-
-			memset(&vw, 0, sizeof(vw));
-			vw.x = 0;
-			vw.y = 0;
-			vw.width = imgwidth;
-			vw.height = imgheight;
-			vw.flags = usb_ibmcam_calculate_fps();
-
-			if (copy_to_user(arg, &vw, sizeof(vw)))
-				return -EFAULT;
-
-			return 0;
-		}
-		case VIDIOCGMBUF:
-		{
-			struct video_mbuf vm;
-
-			memset(&vm, 0, sizeof(vm));
-			vm.size = MAX_FRAME_SIZE * 2;
-			vm.frames = 2;
-			vm.offsets[0] = 0;
-			vm.offsets[1] = MAX_FRAME_SIZE;
-
-			if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
-				return -EFAULT;
-
-			return 0;
-		}
-		case VIDIOCMCAPTURE:
-		{
-			struct video_mmap vm;
-
-			if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))
-				return -EFAULT;
-
-			if (debug >= 1)
-				printk(KERN_DEBUG "frame: %d, size: %dx%d, format: %d\n",
-					vm.frame, vm.width, vm.height, vm.format);
-
-			if (vm.format != VIDEO_PALETTE_RGB24)
-				return -EINVAL;
-
-			if ((vm.frame != 0) && (vm.frame != 1))
-				return -EINVAL;
-
-			if (ibmcam->frame[vm.frame].grabstate == FRAME_GRABBING)
-				return -EBUSY;
-
-			/* Don't compress if the size changed */
-			if ((ibmcam->frame[vm.frame].width != vm.width) ||
-			    (ibmcam->frame[vm.frame].height != vm.height))
-				ibmcam->compress = 0;
-
-			ibmcam->frame[vm.frame].width = vm.width;
-			ibmcam->frame[vm.frame].height = vm.height;
-
-			/* Mark it as ready */
-			ibmcam->frame[vm.frame].grabstate = FRAME_READY;
-
-			return ibmcam_new_frame(ibmcam, vm.frame);
-		}
-		case VIDIOCSYNC:
-		{
-			int frame;
-
-			if (copy_from_user((void *)&frame, arg, sizeof(int)))
-				return -EFAULT;
-
-			if ((unsigned)frame >= IBMCAM_NUMFRAMES) {
-				err("VIDIOCSYNC: invalid frame %d.", frame);
-				return -EINVAL;
-			}
-
-			if (debug >= 1)
-				printk(KERN_DEBUG "ibmcam: syncing to frame %d\n", frame);
-
-			switch (ibmcam->frame[frame].grabstate) {
-			case FRAME_UNUSED:
-				return -EINVAL;
-			case FRAME_READY:
-			case FRAME_GRABBING:
-			case FRAME_ERROR:
-			{
-				int ntries;
-		redo:
-				if (!IBMCAM_IS_OPERATIONAL(ibmcam))
-					return -EIO;
-				ntries = 0; 
-				do {
-					interruptible_sleep_on(&ibmcam->frame[frame].wq);
-					if (signal_pending(current)) {
-						if (flags & FLAGS_RETRY_VIDIOCSYNC) {
-							/* Polling apps will destroy frames with that! */
-							ibmcam_new_frame(ibmcam, frame);
-							usb_ibmcam_testpattern(ibmcam, 1, 0);
-							ibmcam->curframe = -1;
-							ibmcam->frame_num++;
-
-							/* This will request another frame. */
-							if (waitqueue_active(&ibmcam->frame[frame].wq))
-								wake_up_interruptible(&ibmcam->frame[frame].wq);
-							return 0;
-						} else {
-							/* Standard answer: not ready yet! */
-							return -EINTR;
-						}
-					}
-				} while (ibmcam->frame[frame].grabstate == FRAME_GRABBING);
-
-				if (ibmcam->frame[frame].grabstate == FRAME_ERROR) {
-					int ret = ibmcam_new_frame(ibmcam, frame);
-					if (ret < 0)
-						return ret;
-					goto redo;
-				}
-			}
-			case FRAME_DONE:
-				ibmcam->frame[frame].grabstate = FRAME_UNUSED;
-				break;
-			}
-
-			ibmcam->frame[frame].grabstate = FRAME_UNUSED;
-
-			return 0;
-		}
-		case VIDIOCGFBUF:
-		{
-			struct video_buffer vb;
-
-			memset(&vb, 0, sizeof(vb));
-			vb.base = NULL;	/* frame buffer not supported, not used */
-
-			if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
-				return -EFAULT;
-
- 			return 0;
- 		}
-		case VIDIOCKEY:
-			return 0;
-
-		case VIDIOCCAPTURE:
-			return -EINVAL;
-
-		case VIDIOCSFBUF:
-
-		case VIDIOCGTUNER:
-		case VIDIOCSTUNER:
-
-		case VIDIOCGFREQ:
-		case VIDIOCSFREQ:
-
-		case VIDIOCGAUDIO:
-		case VIDIOCSAUDIO:
-			return -EINVAL;
-
-		default:
-			return -ENOIOCTLCMD;
+	switch (IBMCAM_T(uvd)->camera_model) {
+	case IBMCAM_MODEL_1:
+		if (do_stop)
+			ibmcam_video_stop(uvd);
+		ibmcam_veio(uvd, 0, 0x0001, 0x0114);
+		ibmcam_veio(uvd, 0, 0x00c0, 0x010c);
+		usb_clear_halt(uvd->dev, usb_rcvisocpipe(uvd->dev, uvd->video_endp));
+		ibmcam_model1_setup_after_video_if(uvd);
+		break;
+	case IBMCAM_MODEL_2:
+		ibmcam_model2_setup_after_video_if(uvd);
+		break;
+	case IBMCAM_MODEL_3:
+		ibmcam_video_stop(uvd);
+		ibmcam_model3_setup_after_video_if(uvd);
+		break;
+	case IBMCAM_MODEL_4:
+		ibmcam_model4_setup_after_video_if(uvd);
+		break;
 	}
-	return 0;
 }
 
-static long ibmcam_read(struct video_device *dev, char *buf, unsigned long count, int noblock)
+static void ibmcam_video_start(uvd_t *uvd)
 {
-	struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
-	int frmx = -1;
-	volatile struct ibmcam_frame *frame;
-
-	if (debug >= 1)
-		printk(KERN_DEBUG "ibmcam_read: %ld bytes, noblock=%d\n", count, noblock);
-
-	if (!IBMCAM_IS_OPERATIONAL(ibmcam) || (buf == NULL))
-		return -EFAULT;
-
-	/* See if a frame is completed, then use it. */
-	if (ibmcam->frame[0].grabstate >= FRAME_DONE)	/* _DONE or _ERROR */
-		frmx = 0;
-	else if (ibmcam->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
-		frmx = 1;
-
-	if (noblock && (frmx == -1))
-		return -EAGAIN;
-
-	/* If no FRAME_DONE, look for a FRAME_GRABBING state. */
-	/* See if a frame is in process (grabbing), then use it. */
-	if (frmx == -1) {
-		if (ibmcam->frame[0].grabstate == FRAME_GRABBING)
-			frmx = 0;
-		else if (ibmcam->frame[1].grabstate == FRAME_GRABBING)
-			frmx = 1;
-	}
-
-	/* If no frame is active, start one. */
-	if (frmx == -1)
-		ibmcam_new_frame(ibmcam, frmx = 0);
-
-	frame = &ibmcam->frame[frmx];
-
-restart:
-	if (!IBMCAM_IS_OPERATIONAL(ibmcam))
-		return -EIO;
-	while (frame->grabstate == FRAME_GRABBING) {
-		interruptible_sleep_on((void *)&frame->wq);
-		if (signal_pending(current))
-			return -EINTR;
-	}
-
-	if (frame->grabstate == FRAME_ERROR) {
-		frame->bytes_read = 0;
-		if (ibmcam_new_frame(ibmcam, frmx))
-			printk(KERN_ERR "ibmcam_read: ibmcam_new_frame error\n");
-		goto restart;
-	}
-
-	if (debug >= 1)
-		printk(KERN_DEBUG "ibmcam_read: frmx=%d, bytes_read=%ld, scanlength=%ld\n",
-			frmx, frame->bytes_read, frame->scanlength);
-
-	/* copy bytes to user space; we allow for partials reads */
-	if ((count + frame->bytes_read) > frame->scanlength)
-		count = frame->scanlength - frame->bytes_read;
-
-	if (copy_to_user(buf, frame->data + frame->bytes_read, count))
-		return -EFAULT;
-
-	frame->bytes_read += count;
-	if (debug >= 1)
-		printk(KERN_DEBUG "ibmcam_read: {copy} count used=%ld, new bytes_read=%ld\n",
-			count, frame->bytes_read);
-
-	if (frame->bytes_read >= frame->scanlength) { /* All data has been read */
-		frame->bytes_read = 0;
-
-		/* Mark it as available to be used again. */
-		ibmcam->frame[frmx].grabstate = FRAME_UNUSED;
-		if (ibmcam_new_frame(ibmcam, frmx ? 0 : 1))
-			printk(KERN_ERR "ibmcam_read: ibmcam_new_frame returned error\n");
-	}
-
-	return count;
+	ibmcam_change_lighting_conditions(uvd);
+	ibmcam_set_sharpness(uvd);
+	ibmcam_reinit_iso(uvd, 0);
 }
 
-static int ibmcam_mmap(struct video_device *dev, const char *adr, unsigned long size)
+/*
+ * Return negative code on failure, 0 on success.
+ */
+static int ibmcam_setup_on_open(uvd_t *uvd)
 {
-	struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
-	unsigned long start = (unsigned long)adr;
-	unsigned long page, pos;
-
-	if (!IBMCAM_IS_OPERATIONAL(ibmcam))
-		return -EFAULT;
-
-	if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
-		return -EINVAL;
-
-	pos = (unsigned long)ibmcam->fbuf;
-	while (size > 0) {
-		page = kvirt_to_pa(pos);
-		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
-			return -EAGAIN;
-
-		start += PAGE_SIZE;
-		pos += PAGE_SIZE;
-		if (size > PAGE_SIZE)
-			size -= PAGE_SIZE;
-		else
-			size = 0;
+	int setup_ok = 0; /* Success by default */
+	/* Send init sequence only once, it's large! */
+	if (!IBMCAM_T(uvd)->initialized) { /* FIXME rename */
+		switch (IBMCAM_T(uvd)->camera_model) {
+		case IBMCAM_MODEL_1:
+			setup_ok = ibmcam_model1_setup(uvd);
+			break;
+		case IBMCAM_MODEL_2:
+			setup_ok = ibmcam_model2_setup(uvd);
+			break;
+		case IBMCAM_MODEL_3:
+		case IBMCAM_MODEL_4:
+			/* We do all setup when Isoc stream is requested */
+			break;
+		}
+		IBMCAM_T(uvd)->initialized = (setup_ok != 0);
 	}
-
-	return 0;
+	return setup_ok;
 }
 
-static struct video_device ibmcam_template = {
-	name:		"CPiA USB Camera",
-	type:		VID_TYPE_CAPTURE,
-	hardware:	VID_HARDWARE_CPIA,
-	open:		ibmcam_open,
-	close:		ibmcam_close,
-	read:		ibmcam_read,
-	write:		ibmcam_write,
-	ioctl:		ibmcam_ioctl,
-	mmap:		ibmcam_mmap,
-};
-
-static void usb_ibmcam_configure_video(struct usb_ibmcam *ibmcam)
+static void ibmcam_configure_video(uvd_t *uvd)
 {
-	if (ibmcam == NULL)
+	if (uvd == NULL)
 		return;
 
 	RESTRICT_TO_RANGE(init_brightness, 0, 255);
@@ -2883,286 +3610,316 @@
 	RESTRICT_TO_RANGE(init_hue, 0, 255);
 	RESTRICT_TO_RANGE(hue_correction, 0, 255);
 
-	memset(&ibmcam->vpic, 0, sizeof(ibmcam->vpic));
-	memset(&ibmcam->vpic_old, 0x55, sizeof(ibmcam->vpic_old));
-
-	ibmcam->vpic.colour = init_color << 8;
-	ibmcam->vpic.hue = init_hue << 8;
-	ibmcam->vpic.brightness = init_brightness << 8;
-	ibmcam->vpic.contrast = init_contrast << 8;
-	ibmcam->vpic.whiteness = 105 << 8; /* This one isn't used */
-	ibmcam->vpic.depth = 24;
-	ibmcam->vpic.palette = VIDEO_PALETTE_RGB24;
-
-	memset(&ibmcam->vcap, 0, sizeof(ibmcam->vcap));
-	strcpy(ibmcam->vcap.name, "IBM USB Camera");
-	ibmcam->vcap.type = VID_TYPE_CAPTURE;
-	ibmcam->vcap.channels = 1;
-	ibmcam->vcap.audios = 0;
-	ibmcam->vcap.maxwidth = imgwidth;
-	ibmcam->vcap.maxheight = imgheight;
-	ibmcam->vcap.minwidth = min_imgwidth;
-	ibmcam->vcap.minheight = min_imgheight;
-
-	memset(&ibmcam->vchan, 0, sizeof(ibmcam->vchan));
-	ibmcam->vchan.flags = 0;
-	ibmcam->vchan.tuners = 0;
-	ibmcam->vchan.channel = 0;
-	ibmcam->vchan.type = VIDEO_TYPE_CAMERA;
-	strcpy(ibmcam->vchan.name, "Camera");
-}
+	memset(&uvd->vpic, 0, sizeof(uvd->vpic));
+	memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
 
-/*
- * ibmcam_find_struct()
- *
- * This code searches the array of preallocated (static) structures
- * and returns index of the first one that isn't in use. Returns -1
- * if there are no free structures.
- *
- * History:
- * 1/27/00  Created.
- */
-static int ibmcam_find_struct(void)
-{
-	int i, u;
-
-	for (u = 0; u < MAX_IBMCAM; u++) {
-		struct usb_ibmcam *ibmcam = &cams[u];
-		if (!ibmcam->ibmcam_used) /* This one is free */
-		{
-			ibmcam->ibmcam_used = 1;	/* In use now */
-			for (i=0; i < IBMCAM_NUMFRAMES; i++)
-				init_waitqueue_head(&ibmcam->frame[i].wq);
-			init_MUTEX(&ibmcam->lock);	/* to 1 == available */
-			ibmcam->dev = NULL;
-			memcpy(&ibmcam->vdev, &ibmcam_template, sizeof(ibmcam_template));
-			return u;
-		}
-	}
-	return -1;
+	uvd->vpic.colour = init_color << 8;
+	uvd->vpic.hue = init_hue << 8;
+	uvd->vpic.brightness = init_brightness << 8;
+	uvd->vpic.contrast = init_contrast << 8;
+	uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
+	uvd->vpic.depth = 24;
+	uvd->vpic.palette = VIDEO_PALETTE_RGB24;
+
+	memset(&uvd->vcap, 0, sizeof(uvd->vcap));
+	strcpy(uvd->vcap.name, "IBM USB Camera");
+	uvd->vcap.type = VID_TYPE_CAPTURE;
+	uvd->vcap.channels = 1;
+	uvd->vcap.audios = 0;
+	uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
+	uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
+	uvd->vcap.minwidth = min_canvasWidth;
+	uvd->vcap.minheight = min_canvasHeight;
+
+	memset(&uvd->vchan, 0, sizeof(uvd->vchan));
+	uvd->vchan.flags = 0;
+	uvd->vchan.tuners = 0;
+	uvd->vchan.channel = 0;
+	uvd->vchan.type = VIDEO_TYPE_CAMERA;
+	strcpy(uvd->vchan.name, "Camera");
 }
 
 /*
- * usb_ibmcam_probe()
+ * ibmcam_probe()
  *
  * This procedure queries device descriptor and accepts the interface
  * if it looks like IBM C-it camera.
  *
  * History:
- * 1/22/00  Moved camera init code to ibmcam_open()
- * 1/27/00  Changed to use static structures, added locking.
- * 5/24/00  Corrected to prevent race condition (MOD_xxx_USE_COUNT).
- * 7/3/00   Fixed endianness bug.
- */
-static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum,
-			 const struct usb_device_id *id)
-{
-	struct usb_ibmcam *ibmcam = NULL;
-	const struct usb_interface_descriptor *interface;
-	const struct usb_endpoint_descriptor *endpoint;
-	int devnum, model=0;
+ * 22-Jan-2000 Moved camera init code to ibmcam_open()
+ * 27=Jan-2000 Changed to use static structures, added locking.
+ * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
+ * 03-Jul-2000 Fixed endianness bug.
+ * 12-Nov-2000 Reworked to comply with new probe() signature.
+ * 23-Jan-2001 Added compatibility with 2.2.x kernels.
+ */
+static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid)
+{
+	uvd_t *uvd = NULL;
+	int i, nas, model=0, canvasX=0, canvasY=0;
+	int actInterface=-1, inactInterface=-1, maxPS=0;
+	unsigned char video_ep = 0;
 
 	if (debug >= 1)
-		printk(KERN_DEBUG "ibmcam_probe(%p,%u.)\n", dev, ifnum);
+		info("ibmcam_probe(%p,%u.)", dev, ifnum);
 
 	/* We don't handle multi-config cameras */
 	if (dev->descriptor.bNumConfigurations != 1)
 		return NULL;
 
+	/* Is it an IBM camera? */
+	if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
+		return NULL;
+	if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
+	    (dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
+		return NULL;
+
 	/* Check the version/revision */
 	switch (dev->descriptor.bcdDevice) {
 	case 0x0002:
 		if (ifnum != 2)
 			return NULL;
-		printk(KERN_INFO "IBM USB camera found (model 1, rev. 0x%04x).\n",
-			dev->descriptor.bcdDevice);
 		model = IBMCAM_MODEL_1;
 		break;
 	case 0x030A:
 		if (ifnum != 0)
 			return NULL;
-		printk(KERN_INFO "IBM USB camera found (model 2, rev. 0x%04x).\n",
-			dev->descriptor.bcdDevice);
-		model = IBMCAM_MODEL_2;
+		if (dev->descriptor.idProduct == NETCAM_PRODUCT_ID)
+			model = IBMCAM_MODEL_4;
+		else
+			model = IBMCAM_MODEL_2;
 		break;
-
-	/* ibmcam_table contents prevents any other values from ever
-	   being passed to us, so no need for "default" case. */
+	case 0x0301:
+		if (ifnum != 0)
+			return NULL;
+		model = IBMCAM_MODEL_3;
+		break;
+	default:
+		err("IBM camera with revision 0x%04x is not supported.",
+			dev->descriptor.bcdDevice);
+		return NULL;
 	}
+	info("IBM USB camera found (model %d, rev. 0x%04x)",
+		model, dev->descriptor.bcdDevice);
 
 	/* Validate found interface: must have one ISO endpoint */
-	interface = &dev->actconfig->interface[ifnum].altsetting[0];
-	if (interface->bNumEndpoints != 1) {
-		printk(KERN_ERR "IBM camera: interface %d. has %u. endpoints!\n",
-		       ifnum, (unsigned)(interface->bNumEndpoints));
+	nas = dev->actconfig->interface[ifnum].num_altsetting;
+	if (debug > 0)
+		info("Number of alternate settings=%d.", nas);
+	if (nas < 2) {
+		err("Too few alternate settings for this camera!");
 		return NULL;
 	}
-	endpoint = &interface->endpoint[0];
-	if ((endpoint->bmAttributes & 0x03) != 0x01) {
-		printk(KERN_ERR "IBM camera: interface %d. has non-ISO endpoint!\n", ifnum);
-		return NULL;
+	/* Validate all alternate settings */
+	for (i=0; i < nas; i++) {
+		const struct usb_interface_descriptor *interface;
+		const struct usb_endpoint_descriptor *endpoint;
+
+		interface = &dev->actconfig->interface[ifnum].altsetting[i];
+		if (interface->bNumEndpoints != 1) {
+			err("Interface %d. has %u. endpoints!",
+			    ifnum, (unsigned)(interface->bNumEndpoints));
+			return NULL;
+		}
+		endpoint = &interface->endpoint[0];
+		if (video_ep == 0)
+			video_ep = endpoint->bEndpointAddress;
+		else if (video_ep != endpoint->bEndpointAddress) {
+			err("Alternate settings have different endpoint addresses!");
+			return NULL;
+		}
+		if ((endpoint->bmAttributes & 0x03) != 0x01) {
+			err("Interface %d. has non-ISO endpoint!", ifnum);
+			return NULL;
+		}
+		if ((endpoint->bEndpointAddress & 0x80) == 0) {
+			err("Interface %d. has ISO OUT endpoint!", ifnum);
+			return NULL;
+		}
+		if (endpoint->wMaxPacketSize == 0) {
+			if (inactInterface < 0)
+				inactInterface = i;
+			else {
+				err("More than one inactive alt. setting!");
+				return NULL;
+			}
+		} else {
+			if (actInterface < 0) {
+				actInterface = i;
+				maxPS = endpoint->wMaxPacketSize;
+				if (debug > 0)
+					info("Active setting=%d. maxPS=%d.", i, maxPS);
+			} else
+				err("More than one active alt. setting! Ignoring #%d.", i);
+		}
 	}
-	if ((endpoint->bEndpointAddress & 0x80) == 0) {
-		printk(KERN_ERR "IBM camera: interface %d. has ISO OUT endpoint!\n", ifnum);
+	if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
+		err("Failed to recognize the camera!");
 		return NULL;
 	}
 
 	/* Validate options */
-	if (model == IBMCAM_MODEL_1) {
+	switch (model) {
+	case IBMCAM_MODEL_1:
 		RESTRICT_TO_RANGE(lighting, 0, 2);
-		RESTRICT_TO_RANGE(videosize, VIDEOSIZE_128x96, VIDEOSIZE_352x288);
-	} else {
+		RESTRICT_TO_RANGE(size, SIZE_128x96, SIZE_352x288);
+		if (framerate < 0)
+			framerate = 2;
+		canvasX = 352;
+		canvasY = 288;
+		break;
+	case IBMCAM_MODEL_2:
 		RESTRICT_TO_RANGE(lighting, 0, 15);
-		RESTRICT_TO_RANGE(videosize, VIDEOSIZE_176x144, VIDEOSIZE_352x240);
+		RESTRICT_TO_RANGE(size, SIZE_176x144, SIZE_352x240);
+		if (framerate < 0)
+			framerate = 2;
+		canvasX = 352;
+		canvasY = 240;
+		break;
+	case IBMCAM_MODEL_3:
+		RESTRICT_TO_RANGE(lighting, 0, 15); /* FIXME */
+		switch (size) {
+		case SIZE_160x120:
+			canvasX = 160;
+			canvasY = 120;
+			if (framerate < 0)
+				framerate = 2;
+			RESTRICT_TO_RANGE(framerate, 0, 5);
+			break;
+		default:
+			info("IBM camera: using 320x240");
+			size = SIZE_320x240;
+			/* No break here */
+		case SIZE_320x240:
+			canvasX = 320;
+			canvasY = 240;
+			if (framerate < 0)
+				framerate = 3;
+			RESTRICT_TO_RANGE(framerate, 0, 5);
+			break;
+		case SIZE_640x480:
+			canvasX = 640;
+			canvasY = 480;
+			framerate = 0;	/* Slowest, and maybe even that is too fast */
+			break;
+		}
+		break;
+	case IBMCAM_MODEL_4:
+		RESTRICT_TO_RANGE(lighting, 0, 2);
+		switch (size) {
+		case SIZE_128x96:
+			canvasX = 128;
+			canvasY = 96;
+			break;
+		case SIZE_160x120:
+			canvasX = 160;
+			canvasY = 120;
+			break;
+		default:
+			info("IBM NetCamera: using 176x144");
+			size = SIZE_176x144;
+			/* No break here */
+		case SIZE_176x144:
+			canvasX = 176;
+			canvasY = 144;
+			break;
+		case SIZE_320x240:
+			canvasX = 320;
+			canvasY = 240;
+			break;
+		case SIZE_352x288:
+			canvasX = 352;
+			canvasY = 288;
+			break;
+		}
+		break;
+	default:
+		err("IBM camera: Model %d. not supported!", model);
+		return NULL;
 	}
 
 	/* Code below may sleep, need to lock module while we are here */
 	MOD_INC_USE_COUNT;
-
-	devnum = ibmcam_find_struct();
-	if (devnum == -1) {
-		printk(KERN_INFO "IBM USB camera driver: Too many devices!\n");
-		ibmcam = NULL; /* Do not free, it's preallocated */
-		goto probe_done;
-	}
-	ibmcam = &cams[devnum];
-
-	down(&ibmcam->lock);
-	ibmcam->camera_model = model;
-	ibmcam->remove_pending = 0;
-	ibmcam->last_error = 0;
-	ibmcam->dev = dev;
-	ibmcam->iface = ifnum;
-	ibmcam->ifaceAltInactive = 0;
-	ibmcam->ifaceAltActive = 1;
-	ibmcam->video_endp = endpoint->bEndpointAddress;
-	ibmcam->iso_packet_len = 1014;
-	ibmcam->compress = 0;
-	ibmcam->user=0; 
-
-	usb_ibmcam_configure_video(ibmcam);
-	up (&ibmcam->lock);
-
-	if (video_register_device(&ibmcam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
-		printk(KERN_ERR "video_register_device failed\n");
-		ibmcam = NULL; /* Do not free, it's preallocated */
-	}
-	if (debug > 1)
-		printk(KERN_DEBUG "video_register_device() successful\n");
-probe_done:
-	MOD_DEC_USE_COUNT;
-	return ibmcam;
-}
-
-/*
- * usb_ibmcam_release()
- *
- * This code does final release of struct usb_ibmcam. This happens
- * after the device is disconnected -and- all clients closed their files.
- *
- * History:
- * 1/27/00  Created.
- */
-static void usb_ibmcam_release(struct usb_ibmcam *ibmcam)
-{
-	video_unregister_device(&ibmcam->vdev);
-	if (debug > 0)
-		printk(KERN_DEBUG "usb_ibmcam_release: Video unregistered.\n");
-	ibmcam->ibmcam_used = 0;
-	ibmcam->initialized = 0;
-}
-
-/*
- * usb_ibmcam_disconnect()
- *
- * This procedure stops all driver activity, deallocates interface-private
- * structure (pointed by 'ptr') and after that driver should be removable
- * with no ill consequences.
- *
- * This code handles surprise removal. The ibmcam->user is a counter which
- * increments on open() and decrements on close(). If we see here that
- * this counter is not 0 then we have a client who still has us opened.
- * We set ibmcam->remove_pending flag as early as possible, and after that
- * all access to the camera will gracefully fail. These failures should
- * prompt client to (eventually) close the video device, and then - in
- * ibmcam_close() - we decrement ibmcam->ibmcam_used and usage counter.
- *
- * History:
- * 1/22/00  Added polling of MOD_IN_USE to delay removal until all users gone.
- * 1/27/00  Reworked to allow pending disconnects; see ibmcam_close()
- * 5/24/00  Corrected to prevent race condition (MOD_xxx_USE_COUNT).
- */
-static void usb_ibmcam_disconnect(struct usb_device *dev, void *ptr)
-{
-	static const char proc[] = "usb_ibmcam_disconnect";
-	struct usb_ibmcam *ibmcam = (struct usb_ibmcam *) ptr;
-
-	MOD_INC_USE_COUNT;
-
-	if (debug > 0)
-		printk(KERN_DEBUG "%s(%p,%p.)\n", proc, dev, ptr);
-
-	down(&ibmcam->lock);
-	ibmcam->remove_pending = 1; /* Now all ISO data will be ignored */
-
-	/* At this time we ask to cancel outstanding URBs */
-	ibmcam_stop_isoc(ibmcam);
-
-	ibmcam->dev = NULL;    	    /* USB device is no more */
-
-	if (ibmcam->user)
-		printk(KERN_INFO "%s: In use, disconnect pending.\n", proc);
-	else
-		usb_ibmcam_release(ibmcam);
-	up(&ibmcam->lock);
-	printk(KERN_INFO "IBM USB camera disconnected.\n");
-
+	uvd = usbvideo_AllocateDevice(cams);
+	if (uvd != NULL) {
+		/* Here uvd is a fully allocated uvd_t object */
+		uvd->flags = flags;
+		uvd->debug = debug;
+		uvd->dev = dev;
+		uvd->iface = ifnum;
+		uvd->ifaceAltInactive = inactInterface;
+		uvd->ifaceAltActive = actInterface;
+		uvd->video_endp = video_ep;
+		uvd->iso_packet_len = maxPS;
+		uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
+		uvd->defaultPalette = VIDEO_PALETTE_RGB24;
+		uvd->canvas = VIDEOSIZE(canvasX, canvasY);
+		uvd->videosize = ibmcam_size_to_videosize(size);
+
+		/* Initialize ibmcam-specific data */
+		assert(IBMCAM_T(uvd) != NULL);
+		IBMCAM_T(uvd)->camera_model = model;
+		IBMCAM_T(uvd)->initialized = 0;
+
+		ibmcam_configure_video(uvd);
+
+		i = usbvideo_RegisterVideoDevice(uvd);
+		if (i != 0) {
+			err("usbvideo_RegisterVideoDevice() failed.");
+			uvd = NULL;
+		}
+	}
 	MOD_DEC_USE_COUNT;
+	return uvd;
 }
 
-static struct usb_device_id ibmcam_table [] = {
-	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002) },
-	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a) },
-	{ }						/* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, ibmcam_table);
-
-static struct usb_driver ibmcam_driver = {
-	name:		"ibmcam",
-	probe:		usb_ibmcam_probe,
-	disconnect:	usb_ibmcam_disconnect,
-	id_table:	ibmcam_table,
-};
-
 /*
- * usb_ibmcam_init()
+ * ibmcam_init()
  *
  * This code is run to initialize the driver.
  *
  * History:
- * 1/27/00  Reworked to use statically allocated usb_ibmcam structures.
+ * 1/27/00  Reworked to use statically allocated ibmcam structures.
+ * 21/10/00 Completely redesigned to use usbvideo services.
  */
-static int __init usb_ibmcam_init(void)
-{
-	unsigned u;
-
-	/* Initialize struct */
-	for (u = 0; u < MAX_IBMCAM; u++) {
-		struct usb_ibmcam *ibmcam = &cams[u];
-		memset (ibmcam, 0, sizeof(struct usb_ibmcam));
-	}
-	info(DRIVER_VERSION ":" DRIVER_DESC);
-	return usb_register(&ibmcam_driver);
-}
-
-static void __exit usb_ibmcam_cleanup(void)
+static int __init ibmcam_init(void)
 {
-	usb_deregister(&ibmcam_driver);
-}
+	usbvideo_cb_t cbTbl;
+	memset(&cbTbl, 0, sizeof(cbTbl));
+	cbTbl.probe = ibmcam_probe;
+	cbTbl.setupOnOpen = ibmcam_setup_on_open;
+	cbTbl.videoStart = ibmcam_video_start;
+	cbTbl.videoStop = ibmcam_video_stop;
+	cbTbl.processData = ibmcam_ProcessIsocData;
+	cbTbl.postProcess = usbvideo_DeinterlaceFrame;
+	cbTbl.adjustPicture = ibmcam_adjust_picture;
+	cbTbl.getFPS = ibmcam_calculate_fps;
+	return usbvideo_register(
+		&cams,
+		MAX_IBMCAM,
+		sizeof(ibmcam_t),
+		"ibmcam",
+		&cbTbl,
+		THIS_MODULE);
+}
+
+static void __exit ibmcam_cleanup(void)
+{
+	usbvideo_Deregister(&cams);
+}
+
+#if defined(usb_device_id_ver)
+
+static __devinitdata struct usb_device_id id_table[] = {
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) },	/* Model 1 */
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 2 */
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) },	/* Model 3 */
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 4 */
+	{ }  /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
 
-module_init(usb_ibmcam_init);
-module_exit(usb_ibmcam_cleanup);
+#endif /* defined(usb_device_id_ver) */
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+module_init(ibmcam_init);
+module_exit(ibmcam_cleanup);
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c
--- v2.4.10/linux/drivers/usb/kaweth.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/kaweth.c	Tue Oct  9 15:15:02 2001
@@ -949,12 +949,10 @@
  *-------------------------------------------------------------------*/
 static void usb_api_blocking_completion(urb_t *urb)
 {
-        api_wrapper_data *awd = (api_wrapper_data *)urb->context;
-
-        if (waitqueue_active(awd->wakeup)) {
-                wake_up(awd->wakeup);
-	}
+        struct usb_api_data *awd = (struct usb_api_data *)urb->context;
 
+	awd->done=1;
+	wake_up(&awd->wqh);
 }
 
 /*-------------------------------------------------------------------*
@@ -965,36 +963,31 @@
 static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length)
 {
         DECLARE_WAITQUEUE(wait, current);
-        DECLARE_WAIT_QUEUE_HEAD(wqh);
-        api_wrapper_data awd;
+	struct usb_api_data awd;
         int status;
 
-        awd.wakeup = &wqh;
-        init_waitqueue_head(&wqh);
+        init_waitqueue_head(&awd.wqh);
+        awd.done = 0;
+        
         current->state = TASK_INTERRUPTIBLE;
-        add_wait_queue(&wqh, &wait);
+        add_wait_queue(&awd.wqh, &wait);
         urb->context = &awd;
         status = usb_submit_urb(urb);
         if (status) {
                 // something went wrong
                 usb_free_urb(urb);
                 current->state = TASK_RUNNING;
-                remove_wait_queue(&wqh, &wait);
+                remove_wait_queue(&awd.wqh, &wait);
                 return status;
         }
 
-        if (urb->status == -EINPROGRESS) {
-                while (timeout && urb->status == -EINPROGRESS)
-                        status = timeout = schedule_timeout(timeout);
-        } 
-	else {
-                status = 1;
-	}
+	while (timeout && !awd.done)
+		timeout = schedule_timeout(timeout);
 
         current->state = TASK_RUNNING;
-        remove_wait_queue(&wqh, &wait);
+        remove_wait_queue(&awd.wqh, &wait);
 
-        if (!status) {
+        if (!timeout) {
                 // timeout
                 kaweth_warn("usb_control/bulk_msg: timeout");
                 usb_unlink_urb(urb);  // remove urb safely
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c
--- v2.4.10/linux/drivers/usb/mdc800.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/mdc800.c	Tue Oct  9 15:15:02 2001
@@ -718,7 +718,6 @@
 static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos)
 {
 	int i=0;
-	char c;
 
 	spin_lock (&mdc800->io_lock);
 	if (mdc800->state != READY)
@@ -741,14 +740,7 @@
 		}
 
 		/* check for command start */
-		
-		if(get_user(c, buf+i))
-		{
-			spin_unlock (&mdc800->io_lock);
-			return -EFAULT;
-		}
-		
-		if (c == (char) 0x55)
+		if (buf [i] == (char) 0x55)
 		{
 			mdc800->in_count=0;
 			mdc800->out_count=0;
@@ -759,7 +751,7 @@
 		/* save command byte */
 		if (mdc800->in_count < 8)
 		{
-			mdc800->in[mdc800->in_count]=c;
+			mdc800->in[mdc800->in_count]=buf[i];
 			mdc800->in_count++;
 		}
 		else
@@ -990,4 +982,5 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/microtek.c linux/drivers/usb/microtek.c
--- v2.4.10/linux/drivers/usb/microtek.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/microtek.c	Fri Oct  5 12:04:51 2001
@@ -116,6 +116,7 @@
  *	20010320 check return value of scsi_register()
  *	20010320 Version 0.4.3
  *	20010408 Identify version on module load.
+ *	20011003 Fix multiple requests
  */
 
 #include <linux/module.h>
@@ -500,7 +501,6 @@
 		      context
 		);
 
-	transfer->transfer_flags = USB_ASYNC_UNLINK;
 	transfer->status = 0;
 
 	res = usb_submit_urb( transfer );
@@ -520,7 +520,6 @@
 
 	if ( context->final_callback )
 		context->final_callback(context->srb);
-	up( &context->instance->lock );
 
 }
 
@@ -710,7 +709,6 @@
 		goto out;
 	}
 
-	down(&desc->lock);
 	
 	FILL_BULK_URB(&desc->urb,
 		      desc->usb_dev,
@@ -733,7 +731,6 @@
 
 		if(callback)
 			callback(srb);
-	        up(&desc->lock);
 
 	}
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h
--- v2.4.10/linux/drivers/usb/pegasus.h	Tue Jul  3 17:08:21 2001
+++ linux/drivers/usb/pegasus.h	Mon Oct  1 13:45:47 2001
@@ -142,6 +142,7 @@
 #define	VENDOR_SMARTBRIDGES	0x08d1
 #define	VENDOR_SMC		0x0707
 #define	VENDOR_SOHOWARE		0x15e8
+#define	VENDOR_BELKIN		0x050d
 
 #else	/* PEGASUS_DEV */
 
@@ -235,5 +236,8 @@
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "Belkin F5D5050 USB Ethernet",
+		VENDOR_BELKIN, 0x0121,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 
 #endif	/* PEGASUS_DEV */
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/printer.c linux/drivers/usb/printer.c
--- v2.4.10/linux/drivers/usb/printer.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/printer.c	Tue Oct  9 15:15:02 2001
@@ -703,6 +703,9 @@
 }
 
 static struct usb_device_id usblp_ids [] = {
+	{ USB_DEVICE_INFO(7, 1, 1) },
+	{ USB_DEVICE_INFO(7, 1, 2) },
+	{ USB_DEVICE_INFO(7, 1, 3) },
 	{ USB_INTERFACE_INFO(7, 1, 1) },
 	{ USB_INTERFACE_INFO(7, 1, 2) },
 	{ USB_INTERFACE_INFO(7, 1, 3) },
@@ -738,4 +741,5 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/scanner.h linux/drivers/usb/scanner.h
--- v2.4.10/linux/drivers/usb/scanner.h	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/scanner.h	Sun Sep 30 12:26:08 2001
@@ -67,6 +67,7 @@
 	/* Acer */
 	{ USB_DEVICE(0x04a5, 0x2060) },	/* Prisa Acerscan 620U & 640U (!)*/
 	{ USB_DEVICE(0x04a5, 0x2040) },	/* Prisa AcerScan 620U (!) */
+	{ USB_DEVICE(0x04a5, 0x20c0) },  /* Prisa AcerScan 1240UT */
 	{ USB_DEVICE(0x04a5, 0x2022) },	/* Vuego Scan Brisa 340U */
 	/* Agfa */
 	{ USB_DEVICE(0x06bd, 0x0001) },	/* SnapScan 1212U */
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/Config.in linux/drivers/usb/serial/Config.in
--- v2.4.10/linux/drivers/usb/serial/Config.in	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/Config.in	Tue Oct  9 15:15:02 2001
@@ -16,12 +16,15 @@
   dep_tristate '  USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   dep_tristate '  USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   dep_tristate '  USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
+  dep_tristate '  USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   dep_tristate '  USB Inside Out Edgeport Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   dep_tristate '  USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   dep_tristate '  USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then
      bool '    USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28
      bool '    USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X
+     bool '    USB Keyspan USA-28XA Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XA
+     bool '    USB Keyspan USA-28XB Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XB
      bool '    USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19
      bool '    USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X
      bool '    USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/Makefile linux/drivers/usb/serial/Makefile
--- v2.4.10/linux/drivers/usb/serial/Makefile	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/Makefile	Tue Oct  9 15:15:02 2001
@@ -21,6 +21,7 @@
 obj-$(CONFIG_USB_SERIAL_EDGEPORT)		+= io_edgeport.o
 obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
 obj-$(CONFIG_USB_SERIAL_CYBERJACK)		+= cyberjack.o
+obj-$(CONFIG_USB_SERIAL_IR)			+= ir-usb.o
  
 # Objects that export symbols.
 export-objs	:= usbserial.o
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c
--- v2.4.10/linux/drivers/usb/serial/belkin_sa.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/belkin_sa.c	Mon Oct  1 13:45:43 2001
@@ -108,6 +108,12 @@
 	{ USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
 	{ USB_DEVICE(PERACOM_VID, PERACOM_PID) },
 	{ USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
+	{ USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
+	{ }							/* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id belkin_dockstation_table [] = {
+	{ USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
 	{ }							/* Terminating entry */
 };
 
@@ -133,6 +139,27 @@
 
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
+/* All of the device info needed for the Belkin dockstation serial converter */
+struct usb_serial_device_type belkin_dockstation_device = {
+	name:			"Belkin F5U120-PC USB Serial Adapter",
+	id_table:		belkin_dockstation_table,		/* the Belkin F5U103 device */
+	needs_interrupt_in:	MUST_HAVE,			/* this device must have an interrupt in endpoint */
+	needs_bulk_in:		MUST_HAVE,			/* this device must have a bulk in endpoint */
+	needs_bulk_out:		MUST_HAVE,			/* this device must have a bulk out endpoint */
+	num_interrupt_in:	1,
+	num_bulk_in:		1,
+	num_bulk_out:		1,
+	num_ports:		1,
+	open:			belkin_sa_open,
+	close:			belkin_sa_close,
+	read_int_callback:	belkin_sa_read_int_callback,	/* How we get the status info */
+	ioctl:			belkin_sa_ioctl,
+	set_termios:		belkin_sa_set_termios,
+	break_ctl:		belkin_sa_break_ctl,
+	startup:		belkin_sa_startup,
+	shutdown:		belkin_sa_shutdown,
+};
+
 /* All of the device info needed for the Belkin serial converter */
 struct usb_serial_device_type belkin_sa_device = {
 	name:			"Belkin F5U103 USB Serial Adapter",
@@ -345,7 +372,7 @@
 static void belkin_sa_read_int_callback (struct urb *urb)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-	struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private;
+	struct belkin_sa_private *priv;
 	struct usb_serial *serial;
 	unsigned char *data = urb->transfer_buffer;
 
@@ -353,16 +380,17 @@
 	if (urb->status)
 		return;
 	
-	if (port_paranoia_check (port, "belkin_sa_read_interrupt")) return;
+	if (port_paranoia_check (port, __FUNCTION__)) return;
 
 	serial = port->serial;
-	if (serial_paranoia_check (serial, "belkin_sa_read_interrupt")) return;
+	if (serial_paranoia_check (serial, __FUNCTION__)) return;
 	
 	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
 	/* Handle known interrupt data */
 	/* ignore data[0] and data[1] */
 
+	priv = (struct belkin_sa_private *)port->private;
 	priv->last_msr = data[BELKIN_SA_MSR_INDEX];
 	
 	/* Record Control Line states */
@@ -603,6 +631,7 @@
 
 static int __init belkin_sa_init (void)
 {
+	usb_serial_register (&belkin_dockstation_device);
 	usb_serial_register (&belkin_sa_device);
 	usb_serial_register (&belkin_old_device);
 	usb_serial_register (&peracom_device);
@@ -614,6 +643,7 @@
 
 static void __exit belkin_sa_exit (void)
 {
+	usb_serial_deregister (&belkin_dockstation_device);
 	usb_serial_deregister (&belkin_sa_device);
 	usb_serial_deregister (&belkin_old_device);
 	usb_serial_deregister (&peracom_device);
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/belkin_sa.h linux/drivers/usb/serial/belkin_sa.h
--- v2.4.10/linux/drivers/usb/serial/belkin_sa.h	Fri Apr  6 15:51:52 2001
+++ linux/drivers/usb/serial/belkin_sa.h	Mon Oct  1 13:45:43 2001
@@ -33,6 +33,9 @@
 #ifndef __LINUX_USB_SERIAL_BSA_H
 #define __LINUX_USB_SERIAL_BSA_H
 
+#define BELKIN_DOCKSTATION_VID	0x050d	/* Vendor Id */
+#define BELKIN_DOCKSTATION_PID	0x1203	/* Product Id */
+
 #define BELKIN_SA_VID	0x050d	/* Vendor Id */
 #define BELKIN_SA_PID	0x0103	/* Product Id */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c
--- v2.4.10/linux/drivers/usb/serial/cyberjack.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/cyberjack.c	Mon Oct  1 13:45:48 2001
@@ -309,16 +309,16 @@
 	struct usb_serial *serial;
 	unsigned char *data = urb->transfer_buffer;
 
+	if (port_paranoia_check (port, __FUNCTION__)) return;
+
 	dbg(__FUNCTION__ " - port %d", port->number);
 
 	/* the urb might have been killed. */
 	if (urb->status)
 		return;
 
-	if (port_paranoia_check (port, "cyberjack_read_interrupt")) return;
-
 	serial = port->serial;
-	if (serial_paranoia_check (serial, "cyberjack_read_interrupt")) return;
+	if (serial_paranoia_check (serial, __FUNCTION__)) return;
 
 	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c
--- v2.4.10/linux/drivers/usb/serial/io_edgeport.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/io_edgeport.c	Tue Oct  9 15:15:02 2001
@@ -478,7 +478,6 @@
 
 static void unicode_to_ascii		(char *string, short *unicode, int unicode_size);
 
-static int  get_string_desc		(struct usb_device *dev, int Id, struct usb_string_descriptor **pRetDesc);
 
 
 
@@ -614,6 +613,7 @@
 }
 
 
+#if 0
 /************************************************************************
  *
  *  Get string descriptor from device
@@ -644,7 +644,7 @@
 	*pRetDesc = pStringDesc;
 	return 0;
 }
-
+#endif
 
 
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/ir-usb.c linux/drivers/usb/serial/ir-usb.c
--- v2.4.10/linux/drivers/usb/serial/ir-usb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/ir-usb.c	Tue Oct  9 15:15:02 2001
@@ -0,0 +1,446 @@
+/*
+ * USB IR Dongle driver
+ *
+ *	Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.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 driver allows a USB IrDA device to be used as a "dumb" serial device.
+ * This can be useful if you do not have access to a full IrDA stack on the
+ * other side of the connection.  If you do have an IrDA stack on both devices,
+ * please use the usb-irda driver, as it contains the proper error checking and
+ * other goodness of a full IrDA stack.
+ *
+ * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * 
+ * 2001_Oct_07	greg kh
+ *	initial version released.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/fcntl.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <net/irda/irda-usb.h>
+
+#ifdef CONFIG_USB_SERIAL_DEBUG
+	static int debug = 1;
+#else
+	static int debug;
+#endif
+
+#include "usb-serial.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v0.1"
+#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
+#define DRIVER_DESC "USB IR Dongle driver"
+
+static int  ir_startup (struct usb_serial *serial);
+static int  ir_open (struct usb_serial_port *port, struct file *filep);
+static void ir_close (struct usb_serial_port *port, struct file *filep);
+static int  ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
+static void ir_write_bulk_callback (struct urb *urb);
+static void ir_read_bulk_callback (struct urb *urb);
+static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios);
+
+
+static __devinitdata struct usb_device_id id_table [] = {
+	{ USB_DEVICE(0x09c4, 0x0011) },
+	{ }					/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table);
+
+
+struct usb_serial_device_type ir_device = {
+	name:			"IR Dongle",
+	id_table:		id_table,
+	needs_interrupt_in:	MUST_HAVE,
+	needs_bulk_in:		MUST_HAVE,
+	needs_bulk_out:		MUST_HAVE,
+	num_interrupt_in:	1,
+	num_bulk_in:		1,
+	num_bulk_out:		1,
+	num_ports:		1,
+	set_termios:		ir_set_termios,
+	startup:		ir_startup,
+	open:			ir_open,
+	close:			ir_close,
+	write:			ir_write,
+	write_bulk_callback:	ir_write_bulk_callback,
+	read_bulk_callback:	ir_read_bulk_callback,
+};
+
+static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc)
+{
+	dbg("bLength=%x", desc->bLength);
+	dbg("bDescriptorType=%x", desc->bDescriptorType);
+	dbg("bcdSpecRevision=%x", desc->bcdSpecRevision); 
+	dbg("bmDataSize=%x", desc->bmDataSize);
+	dbg("bmWindowSize=%x", desc->bmWindowSize);
+	dbg("bmMinTurnaroundTime=%d", desc->bmMinTurnaroundTime);
+	dbg("wBaudRate=%x", desc->wBaudRate);
+	dbg("bmAdditionalBOFs=%x", desc->bmAdditionalBOFs);
+	dbg("bIrdaRateSniff=%x", desc->bIrdaRateSniff);
+	dbg("bMaxUnicastList=%x", desc->bMaxUnicastList);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Function irda_usb_find_class_desc(dev, ifnum)
+ *
+ *    Returns instance of IrDA class descriptor, or NULL if not found
+ *
+ * The class descriptor is some extra info that IrDA USB devices will
+ * offer to us, describing their IrDA characteristics. We will use that in
+ * irda_usb_init_qos()
+ */
+static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
+{
+	struct usb_interface_descriptor *interface;
+	struct irda_class_desc *desc;
+	struct irda_class_desc *ptr;
+	int ret;
+		
+	desc = kmalloc(sizeof (struct irda_class_desc), GFP_KERNEL);
+	if (desc == NULL) 
+		return NULL;
+	memset(desc, 0, sizeof(struct irda_class_desc));
+	
+	ret = usb_get_class_descriptor(dev, ifnum, USB_DT_IRDA, 0, (void *) desc, sizeof(struct irda_class_desc));
+	dbg(__FUNCTION__ " -  ret=%d", ret);
+	if (ret)
+		dbg(__FUNCTION__ " - usb_get_class_descriptor failed (0x%x)", ret);
+
+	/* Check if we found it? */
+	if (desc->bDescriptorType == USB_DT_IRDA)
+		goto exit;
+
+	dbg(__FUNCTION__ " - parsing extra descriptors...");
+	
+	/* Check if the class descriptor is interleaved with standard descriptors */
+	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	ret = usb_get_extra_descriptor(interface, USB_DT_IRDA, &ptr);
+	if (ret) {
+		kfree(desc);
+		return NULL;
+	}
+	*desc = *ptr;
+exit:
+	irda_usb_dump_class_desc(desc);
+	return desc;
+}
+
+static int ir_startup (struct usb_serial *serial)
+{
+	struct irda_class_desc *irda_desc;
+
+	irda_desc = irda_usb_find_class_desc (serial->dev, 0);
+	if (irda_desc == NULL) {
+		err ("IRDA class descriptor not found, device not bound");
+		return -ENODEV;
+	}
+	dbg (__FUNCTION__" - Baud rates supported: %s%s%s%s%s%s%s%s%s",
+	     (irda_desc->wBaudRate & 0x0001) ? "2400 " : "",
+	     irda_desc->wBaudRate & 0x0002 ? "9600 " : "",
+	     irda_desc->wBaudRate & 0x0004 ? "19200 " : "",
+	     irda_desc->wBaudRate & 0x0008 ? "38400 " : "",
+	     irda_desc->wBaudRate & 0x0010 ? "57600 " : "",
+	     irda_desc->wBaudRate & 0x0020 ? "115200 " : "",
+	     irda_desc->wBaudRate & 0x0040 ? "576000 " : "",
+	     irda_desc->wBaudRate & 0x0080 ? "1152000 " : "",
+	     irda_desc->wBaudRate & 0x0100 ? "4000000 " : "");
+
+	kfree (irda_desc);
+
+	return 0;		
+}
+
+static int ir_open (struct usb_serial_port *port, struct file *filp)
+{
+	struct usb_serial *serial = port->serial;
+	int result = 0;
+
+	if (port_paranoia_check (port, __FUNCTION__))
+		return -ENODEV;
+	
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	down (&port->sem);
+	
+	++port->open_count;
+	MOD_INC_USE_COUNT;
+	
+	if (!port->active) {
+		port->active = 1;
+
+		/* force low_latency on so that our tty_push actually forces the data through, 
+		   otherwise it is scheduled, and with high data rates (like with OHCI) data
+		   can get lost. */
+		port->tty->low_latency = 1;
+		
+		/* Start reading from the device */
+		FILL_BULK_URB(port->read_urb, serial->dev, 
+			      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+			      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
+			      ir_read_bulk_callback, port);
+		result = usb_submit_urb(port->read_urb);
+		if (result)
+			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+	}
+	
+	up (&port->sem);
+	
+	return result;
+}
+
+static void ir_close (struct usb_serial_port *port, struct file * filp)
+{
+	struct usb_serial *serial;
+
+	if (port_paranoia_check (port, __FUNCTION__))
+		return;
+	
+	dbg(__FUNCTION__ " - port %d", port->number);
+			 
+	serial = get_usb_serial (port, __FUNCTION__);
+	if (!serial)
+		return;
+	
+	down (&port->sem);
+
+	--port->open_count;
+
+	if (port->open_count <= 0) {
+		/* shutdown our bulk read */
+		usb_unlink_urb (port->read_urb);
+		port->active = 0;
+		port->open_count = 0;
+
+	}
+	up (&port->sem);
+	MOD_DEC_USE_COUNT;
+}
+
+static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+{
+	unsigned char *transfer_buffer;
+	int result;
+
+	dbg(__FUNCTION__ " - port = %d, count = %d", port->number, count);
+
+	if (!port->tty) {
+		err (__FUNCTION__ " - no tty???");
+		return 0;
+	}
+
+	if (count == 0)
+		return 0;
+
+	if (port->write_urb->status == -EINPROGRESS) {
+		dbg (__FUNCTION__ " - already writing");
+		return 0;
+	}
+
+	/*
+	 * The first byte of the packet we send to the device contains a BOD
+	 * and baud rate change.  So we set it to 0.
+	 * See section 5.4.2.2 of the USB IrDA spec.
+	 */
+	transfer_buffer = port->write_urb->transfer_buffer;
+	count = min (port->bulk_out_size-1, count);
+	if (from_user) {
+		if (copy_from_user (&transfer_buffer[1], buf, count))
+			return -EFAULT;
+	} else {
+		memcpy (&transfer_buffer[1], buf, count);
+	}
+
+	transfer_buffer[0] = 0x00;
+
+	usb_serial_debug_data (__FILE__, __FUNCTION__, count+1, transfer_buffer);
+
+	port->write_urb->transfer_buffer_length = count + 1;
+	port->write_urb->dev = port->serial->dev;
+	result = usb_submit_urb (port->write_urb);
+	if (result)
+		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+	else
+		result = count;
+
+	return result;
+}
+
+static void ir_write_bulk_callback (struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+
+	if (port_paranoia_check (port, __FUNCTION__))
+		return;
+	
+	dbg(__FUNCTION__ " - port %d", port->number);
+	
+	if (urb->status) {
+		dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
+		return;
+	}
+
+	queue_task(&port->tqueue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+	
+	return;
+}
+
+static void ir_read_bulk_callback (struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+	struct tty_struct *tty;
+	unsigned char *data = urb->transfer_buffer;
+	int i;
+	int result;
+
+	if (port_paranoia_check (port, __FUNCTION__))
+		return;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	if (!serial) {
+		dbg(__FUNCTION__ " - bad serial pointer, exiting");
+		return;
+	}
+
+	if (urb->status) {
+		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
+		return;
+	}
+
+	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+
+	tty = port->tty;
+	if (urb->actual_length > 1) {
+		for (i = 1; i < urb->actual_length ; ++i) {
+			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				tty_flip_buffer_push(tty);
+			}
+			/* this doesn't actually push the data through unless tty->low_latency is set */
+			tty_insert_flip_char(tty, data[i], 0);
+		}
+		tty_flip_buffer_push(tty);
+	}
+
+	/* Continue trying to always read  */
+	FILL_BULK_URB(port->read_urb, serial->dev, 
+		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
+		      ir_read_bulk_callback, port);
+	result = usb_submit_urb(port->read_urb);
+	if (result)
+		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+	return;
+}
+
+static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+{
+	unsigned char *transfer_buffer;
+	unsigned int cflag;
+	int result;
+	u8 baud;
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	if ((!port->tty) || (!port->tty->termios)) {
+		dbg(__FUNCTION__" - no tty structures");
+		return;
+	}
+
+	cflag = port->tty->termios->c_cflag;
+	/* check that they really want us to change something */
+	if (old_termios) {
+		if ((cflag == old_termios->c_cflag) &&
+		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
+			dbg(__FUNCTION__ " - nothing to change...");
+			return;
+		}
+	}
+
+	/* All we can change is the baud rate */
+	if (cflag & CBAUD) {
+		dbg (__FUNCTION__ " - asking for baud %d", tty_get_baud_rate(port->tty));
+		/* 
+		 * FIXME, we should compare the baud request against the
+		 * capability stated in the IR header that we got in the
+		 * startup funtion.
+		 */
+		switch (cflag & CBAUD) {
+			case B2400:	baud = SPEED_2400;	break;
+			case B9600:	baud = SPEED_9600;	break;
+			case B19200:	baud = SPEED_19200;	break;
+			case B38400:	baud = SPEED_38400;	break;
+			case B57600:	baud = SPEED_57600;	break;
+			case B115200:	baud = SPEED_115200;	break;
+			case B576000:	baud = SPEED_576000;	break;
+			case B1152000:	baud = SPEED_1152000;	break;
+			case B4000000:	baud = SPEED_4000000;	break;
+			default:
+				err ("ir-usb driver does not support the baudrate (%d) requested", tty_get_baud_rate(port->tty));
+				return;
+		}
+		
+		/* FIXME need to check to see if our write urb is busy right
+		 * now, or use a urb pool. */
+		/* send the baud change out on an "empty" data packet */
+		transfer_buffer = port->write_urb->transfer_buffer;
+		transfer_buffer[0] = baud;
+		port->write_urb->transfer_buffer_length = 1;
+		port->write_urb->dev = port->serial->dev;
+		result = usb_submit_urb (port->write_urb);
+		if (result)
+			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+	}
+	return;
+}
+
+
+static int __init ir_init (void)
+{
+	usb_serial_register (&ir_device);
+	info(DRIVER_DESC " " DRIVER_VERSION);
+	return 0;
+}
+
+
+static void __exit ir_exit (void)
+{
+	usb_serial_deregister (&ir_device);
+}
+
+
+module_init(ir_init);
+module_exit(ir_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
--- v2.4.10/linux/drivers/usb/serial/keyspan.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/keyspan.c	Tue Oct  9 15:15:02 2001
@@ -1,16 +1,15 @@
 /*
   Keyspan USB to Serial Converter driver
  
-  (C) Copyright (C) 2000
-      Hugh Blemings <hugh@linuxcare.com>
+  (C) Copyright (C) 2000-2001
+      Hugh Blemings <hugh@misc.nu>
    
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
 
-  See http://www.linuxcare.com.au/hugh/keyspan.html for more
-  information on this driver.
+  See http://misc.nu/hugh/keyspan.html for more information.
   
   Code in this driver inspired by and in a number of places taken
   from Brian Warner's original Keyspan-PDA driver.
@@ -24,17 +23,26 @@
   having the patience to sit down and explain why and where he'd changed
   stuff. 
   
-  Tip 'o the hat to Linuxcare for supporting staff in their work on
-  open source projects.
+  Tip 'o the hat to IBM (and previously Linuxcare :) for supporting 
+  staff in their work on open source projects.
 
   Change History
+
+    Mon Oct  8 14:29:00 EST 2001 hugh
+      Fixed bug that prevented mulitport devices operating correctly
+      if they weren't the first unit attached.
+
+    Sat Oct  6 12:31:21 EST 2001 hugh
+      Added support for USA-28XA and -28XB, misc cleanups, break support
+      for usa26 based models thanks to David Gibson.
+
     Thu May 31 11:56:42 PDT 2001 gkh
       switched from using spinlock to a semaphore
    
-   (04/08/2001) gb
+    (04/08/2001) gb
 	Identify version on module load.
    
-   (11/01/2000) Adam J. Richter
+    (11/01/2000) Adam J. Richter
 	usb_device_id table support.
    
     Tue Oct 10 23:15:33 EST 2000 Hugh
@@ -73,18 +81,22 @@
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
 	static int debug = 1;
+	#define DEBUG
 #else
 	static int debug;
+	#undef DEBUG
 #endif
 
+#include <linux/usb.h>
+
 #include "usb-serial.h"
 #include "keyspan.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
-#define DRIVER_AUTHOR "Hugh Blemings <hugh@linuxcare.com>"
+#define DRIVER_VERSION "v1.1.1"
+#define DRIVER_AUTHOR "Hugh Blemings <hugh@misc.nu"
 #define DRIVER_DESC "Keyspan USB to Serial Converter Driver"
 
 #define INSTAT_BUFLEN	32
@@ -141,6 +153,7 @@
 	int		dsr_state;
 	int		dcd_state;
 	int		ri_state;
+	int		break_on;
 
 	unsigned long	tx_start_time[2];
 	int		resend_cont;	/* need to resend control packet */
@@ -161,7 +174,6 @@
   #define	dbg	printk 
 #endif
 
-static void keyspan_send_setup(struct usb_serial_port *port);
 
 /* Functions used by new usb-serial code. */
 int keyspan_init (void)
@@ -171,6 +183,8 @@
 	usb_serial_register (&keyspan_usa19w_pre_device);
 	usb_serial_register (&keyspan_usa28_pre_device);
 	usb_serial_register (&keyspan_usa28x_pre_device);
+	usb_serial_register (&keyspan_usa28xa_pre_device);
+	usb_serial_register (&keyspan_usa28xb_pre_device);
 	usb_serial_register (&keyspan_usa49w_pre_device);
 
 	usb_serial_register (&keyspan_usa18x_device);
@@ -178,6 +192,8 @@
 	usb_serial_register (&keyspan_usa19w_device);
 	usb_serial_register (&keyspan_usa28_device);
 	usb_serial_register (&keyspan_usa28x_device);
+	usb_serial_register (&keyspan_usa28xa_device);
+	/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
 	usb_serial_register (&keyspan_usa49w_device);
 
 	info(DRIVER_VERSION ":" DRIVER_DESC);
@@ -192,6 +208,8 @@
 	usb_serial_deregister (&keyspan_usa19w_pre_device);
 	usb_serial_deregister (&keyspan_usa28_pre_device);
 	usb_serial_deregister (&keyspan_usa28x_pre_device);
+	usb_serial_deregister (&keyspan_usa28xa_pre_device);
+	usb_serial_deregister (&keyspan_usa28xb_pre_device);
 	usb_serial_deregister (&keyspan_usa49w_pre_device);
 
 	usb_serial_deregister (&keyspan_usa18x_device);
@@ -199,6 +217,8 @@
 	usb_serial_deregister (&keyspan_usa19w_device);
 	usb_serial_deregister (&keyspan_usa28_device);
 	usb_serial_deregister (&keyspan_usa28x_device);
+	usb_serial_deregister (&keyspan_usa28xa_device);
+	/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
 	usb_serial_deregister (&keyspan_usa49w_device);
 }
 
@@ -207,19 +227,30 @@
 
 static void keyspan_rx_throttle (struct usb_serial_port *port)
 {
-	dbg("keyspan_rx_throttle port %d", port->number);
+	dbg("keyspan_rx_throttle port %d\n", port->number);
 }
 
 
 static void keyspan_rx_unthrottle (struct usb_serial_port *port)
 {
-	dbg("keyspan_rx_unthrottle port %d", port->number);
+	dbg("keyspan_rx_unthrottle port %d\n", port->number);
 }
 
 
 static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
 {
-	dbg("keyspan_break_ctl");
+	struct keyspan_port_private 	*p_priv;
+
+ 	dbg("keyspan_break_ctl\n");
+
+	p_priv = (struct keyspan_port_private *)port->private;
+
+	if (break_state == -1)
+		p_priv->break_on = 1;
+	else
+		p_priv->break_on = 0;
+
+	keyspan_send_setup(port, 0);
 }
 
 
@@ -231,7 +262,7 @@
 	const keyspan_device_details	*d_details;
 	unsigned int 			cflag;
 
-	/*  dbg(__FUNCTION__ "."); */
+	dbg(__FUNCTION__ ".\n"); 
 
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = p_priv->device_details;
@@ -252,7 +283,7 @@
 	p_priv->cflag = cflag;
 	p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
 
-	keyspan_send_setup(port);
+	keyspan_send_setup(port, 0);
 }
 
 static int keyspan_ioctl(struct usb_serial_port *port, struct file *file,
@@ -281,7 +312,7 @@
 			return -EFAULT;
 		p_priv->rts_state = ((value & TIOCM_RTS) ? 1 : 0);
 		p_priv->dtr_state = ((value & TIOCM_DTR) ? 1 : 0);
-		keyspan_send_setup(port);
+		keyspan_send_setup(port, 0);
 		return 0;
 
 	case TIOCMBIS:
@@ -293,7 +324,7 @@
 			p_priv->rts_state = set;
 		if (value & TIOCM_DTR)
 			p_priv->dtr_state = set;
-		keyspan_send_setup(port);
+		keyspan_send_setup(port, 0);
 		return 0;
 	}
 
@@ -308,15 +339,15 @@
 	struct keyspan_port_private 	*p_priv;
 	const keyspan_device_details	*d_details;
 	int				flip;
-	int left, todo;
-	urb_t *this_urb;
-	int err;
+	int 				left, todo;
+	urb_t 				*this_urb;
+	int 				err;
 
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = p_priv->device_details;
 
 #if 0
-	dbg(__FUNCTION__ " for port %d (%d chars [%x]), flip=%d",
+	dbg(__FUNCTION__ " for port %d (%d chars [%x]), flip=%d\n",
 	    port->number, count, buf[0], p_priv->out_flip);
 #endif
 
@@ -330,10 +361,12 @@
 		/* Check we have a valid urb/endpoint before we use it... */
 		if ((this_urb = p_priv->out_urbs[flip]) == 0) {
 			/* no bulk out, so return 0 bytes written */
-			dbg(__FUNCTION__ " no output urb :(");
+			dbg(__FUNCTION__ " no output urb :(\n");
 			return count;
 		}
 
+		dbg(__FUNCTION__ " endpoint %d\n", usb_pipeendpoint(this_urb->pipe));
+
 		if (this_urb->status == -EINPROGRESS) {
 			if (this_urb->transfer_flags & USB_ASYNC_UNLINK)
 				break;
@@ -362,7 +395,7 @@
 		this_urb->transfer_flags &= ~USB_ASYNC_UNLINK;
 		this_urb->dev = port->serial->dev;
 		if ((err = usb_submit_urb(this_urb)) != 0) {
-			dbg("usb_submit_urb(write bulk) failed (%d)", err);
+			dbg("usb_submit_urb(write bulk) failed (%d)\n", err);
 		}
 		p_priv->tx_start_time[flip] = jiffies;
 
@@ -382,12 +415,12 @@
 	struct tty_struct	*tty;
 	unsigned char 		*data = urb->transfer_buffer;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__); 
 
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (urb->status) {
-		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.",
+		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.\n",
 			      		urb->status, endpoint);
 		return;
 	}
@@ -420,7 +453,7 @@
 		/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 	return;
 }
@@ -433,7 +466,7 @@
 
 	port = (struct usb_serial_port *) urb->context;
 	p_priv = (struct keyspan_port_private *)(port->private);
-	/*  dbg (__FUNCTION__ " urb %d", urb == p_priv->out_urbs[1]); */
+	dbg (__FUNCTION__ " urb %d\n", urb == p_priv->out_urbs[1]); 
 
 	if (port->active) {
 		queue_task(&port->tqueue, &tq_immediate);
@@ -443,7 +476,7 @@
 
 static void	usa26_inack_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__); 
 	
 }
 
@@ -456,8 +489,8 @@
 	p_priv = (struct keyspan_port_private *)(port->private);
 
 	if (p_priv->resend_cont) {
-		/*  dbg (__FUNCTION__ " sending setup"); */
-		keyspan_usa26_send_setup(port->serial, port);
+		dbg (__FUNCTION__ " sending setup\n"); 
+		keyspan_usa26_send_setup(port->serial, port, 0);
 	}
 }
 
@@ -473,18 +506,18 @@
 	serial = (struct usb_serial *) urb->context;
 
 	if (urb->status) {
-		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);
 		return;
 	}
 	if (urb->actual_length != 9) {
-		dbg(__FUNCTION__ " %d byte report??", urb->actual_length);
+		dbg(__FUNCTION__ " %d byte report??\n", urb->actual_length);
 		goto exit;
 	}
 
 	msg = (keyspan_usa26_portStatusMessage *)data;
 
 #if 0
-	dbg(__FUNCTION__ " port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d",
+	dbg(__FUNCTION__ " port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d\n",
 	    msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff,
 	    msg->_txXoff, msg->rxEnabled, msg->controlResponse);
 #endif
@@ -494,7 +527,7 @@
 
 	/* Check port number from message and retrieve private data */	
 	if (msg->port >= serial->num_ports) {
-		dbg ("Unexpected port number %d", msg->port);
+		dbg ("Unexpected port number %d\n", msg->port);
 		goto exit;
 	}
 	port = &serial->port[msg->port];
@@ -519,13 +552,13 @@
 	/* Resubmit urb so we continue receiving */
 	urb->dev = serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 static void	usa26_glocont_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 	
 }
 
@@ -538,7 +571,7 @@
 	unsigned char           *data;
 	struct keyspan_port_private             *p_priv;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	port = (struct usb_serial_port *) urb->context;
 	p_priv = (struct keyspan_port_private *)(port->private);
@@ -550,7 +583,7 @@
 	do {
 		if (urb->status) {
 			dbg(__FUNCTION__ "nonzero status: %x on endpoint
-%d.",
+%d.\n",
 			    urb->status, usb_pipeendpoint(urb->pipe));
 			return;
 		}
@@ -570,7 +603,7 @@
 		/* Resubmit urb so we continue receiving */
 		urb->dev = port->serial->dev;
 		if ((err = usb_submit_urb(urb)) != 0) {
-			dbg(__FUNCTION__ "resubmit read urb failed. (%d)",
+			dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n",
 err);
 		}
 		p_priv->in_flip ^= 1;
@@ -581,7 +614,7 @@
 
 static void	usa28_inack_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 static void	usa28_outcont_callback(struct urb *urb)
@@ -593,8 +626,8 @@
 	p_priv = (struct keyspan_port_private *)(port->private);
 
 	if (p_priv->resend_cont) {
-		dbg (__FUNCTION__ " sending setup");
-		keyspan_usa28_send_setup(port->serial, port);
+		dbg (__FUNCTION__ " sending setup\n");
+		keyspan_usa28_send_setup(port->serial, port, 0);
 	}
 }
 
@@ -611,16 +644,16 @@
 	serial = (struct usb_serial *) urb->context;
 
 	if (urb->status) {
-		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);
 		return;
 	}
 
 	if (urb->actual_length != sizeof(struct keyspan_usa28_portStatusMessage)) {
-		dbg(__FUNCTION__ " bad length %d", urb->actual_length);
+		dbg(__FUNCTION__ " bad length %d\n", urb->actual_length);
 		goto exit;
 	}
 
-	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x %x",
+	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x %x\n",
 	    data[0], data[1], data[2], data[3], data[4], data[5],
 	    data[6], data[7], data[8], data[9], data[10], data[11]);*/
 	
@@ -630,7 +663,7 @@
 
 		/* Check port number from message and retrieve private data */	
 	if (msg->port >= serial->num_ports) {
-		dbg ("Unexpected port number %d", msg->port);
+		dbg ("Unexpected port number %d\n", msg->port);
 		goto exit;
 	}
 	port = &serial->port[msg->port];
@@ -655,13 +688,13 @@
 		/* Resubmit urb so we continue receiving */
 	urb->dev = serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 static void	usa28_glocont_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 
@@ -672,7 +705,7 @@
 	struct keyspan_port_private *p_priv;
 	int i;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	serial = (struct usb_serial *) urb->context;
 	for (i = 0; i < serial->num_ports; ++i) {
@@ -680,8 +713,8 @@
 		p_priv = (struct keyspan_port_private *)(port->private);
 
 		if (p_priv->resend_cont) {
-			/*  dbg (__FUNCTION__ " sending setup"); */
-			keyspan_usa49_send_setup(serial, port);
+			dbg (__FUNCTION__ " sending setup\n"); 
+			keyspan_usa49_send_setup(serial, port, 0);
 			break;
 		}
 	}
@@ -699,21 +732,21 @@
 	struct keyspan_port_private	 	*p_priv;
 	int old_dcd_state;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	serial = (struct usb_serial *) urb->context;
 
 	if (urb->status) {
-		dbg(__FUNCTION__ " nonzero status: %x", urb->status);
+		dbg(__FUNCTION__ " nonzero status: %x\n", urb->status);
 		return;
 	}
 
 	if (urb->actual_length != sizeof(struct keyspan_usa49_portStatusMessage)) {
-		dbg(__FUNCTION__ " bad length %d", urb->actual_length);
+		dbg(__FUNCTION__ " bad length %d\n", urb->actual_length);
 		goto exit;
 	}
 
-	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x",
+	/*dbg(__FUNCTION__ " %x %x %x %x %x %x %x %x %x %x %x\n",
 	    data[0], data[1], data[2], data[3], data[4], data[5],
 	    data[6], data[7], data[8], data[9], data[10]);*/
 	
@@ -722,7 +755,7 @@
 
 		/* Check port number from message and retrieve private data */	
 	if (msg->portNumber >= serial->num_ports) {
-		dbg ("Unexpected port number %d", msg->portNumber);
+		dbg ("Unexpected port number %d\n", msg->portNumber);
 		goto exit;
 	}
 	port = &serial->port[msg->portNumber];
@@ -748,13 +781,13 @@
 	urb->dev = serial->dev;
 
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 static void	usa49_inack_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 static void	usa49_indat_callback(struct urb *urb)
@@ -765,12 +798,12 @@
 	struct tty_struct	*tty;
 	unsigned char 		*data = urb->transfer_buffer;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (urb->status) {
-		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.",
+		dbg(__FUNCTION__ "nonzero status: %x on endpoint %d.\n",
 			      		urb->status, endpoint);
 		return;
 	}
@@ -803,21 +836,21 @@
 		/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
 	if ((err = usb_submit_urb(urb)) != 0) {
-		dbg(__FUNCTION__ "resubmit read urb failed. (%d)", err);
+		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
 
 /* not used, usa-49 doesn't have per-port control endpoints */
 static void	usa49_outcont_callback(struct urb *urb)
 {
-	dbg (__FUNCTION__);
+	dbg ("%s\n", __FUNCTION__);
 }
 
 
 
 static int keyspan_write_room (struct usb_serial_port *port)
 {
-//	dbg("keyspan_write_room called");
+	dbg("keyspan_write_room called\n");
 	return (32);
 
 }
@@ -842,7 +875,8 @@
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = s_priv->device_details;
 	
-	/*  dbg("keyspan_open called."); */
+	dbg("keyspan_open called for port%d.\n", port->number); 
+
 	MOD_INC_USE_COUNT;
 
 	down (&port->sem);
@@ -855,7 +889,7 @@
 		return 0;
 
 	p_priv = (struct keyspan_port_private *)(port->private);
-
+	
 	/* Set some sane defaults */
 	p_priv->rts_state = 1;
 	p_priv->dtr_state = 1;
@@ -866,7 +900,7 @@
 			continue;
 		urb->dev = serial->dev;
 		if ((err = usb_submit_urb(urb)) != 0) {
-			dbg(__FUNCTION__ " submit urb %d failed (%d)", i, err);
+			dbg(__FUNCTION__ " submit urb %d failed (%d)\n", i, err);
 		}
 	}
 
@@ -890,9 +924,21 @@
 	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private 	*p_priv;
 
-	/*  dbg("keyspan_close called"); */
+	dbg("keyspan_close called\n");
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
+	
+	p_priv->rts_state = 0;
+	p_priv->dtr_state = 0;
+	
+	keyspan_send_setup(port, 1);
+
+	/*while (p_priv->outcont_urb->status == -EINPROGRESS) {
+		dbg("close - urb in progress\n");
+	}*/
+
+	p_priv->out_flip = 0;
+	p_priv->in_flip = 0;
 
 	down (&port->sem);
 
@@ -928,43 +974,53 @@
 	const struct ezusb_hex_record 	*record;
 	char				*fw_name;
 
-	dbg("Keyspan startup version %04x product %04x",
+	dbg("Keyspan startup version %04x product %04x\n",
 	    serial->dev->descriptor.bcdDevice,
 	    serial->dev->descriptor.idProduct); 
 	
 	if ((serial->dev->descriptor.bcdDevice & 0x8000) != 0x8000) {
-		dbg("Firmware already loaded.  Quitting.");
+		dbg("Firmware already loaded.  Quitting.\n");
 		return(1);
 	}
 
 		/* Select firmware image on the basis of idProduct */
 	switch (serial->dev->descriptor.idProduct) {
-	case 0x0101:
+	case keyspan_usa28_pre_product_id:
 		record = &keyspan_usa28_firmware[0];
 		fw_name = "USA28";
 		break;
 
-	case 0x0102:
+	case keyspan_usa28x_pre_product_id:
 		record = &keyspan_usa28x_firmware[0];
 		fw_name = "USA28X";
 		break;
 
-	case 0x0103:
+	case keyspan_usa28xa_pre_product_id:
+		record = &keyspan_usa28xa_firmware[0];
+		fw_name = "USA28XA";
+		break;
+
+	case keyspan_usa28xb_pre_product_id:
+		record = &keyspan_usa28xb_firmware[0];
+		fw_name = "USA28XB";
+		break;
+
+	case keyspan_usa19_pre_product_id:
 		record = &keyspan_usa19_firmware[0];
 		fw_name = "USA19";
 		break;
 			     
-	case 0x0105:
+	case keyspan_usa18x_pre_product_id:
 		record = &keyspan_usa18x_firmware[0];
 		fw_name = "USA18X";
 		break;
 			     
-	case 0x0106:
+	case keyspan_usa19w_pre_product_id:
 		record = &keyspan_usa19w_firmware[0];
 		fw_name = "USA19W";
 		break;
 		
-	case 0x0109:
+	case keyspan_usa49w_pre_product_id:
 		record = &keyspan_usa49w_firmware[0];
 		fw_name = "USA49W";
 		break;
@@ -980,7 +1036,7 @@
 		return(1);
 	}
 
-	dbg("Uploading Keyspan %s firmware.", fw_name);
+	dbg("Uploading Keyspan %s firmware.\n", fw_name);
 
 		/* download the firmware image */
 	response = ezusb_set_reset(serial, 1);
@@ -1016,10 +1072,10 @@
 	if (endpoint == -1)
 		return NULL;		/* endpoint not needed */
 
-	/*  dbg (__FUNCTION__ " alloc for endpoint %d.", endpoint); */
+	dbg (__FUNCTION__ " alloc for endpoint %d.\n", endpoint);
 	urb = usb_alloc_urb(0);		/* No ISO */
 	if (urb == NULL) {
-		dbg (__FUNCTION__ " alloc for endpoint %d failed.", endpoint);
+		dbg (__FUNCTION__ " alloc for endpoint %d failed.\n", endpoint);
 		return NULL;
 	}
 
@@ -1078,7 +1134,7 @@
 	struct callbacks		*cback;
 	int				endp;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	d_details = s_priv->device_details;
@@ -1197,7 +1253,7 @@
 	u8	best_prescaler;
 	int	i;
 
-	/*  dbg (__FUNCTION__ " %d.", baud_rate); */
+	dbg (__FUNCTION__ " %d.\n", baud_rate);
 
 		/* prevent divide by zero */
 	if( (b16 = baud_rate * 16L) == 0) {
@@ -1253,7 +1309,8 @@
 }
 
 static int keyspan_usa26_send_setup(struct usb_serial *serial,
-				    struct usb_serial_port *port)
+				    struct usb_serial_port *port,
+				    int reset_port)
 {
 	struct keyspan_usa26_portControlMessage	msg;		
 	struct keyspan_serial_private 		*s_priv;
@@ -1263,7 +1320,7 @@
 	urb_t *this_urb;
 	int err;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s reset=%d\n", __FUNCTION__, reset_port); 
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
@@ -1272,9 +1329,11 @@
 	outcont_urb = d_details->outcont_endpoints[port->number];
 	this_urb = p_priv->outcont_urb;
 
+	dbg(__FUNCTION__ " endpoint %d\n", usb_pipeendpoint(this_urb->pipe));
+
 		/* Make sure we have an urb then send the message */
 	if (this_urb == NULL) {
-		dbg(__FUNCTION__ " oops no urb.");
+		dbg(__FUNCTION__ " oops no urb.\n");
 		return -1;
 	}
 
@@ -1293,7 +1352,7 @@
 		if (d_details->calculate_baud_rate
 		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
 		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {
-			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",
+			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.\n",
 			    p_priv->baud);
 			msg.baudLo = 0;
 			msg.baudHi = 125;	/* Values for 9600 baud */
@@ -1331,17 +1390,31 @@
 	msg.forwardingLength = 1;
 	msg.xonChar = 17;
 	msg.xoffChar = 19;
-	
-	msg._txOn = 1;
-	msg._txOff = 0;
-	msg.txFlush = 0;
-	msg.txBreak = 0;
-	msg.rxOn = 1;
-	msg.rxOff = 0;
-	msg.rxFlush = 0;
-	msg.rxForward = 0;
-	/*msg.returnStatus = 1;
-	msg.resetDataToggle = 0xff;*/
+
+	if (reset_port) {
+		msg._txOn = 0;
+		msg._txOff = 1;
+		msg.txFlush = 0;
+		msg.txBreak = 0;
+		msg.rxOn = 0;
+		msg.rxOff = 1;
+		msg.rxFlush = 1;
+		msg.rxForward = 0;
+		msg.returnStatus = 0;
+		msg.resetDataToggle = 0xff;
+	}
+	else {
+		msg._txOn = (! p_priv->break_on);
+		msg._txOff = 0;
+		msg.txFlush = 0;
+		msg.txBreak = (p_priv->break_on);
+		msg.rxOn = 1;
+		msg.rxOff = 0;
+		msg.rxFlush = 0;
+		msg.rxForward = 0;
+		msg.returnStatus = 0;
+		msg.resetDataToggle = 0x0;
+	}
 
 		/* Do handshaking outputs */	
 	msg.setTxTriState_setRts = 0xff;
@@ -1358,7 +1431,7 @@
 
 	this_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(this_urb)) != 0) {
-		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err);
 	}
 #if 0
 	else {
@@ -1372,7 +1445,8 @@
 }
 
 static int keyspan_usa28_send_setup(struct usb_serial *serial,
-				    struct usb_serial_port *port)
+				    struct usb_serial_port *port,
+				    int reset_port)
 {
 	struct keyspan_usa28_portControlMessage	msg;		
 	struct keyspan_serial_private	 	*s_priv;
@@ -1387,13 +1461,13 @@
 
 	/* only do something if we have a bulk out endpoint */
 	if ((this_urb = p_priv->outcont_urb) == NULL) {
-		dbg(__FUNCTION__ " oops no urb.");
+		dbg(__FUNCTION__ " oops no urb.\n");
 		return -1;
 	}
 
 	p_priv->resend_cont = 1;
 	if (this_urb->status == -EINPROGRESS) {
-		dbg (__FUNCTION__ " already writing");
+		dbg (__FUNCTION__ " already writing\n");
 		return(-1);
 	}
 
@@ -1402,7 +1476,7 @@
 	msg.setBaudRate = 1;
 	if (keyspan_usa19_calc_baud(p_priv->baud, d_details->baudclk,
 		&msg.baudHi, &msg.baudLo, NULL) == KEYSPAN_INVALID_BAUD_RATE ) {
-		dbg(__FUNCTION__ "Invalid baud rate requested %d.", 9600);
+		dbg(__FUNCTION__ "Invalid baud rate requested %d.", p_priv->baud);
 		msg.baudLo = 0xff;
 		msg.baudHi = 0xb2;	/* Values for 9600 baud */
 	}
@@ -1443,7 +1517,7 @@
 
 	this_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(this_urb)) != 0) {
-		dbg(__FUNCTION__ " usb_submit_urb(setup) failed");
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed\n");
 	}
 #if 0
 	else {
@@ -1456,17 +1530,19 @@
 }
 
 static int keyspan_usa49_send_setup(struct usb_serial *serial,
-				    struct usb_serial_port *port)
+				    struct usb_serial_port *port,
+				    int reset_port)
 {
 	struct keyspan_usa49_portControlMessage	msg;		
 	struct keyspan_serial_private 		*s_priv;
 	struct keyspan_port_private 		*p_priv;
 	const  keyspan_device_details		*d_details;
 	int 					glocont_urb;
-	urb_t *this_urb;
-	int err;
+	urb_t 					*this_urb;
+	int 					err;
+	int					device_port;
 
-	/*  dbg (__FUNCTION__); */
+	dbg ("%s\n", __FUNCTION__);
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
@@ -1475,11 +1551,14 @@
 	glocont_urb = d_details->glocont_endpoint;
 	this_urb = s_priv->glocont_urb;
 
-	/*  dbg(__FUNCTION__ " port %d\n", port->number); */
+		/* Work out which port within the device is being setup */
+	device_port = port->number - port->serial->minor;
+
+	dbg(__FUNCTION__ " endpoint %d port %d (%d)\n", usb_pipeendpoint(this_urb->pipe), port->number, device_port);
 
 		/* Make sure we have an urb then send the message */
 	if (this_urb == NULL) {
-		dbg(__FUNCTION__ " oops no urb for port %d.", port->number);
+		dbg(__FUNCTION__ " oops no urb for port %d.\n", port->number);
 		return -1;
 	}
 
@@ -1491,7 +1570,8 @@
 
 	memset(&msg, 0, sizeof (struct keyspan_usa49_portControlMessage));
 
-	msg.portNumber = port->number;
+	/*msg.portNumber = port->number;*/
+	msg.portNumber = device_port;
 	
 		/* Only set baud rate if it's changed */	
 	if (p_priv->old_baud != p_priv->baud) {
@@ -1500,7 +1580,7 @@
 		if (d_details->calculate_baud_rate
 		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
 		     &msg.baudLo, &msg.prescaler) == KEYSPAN_INVALID_BAUD_RATE ) {
-			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.",
+			dbg(__FUNCTION__ "Invalid baud rate %d requested, using 9600.\n",
 			    p_priv->baud);
 			msg.baudLo = 0;
 			msg.baudHi = 125;	/* Values for 9600 baud */
@@ -1565,7 +1645,7 @@
 
 	this_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(this_urb)) != 0) {
-		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)", err);
+		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err);
 	}
 #if 0
 	else {
@@ -1578,7 +1658,7 @@
 	return (0);
 }
 
-static void keyspan_send_setup(struct usb_serial_port *port)
+static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
 {
 	struct usb_serial *serial = port->serial;
 	struct keyspan_serial_private 	*s_priv;
@@ -1589,13 +1669,13 @@
 
 	switch (d_details->msg_format) {
 	case msg_usa26:
-		keyspan_usa26_send_setup(serial, port);
+		keyspan_usa26_send_setup(serial, port, reset_port);
 		break;
 	case msg_usa28:
-		keyspan_usa28_send_setup(serial, port);
+		keyspan_usa28_send_setup(serial, port, reset_port);
 		break;
 	case msg_usa49:
-		keyspan_usa49_send_setup(serial, port);
+		keyspan_usa49_send_setup(serial, port, reset_port);
 		break;
 	}
 }
@@ -1610,7 +1690,7 @@
 	struct keyspan_port_private	*p_priv;
 	const keyspan_device_details	*d_details;
 
-	/*  dbg("keyspan_startup called."); */
+	dbg("keyspan_startup called.\n");
 
 	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
 		if (d_details->product_id == serial->dev->descriptor.idProduct)
@@ -1625,7 +1705,7 @@
 	serial->private = kmalloc(sizeof(struct keyspan_serial_private),
 				  GFP_KERNEL);
 	if (!serial->private) {
-		dbg(__FUNCTION__ "kmalloc for keyspan_serial_private failed.");
+		dbg(__FUNCTION__ "kmalloc for keyspan_serial_private failed.\n");
 		return (1);
 	}
 	memset(serial->private, 0, sizeof(struct keyspan_serial_private));
@@ -1639,7 +1719,7 @@
 		port->private = kmalloc(sizeof(struct keyspan_port_private),
 					GFP_KERNEL);
 		if (!port->private) {
-			dbg(__FUNCTION__ "kmalloc for keyspan_port_private (%d) failed!.", i);
+			dbg(__FUNCTION__ "kmalloc for keyspan_port_private (%d) failed!.\n", i);
 			return (1);
 		}
 		memset(port->private, 0, sizeof(struct keyspan_port_private));
@@ -1651,7 +1731,7 @@
 
 	s_priv->instat_urb->dev = serial->dev;
 	if ((err = usb_submit_urb(s_priv->instat_urb)) != 0) {
-		dbg(__FUNCTION__ " submit instat urb failed %d", err);
+		dbg(__FUNCTION__ " submit instat urb failed %d\n", err);
 	}
 			
 	return (0);
@@ -1664,7 +1744,7 @@
 	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private	*p_priv;
 
-	/*  dbg("keyspan_shutdown called"); */
+	dbg("keyspan_shutdown called\n");
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan.h linux/drivers/usb/serial/keyspan.h
--- v2.4.10/linux/drivers/usb/serial/keyspan.h	Thu Jan  4 13:15:32 2001
+++ linux/drivers/usb/serial/keyspan.h	Tue Oct  9 15:15:02 2001
@@ -1,16 +1,15 @@
 /*
   Keyspan USB to Serial Converter driver
  
-  (C) Copyright (C) 2000
-      Hugh Blemings <hugh@linuxcare.com>
+  (C) Copyright (C) 2000-2001
+      Hugh Blemings <hugh@misc.nu>
    
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
 
-  See http://www.linuxcare.com.au/hugh/keyspan.html for more
-  information on this driver.
+  See http://misc.nu/hugh/keyspan.html for more information.
   
   Code in this driver inspired by and in a number of places taken
   from Brian Warner's original Keyspan-PDA driver.
@@ -24,8 +23,8 @@
   having the patience to sit down and explain why and where he'd changed
   stuff.
 
-  Tip 'o the hat to Linuxcare for supporting staff in their work on
-  open source projects.
+  Tip 'o the hat to IBM (and previously Linuxcare :) for supporting 
+  staff in their work on open source projects.
   
   See keyspan.c for update history.
 
@@ -52,6 +51,9 @@
 					 const unsigned char *buf,
 					 int count);
 
+static void keyspan_send_setup		(struct usb_serial_port *port,
+					 int reset_port);
+
 #if 0
 static void keyspan_write_bulk_callback (struct urb *urb);
 #endif
@@ -78,26 +80,30 @@
 //static void keyspan_usa19_setup_urbs	(struct usb_serial *serial);
 
 static int  keyspan_usa28_send_setup	(struct usb_serial *serial,
-					 struct usb_serial_port *port);
+					 struct usb_serial_port *port,
+					 int reset_port);
 static int  keyspan_usa26_send_setup	(struct usb_serial *serial,
-	       				 struct usb_serial_port *port);
+	       				 struct usb_serial_port *port,
+					 int reset_port);
 static int  keyspan_usa49_send_setup	(struct usb_serial *serial,
-					 struct usb_serial_port *port);
+					 struct usb_serial_port *port,
+					 int reset_port);
 
 	/* Functions from usbserial.c for ezusb firmware handling */
 extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit);
 extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest);
 
-	/* Struct used for firmware */
+	/* Struct used for firmware - increased size of data section
+	   to allow Keyspan's 'C' firmware struct to be used unmodified */
 struct ezusb_hex_record {
 	__u16 address;
 	__u8 data_size;
-	__u8 data[16];
+	__u8 data[64];
 };
 	/* Conditionally include firmware images, if they aren't
 	   included create a null pointer instead.  Current 
 	   firmware images aren't optimised to remove duplicate
-	   addresses. */
+	   addresses in the image itself. */
 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28
         #include "keyspan_usa28_fw.h"
 #else
@@ -110,6 +116,18 @@
 	static const struct ezusb_hex_record *keyspan_usa28x_firmware = NULL;
 #endif
 
+#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28XA
+        #include "keyspan_usa28xa_fw.h"
+#else
+	static const struct ezusb_hex_record *keyspan_usa28xa_firmware = NULL;
+#endif
+
+#ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28XB
+        #include "keyspan_usa28xb_fw.h"
+#else
+	static const struct ezusb_hex_record *keyspan_usa28xb_firmware = NULL;
+#endif
+
 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19
         #include "keyspan_usa19_fw.h"
 #else
@@ -149,6 +167,33 @@
 #define		KEYSPAN_MAX_NUM_PORTS		(4)
 #define		KEYSPAN_MAX_FLIPS		(2)
 	
+	/* Device info for the Keyspan serial converter, used
+	   by the overall usb-serial probe function */
+#define KEYSPAN_VENDOR_ID			(0x06cd)
+
+	/* Product IDs for the eight products supported, pre-renumeration */
+#define	keyspan_usa18x_pre_product_id		0x0105
+#define	keyspan_usa19_pre_product_id		0x0103
+#define	keyspan_usa19w_pre_product_id		0x0106
+#define	keyspan_usa28_pre_product_id		0x0101
+#define	keyspan_usa28x_pre_product_id		0x0102
+#define	keyspan_usa28xa_pre_product_id		0x0114
+#define	keyspan_usa28xb_pre_product_id		0x0113
+#define	keyspan_usa49w_pre_product_id		0x0109
+
+	/* Product IDs post-renumeration.  Note that the 28x and 28xb
+	   have the same id's post-renumeration but behave identically
+	   so it's not an issue. */
+#define	keyspan_usa18x_product_id		0x0112
+#define	keyspan_usa19_product_id		0x0107
+#define	keyspan_usa19w_product_id		0x0108
+#define	keyspan_usa28_product_id		0x010f
+#define	keyspan_usa28x_product_id		0x0110
+#define	keyspan_usa28xa_product_id		0x0115
+#define	keyspan_usa28xb_product_id		0x0110
+#define	keyspan_usa49w_product_id		0x010a
+
+
 typedef struct {
 	/* product ID value */
 	int	product_id;
@@ -194,7 +239,7 @@
 	   in Keyspan's documentation) */
 
 static const keyspan_device_details usa18x_device_details = {
-	0x112,				/* product ID */
+	keyspan_usa18x_product_id,	/* product ID */
        	msg_usa26, 			/* msg type*/
 	1,				/* num ports */
 	0,				/* indat endpoint flip */
@@ -210,7 +255,7 @@
 };
 
 static const keyspan_device_details usa19_device_details = {
-	0x107,				/* product ID */
+	keyspan_usa19_product_id,	/* product ID */
        	msg_usa28, 			/* msg type*/
 	1,				/* num ports */
 	1,				/* indat endpoint flip */
@@ -226,7 +271,7 @@
 };
 
 static const keyspan_device_details usa19w_device_details = {
-	0x108,				/* product ID */
+	keyspan_usa19w_product_id,	/* product ID */
        	msg_usa26, 			/* msg type*/
 	1,				/* num ports */
 	0,				/* indat endpoint flip */
@@ -242,7 +287,7 @@
 };
 
 static const keyspan_device_details usa28x_device_details = {
-	0x110,				/* product ID */
+	keyspan_usa28x_product_id,	/* product ID */
        	msg_usa26, 			/* msg type*/
 	2,				/* num ports */
 	0,				/* indat endpoint flip */
@@ -257,8 +302,26 @@
 	KEYSPAN_USA28X_BAUDCLK
 };
 
+static const keyspan_device_details usa28xa_device_details = {
+	keyspan_usa28xa_product_id,	/* product ID */
+       	msg_usa26, 			/* msg type*/
+	2,				/* num ports */
+	0,				/* indat endpoint flip */
+	1,				/* outdat endpoint flip */
+  	{0x81, 0x83},			/* per port indat */
+  	{0x01, 0x03},			/* per port outdat */
+	{0x85, 0x86},			/* per port inack */
+	{0x05, 0x06},			/* per port outcont */
+	0x87,				/* instat endpoint */
+	0x07,				/* glocont endpoint */
+	keyspan_usa19w_calc_baud,	/* calc baud rate */
+	KEYSPAN_USA28X_BAUDCLK
+};
+
+	/* We don't need a separate entry for the usa28xb as it appears as a 28x anyway */
+
 static const keyspan_device_details usa49w_device_details = {
-	0x010a,				/* product ID */
+	keyspan_usa49w_product_id,	/* product ID */
        	msg_usa49, 			/* msg type*/
 	4,				/* num ports */
 	0,				/* indat endpoint flip */
@@ -278,42 +341,27 @@
 	&usa19_device_details,
 	&usa19w_device_details,
 	&usa28x_device_details,
+	&usa28xa_device_details,
 	&usa49w_device_details,
 	NULL
 };
 
-	/* Device info for the Keyspan serial converter, used
-	   by the overall usb-serial probe function */
-#define KEYSPAN_VENDOR_ID			(0x06cd)
-
-    /* Product IDs for the five products supported, pre-renumeration */
-#define	keyspan_usa18x_pre_product_id	0x0105
-#define	keyspan_usa19_pre_product_id	0x0103
-#define	keyspan_usa19w_pre_product_id	0x0106
-#define	keyspan_usa28_pre_product_id	0x0101
-#define	keyspan_usa28x_pre_product_id	0x0102
-#define	keyspan_usa49w_pre_product_id	0x0109
-
-    /* Product IDs post-renumeration */
-#define	keyspan_usa18x_product_id	0x0112
-#define	keyspan_usa19_product_id	0x0107
-#define	keyspan_usa19w_product_id	0x0108
-#define	keyspan_usa28_product_id	0x010f
-#define	keyspan_usa28x_product_id	0x0110
-#define	keyspan_usa49w_product_id	0x010a
-
 static __devinitdata struct usb_device_id keyspan_ids_combined[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_pre_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_pre_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_pre_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)},
 	{ } /* Terminating entry */
 };
@@ -349,6 +397,16 @@
 	{ } /* Terminating entry */
 };
 
+static __devinitdata struct usb_device_id keyspan_usa28xa_pre_ids[] = {
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_pre_product_id) },
+	{ } /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id keyspan_usa28xb_pre_ids[] = {
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_pre_product_id) },
+	{ } /* Terminating entry */
+};
+
 static __devinitdata struct usb_device_id keyspan_usa49w_pre_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_pre_product_id) },
 	{ } /* Terminating entry */
@@ -379,13 +437,17 @@
 	{ } /* Terminating entry */
 };
 
+static __devinitdata struct usb_device_id keyspan_usa28xa_ids[] = {
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
+	{ } /* Terminating entry */
+};
+
 static __devinitdata struct usb_device_id keyspan_usa49w_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id) },
 	{ } /* Terminating entry */
 };
 
-    /* Structs for the devices, pre and post renumeration.
-       These are incomplete at present - HAB 20000708  */
+    /* Structs for the devices, pre and post renumeration. */
 struct usb_serial_device_type keyspan_usa18x_pre_device = {
 	name:			"Keyspan USA18X - (without firmware)",
 	id_table:		keyspan_usa18x_pre_ids,
@@ -453,6 +515,32 @@
 	startup:		keyspan_fake_startup	
 };
 
+struct usb_serial_device_type keyspan_usa28xa_pre_device = {
+	name:			"Keyspan USA28XA - (without firmware)",
+	id_table:		keyspan_usa28xa_pre_ids,
+	needs_interrupt_in:	DONT_CARE,
+	needs_bulk_in:		DONT_CARE,
+	needs_bulk_out:		DONT_CARE,
+	num_interrupt_in:	NUM_DONT_CARE,
+	num_bulk_in:		NUM_DONT_CARE,
+	num_bulk_out:		NUM_DONT_CARE,
+	num_ports:		2,
+	startup:		keyspan_fake_startup	
+};
+
+struct usb_serial_device_type keyspan_usa28xb_pre_device = {
+	name:			"Keyspan USA28XB - (without firmware)",
+	id_table:		keyspan_usa28xb_pre_ids,
+	needs_interrupt_in:	DONT_CARE,
+	needs_bulk_in:		DONT_CARE,
+	needs_bulk_out:		DONT_CARE,
+	num_interrupt_in:	NUM_DONT_CARE,
+	num_bulk_in:		NUM_DONT_CARE,
+	num_bulk_out:		NUM_DONT_CARE,
+	num_ports:		2,
+	startup:		keyspan_fake_startup	
+};
+
 struct usb_serial_device_type keyspan_usa49w_pre_device = {
 	name:			"Keyspan USA49W - (without firmware)",
 	id_table:		keyspan_usa49w_pre_ids,
@@ -565,7 +653,7 @@
 
 
 struct usb_serial_device_type keyspan_usa28x_device = {
-	name:			"Keyspan USA28X",
+	name:			"Keyspan USA28X/XB",
 	id_table:		keyspan_usa28x_ids,
 	needs_interrupt_in:	DONT_CARE,	
 	needs_bulk_in:		DONT_CARE,
@@ -590,7 +678,33 @@
 	shutdown:		keyspan_shutdown,
 
 };
-				
+
+struct usb_serial_device_type keyspan_usa28xa_device = {
+	name:			"Keyspan USA28XA",
+	id_table:		keyspan_usa28xa_ids,
+	needs_interrupt_in:	DONT_CARE,	
+	needs_bulk_in:		DONT_CARE,
+	needs_bulk_out:		DONT_CARE,
+	num_interrupt_in:	NUM_DONT_CARE,
+	num_bulk_in:		NUM_DONT_CARE,
+	num_bulk_out:		NUM_DONT_CARE,
+	num_ports:		2,
+	open:			keyspan_open,
+	close:			keyspan_close,
+	write:			keyspan_write,
+	write_room:		keyspan_write_room,
+//	write_bulk_callback: 	keyspan_write_bulk_callback,
+//	read_int_callback:	keyspan_usa26_read_int_callback,
+	chars_in_buffer:	keyspan_chars_in_buffer,
+	throttle:		keyspan_rx_throttle,
+	unthrottle:		keyspan_rx_unthrottle,
+	ioctl:			keyspan_ioctl,
+	set_termios:		keyspan_set_termios,
+	break_ctl:		keyspan_break_ctl,
+	startup:		keyspan_startup,
+	shutdown:		keyspan_shutdown,
+
+};
 
 struct usb_serial_device_type keyspan_usa49w_device = {
 	name:			"Keyspan USA49W",
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa18x_fw.h linux/drivers/usb/serial/keyspan_usa18x_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa18x_fw.h	Mon Jul 10 14:33:04 2000
+++ linux/drivers/usb/serial/keyspan_usa18x_fw.h	Tue Oct  9 15:15:02 2001
@@ -1,10 +1,10 @@
 /* keyspan_usa18x_fw.h
   
-   Generated from Keyspan firmware image Wed Jul  5 09:18:29 2000 EST
+   Generated from Keyspan firmware image usa16code.h Sat Oct  6 12:16:35 EST 2001
    This firmware is for the Keyspan USA-18X Serial Adaptor
 
    "The firmware contained herein as keyspan_usa18x_fw.h is
-   Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
    ("Keyspan"), as an unpublished work.  This notice does not imply
    unrestricted or public access to this firmware which is a trade secret of
    Keyspan, and which may not be reproduced, used, sold or transferred to any
@@ -18,389 +18,426 @@
 */
 
 static const struct ezusb_hex_record keyspan_usa18x_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x0e, 0x9b} },
-{ 0x0003,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
-{ 0x0013,	16,	{0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90} },
-{ 0x0023,	15,	{0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22} },
-{ 0x0033,	3,	{0x02, 0x13, 0xfc} },
-{ 0x0036,	12,	{0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0043,	3,	{0x02, 0x14, 0x00} },
-{ 0x0046,	16,	{0x30, 0x08, 0x13, 0x12, 0x13, 0xc0, 0xef, 0xc3, 0x95, 0x3c, 0x50, 0x73, 0x90, 0x7f, 0xbf, 0x74} },
-{ 0x0056,	16,	{0x01, 0xf0, 0xc2, 0x08, 0x80, 0x69, 0x30, 0x02, 0x34, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x5f} },
-{ 0x0066,	16,	{0x12, 0x13, 0xc0, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x56, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x08} },
-{ 0x0076,	16,	{0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d} },
-{ 0x0086,	16,	{0x41, 0x12, 0x0d, 0x55, 0xc2, 0x02, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x32, 0x90, 0x7f, 0xc8} },
-{ 0x0096,	16,	{0xe0, 0x20, 0xe1, 0x2b, 0x12, 0x13, 0xc0, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x22, 0x90, 0x7d, 0xc0} },
-{ 0x00a6,	16,	{0xe0, 0x13, 0x92, 0x08, 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0xc1, 0x75} },
-{ 0x00b6,	16,	{0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x55, 0xd2, 0x02, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0x90} },
-{ 0x00c6,	16,	{0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x53, 0x53, 0x36, 0x80, 0x12, 0x13, 0xcc, 0xef} },
-{ 0x00d6,	16,	{0x42, 0x36, 0x12, 0x12, 0x49, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3a, 0x50, 0x0f, 0x12, 0x13, 0xa8} },
-{ 0x00e6,	16,	{0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0a, 0x61, 0xc2, 0x0a, 0xe5, 0x19} },
-{ 0x00f6,	16,	{0x70, 0x04, 0xf5, 0x36, 0x80, 0x57, 0x12, 0x13, 0xcc, 0xef, 0x42, 0x36, 0xe5, 0x36, 0x30, 0xe7} },
-{ 0x0106,	16,	{0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7e} },
-{ 0x0116,	16,	{0x7f, 0x80, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0xb7, 0xe5, 0x19, 0x25} },
-{ 0x0126,	16,	{0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19} },
-{ 0x0136,	16,	{0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x0c, 0x7e} },
-{ 0x0146,	16,	{0x75, 0x0d, 0x81, 0x12, 0x0d, 0x7a, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce} },
-{ 0x0156,	16,	{0xe0, 0x30, 0xe1, 0x06, 0x20, 0x04, 0x03, 0x02, 0x03, 0xbd, 0xc2, 0x04, 0xe4, 0xf5, 0x18, 0x74} },
-{ 0x0166,	16,	{0x40, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00} },
-{ 0x0176,	16,	{0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0c} },
-{ 0x0186,	16,	{0xe5, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68, 0x90, 0x7e} },
-{ 0x0196,	16,	{0x03, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x24, 0x7f, 0x03, 0x7d, 0xcd, 0x12} },
-{ 0x01a6,	16,	{0x12, 0x24, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46} },
-{ 0x01b6,	16,	{0xf0, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x10, 0xa8} },
-{ 0x01c6,	16,	{0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x10, 0xce, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12} },
-{ 0x01d6,	16,	{0x12, 0x24, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x24, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x01e6,	16,	{0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40} },
-{ 0x01f6,	16,	{0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x13, 0xe0} },
-{ 0x0206,	16,	{0x70, 0x08, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12} },
-{ 0x0216,	16,	{0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5} },
-{ 0x0226,	16,	{0x44, 0xf0, 0x90, 0x7e, 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x42, 0x80, 0x80} },
-{ 0x0236,	16,	{0x03, 0x53, 0x42, 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x42, 0x02} },
-{ 0x0246,	16,	{0xa3, 0xe0, 0xff, 0x12, 0x11, 0x1a, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x11, 0x40, 0xaf, 0x42} },
-{ 0x0256,	16,	{0x12, 0x10, 0xf4, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42, 0x12, 0x10} },
-{ 0x0266,	16,	{0xf4, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x02, 0x80, 0x03} },
-{ 0x0276,	16,	{0x53, 0x46, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90} },
-{ 0x0286,	16,	{0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03, 0x53, 0x46} },
-{ 0x0296,	16,	{0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x12} },
-{ 0x02a6,	16,	{0xe0, 0xf5, 0x3a, 0xa3, 0xe0, 0x13, 0x92, 0x0c, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3, 0xe0, 0x60, 0x05} },
-{ 0x02b6,	16,	{0x43, 0x46, 0x10, 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0} },
-{ 0x02c6,	16,	{0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90, 0x7f, 0x98} },
-{ 0x02d6,	16,	{0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11} },
-{ 0x02e6,	16,	{0xf0, 0x12, 0x13, 0x9c, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e, 0xfd, 0xe4, 0xff} },
-{ 0x02f6,	16,	{0xad, 0x3e, 0x12, 0x12, 0x24, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x06, 0x90, 0x7e, 0x17, 0xe0} },
-{ 0x0306,	16,	{0x60, 0x0f, 0x43, 0x3e, 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x12, 0x24, 0x75, 0x29, 0x01, 0xd2} },
-{ 0x0316,	16,	{0x06, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x1b, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44} },
-{ 0x0326,	16,	{0x04, 0x90, 0xc0, 0x00, 0xf0, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x02} },
-{ 0x0336,	16,	{0xc2, 0x08, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13} },
-{ 0x0346,	16,	{0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53} },
-{ 0x0356,	16,	{0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x12, 0x24, 0x75, 0x2b, 0x01, 0xd2, 0x06, 0x90, 0x7e} },
-{ 0x0366,	16,	{0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x12, 0x24, 0xe4, 0xf5} },
-{ 0x0376,	16,	{0x2b, 0xd2, 0x06, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5} },
-{ 0x0386,	16,	{0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0a, 0x90} },
-{ 0x0396,	16,	{0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4, 0xf5, 0x38, 0xd2, 0x06, 0x90, 0x7e, 0x1f} },
-{ 0x03a6,	16,	{0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74} },
-{ 0x03b6,	16,	{0x35, 0xf0, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x18, 0x52, 0xe5, 0x38, 0x60, 0x02, 0x15, 0x38} },
-{ 0x03c6,	16,	{0x20, 0x12, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13} },
-{ 0x03d6,	16,	{0x0a, 0x30, 0x19, 0x02, 0xd2, 0x12, 0x12, 0x13, 0x9c, 0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x2a} },
-{ 0x03e6,	16,	{0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x06, 0x12, 0x13, 0xd8, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65} },
-{ 0x03f6,	16,	{0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x06, 0x30, 0x0c, 0x11, 0x12, 0x13, 0xd8, 0xef, 0x54} },
-{ 0x0406,	16,	{0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19, 0x25, 0xd2, 0x06, 0x20, 0x19, 0x03, 0x02} },
-{ 0x0416,	16,	{0x07, 0xe4, 0x30, 0x09, 0x13, 0x12, 0x14, 0x2b, 0xef, 0xc3, 0x95, 0x3d, 0x50, 0x73, 0x90, 0x7f} },
-{ 0x0426,	16,	{0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0x80, 0x69, 0x30, 0x03, 0x34, 0x90, 0x7f, 0xca, 0xe0, 0x20} },
-{ 0x0436,	16,	{0xe1, 0x5f, 0x12, 0x14, 0x2b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x56, 0x90, 0x7d, 0x40, 0xe0, 0x13} },
-{ 0x0446,	16,	{0x92, 0x09, 0x90, 0x7f, 0xcb, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41, 0x75, 0x0c, 0x7d} },
-{ 0x0456,	16,	{0x75, 0x0d, 0x41, 0x12, 0x0d, 0x9f, 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x32, 0x90} },
-{ 0x0466,	16,	{0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x2b, 0x12, 0x14, 0x2b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x22, 0x90} },
-{ 0x0476,	16,	{0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7c, 0x7f} },
-{ 0x0486,	16,	{0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x9f, 0xd2, 0x03, 0xe4, 0x90, 0x7f, 0xcd} },
-{ 0x0496,	16,	{0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, 0x25, 0x53, 0x37, 0x80, 0x12, 0x14} },
-{ 0x04a6,	16,	{0x37, 0xef, 0x42, 0x37, 0x12, 0x12, 0x93, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3b, 0x50, 0x0f, 0x12} },
-{ 0x04b6,	16,	{0x14, 0x13, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x61, 0xc2, 0x0b} },
-{ 0x04c6,	16,	{0xe5, 0x19, 0x70, 0x04, 0xf5, 0x37, 0x80, 0x57, 0x12, 0x14, 0x37, 0xef, 0x42, 0x37, 0xe5, 0x37} },
-{ 0x04d6,	16,	{0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08} },
-{ 0x04e6,	16,	{0x7e, 0x7d, 0x7f, 0x80, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0xf0, 0xe5} },
-{ 0x04f6,	16,	{0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03} },
-{ 0x0506,	16,	{0x75, 0x19, 0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7d, 0x80, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75} },
-{ 0x0516,	16,	{0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12, 0x0d, 0xc4, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90} },
-{ 0x0526,	16,	{0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x05, 0x03, 0x02, 0x07, 0x8f, 0xc2, 0x05, 0xe4, 0xf5} },
-{ 0x0536,	16,	{0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18} },
-{ 0x0546,	16,	{0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef} },
-{ 0x0556,	16,	{0x12, 0x0c, 0xe5, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68} },
-{ 0x0566,	16,	{0x90, 0x7e, 0x23, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x6e, 0x7f, 0x03, 0x7d} },
-{ 0x0576,	16,	{0xcd, 0x12, 0x12, 0x6e, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00} },
-{ 0x0586,	16,	{0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12} },
-{ 0x0596,	16,	{0x11, 0x8c, 0x90, 0x7e, 0x22, 0xe0, 0xff, 0x12, 0x11, 0xb2, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0} },
-{ 0x05a6,	16,	{0xfd, 0x12, 0x12, 0x6e, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x6e, 0x43, 0x47, 0x80, 0x90, 0x7f} },
-{ 0x05b6,	16,	{0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0} },
-{ 0x05c6,	16,	{0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e} },
-{ 0x05d6,	16,	{0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0} },
-{ 0x05e6,	16,	{0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0} },
-{ 0x05f6,	16,	{0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e, 0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43} },
-{ 0x0606,	16,	{0x80, 0x80, 0x03, 0x53, 0x43, 0x7f, 0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43} },
-{ 0x0616,	16,	{0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x11, 0xd8, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0xfe} },
-{ 0x0626,	16,	{0xaf, 0x43, 0x12, 0x11, 0x66, 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf, 0x43} },
-{ 0x0636,	16,	{0x12, 0x11, 0x66, 0x90, 0x7e, 0x2c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02} },
-{ 0x0646,	16,	{0x80, 0x03, 0x53, 0x47, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47} },
-{ 0x0656,	16,	{0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03} },
-{ 0x0666,	16,	{0x53, 0x47, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90} },
-{ 0x0676,	16,	{0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3, 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0} },
-{ 0x0686,	16,	{0x60, 0x05, 0x43, 0x47, 0x10, 0x80, 0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0} },
-{ 0x0696,	16,	{0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90} },
-{ 0x06a6,	16,	{0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98} },
-{ 0x06b6,	16,	{0x74, 0x09, 0xf0, 0x12, 0x13, 0xf0, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd} },
-{ 0x06c6,	16,	{0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x07, 0x90, 0x7e} },
-{ 0x06d6,	16,	{0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e, 0x75, 0x32} },
-{ 0x06e6,	16,	{0x01, 0xd2, 0x07, 0x90, 0x7e, 0x38, 0xe0, 0x60, 0x1b, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5} },
-{ 0x06f6,	16,	{0x41, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x90, 0x7f, 0xcd, 0xf0} },
-{ 0x0706,	16,	{0xd2, 0x03, 0xc2, 0x09, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, 0x45, 0x40, 0x90, 0x7f, 0x98} },
-{ 0x0716,	16,	{0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3a, 0xe0, 0x60} },
-{ 0x0726,	16,	{0x0f, 0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e, 0x75, 0x34, 0x01, 0xd2, 0x07} },
-{ 0x0736,	16,	{0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e} },
-{ 0x0746,	16,	{0xe4, 0xf5, 0x34, 0xd2, 0x07, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x0a} },
-{ 0x0756,	16,	{0xf0, 0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3d, 0xe0, 0x60, 0x02, 0xd2} },
-{ 0x0766,	16,	{0x0b, 0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, 0xf5, 0x39, 0xd2, 0x07, 0x90} },
-{ 0x0776,	16,	{0x7e, 0x3f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16} },
-{ 0x0786,	16,	{0xf0, 0x74, 0x36, 0xf0, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0x30, 0x18, 0x52, 0xe5, 0x39, 0x60, 0x02} },
-{ 0x0796,	16,	{0x15, 0x39, 0x30, 0x12, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e} },
-{ 0x07a6,	16,	{0x75, 0x13, 0x0a, 0x30, 0x19, 0x02, 0xc2, 0x12, 0x12, 0x13, 0xf0, 0xef, 0x54, 0x01, 0xf5, 0x19} },
-{ 0x07b6,	16,	{0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2, 0x07, 0x12, 0x14, 0x43, 0xef, 0x54, 0x80, 0xf5} },
-{ 0x07c6,	16,	{0x19, 0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, 0x07, 0x30, 0x0d, 0x11, 0x12, 0x14, 0x43} },
-{ 0x07d6,	16,	{0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, 0x85, 0x19, 0x2e, 0xd2, 0x07, 0x30, 0x18} },
-{ 0x07e6,	16,	{0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5} },
-{ 0x07f6,	16,	{0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7} },
-{ 0x0806,	16,	{0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30} },
-{ 0x0816,	16,	{0xe1, 0x03, 0x02, 0x09, 0x18, 0xe5, 0x0a, 0x70, 0x40, 0x30, 0x06, 0x39, 0xe5, 0x38, 0x70, 0x35} },
-{ 0x0826,	16,	{0xc2, 0x06, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00} },
-{ 0x0836,	16,	{0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83} },
-{ 0x0846,	16,	{0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75} },
-{ 0x0856,	16,	{0x38, 0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30} },
-{ 0x0866,	16,	{0x07, 0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d} },
-{ 0x0876,	16,	{0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5} },
-{ 0x0886,	16,	{0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90} },
-{ 0x0896,	16,	{0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5} },
-{ 0x08a6,	16,	{0x0a, 0x64, 0x02, 0x70, 0x36, 0x30, 0x13, 0x2f, 0xc2, 0x13, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00} },
-{ 0x08b6,	16,	{0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25} },
-{ 0x08c6,	16,	{0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05} },
-{ 0x08d6,	16,	{0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15} },
-{ 0x08e6,	16,	{0x15, 0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00} },
-{ 0x08f6,	16,	{0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83} },
-{ 0x0906,	16,	{0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4} },
-{ 0x0916,	2,	{0xf5, 0x0a} },
-{ 0x0918,	1,	{0x22} },
-{ 0x0919,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0d, 0x2f, 0x09, 0xe9, 0x00, 0x0a, 0x5d, 0x01, 0x0a, 0xc9, 0x03} },
-{ 0x0929,	16,	{0x09, 0x3c, 0x06, 0x09, 0xdc, 0x08, 0x09, 0xd6, 0x09, 0x09, 0xbe, 0x0a, 0x09, 0xcd, 0x0b, 0x00} },
-{ 0x0939,	16,	{0x00, 0x0b, 0x18, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x40, 0x24, 0x02} },
-{ 0x0949,	16,	{0x70, 0x69, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b} },
-{ 0x0959,	16,	{0x1f, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, 0x27, 0x8b, 0x18, 0x8a, 0x19, 0x89, 0x1a, 0xea} },
-{ 0x0969,	16,	{0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5} },
-{ 0x0979,	16,	{0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f} },
-{ 0x0989,	16,	{0xea, 0xe0, 0xff, 0x12, 0x0f, 0x76, 0x8b, 0x18, 0x8a, 0x19, 0x89, 0x1a, 0xea, 0x49, 0x60, 0x11} },
-{ 0x0999,	16,	{0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b} },
-{ 0x09a9,	16,	{0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44} },
-{ 0x09b9,	16,	{0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01} },
-{ 0x09c9,	16,	{0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x1f, 0x12, 0x0b, 0x27} },
-{ 0x09d9,	16,	{0x02, 0x0b, 0x1f, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x0b, 0x1f} },
-{ 0x09e9,	16,	{0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2} },
-{ 0x09f9,	16,	{0x0f, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x14, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0} },
-{ 0x0a09,	16,	{0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x1f, 0xe4, 0x90, 0x7f, 0x00} },
-{ 0x0a19,	16,	{0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xec, 0xe0} },
-{ 0x0a29,	16,	{0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} },
-{ 0x0a39,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3} },
-{ 0x0a49,	16,	{0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01} },
-{ 0x0a59,	16,	{0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03} },
-{ 0x0a69,	16,	{0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x0f, 0x02, 0x0b, 0x1f, 0x90} },
-{ 0x0a79,	16,	{0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90} },
-{ 0x0a89,	16,	{0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25} },
-{ 0x0a99,	16,	{0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0} },
-{ 0x0aa9,	16,	{0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7} },
-{ 0x0ab9,	16,	{0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56} },
-{ 0x0ac9,	16,	{0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0} },
-{ 0x0ad9,	16,	{0xb4, 0x01, 0x04, 0xd2, 0x0f, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36} },
-{ 0x0ae9,	16,	{0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54} },
-{ 0x0af9,	16,	{0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
-{ 0x0b09,	16,	{0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90} },
-{ 0x0b19,	13,	{0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
-{ 0x0b26,	1,	{0x22} },
-{ 0x0b27,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x18, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
-{ 0x0b37,	16,	{0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0b47,	16,	{0x18, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4} },
-{ 0x0b57,	16,	{0xf5, 0x24, 0x75, 0x1b, 0x01, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x1b, 0xf9, 0xe4, 0x34, 0x00, 0xfa} },
-{ 0x0b67,	16,	{0xe4, 0x12, 0x0c, 0xe5, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, 0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5} },
-{ 0x0b77,	16,	{0x38, 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x06, 0xc2, 0x0a, 0xc2, 0x04, 0xc2, 0x08, 0xc2, 0x12, 0xd2} },
-{ 0x0b87,	16,	{0x02, 0xd2, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74} },
-{ 0x0b97,	16,	{0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12, 0x24, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0xf4} },
-{ 0x0ba7,	16,	{0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00} },
-{ 0x0bb7,	16,	{0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0} },
-{ 0x0bc7,	16,	{0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x24, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x12} },
-{ 0x0bd7,	16,	{0x24, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f} },
-{ 0x0be7,	16,	{0x12, 0x12, 0x24, 0x7f, 0x01, 0x12, 0x13, 0x27, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x24, 0x20} },
-{ 0x0bf7,	16,	{0x19, 0x03, 0x02, 0x0c, 0x9c, 0x75, 0x2d, 0x01, 0x75, 0x1b, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25} },
-{ 0x0c07,	16,	{0x1b, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0c, 0xe5, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, 0x09} },
-{ 0x0c17,	16,	{0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5, 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x07, 0xc2, 0x0b, 0xc2} },
-{ 0x0c27,	16,	{0x05, 0xc2, 0x09, 0xc2, 0x12, 0xd2, 0x03, 0xd2, 0x01, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75} },
-{ 0x0c37,	16,	{0x45, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12, 0x6e, 0x7f} },
-{ 0x0c47,	16,	{0x10, 0x8f, 0x43, 0x12, 0x11, 0x66, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41} },
-{ 0x0c57,	16,	{0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80} },
-{ 0x0c67,	16,	{0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x6e, 0xe4, 0xff, 0x7e, 0xa3} },
-{ 0x0c77,	16,	{0xad, 0x06, 0x8d, 0x3f, 0x12, 0x12, 0x6e, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00} },
-{ 0x0c87,	16,	{0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x12, 0x6e, 0x7f, 0x01, 0x12, 0x13, 0x48, 0x7f, 0x03} },
-{ 0x0c97,	7,	{0x7d, 0x07, 0x12, 0x12, 0x6e, 0xd2, 0x11} },
-{ 0x0c9e,	1,	{0x22} },
-{ 0x0c9f,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x0caf,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x0cb8,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x0cc8,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x0cd8,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x0ce5,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} },
-{ 0x0cf5,	2,	{0xf3, 0x22} },
-{ 0x0cf7,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0x0d07,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0x0d17,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0x0d27,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0x0d2f,	16,	{0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} },
-{ 0x0d3f,	16,	{0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} },
-{ 0x0d4f,	6,	{0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} },
-{ 0x0d55,	16,	{0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83} },
-{ 0x0d65,	16,	{0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86} },
-{ 0x0d75,	16,	{0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5} },
-{ 0x0d85,	16,	{0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0} },
-{ 0x0d95,	16,	{0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0} },
-{ 0x0da5,	16,	{0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0} },
-{ 0x0db5,	16,	{0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90} },
-{ 0x0dc5,	16,	{0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2} },
-{ 0x0dd5,	16,	{0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05} },
-{ 0x0de5,	4,	{0x86, 0xd2, 0xaf, 0x22} },
-{ 0x0de9,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x0df9,	1,	{0x22} },
-{ 0x0dfa,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x0e0a,	16,	{0xd2, 0x17, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92} },
-{ 0x0e1a,	16,	{0x0f, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74} },
-{ 0x0e2a,	16,	{0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0} },
-{ 0x0e3a,	16,	{0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f} },
-{ 0x0e4a,	16,	{0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x18, 0x12, 0x13, 0x02, 0xc2, 0x10, 0xe4, 0xf5} },
-{ 0x0e5a,	16,	{0x0b, 0xf5, 0x13, 0xc2, 0x15, 0xc2, 0x11, 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0} },
-{ 0x0e6a,	16,	{0x65, 0x17, 0x60, 0x10, 0x30, 0x11, 0x05, 0xd2, 0x18, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0} },
-{ 0x0e7a,	16,	{0xf5, 0x17, 0x80, 0x08, 0x30, 0x11, 0x05, 0xc2, 0x18, 0x12, 0x00, 0x46, 0x30, 0x10, 0x07, 0xc2} },
-{ 0x0e8a,	16,	{0x10, 0x12, 0x09, 0x19, 0x80, 0xd6, 0x30, 0x16, 0xd3, 0xc2, 0x16, 0x12, 0x14, 0x4f, 0x80, 0xcc} },
-{ 0x0e9a,	1,	{0x22} },
-{ 0x0e9b,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x47, 0x02, 0x0e, 0xe2} },
-{ 0x0ea7,	16,	{0x02, 0x0e, 0x0a, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x0eb7,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x0ec7,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x0ed7,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x13, 0x69, 0xe4, 0x7e} },
-{ 0x0ee7,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x0ef7,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x0f07,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x0f17,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x0f27,	16,	{0xe4, 0xfe, 0x75, 0x1d, 0xff, 0x75, 0x1e, 0x19, 0x75, 0x1f, 0x12, 0xab, 0x1d, 0xaa, 0x1e, 0xa9} },
-{ 0x0f37,	16,	{0x1f, 0x90, 0x00, 0x01, 0x12, 0x0c, 0xb8, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x0f47,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x0c, 0xf7, 0x85, 0xf0, 0x1b, 0xf5, 0x1c, 0x62, 0x1b} },
-{ 0x0f57,	16,	{0xe5, 0x1b, 0x62, 0x1c, 0xe5, 0x1c, 0x62, 0x1b, 0x29, 0xfd, 0xe5, 0x1b, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x0f67,	14,	{0x1d, 0xff, 0xf5, 0x1e, 0x89, 0x1f, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0f75,	1,	{0x22} },
-{ 0x0f76,	2,	{0x8f, 0x1b} },
-{ 0x0f78,	16,	{0xe4, 0xf5, 0x1c, 0x75, 0x1d, 0xff, 0x75, 0x1e, 0x19, 0x75, 0x1f, 0x86, 0xab, 0x1d, 0xaa, 0x1e} },
-{ 0x0f88,	16,	{0xa9, 0x1f, 0x90, 0x00, 0x01, 0x12, 0x0c, 0xb8, 0xb4, 0x03, 0x1d, 0xaf, 0x1c, 0x05, 0x1c, 0xef} },
-{ 0x0f98,	16,	{0xb5, 0x1b, 0x01, 0x22, 0x12, 0x0c, 0x9f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0fa8,	14,	{0x1d, 0xff, 0xf5, 0x1e, 0x89, 0x1f, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0fb6,	1,	{0x22} },
-{ 0x0fb7,	16,	{0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e} },
-{ 0x0fc7,	16,	{0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05} },
-{ 0x0fd7,	16,	{0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13} },
-{ 0x0fe7,	9,	{0xcc, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22} },
-{ 0x0ff0,	16,	{0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e} },
-{ 0x1000,	16,	{0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x13, 0xe4, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05} },
-{ 0x1010,	16,	{0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x14} },
-{ 0x1020,	9,	{0x37, 0x8f, 0x1a, 0xef, 0x42, 0x37, 0x80, 0xca, 0x22} },
-{ 0x1029,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} },
-{ 0x1039,	16,	{0x1a, 0x04, 0xc2, 0x1a, 0x80, 0x02, 0xd2, 0x16, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} },
-{ 0x1049,	14,	{0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1057,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} },
-{ 0x1067,	16,	{0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} },
-{ 0x1077,	10,	{0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1081,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} },
-{ 0x1091,	16,	{0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} },
-{ 0x10a1,	7,	{0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x10a8,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x10b8,	16,	{0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x10c8,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x10ce,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x10de,	16,	{0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x10ee,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x10f4,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1104,	16,	{0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x1114,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x111a,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x112a,	16,	{0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x113a,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x1140,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1150,	16,	{0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x1160,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x1166,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1176,	16,	{0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x1186,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x118c,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x119c,	16,	{0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x11ac,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x11b2,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x11c2,	16,	{0x09, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x11d2,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x11d8,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x11e8,	16,	{0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x11f8,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x11fe,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x120e,	16,	{0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x121e,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x1224,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f} },
-{ 0x1234,	16,	{0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90} },
-{ 0x1244,	5,	{0xc0, 0x00, 0xed, 0xf0, 0x22} },
-{ 0x1249,	16,	{0x12, 0x13, 0xb4, 0x8f, 0x1a, 0x12, 0x13, 0xb4, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12} },
-{ 0x1259,	16,	{0x12, 0x13, 0xb4, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0xb4, 0x8f, 0x1b} },
-{ 0x1269,	4,	{0x80, 0xe8, 0xaf, 0x1a} },
-{ 0x126d,	1,	{0x22} },
-{ 0x126e,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f} },
-{ 0x127e,	16,	{0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90} },
-{ 0x128e,	5,	{0xc0, 0x00, 0xed, 0xf0, 0x22} },
-{ 0x1293,	16,	{0x12, 0x14, 0x1f, 0x8f, 0x1a, 0x12, 0x14, 0x1f, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12} },
-{ 0x12a3,	16,	{0x12, 0x14, 0x1f, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x14, 0x1f, 0x8f, 0x1b} },
-{ 0x12b3,	4,	{0x80, 0xe8, 0xaf, 0x1a} },
-{ 0x12b7,	1,	{0x22} },
-{ 0x12b8,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x12c8,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x12d8,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x12dd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x12ed,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x12fd,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1302,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x18, 0x04, 0xe0, 0x44} },
-{ 0x1312,	16,	{0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x13, 0x85, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x1322,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x1327,	16,	{0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x24, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1337,	16,	{0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80, 0xfd, 0x12, 0x12, 0x24} },
-{ 0x1347,	1,	{0x22} },
-{ 0x1348,	16,	{0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x6e, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1358,	16,	{0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, 0xfd, 0x12, 0x12, 0x6e} },
-{ 0x1368,	1,	{0x22} },
-{ 0x1369,	16,	{0x05, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, 0x00, 0xc1, 0x10, 0xc1, 0x16} },
-{ 0x1379,	7,	{0xc1, 0x0f, 0xc1, 0x94, 0x01, 0x0a, 0x00} },
-{ 0x1380,	2,	{0xc1, 0x19} },
-{ 0x1382,	2,	{0xc1, 0x9a} },
-{ 0x1384,	1,	{0x00} },
-{ 0x1385,	16,	{0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, 0x60} },
-{ 0x1395,	7,	{0x05, 0x12, 0x0d, 0xe9, 0x80, 0xee, 0x22} },
-{ 0x139c,	12,	{0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13a8,	12,	{0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13b4,	12,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13c0,	12,	{0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13cc,	12,	{0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13d8,	12,	{0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13e4,	12,	{0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13f0,	12,	{0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13fc,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x1400,	16,	{0x02, 0x10, 0x81, 0x00, 0x02, 0x12, 0xb8, 0x00, 0x02, 0x10, 0x57, 0x00, 0x02, 0x10, 0x29, 0x00} },
-{ 0x1410,	3,	{0x02, 0x12, 0xdd} },
-{ 0x1413,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x141f,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x142b,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x1437,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x1443,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x144f,	10,	{0x12, 0x00, 0x03, 0x12, 0x0d, 0xfa, 0x12, 0x0b, 0x27, 0x22} },
-{ 0x1900,	16,	{0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x12, 0x01, 0x00, 0x00, 0x01, 0x02} },
-{ 0x1910,	16,	{0x00, 0x01, 0x09, 0x02, 0x74, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e} },
-{ 0x1920,	16,	{0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} },
-{ 0x1930,	16,	{0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00} },
-{ 0x1940,	16,	{0x07, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} },
-{ 0x1950,	16,	{0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02} },
-{ 0x1960,	16,	{0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00} },
-{ 0x1970,	16,	{0x00, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07} },
-{ 0x1980,	16,	{0x05, 0x87, 0x02, 0x40, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00} },
-{ 0x1990,	16,	{0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00} },
-{ 0x19a0,	16,	{0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00} },
-{ 0x19b0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00} },
-{ 0x19c0,	16,	{0x6f, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} },
-{ 0x19d0,	16,	{0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00} },
-{ 0x19e0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00} },
-{ 0x19f0,	16,	{0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00} },
-{ 0x1a00,	10,	{0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00} },
-{ 0xffff,	0,	{0x00} }
+ {0x0033,  3, { 0x02, 0x13, 0xab}},
+ {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}},
+ {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}},
+ {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}},
+ {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x33, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}},
+ {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}},
+ {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x33, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}},
+ {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}},
+ {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xca}},
+ {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}},
+ {0x00a6, 16, { 0x12, 0x13, 0x33, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}},
+ {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}},
+ {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xca, 0xd2, 0x03, 0xe4, 0x90, 0x7f}},
+ {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x66, 0x53, 0x36, 0x80, 0x12}},
+ {0x00e6, 16, { 0x13, 0x3f, 0xef, 0x42, 0x36, 0x12, 0x11, 0xed, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3a, 0x50, 0x0f}},
+ {0x00f6, 16, { 0x12, 0x13, 0x1b, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x61, 0xc2}},
+ {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}},
+ {0x0043,  3, { 0x02, 0x13, 0x00}},
+ {0x0000,  3, { 0x02, 0x0e, 0x10}},
+ {0x0106, 64, { 0x0b, 0xe5, 0x19, 0x70, 0x04, 0xf5, 0x36, 0x80, 0x57, 0x12, 0x13, 0x3f, 0xef, 0x42, 0x36, 0xe5, 0x36,
+  0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08,
+  0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x5b, 0xe5,
+  0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40}},
+ {0x0146, 64, { 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75,
+  0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, 0x0c, 0xef, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90,
+  0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x05, 0x03, 0x02, 0x03, 0xc5, 0xc2, 0x05, 0xe4, 0xf5,
+  0x18, 0x74, 0x40, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5}},
+ {0x0186, 64, { 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef,
+  0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68,
+  0x90, 0x7e, 0x03, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xc8, 0x7f, 0x03, 0x7d,
+  0xcd, 0x12, 0x11, 0xc8, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0}},
+ {0x01c6, 64, { 0x00, 0xe5, 0x46, 0xf0, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12,
+  0x10, 0x4c, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x10, 0x72, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0,
+  0xfd, 0x12, 0x11, 0xc8, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xc8, 0x43, 0x46, 0x80, 0x90, 0x7f,
+  0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12}},
+ {0x0206, 64, { 0xf0, 0xe5, 0x40, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e,
+  0x13, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0,
+  0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x44, 0xf0, 0x90, 0x7e, 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43}},
+ {0x0246, 64, { 0x42, 0x80, 0x80, 0x03, 0x53, 0x42, 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43,
+  0x42, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x10, 0xbe, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xe4,
+  0xaf, 0x42, 0x12, 0x10, 0x98, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42,
+  0x12, 0x10, 0x98, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46}},
+ {0x0286, 64, { 0x02, 0x80, 0x03, 0x53, 0x46, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46,
+  0xf0, 0x90, 0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03,
+  0x53, 0x46, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90,
+  0x7e, 0x12, 0xe0, 0xf5, 0x3a, 0xa3, 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3}},
+ {0x02c6, 64, { 0xe0, 0x60, 0x05, 0x43, 0x46, 0x10, 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0,
+  0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90,
+  0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x11, 0xf0, 0x12, 0x13, 0x0f, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e}},
+ {0x0306, 64, { 0xfd, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xc8, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e,
+  0x17, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xc8, 0x75, 0x29,
+  0x01, 0xd2, 0x07, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5,
+  0x40, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11}},
+ {0x0346, 64, { 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0,
+  0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53, 0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xc8,
+  0x75, 0x2b, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff,
+  0xad, 0x3e, 0x12, 0x11, 0xc8, 0xe4, 0xf5, 0x2b, 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60}},
+ {0x0386, 64, { 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e,
+  0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0b, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4,
+  0xf5, 0x38, 0xd2, 0x07, 0x90, 0x7e, 0x1f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0,
+  0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35, 0xf0, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30}},
+ {0x03c6, 64, { 0x1a, 0x52, 0xe5, 0x38, 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40,
+  0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x13, 0x0f,
+  0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13,
+  0x4b, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x07}},
+ {0x0406, 64, { 0x30, 0x0d, 0x11, 0x12, 0x13, 0x4b, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19,
+  0x25, 0xd2, 0x07, 0x20, 0x1b, 0x03, 0x02, 0x07, 0xf4, 0x30, 0x0a, 0x18, 0x12, 0x13, 0x87, 0xef,
+  0xc3, 0x95, 0x3d, 0x40, 0x03, 0x02, 0x04, 0xb2, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x0a,
+  0xc2, 0x00, 0x80, 0x77, 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x6d, 0x12}},
+ {0x0446, 64, { 0x13, 0x87, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f,
+  0xcb, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41,
+  0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x41, 0x12, 0x0d, 0x14, 0xc2, 0x04, 0xe4, 0x90, 0x7f, 0xcb, 0xf0,
+  0x80, 0x39, 0x90, 0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x87, 0xef, 0xc3, 0x94}},
+ {0x0486, 64, { 0x40, 0x50, 0x29, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x19,
+  0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d,
+  0xc1, 0x12, 0x0d, 0x14, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30,
+  0xe1, 0x03, 0x02, 0x05, 0x40, 0x53, 0x37, 0x80, 0x12, 0x13, 0x93, 0xef, 0x42, 0x37, 0x12}},
+ {0x04c6, 64, { 0x12, 0x37, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x6f, 0xef, 0x30, 0xe0, 0x08,
+  0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0c, 0x61, 0xc2, 0x0c, 0xe5, 0x19, 0x70, 0x04, 0xf5, 0x37,
+  0x80, 0x57, 0x12, 0x13, 0x93, 0xef, 0x42, 0x37, 0xe5, 0x37, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3,
+  0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7d, 0x7f, 0x80, 0x75}},
+ {0x0506, 64, { 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0x94, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb,
+  0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08,
+  0xe4, 0x90, 0x7d, 0x80, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12,
+  0x0d, 0x39, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90, 0x7f, 0xd0, 0xe0, 0x30, 0xe1}},
+ {0x0546, 64, { 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0x9f, 0xc2, 0x06, 0xe4, 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5,
+  0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e,
+  0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5,
+  0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x23, 0xe0, 0x60}},
+ {0x0586, 64, { 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x12, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x12, 0x12, 0x43, 0x47,
+  0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e,
+  0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, 0x11, 0x30, 0x90, 0x7e, 0x22, 0xe0,
+  0xff, 0x12, 0x11, 0x56, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, 0xfd, 0x12, 0x12, 0x12, 0x7f}},
+ {0x05c6, 64, { 0x03, 0x7d, 0x07, 0x12, 0x12, 0x12, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0,
+  0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90,
+  0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54}},
+ {0x0606, 64, { 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e,
+  0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f,
+  0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12,
+  0x11, 0x7c, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0xa2, 0xaf, 0x43, 0x12, 0x11, 0x0a}},
+ {0x0646, 64, { 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf, 0x43, 0x12, 0x11, 0x0a, 0x90, 0x7e, 0x2c,
+  0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90,
+  0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60,
+  0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, 0x53, 0x47, 0xfe, 0x90, 0x7f}},
+ {0x0686, 64, { 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3,
+  0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x10, 0x80,
+  0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0,
+  0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0}},
+ {0x06c6, 64, { 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x63,
+  0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12,
+  0x12, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f,
+  0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x12, 0x75, 0x32, 0x01, 0xd2, 0x08, 0x90, 0x7e}},
+ {0x0706, 64, { 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00,
+  0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74,
+  0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f,
+  0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x12, 0x75, 0x34, 0x01, 0xd2, 0x08}},
+ {0x0746, 64, { 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x12, 0xe4,
+  0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0,
+  0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c,
+  0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, 0xf5, 0x39, 0xd2, 0x08, 0x90}},
+ {0x0786, 64, { 0x7e, 0x3f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0,
+  0x74, 0x36, 0xf0, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0x30, 0x1a, 0x52, 0xe5, 0x39, 0x60, 0x02, 0x15,
+  0x39, 0x30, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75,
+  0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, 0x13, 0x12, 0x13, 0x63, 0xef, 0x54, 0x01, 0xf5, 0x19}},
+ {0x07c6, 64, { 0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2, 0x08, 0x12, 0x13, 0x9f, 0xef, 0x54, 0x80, 0xf5, 0x19,
+  0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, 0x08, 0x30, 0x0e, 0x11, 0x12, 0x13, 0x9f, 0xef,
+  0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, 0x85, 0x19, 0x2e, 0xd2, 0x08, 0x30, 0x1a, 0x2a,
+  0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5}},
+ {0x0806, 64, { 0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74,
+  0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1,
+  0x03, 0x02, 0x09, 0x28, 0xe5, 0x0a, 0x70, 0x40, 0x30, 0x07, 0x39, 0xe5, 0x38, 0x70, 0x35, 0xc2,
+  0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}},
+ {0x0846, 64, { 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef,
+  0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x38,
+  0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30, 0x08,
+  0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x08, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d}},
+ {0x0886, 64, { 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82,
+  0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f,
+  0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5, 0x0a,
+  0x64, 0x02, 0x70, 0x36, 0x30, 0x14, 0x2f, 0xc2, 0x14, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00}},
+ {0x08c6, 64, { 0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18,
+  0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05, 0xdb,
+  0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15, 0x15,
+  0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}},
+ {0x0906, 64, { 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef,
+  0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5,
+  0x0a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0e, 0xf4, 0x0a, 0x10, 0x00, 0x0a, 0x84, 0x01, 0x0a,
+  0xf0, 0x03, 0x09, 0x4c, 0x06, 0x0a, 0x03, 0x08, 0x09, 0xfd, 0x09, 0x09, 0xe5, 0x0a, 0x09}},
+ {0x0946, 64, { 0xf4, 0x0b, 0x00, 0x00, 0x0b, 0x3f, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x61,
+  0x24, 0x02, 0x60, 0x03, 0x02, 0x09, 0xdb, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90,
+  0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02,
+  0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x7b, 0x75, 0x83}},
+ {0x0986, 64, { 0x19, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75,
+  0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83,
+  0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b,
+  0x46, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, 0x1a, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90}},
+ {0x09c6, 64, { 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01,
+  0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f,
+  0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea,
+  0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x46, 0x12, 0x0b, 0x4e, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0x00}},
+ {0x0a06, 64, { 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60,
+  0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff,
+  0xa2, 0x16, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74,
+  0x02, 0xf0, 0x02, 0x0b, 0x46, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5}},
+ {0x0a46, 64, { 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f,
+  0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83,
+  0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0,
+  0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f}},
+ {0x0a86, 64, { 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0,
+  0xb4, 0x01, 0x05, 0xc2, 0x10, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02,
+  0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff,
+  0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4}},
+ {0x0ac6, 64, { 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54,
+  0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f,
+  0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60,
+  0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x10, 0x80}},
+ {0x0b06, 64, { 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90,
+  0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25,
+  0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90,
+  0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}},
+ {0x0b46, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74,
+  0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e,
+  0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74,
+  0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, 0x24, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74}},
+ {0x0b86, 64, { 0x24, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5, 0x18, 0xb4,
+  0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5, 0x38, 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x07, 0xc2, 0x0b,
+  0xc2, 0x05, 0xc2, 0x00, 0xc2, 0x09, 0xc2, 0x13, 0xd2, 0x03, 0xd2, 0x01, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd}},
+ {0x0bc6, 64, { 0x12, 0x11, 0xc8, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0x98, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x7f,
+  0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0,
+  0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x11, 0xc8, 0xe4,
+  0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x11, 0xc8, 0x90, 0x7f, 0x98, 0x74, 0x11}},
+ {0x0c06, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x11, 0xc8, 0x7f, 0x01, 0x12, 0x12,
+  0x81, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xc8, 0x20, 0x1b, 0x03, 0x02, 0x0c, 0xc7, 0x75, 0x2d,
+  0x01, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4,
+  0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5}},
+ {0x0c46, 64, { 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x08, 0xc2, 0x0c, 0xc2, 0x06, 0xc2, 0x00, 0xc2, 0x0a, 0xc2, 0x13,
+  0xd2, 0x04, 0xd2, 0x02, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00,
+  0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12, 0x12, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x11,
+  0x0a, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90}},
+ {0x0c86, 64, { 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80,
+  0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x12, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12,
+  0x12, 0x12, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d,
+  0x7f, 0x12, 0x12, 0x12, 0x7f, 0x01, 0x12, 0x12, 0xa2, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12}},
+ {0x0cc6, 64, { 0x12, 0xd2, 0x12, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5,
+  0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86,
+  0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08,
+  0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00}},
+ {0x0d06, 64, { 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05,
+  0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2,
+  0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5}},
+ {0x0d46, 64, { 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86,
+  0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05,
+  0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43,
+  0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92, 0xe0, 0x44}},
+ {0x0d86, 64, { 0x02, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2,
+  0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f,
+  0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90,
+  0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf}},
+ {0x0dc6, 64, { 0xd2, 0x1a, 0x12, 0x12, 0x5c, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2, 0x12, 0x90,
+  0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12, 0x05, 0xd2,
+  0x1a, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30, 0x12, 0x05, 0xc2,
+  0x1a, 0x12, 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x29, 0x80, 0xd6, 0x30}},
+ {0x0e06, 64, { 0x18, 0xd3, 0xc2, 0x18, 0x12, 0x12, 0xf6, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75,
+  0x81, 0x47, 0x02, 0x0e, 0x57, 0x02, 0x0d, 0x7f, 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}},
+ {0x0e46, 64, { 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+  0x90, 0x12, 0xc3, 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}},
+ {0x0e86, 64, { 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf,
+  0xe9, 0xde, 0xe7, 0x80, 0xbe, 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}},
+ {0x0ec6, 64, { 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, 0xd0, 0x83, 0xd0,
+  0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8}},
+ {0x0f06, 64, { 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3,
+  0xa3, 0x80, 0xdf, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19, 0x75, 0x1c,
+  0x86, 0xab, 0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xb5, 0xb4, 0x03, 0x1d,
+  0xaf, 0x19, 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0x9c, 0x7e, 0x00, 0x29}},
+ {0x0f46, 64, { 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b, 0x00, 0x7a,
+  0x00, 0x79, 0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c,
+  0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac,
+  0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5}},
+ {0x0f86, 64, { 0x08, 0x60, 0x0a, 0x12, 0x13, 0x3f, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f, 0x1a, 0x05,
+  0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a,
+  0xf0, 0x12, 0x13, 0x57, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5,
+  0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x93, 0x8f}},
+ {0x0fc6, 64, { 0x1a, 0xef, 0x42, 0x37, 0x80, 0xca, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84,
+  0xc0, 0x86, 0x75, 0x86, 0x00, 0x30, 0x15, 0x04, 0xc2, 0x15, 0x80, 0x02, 0xd2, 0x18, 0x53, 0x91,
+  0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0,
+  0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0}},
+ {0x1006, 64, { 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04,
+  0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0,
+  0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x11, 0x53,
+  0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0}},
+ {0x1046, 64, { 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf,
+  0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13,
+  0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0}},
+ {0x1086, 64, { 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0,
+  0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44,
+  0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0}},
+ {0x10c6, 64, { 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f,
+  0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90,
+  0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90}},
+ {0x1106, 64, { 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90,
+  0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0,
+  0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90,
+  0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef}},
+ {0x1146, 64, { 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90,
+  0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09,
+  0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f,
+  0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74}},
+ {0x1186, 64, { 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74,
+  0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b,
+  0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00,
+  0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00}},
+ {0x11c6, 64, { 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90,
+  0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0,
+  0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x27, 0x8f, 0x1a, 0x12, 0x13, 0x27, 0x8f, 0x1b,
+  0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x27, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b}},
+ {0x1206, 64, { 0x60, 0x07, 0x12, 0x13, 0x27, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b,
+  0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90,
+  0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22,
+  0x12, 0x13, 0x7b, 0x8f, 0x1a, 0x12, 0x13, 0x7b, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60}},
+ {0x1246, 64, { 0x12, 0x12, 0x13, 0x7b, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x7b, 0x8f, 0x1b,
+  0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0,
+  0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x12, 0xdf, 0x90, 0x7f,
+  0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5}},
+ {0x1286, 64, { 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xc8, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee,
+  0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80, 0xfd, 0x12, 0x11, 0xc8, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5,
+  0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x12, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00,
+  0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, 0xfd, 0x12, 0x12, 0x12, 0x22, 0x05, 0x0e, 0x02}},
+ {0x12c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, 0x00, 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10,
+  0xc1, 0x16, 0x01, 0x0a, 0x00, 0xc1, 0x1b, 0x00, 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19,
+  0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, 0x60, 0x05, 0x12, 0x0d, 0x5e, 0x80, 0xee, 0x22, 0x12,
+  0x00, 0x03, 0x12, 0x0d, 0x6f, 0x12, 0x0b, 0x4e, 0x22, 0x02, 0x10, 0x25, 0x00, 0x02, 0x13}},
+ {0x1306, 64, { 0x04, 0x00, 0x02, 0x0f, 0xfb, 0x00, 0x02, 0x0f, 0xcd, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0,
+  0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22,
+  0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90}},
+ {0x1346, 64, { 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22,
+  0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0,
+  0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff}},
+ {0x1386, 64, { 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0,
+  0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x01, 0xff, 0x00}},
+ {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x12, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65,
+  0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53,
+  0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c,
+  0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}},
+ {0x1a06, 20, { 0x72, 0x00, 0x10, 0x03, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30,
+  0x00, 0x00, 0x00}},
+ { 0xffff,	0,	{0x00} }
 };
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa19_fw.h linux/drivers/usb/serial/keyspan_usa19_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa19_fw.h	Mon Jul 10 14:33:04 2000
+++ linux/drivers/usb/serial/keyspan_usa19_fw.h	Tue Oct  9 15:15:02 2001
@@ -1,10 +1,10 @@
 /* keyspan_usa19_fw.h
   
-   Generated from Keyspan firmware image Wed Jul  5 09:18:29 2000 EST
+   Generated from Keyspan firmware image usa19code.h Sat Oct  6 12:14:44 EST 2001
    This firmware is for the Keyspan USA-19 Serial Adaptor
 
    "The firmware contained herein as keyspan_usa19_fw.h is
-   Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
    ("Keyspan"), as an unpublished work.  This notice does not imply
    unrestricted or public access to this firmware which is a trade secret of
    Keyspan, and which may not be reproduced, used, sold or transferred to any
@@ -18,282 +18,263 @@
 */
 
 static const struct ezusb_hex_record keyspan_usa19_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x0b, 0x82} },
-{ 0x0003,	16,	{0x8e, 0x13, 0x8f, 0x14, 0xe5, 0x14, 0x15, 0x14, 0xae, 0x13, 0x70, 0x02, 0x15, 0x13, 0x4e, 0x60} },
-{ 0x0013,	7,	{0x05, 0x12, 0x0f, 0x38, 0x80, 0xee, 0x22} },
-{ 0x001a,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x0023,	3,	{0x02, 0x00, 0x46} },
-{ 0x0026,	10,	{0x12, 0x0d, 0xac, 0x12, 0x0f, 0x49, 0x12, 0x0d, 0x08, 0x22} },
-{ 0x0033,	3,	{0x02, 0x00, 0x1a} },
-{ 0x0043,	3,	{0x02, 0x0f, 0x00} },
-{ 0x0046,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08} },
-{ 0x0056,	16,	{0x30, 0x99, 0x0e, 0x30, 0x06, 0x07, 0xa2, 0x09, 0x92, 0x9b, 0x85, 0x35, 0x99, 0xc2, 0x99, 0xd2} },
-{ 0x0066,	16,	{0x0d, 0x20, 0x0d, 0x03, 0x02, 0x04, 0x25, 0xc2, 0x0d, 0x20, 0x01, 0x03, 0x02, 0x02, 0x50, 0x20} },
-{ 0x0076,	16,	{0x06, 0x03, 0x02, 0x01, 0x27, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x3e, 0x20, 0x07, 0x36, 0x20} },
-{ 0x0086,	16,	{0x04, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0c, 0x29, 0x30, 0x0b, 0x12, 0xaf} },
-{ 0x0096,	16,	{0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92} },
-{ 0x00a6,	16,	{0x09, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0} },
-{ 0x00b6,	16,	{0xf5, 0x35, 0x02, 0x04, 0x23, 0xc2, 0x06, 0x02, 0x04, 0x23, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2} },
-{ 0x00c6,	16,	{0x01, 0x30, 0x08, 0x0c, 0xc2, 0x08, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0xc2, 0x06, 0x02, 0x04, 0x23} },
-{ 0x00d6,	16,	{0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x06, 0x02, 0x04, 0x23, 0x90, 0x7f, 0xc9, 0xe0} },
-{ 0x00e6,	16,	{0xf5, 0x50, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x08, 0x20, 0x07, 0x2d, 0x20, 0x04, 0x2a, 0x90} },
-{ 0x00f6,	16,	{0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0c, 0x20, 0x30, 0x0b, 0x11, 0x90, 0x7d, 0xc1, 0xe0} },
-{ 0x0106,	16,	{0x13, 0x92, 0x09, 0xa3, 0xe0, 0xf5, 0x35, 0x75, 0x37, 0x03, 0x02, 0x04, 0x23, 0x75, 0x37, 0x02} },
-{ 0x0116,	16,	{0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x35, 0x02, 0x04, 0x23, 0x75, 0x37, 0x01, 0xc2, 0x06, 0x02, 0x04} },
-{ 0x0126,	16,	{0x23, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x03, 0x02, 0x01, 0xc9, 0x90, 0x7f, 0xc6, 0xe0, 0x30} },
-{ 0x0136,	16,	{0xe1, 0x07, 0xc2, 0x0f, 0xd2, 0x0e, 0x02, 0x04, 0x23, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x50, 0x90} },
-{ 0x0146,	16,	{0x7e, 0x40, 0xe0, 0x13, 0x92, 0x08, 0x20, 0x07, 0x72, 0x20, 0x04, 0x6f, 0x90, 0x7f, 0x9b, 0xe0} },
-{ 0x0156,	16,	{0x30, 0xe3, 0x03, 0x20, 0x0c, 0x65, 0x30, 0x0b, 0x10, 0x90, 0x7e, 0x41, 0xe0, 0x13, 0x92, 0x9b} },
-{ 0x0166,	16,	{0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x03, 0x80, 0x09, 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x99, 0x75} },
-{ 0x0176,	16,	{0x37, 0x02, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x01} },
-{ 0x0186,	16,	{0x20, 0x08, 0x03, 0x02, 0x04, 0x23, 0xc2, 0x08, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x23} },
-{ 0x0196,	16,	{0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5} },
-{ 0x01a6,	16,	{0x83, 0xe0, 0x13, 0x92, 0x09, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x01b6,	16,	{0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x06, 0x02, 0x04, 0x23, 0x75, 0x37, 0x01, 0xc2, 0x0f} },
-{ 0x01c6,	16,	{0x02, 0x04, 0x23, 0x30, 0x07, 0x03, 0x02, 0x02, 0x4b, 0x20, 0x04, 0x79, 0x90, 0x7f, 0x9b, 0xe0} },
-{ 0x01d6,	16,	{0x30, 0xe3, 0x03, 0x20, 0x0c, 0x6f, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f} },
-{ 0x01e6,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xaf, 0x37, 0x05, 0x37, 0x74} },
-{ 0x01f6,	16,	{0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, 0x37, 0xc3, 0x95} },
-{ 0x0206,	16,	{0x50, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x01, 0x20, 0x08, 0x03, 0x02, 0x04, 0x23} },
-{ 0x0216,	16,	{0xc2, 0x08, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x23, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05} },
-{ 0x0226,	16,	{0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x09, 0xaf} },
-{ 0x0236,	16,	{0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35} },
-{ 0x0246,	16,	{0xd2, 0x06, 0x02, 0x04, 0x23, 0xc2, 0x0f, 0x02, 0x04, 0x23, 0x20, 0x06, 0x03, 0x02, 0x03, 0x02} },
-{ 0x0256,	16,	{0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x3e, 0x20, 0x07, 0x36, 0x20, 0x04, 0x33, 0x90, 0x7f, 0x9b} },
-{ 0x0266,	16,	{0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0c, 0x29, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0} },
-{ 0x0276,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x09, 0xaf, 0x37, 0x05, 0x37} },
-{ 0x0286,	16,	{0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0x02, 0x04, 0x23} },
-{ 0x0296,	16,	{0xc2, 0x06, 0x02, 0x04, 0x23, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x01, 0x30, 0x08, 0x0c, 0xc2} },
-{ 0x02a6,	16,	{0x08, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0xc2, 0x06, 0x02, 0x04, 0x23, 0x90, 0x7f, 0xc6, 0xe0, 0x30} },
-{ 0x02b6,	16,	{0xe1, 0x05, 0xc2, 0x06, 0x02, 0x04, 0x23, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x50, 0x90, 0x7e, 0x40} },
-{ 0x02c6,	16,	{0xe0, 0x13, 0x92, 0x08, 0x20, 0x07, 0x2d, 0x20, 0x04, 0x2a, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3} },
-{ 0x02d6,	16,	{0x03, 0x20, 0x0c, 0x20, 0x30, 0x0b, 0x11, 0x90, 0x7e, 0x41, 0xe0, 0x13, 0x92, 0x09, 0xa3, 0xe0} },
-{ 0x02e6,	16,	{0xf5, 0x35, 0x75, 0x37, 0x03, 0x02, 0x04, 0x23, 0x75, 0x37, 0x02, 0x90, 0x7e, 0x41, 0xe0, 0xf5} },
-{ 0x02f6,	16,	{0x35, 0x02, 0x04, 0x23, 0x75, 0x37, 0x01, 0xc2, 0x06, 0x02, 0x04, 0x23, 0xe5, 0x37, 0xc3, 0x95} },
-{ 0x0306,	16,	{0x50, 0x50, 0x03, 0x02, 0x03, 0xa4, 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x0f, 0xd2} },
-{ 0x0316,	16,	{0x0e, 0x02, 0x04, 0x23, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x50, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92} },
-{ 0x0326,	16,	{0x08, 0x20, 0x07, 0x72, 0x20, 0x04, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0c} },
-{ 0x0336,	16,	{0x65, 0x30, 0x0b, 0x10, 0x90, 0x7d, 0xc1, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75} },
-{ 0x0346,	16,	{0x37, 0x03, 0x80, 0x09, 0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x02, 0xe5, 0x37, 0xc3} },
-{ 0x0356,	16,	{0x95, 0x50, 0x40, 0x17, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x01, 0x20, 0x08, 0x03, 0x02, 0x04} },
-{ 0x0366,	16,	{0x23, 0xc2, 0x08, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x23, 0x30, 0x0b, 0x12, 0xaf, 0x37} },
-{ 0x0376,	16,	{0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x09} },
-{ 0x0386,	16,	{0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5} },
-{ 0x0396,	16,	{0x35, 0xd2, 0x06, 0x02, 0x04, 0x23, 0x75, 0x37, 0x01, 0xc2, 0x0f, 0x02, 0x04, 0x23, 0x30, 0x07} },
-{ 0x03a6,	16,	{0x03, 0x02, 0x04, 0x21, 0x20, 0x04, 0x74, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0c} },
-{ 0x03b6,	16,	{0x6a, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d} },
-{ 0x03c6,	16,	{0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4} },
-{ 0x03d6,	16,	{0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x13, 0x90, 0x7f} },
-{ 0x03e6,	16,	{0xc9, 0xe4, 0xf0, 0xd2, 0x01, 0x30, 0x08, 0x35, 0xc2, 0x08, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x80} },
-{ 0x03f6,	16,	{0x2c, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d} },
-{ 0x0406,	16,	{0xf5, 0x83, 0xe0, 0x13, 0x92, 0x09, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4} },
-{ 0x0416,	16,	{0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x06, 0x80, 0x02, 0xc2, 0x0f, 0xd2, 0x11, 0x20} },
-{ 0x0426,	5,	{0x98, 0x03, 0x02, 0x05, 0x61} },
-{ 0x042b,	16,	{0xc2, 0x98, 0x20, 0x00, 0x03, 0x02, 0x04, 0xce, 0x20, 0x10, 0x27, 0xaf, 0x36, 0x05, 0x36, 0x74} },
-{ 0x043b,	16,	{0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x0b, 0x4d, 0xaf} },
-{ 0x044b,	16,	{0x36, 0x05, 0x36, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0} },
-{ 0x045b,	16,	{0x80, 0x3a, 0x85, 0x99, 0x10, 0xe5, 0x10, 0xb5, 0x44, 0x04, 0xd2, 0x04, 0x80, 0x2e, 0xe5, 0x10} },
-{ 0x046b,	16,	{0xb5, 0x43, 0x04, 0xc2, 0x04, 0x80, 0x25, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x80, 0x2f, 0xf5, 0x82} },
-{ 0x047b,	16,	{0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x10, 0xf0, 0x30, 0x0b, 0x11, 0xaf, 0x36, 0x05, 0x36, 0x74} },
-{ 0x048b,	16,	{0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0a, 0xe5, 0x36} },
-{ 0x049b,	16,	{0xc3, 0x95, 0x40, 0x50, 0x03, 0x02, 0x05, 0x5f, 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x16, 0xe5} },
-{ 0x04ab,	16,	{0x36, 0xc3, 0x94, 0x40, 0x50, 0x03, 0x02, 0x05, 0x5f, 0x15, 0x36, 0x15, 0x36, 0x05, 0x2b, 0x43} },
-{ 0x04bb,	16,	{0x33, 0x01, 0x02, 0x05, 0x5f, 0x90, 0x7f, 0xb7, 0xe5, 0x36, 0xf0, 0x75, 0x36, 0x00, 0xc2, 0x00} },
-{ 0x04cb,	16,	{0x02, 0x05, 0x5f, 0x20, 0x10, 0x27, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4} },
-{ 0x04db,	16,	{0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x0b, 0x4d, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00} },
-{ 0x04eb,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99, 0x10} },
-{ 0x04fb,	16,	{0xe5, 0x10, 0xb5, 0x44, 0x04, 0xd2, 0x04, 0x80, 0x2e, 0xe5, 0x10, 0xb5, 0x43, 0x04, 0xc2, 0x04} },
-{ 0x050b,	16,	{0x80, 0x25, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83} },
-{ 0x051b,	16,	{0xe5, 0x10, 0xf0, 0x30, 0x0b, 0x11, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4} },
-{ 0x052b,	16,	{0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0a, 0xe5, 0x36, 0xc3, 0x95, 0x40, 0x40, 0x24} },
-{ 0x053b,	16,	{0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x12, 0xe5, 0x36, 0xc3, 0x94, 0x40, 0x40, 0x16, 0x15, 0x36} },
-{ 0x054b,	16,	{0x15, 0x36, 0x05, 0x2b, 0x43, 0x33, 0x01, 0x80, 0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x36, 0xf0, 0x75} },
-{ 0x055b,	6,	{0x36, 0x00, 0xd2, 0x00, 0xd2, 0x11} },
-{ 0x0561,	16,	{0x30, 0x11, 0x05, 0xc2, 0x11, 0x02, 0x00, 0x56, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83} },
-{ 0x0571,	3,	{0xd0, 0xe0, 0x32} },
-{ 0x0574,	16,	{0x90, 0x7f, 0xca, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x06, 0xa5, 0xe4, 0xf5, 0x13, 0x74, 0x40, 0x25} },
-{ 0x0584,	16,	{0x13, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x13, 0x7c, 0x00, 0x7b, 0x00} },
-{ 0x0594,	16,	{0x24, 0x38, 0xf9, 0xec, 0x34, 0x00, 0xfa, 0xef, 0x12, 0x0c, 0x54, 0x05, 0x13, 0xe5, 0x13, 0xb4} },
-{ 0x05a4,	16,	{0x18, 0xdb, 0xe5, 0x38, 0x60, 0x0c, 0x75, 0xc9, 0x20, 0x75, 0xc8, 0x34, 0x85, 0x39, 0xca, 0x85} },
-{ 0x05b4,	16,	{0x3a, 0xcb, 0xe5, 0x3b, 0x13, 0x92, 0x0b, 0x92, 0x9f, 0xe5, 0x3c, 0x13, 0x92, 0x0c, 0xe5, 0x3d} },
-{ 0x05c4,	16,	{0x13, 0x92, 0x10, 0xe5, 0x3e, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07} },
-{ 0x05d4,	16,	{0x90, 0x7f, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x3f, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54} },
-{ 0x05e4,	16,	{0x7f, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x45, 0x60, 0x0b, 0xc2} },
-{ 0x05f4,	16,	{0x07, 0xc2, 0x04, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x46, 0x60, 0x0c, 0xd2, 0x04} },
-{ 0x0604,	16,	{0x43, 0x33, 0x01, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x47, 0x60, 0x17, 0xc2, 0xaf} },
-{ 0x0614,	16,	{0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0xc2, 0x06, 0xd2, 0x01, 0xc2, 0x08, 0xf5} },
-{ 0x0624,	16,	{0x50, 0xf5, 0x37, 0xd2, 0xaf, 0xe5, 0x48, 0x60, 0x05, 0x30, 0x10, 0x02, 0xd2, 0x04, 0xe5, 0x49} },
-{ 0x0634,	16,	{0x60, 0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9e, 0xe0, 0x44, 0x02, 0xf0} },
-{ 0x0644,	16,	{0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x4a, 0x60, 0x0a, 0xd2, 0x9c, 0xc2, 0x98, 0x75} },
-{ 0x0654,	16,	{0x2c, 0x01, 0x75, 0x31, 0x1e, 0xe5, 0x4b, 0x60, 0x07, 0xc2, 0x9c, 0xe4, 0xf5, 0x36, 0xf5, 0x2c} },
-{ 0x0664,	16,	{0xe5, 0x4c, 0x60, 0x03, 0xe4, 0xf5, 0x36, 0xe5, 0x4d, 0x60, 0x02, 0xd2, 0x02, 0xe5, 0x4e, 0x60} },
-{ 0x0674,	16,	{0x0a, 0xe5, 0x4a, 0x70, 0x02, 0xf5, 0x31, 0xe5, 0x4e, 0x42, 0x33, 0xe5, 0x4f, 0x60, 0x1b, 0x90} },
-{ 0x0684,	16,	{0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0, 0x74, 0x32, 0xf0, 0x74, 0x13} },
-{ 0x0694,	16,	{0xf0, 0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0, 0xd2, 0x03, 0xe4, 0x90, 0x7f, 0xcb} },
-{ 0x06a4,	16,	{0xf0, 0xa2, 0x07, 0xe4, 0x33, 0xff, 0x65, 0x29, 0x60, 0x05, 0x8f, 0x29, 0x43, 0x33, 0x01, 0xa2} },
-{ 0x06b4,	16,	{0x04, 0xe4, 0x33, 0xff, 0x65, 0x2a, 0x60, 0x05, 0x8f, 0x2a, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b} },
-{ 0x06c4,	16,	{0xe0, 0x54, 0x08, 0xb5, 0x25, 0x0a, 0xe0, 0x54, 0x08, 0x64, 0x08, 0xf5, 0x25, 0x43, 0x33, 0x01} },
-{ 0x06d4,	16,	{0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x10, 0xb5, 0x26, 0x0a, 0xe0, 0x54, 0x10, 0x64, 0x10, 0xf5, 0x26} },
-{ 0x06e4,	16,	{0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x40, 0xb5, 0x27, 0x0a, 0xe0, 0x54, 0x40, 0x64} },
-{ 0x06f4,	16,	{0x40, 0xf5, 0x27, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x20, 0xb5, 0x28, 0x0a, 0xe0} },
-{ 0x0704,	16,	{0x54, 0x20, 0x64, 0x20, 0xf5, 0x28, 0x43, 0x33, 0x01, 0x30, 0x02, 0x35, 0xc2, 0xaf, 0x30, 0x00} },
-{ 0x0714,	16,	{0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x36, 0x60, 0x09, 0x90, 0x7f, 0xb7, 0xf0} },
-{ 0x0724,	16,	{0xe4, 0xf5, 0x36, 0xc2, 0x00, 0xc2, 0x02, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f} },
-{ 0x0734,	16,	{0xe5, 0x36, 0x60, 0x09, 0x90, 0x7f, 0xb9, 0xf0, 0xe4, 0xf5, 0x36, 0xd2, 0x00, 0xc2, 0x02, 0xd2} },
-{ 0x0744,	16,	{0xaf, 0x30, 0x0e, 0x37, 0x30, 0x01, 0x1b, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7e} },
-{ 0x0754,	16,	{0x40, 0xe0, 0x13, 0x92, 0x08, 0x75, 0x37, 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x50, 0xc2, 0x0e} },
-{ 0x0764,	16,	{0x80, 0x19, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x08} },
-{ 0x0774,	16,	{0x75, 0x37, 0x01, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x50, 0xc2, 0x0e, 0x30, 0x0f, 0x03, 0x02, 0x08} },
-{ 0x0784,	16,	{0x87, 0x30, 0x0e, 0x03, 0x02, 0x08, 0x87, 0x30, 0x0c, 0x0a, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3} },
-{ 0x0794,	16,	{0x03, 0x02, 0x08, 0x87, 0x30, 0x04, 0x03, 0x02, 0x08, 0x87, 0x30, 0x07, 0x03, 0x02, 0x08, 0x87} },
-{ 0x07a4,	16,	{0x30, 0x01, 0x62, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4} },
-{ 0x07b4,	16,	{0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5} },
-{ 0x07c4,	16,	{0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x14, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x2a} },
-{ 0x07d4,	16,	{0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5} },
-{ 0x07e4,	16,	{0x83, 0xe0, 0x13, 0x92, 0x09, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x07f4,	16,	{0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x06, 0x80, 0x6b, 0xc2, 0x06, 0xe4, 0x90, 0x7f, 0xc7} },
-{ 0x0804,	16,	{0xf0, 0xc2, 0x01, 0x80, 0x60, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5} },
-{ 0x0814,	16,	{0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0} },
-{ 0x0824,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x14, 0xe5, 0x37, 0xc3, 0x95, 0x50} },
-{ 0x0834,	16,	{0x50, 0x2a, 0x30, 0x0b, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x0844,	16,	{0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x09, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82} },
-{ 0x0854,	16,	{0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x06, 0x80, 0x09, 0xc2, 0x06, 0xe4, 0x90} },
-{ 0x0864,	16,	{0x7f, 0xc9, 0xf0, 0xd2, 0x01, 0x30, 0x0b, 0x04, 0xa2, 0x18, 0x92, 0x9b, 0xd2, 0x0f, 0xc2, 0xaf} },
-{ 0x0874,	16,	{0x85, 0x14, 0x99, 0x20, 0x06, 0x0b, 0x30, 0x08, 0x08, 0xc2, 0x08, 0x90, 0x7f, 0xbb, 0x74, 0x01} },
-{ 0x0884,	16,	{0xf0, 0xd2, 0xaf, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x51, 0xe5, 0x33, 0x60, 0x4d, 0xe5, 0x31} },
-{ 0x0894,	16,	{0x70, 0x49, 0xe5, 0x33, 0x30, 0xe1, 0x08, 0xe4, 0xf5, 0x2f, 0x75, 0x33, 0x01, 0x80, 0x0b, 0xa2} },
-{ 0x08a4,	16,	{0x03, 0xe4, 0x33, 0xf5, 0x2f, 0xc2, 0x03, 0xe4, 0xf5, 0x33, 0xe4, 0xf5, 0x13, 0x7e, 0x00, 0x7b} },
-{ 0x08b4,	16,	{0x00, 0x74, 0x24, 0x25, 0x13, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0c, 0x0e, 0xff, 0x74, 0x00} },
-{ 0x08c4,	16,	{0x25, 0x13, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x13, 0xe5, 0x13, 0xb4} },
-{ 0x08d4,	11,	{0x0c, 0xdb, 0x90, 0x7f, 0xbd, 0x74, 0x0c, 0xf0, 0x75, 0x31, 0x10} },
-{ 0x08df,	1,	{0x22} },
-{ 0x08e0,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0c, 0x66, 0x09, 0xb1, 0x00, 0x0a, 0x25, 0x01, 0x0a, 0x91, 0x03} },
-{ 0x08f0,	16,	{0x09, 0x03, 0x06, 0x09, 0xa4, 0x08, 0x09, 0x9e, 0x09, 0x09, 0x86, 0x0a, 0x09, 0x95, 0x0b, 0x00} },
-{ 0x0900,	16,	{0x00, 0x0a, 0xe0, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x4b, 0x24, 0x02} },
-{ 0x0910,	16,	{0x70, 0x6a, 0x74, 0x0f, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x64, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0a} },
-{ 0x0920,	16,	{0xe7, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0xb5} },
-{ 0x0930,	16,	{0x75, 0x83, 0x0f, 0xef, 0xf0, 0x75, 0x82, 0xae, 0x75, 0x83, 0x0f, 0xf0, 0x75, 0x82, 0xa7, 0x75} },
-{ 0x0940,	16,	{0x83, 0x0f, 0xf0, 0x75, 0x82, 0xa0, 0x75, 0x83, 0x0f, 0xf0, 0x74, 0x0f, 0x90, 0x7f, 0xd4, 0xf0} },
-{ 0x0950,	16,	{0x74, 0x76, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0d} },
-{ 0x0960,	16,	{0xf1, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02} },
-{ 0x0970,	16,	{0x0a, 0xe7, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xb4, 0xe0} },
-{ 0x0980,	16,	{0x44, 0x01, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0x00, 0xe5, 0x18, 0xf0, 0x90, 0x7f, 0xb5, 0x74} },
-{ 0x0990,	16,	{0x01, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x18, 0x02, 0x0a, 0xe7, 0x12, 0x0d} },
-{ 0x09a0,	16,	{0x08, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x0a} },
-{ 0x09b0,	16,	{0xe7, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b} },
-{ 0x09c0,	16,	{0xa2, 0x12, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x15, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00} },
-{ 0x09d0,	16,	{0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0a, 0xe7, 0xe4, 0x90, 0x7f} },
-{ 0x09e0,	16,	{0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xec} },
-{ 0x09f0,	16,	{0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24} },
-{ 0x0a00,	16,	{0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4} },
-{ 0x0a10,	16,	{0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xb4, 0xe0, 0x44} },
-{ 0x0a20,	16,	{0x01, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60} },
-{ 0x0a30,	16,	{0x03, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x12, 0x02, 0x0a, 0xe7} },
-{ 0x0a40,	16,	{0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0a, 0xe7, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38} },
-{ 0x0a50,	16,	{0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f} },
-{ 0x0a60,	16,	{0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec} },
-{ 0x0a70,	16,	{0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f} },
-{ 0x0a80,	16,	{0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80} },
-{ 0x0a90,	16,	{0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea} },
-{ 0x0aa0,	16,	{0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x12, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80} },
-{ 0x0ab0,	16,	{0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4} },
-{ 0x0ac0,	16,	{0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} },
-{ 0x0ad0,	16,	{0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07} },
-{ 0x0ae0,	14,	{0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
-{ 0x0aee,	1,	{0x22} },
-{ 0x0aef,	16,	{0x20, 0x14, 0x03, 0x02, 0x0b, 0x81, 0xe5, 0x31, 0x60, 0x02, 0x15, 0x31, 0xe5, 0x36, 0x60, 0x4f} },
-{ 0x0aff,	16,	{0x65, 0x34, 0x70, 0x45, 0xe5, 0x32, 0xf4, 0x60, 0x02, 0x05, 0x32, 0xe5, 0x32, 0xc3, 0x95, 0x41} },
-{ 0x0b0f,	16,	{0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x00, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f} },
-{ 0x0b1f,	16,	{0xb7, 0xe5, 0x36, 0xf0, 0xc2, 0x00, 0xe4, 0xf5, 0x36, 0xf5, 0x32, 0xf5, 0x34, 0x80, 0x16, 0x90} },
-{ 0x0b2f,	16,	{0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0x90, 0x7f, 0xb9, 0xe5, 0x36, 0xf0, 0xd2, 0x00, 0xe4, 0xf5} },
-{ 0x0b3f,	16,	{0x36, 0xf5, 0x32, 0xf5, 0x34, 0xd2, 0xaf, 0x80, 0x06, 0x85, 0x36, 0x34, 0xe4, 0xf5, 0x32, 0xe5} },
-{ 0x0b4f,	16,	{0x2c, 0x60, 0x2f, 0x20, 0x0a, 0x07, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe0, 0x0f, 0xe5, 0x2d, 0x60} },
-{ 0x0b5f,	16,	{0x06, 0xe4, 0xf5, 0x2d, 0x43, 0x33, 0x01, 0xe4, 0xf5, 0x30, 0x80, 0x14, 0xe5, 0x30, 0xd3, 0x95} },
-{ 0x0b6f,	16,	{0x42, 0x50, 0x0d, 0xe5, 0x30, 0xb5, 0x42, 0x06, 0x75, 0x2d, 0x01, 0x43, 0x33, 0x01, 0x05, 0x30} },
-{ 0x0b7f,	3,	{0xc2, 0x0a, 0x22} },
-{ 0x0b82,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x50, 0x02, 0x0b, 0xc9} },
-{ 0x0b8e,	16,	{0x02, 0x0c, 0x8c, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x0b9e,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x0bae,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x0bbe,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x0d, 0x5c, 0xe4, 0x7e} },
-{ 0x0bce,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x0bde,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x0bee,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x0bfe,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x0c0e,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x0c1e,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x0c27,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x0c37,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x0c47,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x0c54,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} },
-{ 0x0c64,	2,	{0xf3, 0x22} },
-{ 0x0c66,	16,	{0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} },
-{ 0x0c76,	16,	{0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} },
-{ 0x0c86,	6,	{0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} },
-{ 0x0c8c,	16,	{0x75, 0x12, 0x01, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3} },
-{ 0x0c9c,	16,	{0x92, 0x12, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde} },
-{ 0x0cac,	16,	{0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9} },
-{ 0x0cbc,	16,	{0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90} },
-{ 0x0ccc,	16,	{0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2, 0x18, 0x12, 0x0f, 0x13, 0xc2} },
-{ 0x0cdc,	16,	{0x13, 0x30, 0x14, 0x03, 0x12, 0x05, 0x74, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x11, 0x60, 0x08, 0xe0} },
-{ 0x0cec,	16,	{0xf5, 0x11, 0x12, 0x0a, 0xef, 0x80, 0xea, 0x30, 0x13, 0x07, 0xc2, 0x13, 0x12, 0x08, 0xe0, 0x80} },
-{ 0x0cfc,	11,	{0xe0, 0x30, 0x16, 0xdd, 0xc2, 0x16, 0x12, 0x00, 0x26, 0x80, 0xd6} },
-{ 0x0d07,	1,	{0x22} },
-{ 0x0d08,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x10} },
-{ 0x0d18,	16,	{0xf0, 0x90, 0x7f, 0x94, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0x9d, 0x04, 0xf0, 0x90, 0x7f, 0x97, 0x74} },
-{ 0x0d28,	16,	{0x20, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x84, 0xf0, 0xe4, 0x90} },
-{ 0x0d38,	16,	{0x7f, 0x98, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x75} },
-{ 0x0d48,	16,	{0x98, 0x40, 0x43, 0xa8, 0x10, 0x90, 0x7f, 0xde, 0x74, 0x1f, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x0f} },
-{ 0x0d58,	4,	{0xf0, 0xd2, 0x14, 0x22} },
-{ 0x0d5c,	12,	{0xc1, 0x13, 0xc1, 0x16, 0xc1, 0x12, 0xc1, 0x95, 0xc1, 0x14, 0xc1, 0x11} },
-{ 0x0d68,	16,	{0x0c, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30} },
-{ 0x0d78,	16,	{0x00, 0x01, 0x33, 0x01, 0x01, 0x32, 0x00, 0x01, 0x37, 0x00, 0x01, 0x50, 0x00, 0x01, 0x36, 0x00} },
-{ 0x0d88,	16,	{0x01, 0x34, 0x00, 0xc1, 0x03, 0xc1, 0x0a, 0xc1, 0x8e, 0xc1, 0x0d, 0xc1, 0x02, 0xc1, 0x0c, 0xc1} },
-{ 0x0d98,	16,	{0x10, 0xc1, 0x08, 0xc1, 0x0f, 0xc1, 0x06, 0xc1, 0x07, 0xc1, 0x04, 0xc1, 0x0b, 0xc1, 0x80, 0xc1} },
-{ 0x0da8,	1,	{0x81} },
-{ 0x0da9,	2,	{0xc1, 0x97} },
-{ 0x0dab,	1,	{0x00} },
-{ 0x0dac,	16,	{0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9d} },
-{ 0x0dbc,	16,	{0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x54} },
-{ 0x0dcc,	16,	{0xfd, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x20, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x9d} },
-{ 0x0ddc,	16,	{0xe0, 0x44, 0xfd, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0xe4} },
-{ 0x0dec,	5,	{0x90, 0x7f, 0x98, 0xf0, 0x22} },
-{ 0x0df1,	2,	{0x8f, 0x13} },
-{ 0x0df3,	16,	{0xe4, 0xf5, 0x14, 0x75, 0x15, 0xff, 0x75, 0x16, 0x0f, 0x75, 0x17, 0xb9, 0xab, 0x15, 0xaa, 0x16} },
-{ 0x0e03,	16,	{0xa9, 0x17, 0x90, 0x00, 0x01, 0x12, 0x0c, 0x27, 0xb4, 0x03, 0x1d, 0xaf, 0x14, 0x05, 0x14, 0xef} },
-{ 0x0e13,	16,	{0xb5, 0x13, 0x01, 0x22, 0x12, 0x0c, 0x0e, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0e23,	14,	{0x15, 0xff, 0xf5, 0x16, 0x89, 0x17, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0e31,	1,	{0x22} },
-{ 0x0e32,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} },
-{ 0x0e42,	16,	{0x17, 0x04, 0xc2, 0x17, 0x80, 0x02, 0xd2, 0x16, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} },
-{ 0x0e52,	14,	{0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e60,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} },
-{ 0x0e70,	16,	{0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} },
-{ 0x0e80,	10,	{0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e8a,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} },
-{ 0x0e9a,	16,	{0x13, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} },
-{ 0x0eaa,	7,	{0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0eb1,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x0ec1,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x0ed1,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ed6,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x0ee6,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x0ef6,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0f00,	16,	{0x02, 0x0e, 0x8a, 0x00, 0x02, 0x0e, 0xb1, 0x00, 0x02, 0x0e, 0x60, 0x00, 0x02, 0x0e, 0x32, 0x00} },
-{ 0x0f10,	3,	{0x02, 0x0e, 0xd6} },
-{ 0x0f13,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x18, 0x04, 0xe0, 0x44} },
-{ 0x0f23,	16,	{0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x0f33,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x0f38,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x0f48,	1,	{0x22} },
-{ 0x0f49,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x0f64,	16,	{0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x07, 0x01, 0x01, 0x00, 0x01, 0x02} },
-{ 0x0f74,	16,	{0x00, 0x01, 0x09, 0x02, 0x43, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x07} },
-{ 0x0f84,	16,	{0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} },
-{ 0x0f94,	16,	{0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00} },
-{ 0x0fa4,	16,	{0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} },
-{ 0x0fb4,	16,	{0x84, 0x02, 0x40, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79} },
-{ 0x0fc4,	16,	{0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x0e, 0x03, 0x53, 0x00, 0x65, 0x00, 0x72} },
-{ 0x0fd4,	9,	{0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x00, 0x00} },
+ {0x0026, 10, { 0x12, 0x0d, 0xbb, 0x12, 0x0e, 0xee, 0x12, 0x0d, 0x67, 0x22}},
+ {0x0033,  3, { 0x02, 0x00, 0x1a}},
+ {0x001a,  4, { 0x53, 0xd8, 0xef, 0x32}},
+ {0x0003, 16, { 0x8e, 0x13, 0x8f, 0x14, 0xe5, 0x14, 0x15, 0x14, 0xae, 0x13, 0x70, 0x02, 0x15, 0x13, 0x4e, 0x60}},
+ {0x0013,  7, { 0x05, 0x12, 0x0e, 0xdd, 0x80, 0xee, 0x22}},
+ {0x0023,  3, { 0x02, 0x00, 0x46}},
+ {0x0046, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08}},
+ {0x0056, 16, { 0x30, 0x99, 0x0e, 0x30, 0x08, 0x07, 0xa2, 0x0b, 0x92, 0x9b, 0x85, 0x35, 0x99, 0xc2, 0x99, 0xd2}},
+ {0x0066, 16, { 0x0f, 0x20, 0x0f, 0x03, 0x02, 0x04, 0x31, 0xc2, 0x0f, 0x20, 0x02, 0x03, 0x02, 0x02, 0x56, 0x20}},
+ {0x0076, 16, { 0x08, 0x03, 0x02, 0x01, 0x27, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x3e, 0x20, 0x09, 0x36, 0x20}},
+ {0x0086, 16, { 0x06, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x29, 0x30, 0x0d, 0x12, 0xaf}},
+ {0x0096, 16, { 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92}},
+ {0x00a6, 16, { 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0}},
+ {0x00b6, 16, { 0xf5, 0x35, 0x02, 0x04, 0x2f, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2}},
+ {0x00c6, 16, { 0x02, 0x30, 0x0a, 0x0c, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0xc2, 0x08, 0x02, 0x04, 0x2f}},
+ {0x00d6, 16, { 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc9, 0xe0}},
+ {0x00e6, 16, { 0xf5, 0x50, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x20, 0x09, 0x2d, 0x20, 0x06, 0x2a, 0x90}},
+ {0x00f6, 16, { 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x20, 0x30, 0x0d, 0x11, 0x90, 0x7d, 0xc1, 0xe0}},
+ {0x0043,  3, { 0x02, 0x0f, 0x00}},
+ {0x0000,  3, { 0x02, 0x0c, 0x5d}},
+ {0x0106, 64, { 0x13, 0x92, 0x0b, 0xa3, 0xe0, 0xf5, 0x35, 0x75, 0x37, 0x03, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x02, 0x90,
+  0x7d, 0xc1, 0xe0, 0xf5, 0x35, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x01, 0xc2, 0x08, 0x02, 0x04, 0x2f,
+  0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x03, 0x02, 0x01, 0xcf, 0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1,
+  0x07, 0xc2, 0x10, 0xc2, 0x03, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x50, 0x90}},
+ {0x0146, 64, { 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x30, 0x09, 0x03, 0x02, 0x01, 0xc7, 0x20, 0x06, 0x72, 0x20, 0x00,
+  0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x65, 0x30, 0x0d, 0x10, 0x90, 0x7e,
+  0x41, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x03, 0x80, 0x09, 0x90, 0x7e,
+  0x41, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x02, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x17, 0x90}},
+ {0x0186, 64, { 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x02, 0x20, 0x0a, 0x03, 0x02, 0x04, 0x2f, 0xc2, 0x0a, 0x90, 0x7f, 0xbb,
+  0x04, 0xf0, 0x02, 0x04, 0x2f, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5,
+  0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40,
+  0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x02, 0x04}},
+ {0x01c6, 64, { 0x2f, 0x75, 0x37, 0x01, 0xc2, 0x10, 0x02, 0x04, 0x2f, 0x30, 0x09, 0x03, 0x02, 0x02, 0x51, 0x20, 0x06,
+  0x79, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x6f, 0x30, 0x0d, 0x12, 0xaf, 0x37,
+  0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b,
+  0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0}},
+ {0x0206, 64, { 0xf5, 0x99, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x02, 0x20,
+  0x0a, 0x03, 0x02, 0x04, 0x2f, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x02, 0x04, 0x2f, 0x30,
+  0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83,
+  0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34}},
+ {0x0246, 64, { 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x02, 0x04, 0x2f, 0xc2, 0x10, 0x02, 0x04, 0x2f, 0x20,
+  0x08, 0x03, 0x02, 0x03, 0x08, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x3e, 0x20, 0x09, 0x36, 0x20,
+  0x06, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x29, 0x30, 0x0d, 0x12, 0xaf,
+  0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13}},
+ {0x0286, 64, { 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0,
+  0xf5, 0x35, 0x02, 0x04, 0x2f, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2,
+  0x02, 0x30, 0x0a, 0x0c, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0xc2, 0x08, 0x02, 0x04, 0x2f,
+  0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x08, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc7}},
+ {0x02c6, 64, { 0xe0, 0xf5, 0x50, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x20, 0x09, 0x2d, 0x20, 0x06, 0x2a, 0x90,
+  0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x20, 0x30, 0x0d, 0x11, 0x90, 0x7e, 0x41, 0xe0,
+  0x13, 0x92, 0x0b, 0xa3, 0xe0, 0xf5, 0x35, 0x75, 0x37, 0x03, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x02,
+  0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x35, 0x02, 0x04, 0x2f, 0x75, 0x37, 0x01, 0xc2, 0x08, 0x02}},
+ {0x0306, 64, { 0x04, 0x2f, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x03, 0x02, 0x03, 0xb0, 0x90, 0x7f, 0xc8, 0xe0, 0x30,
+  0xe1, 0x07, 0xc2, 0x10, 0xc2, 0x03, 0x02, 0x04, 0x2f, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x50, 0x90,
+  0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x30, 0x09, 0x03, 0x02, 0x03, 0xa8, 0x20, 0x06, 0x72, 0x20,
+  0x00, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x65, 0x30, 0x0d, 0x10}},
+ {0x0346, 64, { 0x90, 0x7d, 0xc1, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x03, 0x80, 0x09, 0x90,
+  0x7d, 0xc1, 0xe0, 0xf5, 0x99, 0x75, 0x37, 0x02, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x17, 0x90,
+  0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x02, 0x20, 0x0a, 0x03, 0x02, 0x04, 0x2f, 0xc2, 0x0a, 0x90, 0x7f,
+  0xbb, 0x04, 0xf0, 0x02, 0x04, 0x2f, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0}},
+ {0x0386, 64, { 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74,
+  0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x02, 0x04,
+  0x2f, 0x75, 0x37, 0x01, 0xc2, 0x10, 0x02, 0x04, 0x2f, 0x30, 0x09, 0x03, 0x02, 0x04, 0x2d, 0x20,
+  0x06, 0x74, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x20, 0x0e, 0x6a, 0x30, 0x0d, 0x12}},
+ {0x03c6, 64, { 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92,
+  0x9b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0,
+  0xf5, 0x99, 0xe5, 0x37, 0xc3, 0x95, 0x50, 0x40, 0x13, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x02,
+  0x30, 0x0a, 0x35, 0xc2, 0x0a, 0x90, 0x7f, 0xbb, 0x04, 0xf0, 0x80, 0x2c, 0x30, 0x0d, 0x12}},
+ {0x0406, 64, { 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92,
+  0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0,
+  0xf5, 0x35, 0xd2, 0x08, 0x80, 0x02, 0xc2, 0x10, 0xd2, 0x12, 0x20, 0x98, 0x03, 0x02, 0x05, 0x6d,
+  0xc2, 0x98, 0x20, 0x01, 0x03, 0x02, 0x04, 0xda, 0x20, 0x11, 0x27, 0xaf, 0x36, 0x05, 0x36}},
+ {0x0446, 64, { 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x0d, 0x4d, 0xaf,
+  0x36, 0x05, 0x36, 0x74, 0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0,
+  0x80, 0x3a, 0x85, 0x99, 0x10, 0xe5, 0x10, 0xb5, 0x44, 0x04, 0xd2, 0x06, 0x80, 0x2e, 0xe5, 0x10,
+  0xb5, 0x43, 0x04, 0xc2, 0x06, 0x80, 0x25, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x80, 0x2f, 0xf5}},
+ {0x0486, 64, { 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x10, 0xf0, 0x30, 0x0d, 0x11, 0xaf, 0x36, 0x05, 0x36, 0x74,
+  0x80, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0c, 0xe5, 0x36,
+  0xc3, 0x95, 0x40, 0x50, 0x03, 0x02, 0x05, 0x6b, 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x16, 0xe5,
+  0x36, 0xc3, 0x94, 0x40, 0x50, 0x03, 0x02, 0x05, 0x6b, 0x15, 0x36, 0x15, 0x36, 0x05, 0x2b}},
+ {0x04c6, 64, { 0x43, 0x33, 0x01, 0x02, 0x05, 0x6b, 0x90, 0x7f, 0xb7, 0xe5, 0x36, 0xf0, 0x75, 0x36, 0x00, 0xc2, 0x01,
+  0x02, 0x05, 0x6b, 0x20, 0x11, 0x27, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4,
+  0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x0d, 0x4d, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00,
+  0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x3a, 0x85, 0x99}},
+ {0x0506, 64, { 0x10, 0xe5, 0x10, 0xb5, 0x44, 0x04, 0xd2, 0x06, 0x80, 0x2e, 0xe5, 0x10, 0xb5, 0x43, 0x04, 0xc2, 0x06,
+  0x80, 0x25, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83,
+  0xe5, 0x10, 0xf0, 0x30, 0x0d, 0x11, 0xaf, 0x36, 0x05, 0x36, 0x74, 0x00, 0x2f, 0xf5, 0x82, 0xe4,
+  0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x0c, 0xe5, 0x36, 0xc3, 0x95, 0x40, 0x40}},
+ {0x0546, 64, { 0x24, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x12, 0xe5, 0x36, 0xc3, 0x94, 0x40, 0x40, 0x16, 0x15, 0x36,
+  0x15, 0x36, 0x05, 0x2b, 0x43, 0x33, 0x01, 0x80, 0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x36, 0xf0, 0x75,
+  0x36, 0x00, 0xd2, 0x01, 0xd2, 0x12, 0x30, 0x12, 0x05, 0xc2, 0x12, 0x02, 0x00, 0x56, 0xd0, 0xd0,
+  0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xca, 0xe0, 0x30, 0xe1}},
+ {0x0586, 64, { 0x03, 0x02, 0x06, 0xa7, 0xe4, 0xf5, 0x13, 0x74, 0x40, 0x25, 0x13, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5,
+  0x83, 0xe0, 0xff, 0xe5, 0x13, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x38, 0xf9, 0xec, 0x34, 0x00, 0xfa,
+  0xef, 0x12, 0x0d, 0x2f, 0x05, 0x13, 0xe5, 0x13, 0xb4, 0x18, 0xdb, 0xe5, 0x38, 0x60, 0x0c, 0x75,
+  0xc9, 0x20, 0x75, 0xc8, 0x34, 0x85, 0x39, 0xca, 0x85, 0x3a, 0xcb, 0xe5, 0x3b, 0x13, 0x92}},
+ {0x05c6, 64, { 0x0d, 0x92, 0x9f, 0xe5, 0x3c, 0x13, 0x92, 0x0e, 0xe5, 0x3d, 0x13, 0x92, 0x11, 0xe5, 0x3e, 0x60, 0x09,
+  0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x04, 0xf0,
+  0xe5, 0x3f, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98,
+  0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x45, 0x60, 0x0b, 0xc2, 0x09, 0xc2, 0x06, 0x90, 0x7f, 0x95}},
+ {0x0606, 64, { 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x46, 0x60, 0x0c, 0xd2, 0x06, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x95, 0xe0,
+  0x44, 0x02, 0xf0, 0xe5, 0x47, 0x60, 0x0d, 0xc2, 0xaf, 0xc2, 0x08, 0xd2, 0x00, 0xe4, 0xf5, 0x50,
+  0xf5, 0x37, 0xd2, 0xaf, 0xe5, 0x48, 0x60, 0x05, 0x30, 0x11, 0x02, 0xd2, 0x06, 0xe5, 0x49, 0x60,
+  0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9e, 0xe0, 0x44, 0x02, 0xf0}},
+ {0x0646, 64, { 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x4a, 0x60, 0x0a, 0xd2, 0x9c, 0xc2, 0x98, 0x75, 0x2c,
+  0x01, 0x75, 0x31, 0x1e, 0xe5, 0x4b, 0x60, 0x07, 0xc2, 0x9c, 0xe4, 0xf5, 0x36, 0xf5, 0x2c, 0xe5,
+  0x4c, 0x60, 0x03, 0xe4, 0xf5, 0x36, 0xe5, 0x4d, 0x60, 0x02, 0xd2, 0x04, 0xe5, 0x4e, 0x60, 0x0a,
+  0xe5, 0x4a, 0x70, 0x02, 0xf5, 0x31, 0xe5, 0x4e, 0x42, 0x33, 0xe5, 0x4f, 0x60, 0x1b, 0x90}},
+ {0x0686, 64, { 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0, 0x74, 0x32, 0xf0, 0x74, 0x13, 0xf0,
+  0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0, 0xd2, 0x05, 0xe4, 0x90, 0x7f, 0xcb, 0xf0,
+  0xa2, 0x09, 0xe4, 0x33, 0xff, 0x65, 0x29, 0x60, 0x05, 0x8f, 0x29, 0x43, 0x33, 0x01, 0xa2, 0x06,
+  0xe4, 0x33, 0xff, 0x65, 0x2a, 0x60, 0x05, 0x8f, 0x2a, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b}},
+ {0x06c6, 64, { 0xe0, 0x54, 0x08, 0xb5, 0x25, 0x0a, 0xe0, 0x54, 0x08, 0x64, 0x08, 0xf5, 0x25, 0x43, 0x33, 0x01, 0x90,
+  0x7f, 0x9b, 0xe0, 0x54, 0x10, 0xb5, 0x26, 0x0a, 0xe0, 0x54, 0x10, 0x64, 0x10, 0xf5, 0x26, 0x43,
+  0x33, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x40, 0xb5, 0x27, 0x0a, 0xe0, 0x54, 0x40, 0x64, 0x40,
+  0xf5, 0x27, 0x43, 0x33, 0x01, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x20, 0xb5, 0x28, 0x0a, 0xe0}},
+ {0x0706, 64, { 0x54, 0x20, 0x64, 0x20, 0xf5, 0x28, 0x43, 0x33, 0x01, 0x30, 0x04, 0x35, 0xc2, 0xaf, 0x30, 0x01, 0x18,
+  0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x36, 0x60, 0x09, 0x90, 0x7f, 0xb7, 0xf0, 0xe4,
+  0xf5, 0x36, 0xc2, 0x01, 0xc2, 0x04, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0xe5,
+  0x36, 0x60, 0x09, 0x90, 0x7f, 0xb9, 0xf0, 0xe4, 0xf5, 0x36, 0xd2, 0x01, 0xc2, 0x04, 0xd2}},
+ {0x0746, 64, { 0xaf, 0x20, 0x03, 0x37, 0x30, 0x02, 0x1b, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7e, 0x40,
+  0xe0, 0x13, 0x92, 0x0a, 0x75, 0x37, 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x50, 0xd2, 0x03, 0x80,
+  0x19, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x75,
+  0x37, 0x01, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x50, 0xd2, 0x03, 0x20, 0x10, 0x33, 0x20, 0x00}},
+ {0x0786, 64, { 0x06, 0xe5, 0x37, 0x65, 0x50, 0x70, 0x2a, 0x30, 0x03, 0x1a, 0x30, 0x02, 0x09, 0xe4, 0x90, 0x7f, 0xc7,
+  0xf0, 0xc2, 0x02, 0x80, 0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x02, 0xc2, 0x03, 0xe4, 0xf5,
+  0x50, 0xf5, 0x37, 0x30, 0x0a, 0x0a, 0xc2, 0x0a, 0xc2, 0x00, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0,
+  0x30, 0x10, 0x03, 0x02, 0x08, 0xc1, 0x20, 0x03, 0x03, 0x02, 0x08, 0xc1, 0x30, 0x0e, 0x0a}},
+ {0x07c6, 64, { 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe3, 0x03, 0x02, 0x08, 0xc1, 0x30, 0x06, 0x03, 0x02, 0x08, 0xc1, 0x30,
+  0x09, 0x03, 0x02, 0x08, 0xc1, 0x30, 0x02, 0x62, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74,
+  0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x19, 0xaf, 0x37, 0x05,
+  0x37, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x14, 0xe5}},
+ {0x0806, 64, { 0x37, 0xc3, 0x95, 0x50, 0x50, 0x2a, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40, 0x2f, 0xf5,
+  0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05, 0x37, 0x74, 0x40,
+  0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x80, 0x6b, 0xc2,
+  0x08, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x02, 0x80, 0x60, 0x30, 0x0d, 0x12, 0xaf, 0x37}},
+ {0x0846, 64, { 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x19, 0xaf,
+  0x37, 0x05, 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x14,
+  0xe5, 0x37, 0xc3, 0x95, 0x50, 0x50, 0x2a, 0x30, 0x0d, 0x12, 0xaf, 0x37, 0x05, 0x37, 0x74, 0xc0,
+  0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x0b, 0xaf, 0x37, 0x05}},
+ {0x0886, 64, { 0x37, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x35, 0xd2, 0x08, 0x80,
+  0x09, 0xc2, 0x08, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x02, 0x30, 0x0d, 0x04, 0xa2, 0x19, 0x92,
+  0x9b, 0xd2, 0x10, 0xc2, 0xaf, 0x85, 0x14, 0x99, 0x20, 0x08, 0x0d, 0x30, 0x0a, 0x0a, 0xc2, 0x0a,
+  0xc2, 0x00, 0x90, 0x7f, 0xbb, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90, 0x7f, 0xbc, 0xe0, 0x20}},
+ {0x08c6, 64, { 0xe1, 0x51, 0xe5, 0x33, 0x60, 0x4d, 0xe5, 0x31, 0x70, 0x49, 0xe5, 0x33, 0x30, 0xe1, 0x08, 0xe4, 0xf5,
+  0x2f, 0x75, 0x33, 0x01, 0x80, 0x0b, 0xa2, 0x05, 0xe4, 0x33, 0xf5, 0x2f, 0xc2, 0x05, 0xe4, 0xf5,
+  0x33, 0xe4, 0xf5, 0x13, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x13, 0xf9, 0xee, 0x34, 0x00,
+  0xfa, 0x12, 0x0c, 0xe9, 0xff, 0x74, 0x00, 0x25, 0x13, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5}},
+ {0x0906, 64, { 0x83, 0xef, 0xf0, 0x05, 0x13, 0xe5, 0x13, 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xbd, 0x74, 0x0c, 0xf0, 0x75,
+  0x31, 0x10, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0d, 0x41, 0x09, 0xff, 0x00, 0x0a, 0x73, 0x01,
+  0x0a, 0xdf, 0x03, 0x09, 0x3d, 0x06, 0x09, 0xf0, 0x08, 0x09, 0xe4, 0x09, 0x09, 0xcc, 0x0a, 0x09,
+  0xdb, 0x0b, 0x00, 0x00, 0x0b, 0x2e, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14}},
+ {0x0946, 64, { 0x60, 0x57, 0x24, 0x02, 0x70, 0x76, 0x74, 0x0f, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x64, 0x90, 0x7f, 0xd5,
+  0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03,
+  0x75, 0x82, 0xb5, 0x75, 0x83, 0x0f, 0xef, 0xf0, 0x75, 0x82, 0xae, 0x75, 0x83, 0x0f, 0xf0, 0x75,
+  0x82, 0xa7, 0x75, 0x83, 0x0f, 0xf0, 0x75, 0x82, 0xa0, 0x75, 0x83, 0x0f, 0xf0, 0x90, 0x7f}},
+ {0x0986, 64, { 0xea, 0xe0, 0x04, 0x75, 0x82, 0x7b, 0x75, 0x83, 0x0f, 0xf0, 0x74, 0x0f, 0x90, 0x7f, 0xd4, 0xf0, 0x74,
+  0x76, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0e, 0x44,
+  0xea, 0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b,
+  0x35, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xb4, 0xe0}},
+ {0x09c6, 64, { 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01,
+  0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x19, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xea,
+  0xe0, 0xf5, 0x18, 0x12, 0x0d, 0x67, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0x00, 0xe5, 0x18, 0xf0, 0x90,
+  0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60}},
+ {0x0a06, 64, { 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x13, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2,
+  0x17, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02,
+  0xf0, 0x02, 0x0b, 0x35, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02,
+  0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f}},
+ {0x0a46, 64, { 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0,
+  0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02,
+  0x0b, 0x35, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xe8, 0xe0,
+  0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xea, 0xe0}},
+ {0x0a86, 64, { 0xb4, 0x01, 0x05, 0xc2, 0x13, 0x02, 0x0b, 0x35, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b,
+  0x35, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4,
+  0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f,
+  0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54}},
+ {0x0ac6, 64, { 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90,
+  0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18,
+  0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x13, 0x80, 0x3f, 0x90,
+  0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90}},
+ {0x0b06, 64, { 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0,
+  0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f,
+  0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f,
+  0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x20, 0x15, 0x03, 0x02, 0x0b, 0xcf, 0xe5, 0x31, 0x60}},
+ {0x0b46, 64, { 0x02, 0x15, 0x31, 0xe5, 0x36, 0x60, 0x4f, 0x65, 0x34, 0x70, 0x45, 0xe5, 0x32, 0xf4, 0x60, 0x02, 0x05,
+  0x32, 0xe5, 0x32, 0xc3, 0x95, 0x41, 0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x01, 0x18, 0x90, 0x7f, 0xb8,
+  0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f, 0xb7, 0xe5, 0x36, 0xf0, 0xc2, 0x01, 0xe4, 0xf5, 0x36, 0xf5,
+  0x32, 0xf5, 0x34, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0x90, 0x7f, 0xb9}},
+ {0x0b86, 64, { 0xe5, 0x36, 0xf0, 0xd2, 0x01, 0xe4, 0xf5, 0x36, 0xf5, 0x32, 0xf5, 0x34, 0xd2, 0xaf, 0x80, 0x06, 0x85,
+  0x36, 0x34, 0xe4, 0xf5, 0x32, 0xe5, 0x2c, 0x60, 0x2f, 0x20, 0x0c, 0x07, 0x90, 0x7f, 0x9b, 0xe0,
+  0x30, 0xe0, 0x0f, 0xe5, 0x2d, 0x60, 0x06, 0xe4, 0xf5, 0x2d, 0x43, 0x33, 0x01, 0xe4, 0xf5, 0x30,
+  0x80, 0x14, 0xe5, 0x30, 0xd3, 0x95, 0x42, 0x50, 0x0d, 0xe5, 0x30, 0xb5, 0x42, 0x06, 0x75}},
+ {0x0bc6, 64, { 0x2d, 0x01, 0x43, 0x33, 0x01, 0x05, 0x30, 0xc2, 0x0c, 0x22, 0x75, 0x12, 0x01, 0xc2, 0x14, 0xc2, 0x18,
+  0xc2, 0x13, 0xc2, 0x17, 0xc2, 0x15, 0xc2, 0x12, 0xd2, 0x16, 0xe4, 0xf5, 0x18, 0x90, 0x7f, 0x92,
+  0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x13, 0xe4, 0x33, 0xfe, 0xef,
+  0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f}},
+ {0x0c06, 64, { 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53,
+  0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0,
+  0xd2, 0xaf, 0xd2, 0xbc, 0xd2, 0x19, 0x12, 0x0f, 0x36, 0xc2, 0x14, 0x30, 0x15, 0x03, 0x12, 0x05,
+  0x80, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x11, 0x60, 0x08, 0xe0, 0xf5, 0x11, 0x12, 0x0b, 0x3d}},
+ {0x0c46, 64, { 0x80, 0xea, 0x30, 0x14, 0x07, 0xc2, 0x14, 0x12, 0x09, 0x1a, 0x80, 0xe0, 0x30, 0x18, 0xdd, 0xc2, 0x18,
+  0x12, 0x00, 0x26, 0x80, 0xd6, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x50, 0x02,
+  0x0c, 0xa4, 0x02, 0x0b, 0xd0, 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}},
+ {0x0c86, 64, { 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, 0x0e, 0x00,
+  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}},
+ {0x0cc6, 64, { 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, 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}},
+ {0x0d06, 64, { 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, 0xd0, 0x83, 0xd0, 0x82, 0xf8}},
+ {0x0d46, 64, { 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,
+  0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x10,
+  0xf0, 0x90, 0x7f, 0x94, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0x9d, 0x04, 0xf0, 0x90, 0x7f, 0x97}},
+ {0x0d86, 64, { 0x74, 0x20, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x03, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x84, 0xf0, 0xe4, 0x90,
+  0x7f, 0x98, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x75,
+  0x98, 0x40, 0x43, 0xa8, 0x10, 0x90, 0x7f, 0xde, 0x74, 0x1f, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x0f,
+  0xf0, 0xd2, 0x15, 0x22, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f}},
+ {0x0dc6, 64, { 0x93, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x02, 0xf0, 0x90,
+  0x7f, 0x9d, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x20, 0xf0, 0xe4, 0x90, 0x7f, 0x96,
+  0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0xfd, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9e,
+  0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22, 0x0c, 0x24, 0x00, 0x00, 0x00, 0x00}},
+ {0x0e06, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x01, 0x33, 0x01, 0x01, 0x32, 0x00,
+  0x01, 0x37, 0x00, 0x01, 0x50, 0x00, 0x01, 0x36, 0x00, 0x01, 0x34, 0x00, 0xc1, 0x05, 0xc1, 0x0c,
+  0xc1, 0x03, 0xc1, 0x0f, 0xc1, 0x04, 0xc1, 0x0e, 0xc1, 0x11, 0xc1, 0x0a, 0xc1, 0x10, 0xc1, 0x08,
+  0xc1, 0x09, 0xc1, 0x06, 0xc1, 0x00, 0xc1, 0x0d, 0xc1, 0x81, 0xc1, 0x82, 0x00, 0x8f, 0x13}},
+ {0x0e46, 64, { 0xe4, 0xf5, 0x14, 0x75, 0x15, 0xff, 0x75, 0x16, 0x0f, 0x75, 0x17, 0xb9, 0xab, 0x15, 0xaa, 0x16, 0xa9,
+  0x17, 0x90, 0x00, 0x01, 0x12, 0x0d, 0x02, 0xb4, 0x03, 0x1d, 0xaf, 0x14, 0x05, 0x14, 0xef, 0xb5,
+  0x13, 0x01, 0x22, 0x12, 0x0c, 0xe9, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x15,
+  0xff, 0xf5, 0x16, 0x89, 0x17, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x22, 0xc0}},
+ {0x0e86, 64, { 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30, 0x16, 0x04,
+  0xc2, 0x16, 0x80, 0x02, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0,
+  0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83,
+  0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4}},
+ {0x0ec6, 64, { 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0,
+  0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3,
+  0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x02, 0x0f, 0x0f, 0x00, 0x02, 0x0f}},
+ {0x0f06, 64, { 0x04, 0x00, 0x02, 0x0e, 0xb3, 0x00, 0x02, 0x0e, 0x85, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85,
+  0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x14, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74,
+  0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90,
+  0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x19, 0x04, 0xe0, 0x44}},
+ {0x0f46, 64, { 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0,
+  0x44, 0x04, 0xf0, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00,
+  0x01, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x07, 0x01, 0x01, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09,
+  0x02, 0x43, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x07, 0xff, 0x00}},
+ {0x0f86, 64, { 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07,
+  0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82,
+  0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40,
+  0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73}},
+ {0x0fc6, 23, { 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x0e, 0x03, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00,
+  0x61, 0x00, 0x6c, 0x00, 0x00, 0x00}},
 { 0xffff,	0,	{0x00} }
 };
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa19w_fw.h linux/drivers/usb/serial/keyspan_usa19w_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa19w_fw.h	Mon Jul 10 14:33:04 2000
+++ linux/drivers/usb/serial/keyspan_usa19w_fw.h	Tue Oct  9 15:15:02 2001
@@ -1,10 +1,10 @@
 /* keyspan_usa19w_fw.h
   
-   Generated from Keyspan firmware image Wed Jul  5 09:18:29 2000 EST
+   Generated from Keyspan firmware image usa17code.h Sat Oct  6 12:13:03 EST 2001
    This firmware is for the Keyspan USA-19W Serial Adaptor
 
    "The firmware contained herein as keyspan_usa19w_fw.h is
-   Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
    ("Keyspan"), as an unpublished work.  This notice does not imply
    unrestricted or public access to this firmware which is a trade secret of
    Keyspan, and which may not be reproduced, used, sold or transferred to any
@@ -18,287 +18,425 @@
 */
 
 static const struct ezusb_hex_record keyspan_usa19w_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x09, 0x60} },
-{ 0x0003,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
-{ 0x0013,	16,	{0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90} },
-{ 0x0023,	15,	{0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x17, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22} },
-{ 0x0033,	3,	{0x02, 0x0e, 0x43} },
-{ 0x0036,	12,	{0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0043,	3,	{0x02, 0x0e, 0x00} },
-{ 0x0046,	16,	{0x30, 0x0d, 0x13, 0x12, 0x0e, 0x1f, 0xef, 0xc3, 0x95, 0x14, 0x50, 0x73, 0x90, 0x7f, 0xbf, 0x74} },
-{ 0x0056,	16,	{0x01, 0xf0, 0xc2, 0x0d, 0x80, 0x69, 0x30, 0x0a, 0x34, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x5f} },
-{ 0x0066,	16,	{0x12, 0x0e, 0x1f, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x56, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x0d} },
-{ 0x0076,	16,	{0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x23, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x27, 0x7e, 0x75, 0x28} },
-{ 0x0086,	16,	{0x41, 0x12, 0x08, 0xab, 0xc2, 0x0a, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x32, 0x90, 0x7f, 0xc8} },
-{ 0x0096,	16,	{0xe0, 0x20, 0xe1, 0x2b, 0x12, 0x0e, 0x1f, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x22, 0x90, 0x7d, 0xc0} },
-{ 0x00a6,	16,	{0xe0, 0x13, 0x92, 0x0d, 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x23, 0x7e, 0x7d, 0x7f, 0xc1, 0x75} },
-{ 0x00b6,	16,	{0x27, 0x7d, 0x75, 0x28, 0xc1, 0x12, 0x08, 0xab, 0xd2, 0x0a, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0x90} },
-{ 0x00c6,	16,	{0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x4d, 0x53, 0x11, 0x80, 0x12, 0x0e, 0x2b, 0xef} },
-{ 0x00d6,	16,	{0x42, 0x11, 0x12, 0x0c, 0xc8, 0x8f, 0x34, 0xef, 0xc3, 0x95, 0x13, 0x50, 0x0f, 0x12, 0x0d, 0xf1} },
-{ 0x00e6,	16,	{0xef, 0x30, 0xe0, 0x08, 0xe5, 0x11, 0x20, 0xe7, 0x03, 0x30, 0x10, 0x5b, 0xc2, 0x10, 0xe5, 0x34} },
-{ 0x00f6,	16,	{0x70, 0x04, 0xf5, 0x11, 0x80, 0x51, 0xe5, 0x11, 0x30, 0xe7, 0x26, 0xe5, 0x34, 0xd3, 0x94, 0x20} },
-{ 0x0106,	16,	{0x40, 0x03, 0x75, 0x34, 0x20, 0x85, 0x34, 0x23, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x27, 0x7e, 0x75} },
-{ 0x0116,	16,	{0x28, 0x80, 0xaf, 0x11, 0x12, 0x0b, 0x01, 0xe5, 0x34, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80} },
-{ 0x0126,	16,	{0x26, 0xe5, 0x34, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x34, 0x3f, 0x85, 0x34, 0x23, 0xe4, 0x90} },
-{ 0x0136,	16,	{0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x27, 0x7e, 0x75, 0x28, 0x81, 0x12, 0x08, 0xd0} },
-{ 0x0146,	16,	{0xe5, 0x34, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x0b} },
-{ 0x0156,	16,	{0x03, 0x02, 0x03, 0xb2, 0xe4, 0xf5, 0x33, 0x74, 0x40, 0x25, 0x33, 0xf5, 0x82, 0xe4, 0x34, 0x7c} },
-{ 0x0166,	16,	{0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x33, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00} },
-{ 0x0176,	16,	{0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x08, 0x3b, 0x05, 0x33, 0xe5, 0x33, 0xb4, 0x20, 0xd7} },
-{ 0x0186,	16,	{0x90, 0x7e, 0x00, 0xe0, 0x60, 0x6e, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12, 0x0c, 0xa3} },
-{ 0x0196,	16,	{0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x0b, 0xe5, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x0c, 0x0b} },
-{ 0x01a6,	16,	{0xd2, 0x0e, 0xd2, 0x0f, 0x75, 0x34, 0x04, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x05, 0xc2, 0x0f, 0x43} },
-{ 0x01b6,	16,	{0x34, 0xc0, 0x90, 0x7e, 0x04, 0xe0, 0xb4, 0x01, 0x07, 0xc2, 0x0f, 0x43, 0x34, 0x0b, 0x80, 0x10} },
-{ 0x01c6,	16,	{0x90, 0x7e, 0x04, 0xe0, 0x60, 0x07, 0xc2, 0x0e, 0x43, 0x34, 0x09, 0x80, 0x03, 0x43, 0x34, 0x02} },
-{ 0x01d6,	16,	{0x7f, 0x03, 0xad, 0x34, 0x12, 0x0c, 0xa3, 0x43, 0x19, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0} },
-{ 0x01e6,	16,	{0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x16, 0x44, 0x06} },
-{ 0x01f6,	16,	{0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x18} },
-{ 0x0206,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x18, 0xf0, 0x90, 0x7e, 0x07, 0xe0} },
-{ 0x0216,	16,	{0x60, 0x42, 0x90, 0x7e, 0x13, 0xe0, 0x60, 0x05, 0x43, 0x15, 0x04, 0x80, 0x03, 0x53, 0x15, 0xfb} },
-{ 0x0226,	16,	{0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0xa3, 0x90, 0x7e, 0x08, 0xe0, 0x60, 0x05, 0x43, 0x17, 0x80} },
-{ 0x0236,	16,	{0x80, 0x03, 0x53, 0x17, 0x7f, 0x53, 0x17, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x17} },
-{ 0x0246,	16,	{0x02, 0xa3, 0xe0, 0xff, 0x12, 0x0c, 0x57, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x0c, 0x7d, 0xaf} },
-{ 0x0256,	16,	{0x17, 0x12, 0x0c, 0x31, 0x90, 0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x19} },
-{ 0x0266,	16,	{0x01, 0x80, 0x03, 0x53, 0x19, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5} },
-{ 0x0276,	16,	{0x19, 0xf0, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x19, 0x02, 0x80} },
-{ 0x0286,	16,	{0x03, 0x53, 0x19, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0} },
-{ 0x0296,	16,	{0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x13, 0xa3, 0xe0, 0x13, 0x92, 0x11, 0xa3, 0xe0, 0xf5, 0x14, 0xa3} },
-{ 0x02a6,	16,	{0xe0, 0x60, 0x05, 0x43, 0x19, 0x10, 0x80, 0x03, 0x53, 0x19, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14} },
-{ 0x02b6,	16,	{0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x18, 0xbf} },
-{ 0x02c6,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f} },
-{ 0x02d6,	16,	{0x98, 0x74, 0x11, 0xf0, 0x12, 0x0d, 0xe5, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x15} },
-{ 0x02e6,	16,	{0xfd, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0xa3, 0xe4, 0xf5, 0x0e, 0xf5, 0x0d, 0xd2, 0x0c, 0x90} },
-{ 0x02f6,	16,	{0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, 0x15, 0x02, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0xa3, 0x75} },
-{ 0x0306,	16,	{0x0d, 0x01, 0xd2, 0x0c, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x1b, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0} },
-{ 0x0316,	16,	{0xe5, 0x16, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9} },
-{ 0x0326,	16,	{0xf0, 0xd2, 0x0a, 0xc2, 0x0d, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x18, 0x40, 0x90, 0x7f} },
-{ 0x0336,	16,	{0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0} },
-{ 0x0346,	16,	{0x60, 0x0f, 0x53, 0x15, 0xfe, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0xa3, 0x75, 0x0f, 0x01, 0xd2} },
-{ 0x0356,	16,	{0x0c, 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x15, 0x01, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c} },
-{ 0x0366,	16,	{0xa3, 0xe4, 0xf5, 0x0f, 0xd2, 0x0c, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0376,	16,	{0x12, 0xf0, 0xe5, 0x16, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02} },
-{ 0x0386,	16,	{0xd2, 0x10, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x10, 0x01, 0xe4, 0xf5, 0x12, 0xd2, 0x0c} },
-{ 0x0396,	16,	{0x90, 0x7e, 0x1f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74} },
-{ 0x03a6,	16,	{0x15, 0xf0, 0x74, 0x35, 0xf0, 0xc2, 0x0b, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x13, 0x71, 0xe5} },
-{ 0x03b6,	16,	{0x12, 0x60, 0x02, 0x15, 0x12, 0xe5, 0x2e, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x2e, 0x80, 0x60} },
-{ 0x03c6,	16,	{0x75, 0x2e, 0x0a, 0x12, 0x0d, 0xe5, 0xef, 0x54, 0x01, 0xf5, 0x34, 0x65, 0x0e, 0x60, 0x07, 0x85} },
-{ 0x03d6,	16,	{0x34, 0x0e, 0xd2, 0x0c, 0x80, 0x11, 0x12, 0x0e, 0x37, 0xef, 0x54, 0x10, 0xf5, 0x34, 0x65, 0x09} },
-{ 0x03e6,	16,	{0x60, 0x05, 0x85, 0x34, 0x09, 0xd2, 0x0c, 0x12, 0x0e, 0x37, 0xef, 0x54, 0x80, 0xf5, 0x34, 0x65} },
-{ 0x03f6,	16,	{0x0a, 0x60, 0x05, 0x85, 0x34, 0x0a, 0xd2, 0x0c, 0x12, 0x0e, 0x37, 0xef, 0x54, 0x20, 0xf5, 0x34} },
-{ 0x0406,	16,	{0x65, 0x0b, 0x60, 0x08, 0x85, 0x34, 0x0b, 0x30, 0x0e, 0x02, 0xd2, 0x0c, 0x12, 0x0e, 0x37, 0xef} },
-{ 0x0416,	16,	{0x54, 0x40, 0xf5, 0x34, 0x65, 0x0c, 0x60, 0x08, 0x85, 0x34, 0x0c, 0x30, 0x0f, 0x02, 0xd2, 0x0c} },
-{ 0x0426,	16,	{0x30, 0x13, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09} },
-{ 0x0436,	16,	{0xe0, 0xf5, 0x30, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x31, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90} },
-{ 0x0446,	16,	{0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2} },
-{ 0x0456,	16,	{0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, 0x17, 0xe5, 0x25, 0x70, 0x40, 0x30, 0x0c, 0x39, 0xe5, 0x12} },
-{ 0x0466,	16,	{0x70, 0x35, 0xc2, 0x0c, 0xf5, 0x33, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x08, 0x25, 0x33, 0xf9, 0xee} },
-{ 0x0476,	16,	{0x34, 0x00, 0xfa, 0x12, 0x07, 0xf5, 0xff, 0x74, 0x80, 0x25, 0x33, 0xf5, 0x82, 0xe4, 0x34, 0x7b} },
-{ 0x0486,	16,	{0xf5, 0x83, 0xef, 0xf0, 0x05, 0x33, 0xe5, 0x33, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09} },
-{ 0x0496,	16,	{0xf0, 0x75, 0x12, 0x10, 0xe4, 0xf5, 0x10, 0x75, 0x25, 0x02, 0x22, 0xe5, 0x25, 0x64, 0x02, 0x70} },
-{ 0x04a6,	16,	{0x36, 0x30, 0x05, 0x2f, 0xc2, 0x05, 0xf5, 0x33, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x29, 0x25, 0x33} },
-{ 0x04b6,	16,	{0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x07, 0xf5, 0xff, 0x74, 0x80, 0x25, 0x33, 0xf5, 0x82, 0xe4} },
-{ 0x04c6,	16,	{0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x33, 0xe5, 0x33, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3} },
-{ 0x04d6,	16,	{0x74, 0x05, 0xf0, 0x75, 0x25, 0x03, 0x22, 0xe5, 0x30, 0x60, 0x33, 0x75, 0x2f, 0x03, 0x15, 0x30} },
-{ 0x04e6,	16,	{0xe4, 0xf5, 0x33, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2f, 0x25, 0x33, 0xf9, 0xee, 0x34, 0x00, 0xfa} },
-{ 0x04f6,	16,	{0x12, 0x07, 0xf5, 0xff, 0x74, 0x80, 0x25, 0x33, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef} },
-{ 0x0506,	16,	{0xf0, 0x05, 0x33, 0xe5, 0x33, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5} },
-{ 0x0516,	1,	{0x25} },
-{ 0x0517,	1,	{0x22} },
-{ 0x0518,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x08, 0x85, 0x05, 0xe8, 0x00, 0x06, 0x5c, 0x01, 0x06, 0xc9, 0x03} },
-{ 0x0528,	16,	{0x05, 0x3b, 0x06, 0x05, 0xdb, 0x08, 0x05, 0xd5, 0x09, 0x05, 0xbd, 0x0a, 0x05, 0xcc, 0x0b, 0x00} },
-{ 0x0538,	16,	{0x00, 0x07, 0x19, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x40, 0x24, 0x02} },
-{ 0x0548,	16,	{0x70, 0x69, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07} },
-{ 0x0558,	16,	{0x20, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x71, 0x8b, 0x33, 0x8a, 0x34, 0x89, 0x35, 0xea} },
-{ 0x0568,	16,	{0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5} },
-{ 0x0578,	16,	{0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f} },
-{ 0x0588,	16,	{0xea, 0xe0, 0xff, 0x12, 0x0a, 0xc0, 0x8b, 0x33, 0x8a, 0x34, 0x89, 0x35, 0xea, 0x49, 0x60, 0x11} },
-{ 0x0598,	16,	{0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07} },
-{ 0x05a8,	16,	{0x20, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0xb4, 0xe0, 0x44} },
-{ 0x05b8,	16,	{0x01, 0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0x00, 0xe5, 0x24, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01} },
-{ 0x05c8,	16,	{0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x24, 0x02, 0x07, 0x20, 0x12, 0x07, 0x28} },
-{ 0x05d8,	16,	{0x02, 0x07, 0x20, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x07, 0x20} },
-{ 0x05e8,	16,	{0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2} },
-{ 0x05f8,	16,	{0x01, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0} },
-{ 0x0608,	16,	{0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x20, 0xe4, 0x90, 0x7f, 0x00} },
-{ 0x0618,	16,	{0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0xec, 0xe0} },
-{ 0x0628,	16,	{0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} },
-{ 0x0638,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3} },
-{ 0x0648,	16,	{0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01} },
-{ 0x0658,	16,	{0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1e, 0x24, 0x02, 0x60, 0x03} },
-{ 0x0668,	16,	{0x02, 0x07, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x06, 0x12, 0x0e, 0x47, 0x02, 0x07, 0x20} },
-{ 0x0678,	16,	{0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x20, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38} },
-{ 0x0688,	16,	{0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f} },
-{ 0x0698,	16,	{0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec} },
-{ 0x06a8,	16,	{0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f} },
-{ 0x06b8,	16,	{0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x60, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80} },
-{ 0x06c8,	16,	{0x57, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x24, 0x02, 0x70, 0x4b, 0x90, 0x7f, 0xea} },
-{ 0x06d8,	16,	{0xe0, 0xb4, 0x01, 0x05, 0x12, 0x0d, 0xfd, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0} },
-{ 0x06e8,	16,	{0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff} },
-{ 0x06f8,	16,	{0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x0708,	16,	{0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80} },
-{ 0x0718,	15,	{0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
-{ 0x0727,	1,	{0x22} },
-{ 0x0728,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
-{ 0x0738,	16,	{0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0748,	16,	{0x18, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4} },
-{ 0x0758,	16,	{0xf5, 0x08, 0x7f, 0x01, 0x7b, 0x00, 0x74, 0x08, 0x2f, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12} },
-{ 0x0768,	16,	{0x08, 0x3b, 0x0f, 0xbf, 0x09, 0xee, 0x75, 0x13, 0x01, 0xe4, 0xf5, 0x12, 0xf5, 0x2e, 0xf5, 0x11} },
-{ 0x0778,	16,	{0xc2, 0x0c, 0xc2, 0x10, 0xc2, 0x0b, 0xc2, 0x0d, 0xc2, 0x04, 0xd2, 0x0a, 0xd2, 0x09, 0x90, 0x7f} },
-{ 0x0788,	16,	{0x98, 0x74, 0x13, 0xf0, 0x75, 0x18, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4} },
-{ 0x0798,	16,	{0xfd, 0x12, 0x0c, 0xa3, 0x7f, 0x10, 0x8f, 0x17, 0x12, 0x0c, 0x31, 0x90, 0x7f, 0x98, 0x74, 0x12} },
-{ 0x07a8,	16,	{0xf0, 0x7f, 0x01, 0x8f, 0x16, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x07b8,	16,	{0x14, 0xf0, 0x75, 0x19, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x0c} },
-{ 0x07c8,	16,	{0xa3, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x15, 0x12, 0x0c, 0xa3, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x07d8,	16,	{0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x0c, 0xa3, 0x7f, 0x01} },
-{ 0x07e8,	12,	{0x12, 0x0d, 0x7d, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x0c, 0xa3, 0xd2, 0x03} },
-{ 0x07f4,	1,	{0x22} },
-{ 0x07f5,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x0805,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x080e,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x081e,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x082e,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x083b,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} },
-{ 0x084b,	2,	{0xf3, 0x22} },
-{ 0x084d,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0x085d,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0x086d,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0x087d,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0x0885,	16,	{0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} },
-{ 0x0895,	16,	{0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} },
-{ 0x08a5,	6,	{0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} },
-{ 0x08ab,	16,	{0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83} },
-{ 0x08bb,	16,	{0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86} },
-{ 0x08cb,	16,	{0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5} },
-{ 0x08db,	16,	{0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0} },
-{ 0x08eb,	16,	{0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0} },
-{ 0x08fb,	16,	{0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0} },
-{ 0x090b,	16,	{0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90} },
-{ 0x091b,	16,	{0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2} },
-{ 0x092b,	16,	{0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05} },
-{ 0x093b,	4,	{0x86, 0xd2, 0xaf, 0x22} },
-{ 0x093f,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x094f,	1,	{0x22} },
-{ 0x0950,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x0960,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x3a, 0x02, 0x09, 0xa7} },
-{ 0x096c,	16,	{0x02, 0x09, 0xec, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x097c,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x098c,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x099c,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x0d, 0x9e, 0xe4, 0x7e} },
-{ 0x09ac,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x09bc,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x09cc,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x09dc,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x09ec,	16,	{0xd2, 0x12, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x0e, 0x47, 0xd2, 0xe8, 0x43, 0xd8} },
-{ 0x09fc,	16,	{0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff} },
-{ 0x0a0c,	16,	{0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0} },
-{ 0x0a1c,	16,	{0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x13, 0x12, 0x0d, 0x37} },
-{ 0x0a2c,	16,	{0xc2, 0x02, 0xe4, 0xf5, 0x26, 0xf5, 0x2e, 0xc2, 0x07, 0xc2, 0x03, 0x90, 0x7f, 0xa1, 0x04, 0xf0} },
-{ 0x0a3c,	16,	{0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x32, 0x60, 0x10, 0x30, 0x03, 0x05, 0xd2, 0x13, 0x12, 0x00, 0x46} },
-{ 0x0a4c,	16,	{0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x32, 0x80, 0x08, 0x30, 0x03, 0x05, 0xc2, 0x13, 0x12, 0x00, 0x46} },
-{ 0x0a5c,	16,	{0x30, 0x02, 0x07, 0xc2, 0x02, 0x12, 0x05, 0x18, 0x80, 0xd6, 0x30, 0x08, 0xd3, 0xc2, 0x08, 0x12} },
-{ 0x0a6c,	4,	{0x0b, 0x68, 0x80, 0xcc} },
-{ 0x0a70,	1,	{0x22} },
-{ 0x0a71,	16,	{0xe4, 0xfe, 0x75, 0x38, 0xff, 0x75, 0x39, 0x19, 0x75, 0x3a, 0x12, 0xab, 0x38, 0xaa, 0x39, 0xa9} },
-{ 0x0a81,	16,	{0x3a, 0x90, 0x00, 0x01, 0x12, 0x08, 0x0e, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x0a91,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x08, 0x4d, 0x85, 0xf0, 0x36, 0xf5, 0x37, 0x62, 0x36} },
-{ 0x0aa1,	16,	{0xe5, 0x36, 0x62, 0x37, 0xe5, 0x37, 0x62, 0x36, 0x29, 0xfd, 0xe5, 0x36, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x0ab1,	14,	{0x38, 0xff, 0xf5, 0x39, 0x89, 0x3a, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0abf,	1,	{0x22} },
-{ 0x0ac0,	2,	{0x8f, 0x36} },
-{ 0x0ac2,	16,	{0xe4, 0xf5, 0x37, 0x75, 0x38, 0xff, 0x75, 0x39, 0x19, 0x75, 0x3a, 0x86, 0xab, 0x38, 0xaa, 0x39} },
-{ 0x0ad2,	16,	{0xa9, 0x3a, 0x90, 0x00, 0x01, 0x12, 0x08, 0x0e, 0xb4, 0x03, 0x1d, 0xaf, 0x37, 0x05, 0x37, 0xef} },
-{ 0x0ae2,	16,	{0xb5, 0x36, 0x01, 0x22, 0x12, 0x07, 0xf5, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0af2,	14,	{0x38, 0xff, 0xf5, 0x39, 0x89, 0x3a, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0b00,	1,	{0x22} },
-{ 0x0b01,	16,	{0x8f, 0x35, 0x05, 0x28, 0xe5, 0x28, 0xae, 0x27, 0x70, 0x02, 0x05, 0x27, 0x14, 0xf5, 0x82, 0x8e} },
-{ 0x0b11,	16,	{0x83, 0xe5, 0x35, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x28, 0xe5, 0x28, 0xac, 0x27, 0x70, 0x02, 0x05} },
-{ 0x0b21,	16,	{0x27, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x23, 0xe5, 0x23, 0x60, 0x0a, 0x12, 0x0e} },
-{ 0x0b31,	9,	{0x2b, 0x8f, 0x35, 0xef, 0x42, 0x11, 0x80, 0xca, 0x22} },
-{ 0x0b3a,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} },
-{ 0x0b4a,	16,	{0x14, 0x04, 0xc2, 0x14, 0x80, 0x02, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} },
-{ 0x0b5a,	14,	{0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0b68,	16,	{0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x33, 0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0} },
-{ 0x0b78,	16,	{0x12, 0x09, 0x50, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x0e, 0x30, 0x01, 0x05, 0x12, 0x0d, 0xcf} },
-{ 0x0b88,	11,	{0x80, 0x06, 0x12, 0x0d, 0x5c, 0xef, 0x60, 0xe1, 0x12, 0x07, 0x28} },
-{ 0x0b93,	1,	{0x22} },
-{ 0x0b94,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} },
-{ 0x0ba4,	16,	{0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} },
-{ 0x0bb4,	10,	{0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0bbe,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} },
-{ 0x0bce,	16,	{0x02, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} },
-{ 0x0bde,	7,	{0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0be5,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0bf5,	16,	{0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54} },
-{ 0x0c05,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x0c0b,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0c1b,	16,	{0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54} },
-{ 0x0c2b,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x0c31,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0c41,	16,	{0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54} },
-{ 0x0c51,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x0c57,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0c67,	16,	{0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54} },
-{ 0x0c77,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x0c7d,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0c8d,	16,	{0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54} },
-{ 0x0c9d,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x0ca3,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f} },
-{ 0x0cb3,	16,	{0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90} },
-{ 0x0cc3,	5,	{0xc0, 0x00, 0xed, 0xf0, 0x22} },
-{ 0x0cc8,	16,	{0x12, 0x0e, 0x13, 0x8f, 0x35, 0x12, 0x0e, 0x13, 0x8f, 0x36, 0xe5, 0x35, 0x65, 0x36, 0x60, 0x12} },
-{ 0x0cd8,	16,	{0x12, 0x0e, 0x13, 0x8f, 0x35, 0xe5, 0x35, 0x65, 0x36, 0x60, 0x07, 0x12, 0x0e, 0x13, 0x8f, 0x36} },
-{ 0x0ce8,	4,	{0x80, 0xe8, 0xaf, 0x35} },
-{ 0x0cec,	1,	{0x22} },
-{ 0x0ced,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x0cfd,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x0d0d,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d12,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x0d22,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x0d32,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d37,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x13, 0x04, 0xe0, 0x44} },
-{ 0x0d47,	16,	{0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x0d, 0xb8, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x0d57,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x0d5c,	16,	{0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x34, 0x12, 0x07, 0x28, 0x12, 0x0e, 0x37, 0xef, 0x30, 0xe6, 0x0b} },
-{ 0x0d6c,	16,	{0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x34, 0x60, 0xf1, 0x7f, 0x01, 0x22, 0x12, 0x00, 0x03, 0x7f, 0x00} },
-{ 0x0d7c,	1,	{0x22} },
-{ 0x0d7d,	16,	{0xae, 0x07, 0xe4, 0xff, 0xe5, 0x15, 0x54, 0x7f, 0xfd, 0x12, 0x0c, 0xa3, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0d8d,	16,	{0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x15, 0x44, 0x80, 0xfd, 0x12, 0x0c, 0xa3} },
-{ 0x0d9d,	1,	{0x22} },
-{ 0x0d9e,	16,	{0x05, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x2f, 0x03, 0x00, 0x00, 0xc1, 0x02, 0xc1, 0x08} },
-{ 0x0dae,	7,	{0xc1, 0x01, 0xc1, 0x86, 0x01, 0x25, 0x00} },
-{ 0x0db5,	2,	{0xc1, 0x94} },
-{ 0x0db7,	1,	{0x00} },
-{ 0x0db8,	16,	{0x8e, 0x34, 0x8f, 0x35, 0xe5, 0x35, 0x15, 0x35, 0xae, 0x34, 0x70, 0x02, 0x15, 0x34, 0x4e, 0x60} },
-{ 0x0dc8,	7,	{0x05, 0x12, 0x09, 0x3f, 0x80, 0xee, 0x22} },
-{ 0x0dcf,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x0d, 0xb8, 0x90, 0x7f} },
-{ 0x0ddf,	6,	{0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22} },
-{ 0x0de5,	12,	{0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0df1,	12,	{0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0dfd,	3,	{0xd2, 0x01, 0x22} },
-{ 0x0e00,	16,	{0x02, 0x0b, 0xbe, 0x00, 0x02, 0x0c, 0xed, 0x00, 0x02, 0x0b, 0x94, 0x00, 0x02, 0x0b, 0x3a, 0x00} },
-{ 0x0e10,	3,	{0x02, 0x0d, 0x12} },
-{ 0x0e13,	12,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0e1f,	12,	{0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0e2b,	12,	{0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0e37,	12,	{0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0e43,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x0e47,	3,	{0xc2, 0x01, 0x22} },
-{ 0x1900,	16,	{0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x08, 0x01, 0x00, 0x00, 0x01, 0x02} },
-{ 0x1910,	16,	{0x00, 0x01, 0x09, 0x02, 0x74, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e} },
-{ 0x1920,	16,	{0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} },
-{ 0x1930,	16,	{0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00} },
-{ 0x1940,	16,	{0x07, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} },
-{ 0x1950,	16,	{0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02} },
-{ 0x1960,	16,	{0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00} },
-{ 0x1970,	16,	{0x00, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07} },
-{ 0x1980,	16,	{0x05, 0x87, 0x02, 0x40, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00} },
-{ 0x1990,	16,	{0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00} },
-{ 0x19a0,	16,	{0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00} },
-{ 0x19b0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00} },
-{ 0x19c0,	16,	{0x6f, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} },
-{ 0x19d0,	16,	{0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00} },
-{ 0x19e0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00} },
-{ 0x19f0,	16,	{0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00} },
-{ 0x1a00,	10,	{0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00} },
+ {0x0033,  3, { 0x02, 0x0d, 0x6c}},
+ {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}},
+ {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}},
+ {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x17, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}},
+ {0x0046, 16, { 0x30, 0x0f, 0x18, 0x12, 0x0d, 0x48, 0xef, 0xc3, 0x95, 0x14, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}},
+ {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x0f, 0xc2, 0x0a, 0x80, 0x77, 0x30, 0x0c, 0x3b, 0x90, 0x7f}},
+ {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x0d, 0x48, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}},
+ {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x0f, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x1c, 0x20, 0x0a, 0x11, 0x60}},
+ {0x0086, 16, { 0x0f, 0xf5, 0x23, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x27, 0x7e, 0x75, 0x28, 0x41, 0x12, 0x08, 0x05}},
+ {0x0096, 16, { 0xc2, 0x0c, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}},
+ {0x00a6, 16, { 0x12, 0x0d, 0x48, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x0f}},
+ {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x1c, 0x20, 0x0a, 0x11, 0x60, 0x0f, 0xf5, 0x23, 0x7e, 0x7d}},
+ {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x27, 0x7d, 0x75, 0x28, 0xc1, 0x12, 0x08, 0x05, 0xd2, 0x0c, 0xe4, 0x90, 0x7f}},
+ {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x60, 0x53, 0x11, 0x80, 0x12}},
+ {0x00e6, 16, { 0x0d, 0x54, 0xef, 0x42, 0x11, 0x12, 0x0c, 0x51, 0x8f, 0x1c, 0xef, 0xc3, 0x95, 0x13, 0x50, 0x0f}},
+ {0x00f6, 16, { 0x12, 0x0d, 0x30, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x11, 0x20, 0xe7, 0x03, 0x30, 0x12, 0x5b, 0xc2}},
+ {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}},
+ {0x0043,  3, { 0x02, 0x0e, 0x00}},
+ {0x0000,  3, { 0x02, 0x08, 0xba}},
+ {0x0106, 64, { 0x12, 0xe5, 0x1c, 0x70, 0x04, 0xf5, 0x11, 0x80, 0x51, 0xe5, 0x11, 0x30, 0xe7, 0x26, 0xe5, 0x1c, 0xd3,
+  0x94, 0x20, 0x40, 0x03, 0x75, 0x1c, 0x20, 0x85, 0x1c, 0x23, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x27,
+  0x7e, 0x75, 0x28, 0x80, 0xaf, 0x11, 0x12, 0x0a, 0x8a, 0xe5, 0x1c, 0x25, 0xe0, 0x90, 0x7f, 0xb7,
+  0xf0, 0x80, 0x26, 0xe5, 0x1c, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x1c, 0x3f, 0x85, 0x1c}},
+ {0x0146, 64, { 0x23, 0xe4, 0x90, 0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x27, 0x7e, 0x75, 0x28, 0x81, 0x12,
+  0x08, 0x2a, 0xe5, 0x1c, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06,
+  0x20, 0x0d, 0x03, 0x02, 0x03, 0xba, 0xe4, 0xf5, 0x1b, 0x74, 0x40, 0x25, 0x1b, 0xf5, 0x82, 0xe4,
+  0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1b, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79}},
+ {0x0186, 64, { 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0a, 0x11, 0x05, 0x1b, 0xe5, 0x1b, 0xb4,
+  0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x6e, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12,
+  0x0c, 0x2c, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x0b, 0x6e, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12,
+  0x0b, 0x94, 0xd2, 0x10, 0xd2, 0x11, 0x75, 0x1c, 0x04, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x05}},
+ {0x01c6, 64, { 0xc2, 0x11, 0x43, 0x1c, 0xc0, 0x90, 0x7e, 0x04, 0xe0, 0xb4, 0x01, 0x07, 0xc2, 0x11, 0x43, 0x1c, 0x0b,
+  0x80, 0x10, 0x90, 0x7e, 0x04, 0xe0, 0x60, 0x07, 0xc2, 0x10, 0x43, 0x1c, 0x09, 0x80, 0x03, 0x43,
+  0x1c, 0x02, 0x7f, 0x03, 0xad, 0x1c, 0x12, 0x0c, 0x2c, 0x43, 0x19, 0x80, 0x90, 0x7f, 0x98, 0x74,
+  0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5}},
+ {0x0206, 64, { 0x16, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f,
+  0xf5, 0x18, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x18, 0xf0, 0x90, 0x7e,
+  0x07, 0xe0, 0x60, 0x42, 0x90, 0x7e, 0x13, 0xe0, 0x60, 0x05, 0x43, 0x15, 0x04, 0x80, 0x03, 0x53,
+  0x15, 0xfb, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0x2c, 0x90, 0x7e, 0x08, 0xe0, 0x60, 0x05}},
+ {0x0246, 64, { 0x43, 0x17, 0x80, 0x80, 0x03, 0x53, 0x17, 0x7f, 0x53, 0x17, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11,
+  0x43, 0x17, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x0b, 0xe0, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x0c,
+  0x06, 0xaf, 0x17, 0x12, 0x0b, 0xba, 0x90, 0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05,
+  0x43, 0x19, 0x01, 0x80, 0x03, 0x53, 0x19, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90}},
+ {0x0286, 64, { 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x19,
+  0x02, 0x80, 0x03, 0x53, 0x19, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5,
+  0x19, 0xf0, 0x90, 0x7e, 0x12, 0xe0, 0xf5, 0x13, 0xa3, 0xe0, 0x13, 0x92, 0x13, 0xa3, 0xe0, 0xf5,
+  0x14, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x19, 0x10, 0x80, 0x03, 0x53, 0x19, 0xef, 0x90, 0x7f}},
+ {0x02c6, 64, { 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x19, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53,
+  0x18, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0,
+  0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x12, 0x0d, 0x24, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0,
+  0x53, 0x15, 0xfd, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0x2c, 0xe4, 0xf5, 0x0e, 0xf5, 0x0d}},
+ {0x0306, 64, { 0xd2, 0x0e, 0x90, 0x7e, 0x17, 0xe0, 0x60, 0x0f, 0x43, 0x15, 0x02, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c,
+  0x2c, 0x75, 0x0d, 0x01, 0xd2, 0x0e, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74,
+  0x12, 0xf0, 0xe5, 0x16, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x0a, 0x90, 0x7e, 0x19, 0xe0,
+  0x60, 0x11, 0x43, 0x18, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f}},
+ {0x0346, 64, { 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53, 0x15, 0xfe, 0xe4, 0xff, 0xad, 0x15,
+  0x12, 0x0c, 0x2c, 0x75, 0x0f, 0x01, 0xd2, 0x0e, 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x15,
+  0x01, 0xe4, 0xff, 0xad, 0x15, 0x12, 0x0c, 0x2c, 0xe4, 0xf5, 0x0f, 0xd2, 0x0e, 0x90, 0x7e, 0x1c,
+  0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x16, 0x44, 0x02, 0x90, 0xc0}},
+ {0x0386, 64, { 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x12, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75,
+  0x10, 0x01, 0xe4, 0xf5, 0x12, 0xd2, 0x0e, 0x90, 0x7e, 0x1f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7,
+  0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35, 0xf0, 0xc2, 0x0d, 0xe4, 0x90,
+  0x7f, 0xcf, 0xf0, 0x30, 0x15, 0x71, 0xe5, 0x12, 0x60, 0x02, 0x15, 0x12, 0xe5, 0x2e, 0xd3}},
+ {0x03c6, 64, { 0x94, 0x00, 0x40, 0x04, 0x15, 0x2e, 0x80, 0x60, 0x75, 0x2e, 0x0a, 0x12, 0x0d, 0x24, 0xef, 0x54, 0x01,
+  0xf5, 0x1c, 0x65, 0x0e, 0x60, 0x07, 0x85, 0x1c, 0x0e, 0xd2, 0x0e, 0x80, 0x11, 0x12, 0x0d, 0x60,
+  0xef, 0x54, 0x10, 0xf5, 0x1c, 0x65, 0x09, 0x60, 0x05, 0x85, 0x1c, 0x09, 0xd2, 0x0e, 0x12, 0x0d,
+  0x60, 0xef, 0x54, 0x80, 0xf5, 0x1c, 0x65, 0x0a, 0x60, 0x05, 0x85, 0x1c, 0x0a, 0xd2, 0x0e}},
+ {0x0406, 64, { 0x12, 0x0d, 0x60, 0xef, 0x54, 0x20, 0xf5, 0x1c, 0x65, 0x0b, 0x60, 0x08, 0x85, 0x1c, 0x0b, 0x30, 0x10,
+  0x02, 0xd2, 0x0e, 0x12, 0x0d, 0x60, 0xef, 0x54, 0x40, 0xf5, 0x1c, 0x65, 0x0c, 0x60, 0x08, 0x85,
+  0x1c, 0x0c, 0x30, 0x11, 0x02, 0xd2, 0x0e, 0x30, 0x15, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1,
+  0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x30, 0x90, 0x7b, 0x42, 0xe0, 0xf5}},
+ {0x0446, 64, { 0x31, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4,
+  0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, 0x1f, 0xe5, 0x25,
+  0x70, 0x40, 0x30, 0x0e, 0x39, 0xe5, 0x12, 0x70, 0x35, 0xc2, 0x0e, 0xf5, 0x1b, 0x7e, 0x00, 0x7b,
+  0x00, 0x74, 0x08, 0x25, 0x1b, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x09, 0xcb, 0xff, 0x74}},
+ {0x0486, 64, { 0x80, 0x25, 0x1b, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1b, 0xe5, 0x1b, 0xb4,
+  0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x12, 0x10, 0xe4, 0xf5, 0x10, 0x75, 0x25,
+  0x02, 0x22, 0xe5, 0x25, 0x64, 0x02, 0x70, 0x36, 0x30, 0x05, 0x2f, 0xc2, 0x05, 0xf5, 0x1b, 0x7e,
+  0x00, 0x7b, 0x00, 0x74, 0x29, 0x25, 0x1b, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x09, 0xcb}},
+ {0x04c6, 64, { 0xff, 0x74, 0x80, 0x25, 0x1b, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1b, 0xe5,
+  0x1b, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x25, 0x03, 0x22, 0xe5, 0x30,
+  0x60, 0x33, 0x75, 0x2f, 0x03, 0x15, 0x30, 0xe4, 0xf5, 0x1b, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2f,
+  0x25, 0x1b, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x09, 0xcb, 0xff, 0x74, 0x80, 0x25, 0x1b}},
+ {0x0506, 64, { 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, 0x03, 0xdb, 0x90,
+  0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x25, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0a, 0x23,
+  0x05, 0xf6, 0x00, 0x06, 0x6a, 0x01, 0x06, 0xd7, 0x03, 0x05, 0x43, 0x06, 0x05, 0xe9, 0x08, 0x05,
+  0xe3, 0x09, 0x05, 0xcb, 0x0a, 0x05, 0xda, 0x0b, 0x00, 0x00, 0x07, 0x27, 0x90, 0x7f, 0xeb}},
+ {0x0546, 64, { 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x50, 0x24, 0x02, 0x70, 0x6f, 0x74, 0x19, 0x90, 0x7f, 0xd4,
+  0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04,
+  0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82,
+  0x74, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea}},
+ {0x0586, 64, { 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12,
+  0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x49, 0xea,
+  0x49, 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x07, 0x2e,
+  0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xb4, 0xe0, 0x44}},
+ {0x05c6, 64, { 0x01, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0x00, 0xe5, 0x24, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0,
+  0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x24, 0x02, 0x07, 0x2e, 0x12, 0x07, 0x36, 0x02,
+  0x07, 0x2e, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x07, 0x2e, 0x90,
+  0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2}},
+ {0x0606, 64, { 0x01, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x07, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4,
+  0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x2e, 0xe4, 0x90, 0x7f, 0x00, 0xf0,
+  0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xec, 0xe0, 0xf4,
+  0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4}},
+ {0x0646, 64, { 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0,
+  0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0,
+  0x02, 0x07, 0x2e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1e, 0x24, 0x02, 0x60, 0x03, 0x02,
+  0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x06, 0x12, 0x0d, 0x73, 0x02, 0x07, 0x2e}},
+ {0x0686, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x07, 0x2e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90,
+  0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25,
+  0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0,
+  0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f}},
+ {0x06c6, 64, { 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x60, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x57,
+  0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x24, 0x02, 0x70, 0x4b, 0x90, 0x7f, 0xea, 0xe0,
+  0xb4, 0x01, 0x05, 0x12, 0x0d, 0x70, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80,
+  0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff}},
+ {0x0706, 64, { 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f,
+  0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07,
+  0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4,
+  0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}},
+ {0x0746, 64, { 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18,
+  0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5,
+  0x08, 0x7f, 0x01, 0x7b, 0x00, 0x74, 0x08, 0x2f, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0a,
+  0x11, 0x0f, 0xbf, 0x09, 0xee, 0x75, 0x13, 0x01, 0xe4, 0xf5, 0x12, 0xf5, 0x2e, 0xf5, 0x11}},
+ {0x0786, 64, { 0xc2, 0x0e, 0xc2, 0x12, 0xc2, 0x0d, 0xc2, 0x0a, 0xc2, 0x0f, 0xc2, 0x04, 0xd2, 0x0c, 0xd2, 0x0b, 0x90,
+  0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x18, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c,
+  0xe4, 0xfd, 0x12, 0x0c, 0x2c, 0x7f, 0x10, 0x8f, 0x17, 0x12, 0x0b, 0xba, 0x90, 0x7f, 0x98, 0x74,
+  0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x16, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f}},
+ {0x07c6, 64, { 0x98, 0x74, 0x14, 0xf0, 0x75, 0x19, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12,
+  0x0c, 0x2c, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x15, 0x12, 0x0c, 0x2c, 0x90, 0x7f, 0x98,
+  0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x0c, 0x2c, 0x7f,
+  0x01, 0x12, 0x0c, 0xbc, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x0c, 0x2c, 0xd2, 0x03, 0x22, 0x90}},
+ {0x0806, 64, { 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf,
+  0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7,
+  0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5,
+  0x27, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3}},
+ {0x0846, 64, { 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x23,
+  0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05,
+  0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x08, 0xf0, 0xaf, 0x23, 0xe5, 0x28, 0xf5, 0x82, 0xe5, 0x27, 0xf5, 0x83, 0xc2, 0xaf}},
+ {0x0886, 64, { 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2,
+  0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83,
+  0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x31, 0x02, 0x09, 0x01}},
+ {0x08c6, 64, { 0x02, 0x09, 0x46, 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, 0x0c, 0xdd, 0xe4, 0x7e}},
+ {0x0906, 64, { 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}},
+ {0x0946, 64, { 0xd2, 0x14, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x12, 0x0d, 0x73, 0xd2, 0xe8, 0x43, 0xd8, 0x20,
+  0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0,
+  0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44,
+  0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x15, 0x12, 0x0c, 0x76}},
+ {0x0986, 64, { 0xc2, 0x02, 0xe4, 0xf5, 0x26, 0xf5, 0x2e, 0xc2, 0x08, 0xc2, 0x03, 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90,
+  0x7f, 0xd8, 0xe0, 0x65, 0x1a, 0x60, 0x10, 0x30, 0x03, 0x05, 0xd2, 0x15, 0x12, 0x00, 0x46, 0x90,
+  0x7f, 0xd8, 0xe0, 0xf5, 0x1a, 0x80, 0x08, 0x30, 0x03, 0x05, 0xc2, 0x15, 0x12, 0x00, 0x46, 0x30,
+  0x02, 0x07, 0xc2, 0x02, 0x12, 0x05, 0x20, 0x80, 0xd6, 0x30, 0x09, 0xd3, 0xc2, 0x09, 0x12}},
+ {0x09c6, 64, { 0x0a, 0xf1, 0x80, 0xcc, 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}},
+ {0x0a06, 64, { 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, 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}},
+ {0x0a46, 64, { 0xa3, 0x80, 0xdf, 0x8f, 0x1b, 0xe4, 0xf5, 0x1c, 0x75, 0x1d, 0xff, 0x75, 0x1e, 0x19, 0x75, 0x1f, 0x86,
+  0xab, 0x1d, 0xaa, 0x1e, 0xa9, 0x1f, 0x90, 0x00, 0x01, 0x12, 0x09, 0xe4, 0xb4, 0x03, 0x1d, 0xaf,
+  0x1c, 0x05, 0x1c, 0xef, 0xb5, 0x1b, 0x01, 0x22, 0x12, 0x09, 0xcb, 0x7e, 0x00, 0x29, 0xff, 0xee,
+  0x3a, 0xa9, 0x07, 0x75, 0x1d, 0xff, 0xf5, 0x1e, 0x89, 0x1f, 0x80, 0xd4, 0x7b, 0x00, 0x7a}},
+ {0x0a86, 64, { 0x00, 0x79, 0x00, 0x22, 0x8f, 0x1d, 0x05, 0x28, 0xe5, 0x28, 0xae, 0x27, 0x70, 0x02, 0x05, 0x27, 0x14,
+  0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1d, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x28, 0xe5, 0x28, 0xac, 0x27,
+  0x70, 0x02, 0x05, 0x27, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x23, 0xe5, 0x23, 0x60,
+  0x0a, 0x12, 0x0d, 0x54, 0x8f, 0x1d, 0xef, 0x42, 0x11, 0x80, 0xca, 0x22, 0xc0, 0xe0, 0xc0}},
+ {0x0ac6, 64, { 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30, 0x06, 0x04, 0xc2, 0x06,
+  0x80, 0x02, 0xd2, 0x09, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0,
+  0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x1b,
+  0x12, 0x00, 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x12, 0x08, 0xaa, 0x90, 0x7f}},
+ {0x0b06, 64, { 0xd6, 0xe0, 0x30, 0xe7, 0x0e, 0x30, 0x01, 0x05, 0x12, 0x0d, 0x0e, 0x80, 0x06, 0x12, 0x0c, 0x9b, 0xef,
+  0x60, 0xe1, 0x12, 0x07, 0x36, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84,
+  0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab,
+  0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0}},
+ {0x0b46, 64, { 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2,
+  0x02, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85,
+  0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00,
+  0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90}},
+ {0x0b86, 64, { 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90,
+  0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0,
+  0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0}},
+ {0x0bc6, 64, { 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0,
+  0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90,
+  0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0,
+  0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22}},
+ {0x0c06, 64, { 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16,
+  0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f,
+  0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x18, 0x54, 0x7f, 0x90,
+  0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90}},
+ {0x0c46, 64, { 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x0d, 0x3c, 0x8f, 0x1d, 0x12,
+  0x0d, 0x3c, 0x8f, 0x1e, 0xe5, 0x1d, 0x65, 0x1e, 0x60, 0x12, 0x12, 0x0d, 0x3c, 0x8f, 0x1d, 0xe5,
+  0x1d, 0x65, 0x1e, 0x60, 0x07, 0x12, 0x0d, 0x3c, 0x8f, 0x1e, 0x80, 0xe8, 0xaf, 0x1d, 0x22, 0x90,
+  0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x15, 0x04, 0xe0, 0x44}},
+ {0x0c86, 64, { 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x0c, 0xf7, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0,
+  0x44, 0x04, 0xf0, 0x22, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x1c, 0x12, 0x07, 0x36, 0x12, 0x0d, 0x60,
+  0xef, 0x30, 0xe6, 0x0b, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x1c, 0x60, 0xf1, 0x7f, 0x01, 0x22, 0x12,
+  0x00, 0x03, 0x7f, 0x00, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x15, 0x54, 0x7f, 0xfd, 0x12}},
+ {0x0cc6, 64, { 0x0c, 0x2c, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x15, 0x44,
+  0x80, 0xfd, 0x12, 0x0c, 0x2c, 0x22, 0x05, 0x29, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x2f, 0x03,
+  0x00, 0x00, 0xc1, 0x86, 0xc1, 0x02, 0xc1, 0x09, 0xc1, 0x01, 0xc1, 0x07, 0x01, 0x25, 0x00, 0x00,
+  0x8e, 0x1c, 0x8f, 0x1d, 0xe5, 0x1d, 0x15, 0x1d, 0xae, 0x1c, 0x70, 0x02, 0x15, 0x1c, 0x4e}},
+ {0x0d06, 64, { 0x60, 0x05, 0x12, 0x08, 0x99, 0x80, 0xee, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d,
+  0x7e, 0x00, 0x12, 0x0c, 0xf7, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90,
+  0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0}},
+ {0x0d46, 64, { 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90,
+  0xc0, 0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0xd2, 0x01, 0x22, 0xc2, 0x01, 0x22, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0d86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0dc6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 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, 0x0b, 0x47, 0x00, 0x02, 0x0e}},
+ {0x0e06, 64, { 0x04, 0x00, 0x02, 0x0b, 0x1d, 0x00, 0x02, 0x0a, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0e46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0e86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0ec6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0f06, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0f46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0f86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x0fc6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1006, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1046, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1086, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x10c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1106, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1146, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1186, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x11c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1206, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1246, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1286, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x12c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1306, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1346, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1386, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x01, 0xff, 0x00}},
+ {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x08, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x00, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65,
+  0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53,
+  0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c,
+  0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}},
+ {0x1a06,  4, { 0x72, 0x00, 0x00, 0x00}},
 { 0xffff,	0,	{0x00} }
 };
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa26msg.h linux/drivers/usb/serial/keyspan_usa26msg.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa26msg.h	Thu Dec  7 16:13:38 2000
+++ linux/drivers/usb/serial/keyspan_usa26msg.h	Tue Oct  9 15:15:02 2001
@@ -103,39 +103,39 @@
 			when necessary, to reduce overhead on the USA26):
 	*/
 	u8	setClocking,	// BOTH: host requests baud rate be set
-		baudLo,			// BOTH: host does baud divisor calculation
-		baudHi,			// BOTH: baudHi is only used for first port (gives lower rates)
+		baudLo,		// BOTH: host does baud divisor calculation
+		baudHi,		// BOTH: baudHi is only used for first port (gives lower rates)
 		externalClock_txClocking,
-						// USA26: 0=internal, other=external
-						// USA17: 0=internal, other=external/RI
+					// USA26: 0=internal, other=external
+					// USA17: 0=internal, other=external/RI
 		rxClocking,		// USA17: 0=internal, 1=external/RI, other=external/DSR
 
 
 		setLcr,			// BOTH: host requests lcr be set
 		lcr,			// BOTH: use PARITY, STOPBITS, DATABITS below
 
-		setFlowControl,	// BOTH: host requests flow control be set
-		ctsFlowControl,	// BOTH: 1=use CTS flow control, 0=don't
-		xonFlowControl,	// BOTH: 1=use XON/XOFF flow control, 0=don't
+		setFlowControl,		// BOTH: host requests flow control be set
+		ctsFlowControl,		// BOTH: 1=use CTS flow control, 0=don't
+		xonFlowControl,		// BOTH: 1=use XON/XOFF flow control, 0=don't
 		xonChar,		// BOTH: specified in current character format
 		xoffChar,		// BOTH: specified in current character format
 
 		setTxTriState_setRts,
-						// USA26: host requests TX tri-state be set
-						// USA17: host requests RTS output be set
-		txTriState_rts,	// BOTH: 1=active (normal), 0=tristate (off)
+					// USA26: host requests TX tri-state be set
+					// USA17: host requests RTS output be set
+		txTriState_rts,		// BOTH: 1=active (normal), 0=tristate (off)
 
 		setHskoa_setDtr,
-						// USA26: host requests HSKOA output be set
-						// USA17: host requests DTR output be set
+					// USA26: host requests HSKOA output be set
+					// USA17: host requests DTR output be set
 		hskoa_dtr,		// BOTH: 1=on, 0=off
 
-		setPrescaler,	// USA26: host requests prescalar be set (default: 13)
+		setPrescaler,		// USA26: host requests prescalar be set (default: 13)
 		prescaler;		// BOTH: specified as N/8; values 8-ff are valid
-						// must be set any time internal baud rate is set;
-						// must not be set when external clocking is used
-						// note: in USA17, prescaler is applied whenever
-						// setClocking is requested
+					// must be set any time internal baud rate is set;
+					// must not be set when external clocking is used
+					// note: in USA17, prescaler is applied whenever
+					// setClocking is requested
 
 	/*
 		3.	configuration data which is simply used as is (no overhead,
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa28_fw.h linux/drivers/usb/serial/keyspan_usa28_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa28_fw.h	Mon Jul 10 14:33:04 2000
+++ linux/drivers/usb/serial/keyspan_usa28_fw.h	Tue Oct  9 15:15:02 2001
@@ -1,10 +1,10 @@
 /* keyspan_usa28_fw.h
   
-   Generated from Keyspan firmware image Wed Jul  5 09:18:29 2000 EST
+   Generated from Keyspan firmware image usa28code.h Sat Oct  6 12:11:26 EST 2001
    This firmware is for the Keyspan USA-28 Serial Adaptor
 
    "The firmware contained herein as keyspan_usa28_fw.h is
-   Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
    ("Keyspan"), as an unpublished work.  This notice does not imply
    unrestricted or public access to this firmware which is a trade secret of
    Keyspan, and which may not be reproduced, used, sold or transferred to any
@@ -18,445 +18,444 @@
 */
 
 static const struct ezusb_hex_record keyspan_usa28_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x15, 0xc5} },
-{ 0x0003,	3,	{0x02, 0x00, 0x46} },
-{ 0x0006,	16,	{0x8e, 0x12, 0x8f, 0x13, 0xe5, 0x13, 0x15, 0x13, 0xae, 0x12, 0x70, 0x02, 0x15, 0x12, 0x4e, 0x60} },
-{ 0x0016,	7,	{0x05, 0x12, 0x18, 0x7d, 0x80, 0xee, 0x22} },
-{ 0x001d,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x0023,	3,	{0x02, 0x00, 0x46} },
-{ 0x0026,	10,	{0x12, 0x17, 0x91, 0x12, 0x18, 0x8e, 0x12, 0x14, 0x47, 0x22} },
-{ 0x0033,	3,	{0x02, 0x00, 0x1d} },
-{ 0x003b,	3,	{0x02, 0x00, 0x46} },
-{ 0x0043,	3,	{0x02, 0x1b, 0x00} },
-{ 0x0046,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08} },
-{ 0x0056,	16,	{0x30, 0x99, 0x0e, 0x30, 0x0e, 0x07, 0xa2, 0x14, 0x92, 0x9b, 0x85, 0x46, 0x99, 0xc2, 0x99, 0xd2} },
-{ 0x0066,	16,	{0x1c, 0x30, 0xc1, 0x0e, 0x30, 0x0f, 0x07, 0xa2, 0x15, 0x92, 0xc3, 0x85, 0x47, 0xc1, 0xc2, 0xc1} },
-{ 0x0076,	16,	{0xd2, 0x1d, 0x20, 0x1c, 0x03, 0x02, 0x04, 0x36, 0xc2, 0x1c, 0x20, 0x02, 0x03, 0x02, 0x02, 0x61} },
-{ 0x0086,	16,	{0x20, 0x0e, 0x03, 0x02, 0x01, 0x38, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x3e, 0x20, 0x10, 0x36} },
-{ 0x0096,	16,	{0x20, 0x08, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x19, 0x29, 0x30, 0x18, 0x12} },
-{ 0x00a6,	16,	{0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13} },
-{ 0x00b6,	16,	{0x92, 0x14, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83} },
-{ 0x00c6,	16,	{0xe0, 0xf5, 0x46, 0x02, 0x04, 0x34, 0xc2, 0x0e, 0x02, 0x04, 0x34, 0x90, 0x7f, 0xc7, 0xe4, 0xf0} },
-{ 0x00d6,	16,	{0xc2, 0x02, 0x30, 0x12, 0x0c, 0xc2, 0x12, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0xc2, 0x0e, 0x02, 0x04} },
-{ 0x00e6,	16,	{0x34, 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x0e, 0x02, 0x04, 0x34, 0x90, 0x7f, 0xc9} },
-{ 0x00f6,	16,	{0xe0, 0xf5, 0x7c, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x12, 0x20, 0x10, 0x2d, 0x20, 0x08, 0x2a} },
-{ 0x0106,	16,	{0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x19, 0x20, 0x30, 0x18, 0x11, 0x90, 0x7d, 0xc1} },
-{ 0x0116,	16,	{0xe0, 0x13, 0x92, 0x14, 0xa3, 0xe0, 0xf5, 0x46, 0x75, 0x4a, 0x03, 0x02, 0x04, 0x34, 0x75, 0x4a} },
-{ 0x0126,	16,	{0x02, 0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x34, 0x75, 0x4a, 0x01, 0xc2, 0x0e, 0x02} },
-{ 0x0136,	16,	{0x04, 0x34, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x03, 0x02, 0x01, 0xda, 0x90, 0x7f, 0xc6, 0xe0} },
-{ 0x0146,	16,	{0x30, 0xe1, 0x07, 0xc2, 0x20, 0xd2, 0x1e, 0x02, 0x04, 0x34, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x7c} },
-{ 0x0156,	16,	{0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x12, 0x20, 0x10, 0x72, 0x20, 0x08, 0x6f, 0x90, 0x7f, 0x9b} },
-{ 0x0166,	16,	{0xe0, 0x20, 0xe3, 0x03, 0x20, 0x19, 0x65, 0x30, 0x18, 0x10, 0x90, 0x7e, 0x41, 0xe0, 0x13, 0x92} },
-{ 0x0176,	16,	{0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x03, 0x80, 0x09, 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x99} },
-{ 0x0186,	16,	{0x75, 0x4a, 0x02, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2} },
-{ 0x0196,	16,	{0x02, 0x20, 0x12, 0x03, 0x02, 0x04, 0x34, 0xc2, 0x12, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x02, 0x04} },
-{ 0x01a6,	16,	{0x34, 0x30, 0x18, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e} },
-{ 0x01b6,	16,	{0xf5, 0x83, 0xe0, 0x13, 0x92, 0x14, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4} },
-{ 0x01c6,	16,	{0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x0e, 0x02, 0x04, 0x34, 0x75, 0x4a, 0x01, 0xc2} },
-{ 0x01d6,	16,	{0x20, 0x02, 0x04, 0x34, 0x30, 0x10, 0x03, 0x02, 0x02, 0x5c, 0x20, 0x08, 0x79, 0x90, 0x7f, 0x9b} },
-{ 0x01e6,	16,	{0xe0, 0x20, 0xe3, 0x03, 0x20, 0x19, 0x6f, 0x30, 0x18, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40} },
-{ 0x01f6,	16,	{0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xae, 0x4a, 0x05, 0x4a} },
-{ 0x0206,	16,	{0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, 0x4a, 0xc3} },
-{ 0x0216,	16,	{0x95, 0x7c, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x02, 0x20, 0x12, 0x03, 0x02, 0x04} },
-{ 0x0226,	16,	{0x34, 0xc2, 0x12, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x02, 0x04, 0x34, 0x30, 0x18, 0x12, 0xae, 0x4a} },
-{ 0x0236,	16,	{0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x14} },
-{ 0x0246,	16,	{0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5} },
-{ 0x0256,	16,	{0x46, 0xd2, 0x0e, 0x02, 0x04, 0x34, 0xc2, 0x20, 0x02, 0x04, 0x34, 0x20, 0x0e, 0x03, 0x02, 0x03} },
-{ 0x0266,	16,	{0x13, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x3e, 0x20, 0x10, 0x36, 0x20, 0x08, 0x33, 0x90, 0x7f} },
-{ 0x0276,	16,	{0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x19, 0x29, 0x30, 0x18, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74} },
-{ 0x0286,	16,	{0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x14, 0xae, 0x4a, 0x05} },
-{ 0x0296,	16,	{0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0x02, 0x04} },
-{ 0x02a6,	16,	{0x34, 0xc2, 0x0e, 0x02, 0x04, 0x34, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x02, 0x30, 0x12, 0x0c} },
-{ 0x02b6,	16,	{0xc2, 0x12, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0xc2, 0x0e, 0x02, 0x04, 0x34, 0x90, 0x7f, 0xc6, 0xe0} },
-{ 0x02c6,	16,	{0x30, 0xe1, 0x05, 0xc2, 0x0e, 0x02, 0x04, 0x34, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x7c, 0x90, 0x7e} },
-{ 0x02d6,	16,	{0x40, 0xe0, 0x13, 0x92, 0x12, 0x20, 0x10, 0x2d, 0x20, 0x08, 0x2a, 0x90, 0x7f, 0x9b, 0xe0, 0x20} },
-{ 0x02e6,	16,	{0xe3, 0x03, 0x20, 0x19, 0x20, 0x30, 0x18, 0x11, 0x90, 0x7e, 0x41, 0xe0, 0x13, 0x92, 0x14, 0xa3} },
-{ 0x02f6,	16,	{0xe0, 0xf5, 0x46, 0x75, 0x4a, 0x03, 0x02, 0x04, 0x34, 0x75, 0x4a, 0x02, 0x90, 0x7e, 0x41, 0xe0} },
-{ 0x0306,	16,	{0xf5, 0x46, 0x02, 0x04, 0x34, 0x75, 0x4a, 0x01, 0xc2, 0x0e, 0x02, 0x04, 0x34, 0xe5, 0x4a, 0xc3} },
-{ 0x0316,	16,	{0x95, 0x7c, 0x50, 0x03, 0x02, 0x03, 0xb5, 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x20} },
-{ 0x0326,	16,	{0xd2, 0x1e, 0x02, 0x04, 0x34, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x7c, 0x90, 0x7d, 0xc0, 0xe0, 0x13} },
-{ 0x0336,	16,	{0x92, 0x12, 0x20, 0x10, 0x72, 0x20, 0x08, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20} },
-{ 0x0346,	16,	{0x19, 0x65, 0x30, 0x18, 0x10, 0x90, 0x7d, 0xc1, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99} },
-{ 0x0356,	16,	{0x75, 0x4a, 0x03, 0x80, 0x09, 0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x02, 0xe5, 0x4a} },
-{ 0x0366,	16,	{0xc3, 0x95, 0x7c, 0x40, 0x17, 0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x02, 0x20, 0x12, 0x03, 0x02} },
-{ 0x0376,	16,	{0x04, 0x34, 0xc2, 0x12, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x02, 0x04, 0x34, 0x30, 0x18, 0x12, 0xae} },
-{ 0x0386,	16,	{0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92} },
-{ 0x0396,	16,	{0x14, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0} },
-{ 0x03a6,	16,	{0xf5, 0x46, 0xd2, 0x0e, 0x02, 0x04, 0x34, 0x75, 0x4a, 0x01, 0xc2, 0x20, 0x02, 0x04, 0x34, 0x30} },
-{ 0x03b6,	16,	{0x10, 0x03, 0x02, 0x04, 0x32, 0x20, 0x08, 0x74, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20} },
-{ 0x03c6,	16,	{0x19, 0x6a, 0x30, 0x18, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x03d6,	16,	{0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x9b, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82} },
-{ 0x03e6,	16,	{0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x99, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x13, 0x90} },
-{ 0x03f6,	16,	{0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x02, 0x30, 0x12, 0x35, 0xc2, 0x12, 0x90, 0x7f, 0xbf, 0x04, 0xf0} },
-{ 0x0406,	16,	{0x80, 0x2c, 0x30, 0x18, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x0416,	16,	{0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x14, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82} },
-{ 0x0426,	16,	{0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x0e, 0x80, 0x02, 0xc2, 0x20, 0xd2, 0x24} },
-{ 0x0436,	16,	{0x20, 0x1d, 0x03, 0x02, 0x07, 0xf4, 0xc2, 0x1d, 0x20, 0x03, 0x03, 0x02, 0x06, 0x1f, 0x20, 0x0f} },
-{ 0x0446,	16,	{0x03, 0x02, 0x04, 0xf6, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x3e, 0x20, 0x11, 0x36, 0x20, 0x0a} },
-{ 0x0456,	16,	{0x33, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1b, 0x29, 0x30, 0x1a, 0x12, 0xae, 0x4b} },
-{ 0x0466,	16,	{0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x15} },
-{ 0x0476,	16,	{0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5} },
-{ 0x0486,	16,	{0x47, 0x02, 0x07, 0xf2, 0xc2, 0x0f, 0x02, 0x07, 0xf2, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x03} },
-{ 0x0496,	16,	{0x30, 0x13, 0x0c, 0xc2, 0x13, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0xc2, 0x0f, 0x02, 0x07, 0xf2, 0x90} },
-{ 0x04a6,	16,	{0x7f, 0xcc, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x0f, 0x02, 0x07, 0xf2, 0x90, 0x7f, 0xcd, 0xe0, 0xf5} },
-{ 0x04b6,	16,	{0x7d, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x13, 0x20, 0x11, 0x2d, 0x20, 0x0a, 0x2a, 0x90, 0x7f} },
-{ 0x04c6,	16,	{0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1b, 0x20, 0x30, 0x1a, 0x11, 0x90, 0x7c, 0xc1, 0xe0, 0x13} },
-{ 0x04d6,	16,	{0x92, 0x15, 0xa3, 0xe0, 0xf5, 0x47, 0x75, 0x4b, 0x03, 0x02, 0x07, 0xf2, 0x75, 0x4b, 0x02, 0x90} },
-{ 0x04e6,	16,	{0x7c, 0xc1, 0xe0, 0xf5, 0x47, 0x02, 0x07, 0xf2, 0x75, 0x4b, 0x01, 0xc2, 0x0f, 0x02, 0x07, 0xf2} },
-{ 0x04f6,	16,	{0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x03, 0x02, 0x05, 0x98, 0x90, 0x7f, 0xca, 0xe0, 0x30, 0xe1} },
-{ 0x0506,	16,	{0x07, 0xc2, 0x21, 0xd2, 0x1f, 0x02, 0x07, 0xf2, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0x90, 0x7d} },
-{ 0x0516,	16,	{0x40, 0xe0, 0x13, 0x92, 0x13, 0x20, 0x11, 0x72, 0x20, 0x0a, 0x6f, 0x90, 0x7f, 0x9a, 0xe0, 0x20} },
-{ 0x0526,	16,	{0xe5, 0x03, 0x20, 0x1b, 0x65, 0x30, 0x1a, 0x10, 0x90, 0x7d, 0x41, 0xe0, 0x13, 0x92, 0xc3, 0xa3} },
-{ 0x0536,	16,	{0xe0, 0xf5, 0xc1, 0x75, 0x4b, 0x03, 0x80, 0x09, 0x90, 0x7d, 0x41, 0xe0, 0xf5, 0xc1, 0x75, 0x4b} },
-{ 0x0546,	16,	{0x02, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x03, 0x20} },
-{ 0x0556,	16,	{0x13, 0x03, 0x02, 0x07, 0xf2, 0xc2, 0x13, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x07, 0xf2, 0x30} },
-{ 0x0566,	16,	{0x1a, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83} },
-{ 0x0576,	16,	{0xe0, 0x13, 0x92, 0x15, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d} },
-{ 0x0586,	16,	{0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x0f, 0x02, 0x07, 0xf2, 0x75, 0x4b, 0x01, 0xc2, 0x21, 0x02} },
-{ 0x0596,	16,	{0x07, 0xf2, 0x30, 0x11, 0x03, 0x02, 0x06, 0x1a, 0x20, 0x0a, 0x79, 0x90, 0x7f, 0x9a, 0xe0, 0x20} },
-{ 0x05a6,	16,	{0xe5, 0x03, 0x20, 0x1b, 0x6f, 0x30, 0x1a, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5} },
-{ 0x05b6,	16,	{0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0xc3, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40} },
-{ 0x05c6,	16,	{0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0xc1, 0xe5, 0x4b, 0xc3, 0x95, 0x7d} },
-{ 0x05d6,	16,	{0x40, 0x17, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x03, 0x20, 0x13, 0x03, 0x02, 0x07, 0xf2, 0xc2} },
-{ 0x05e6,	16,	{0x13, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x07, 0xf2, 0x30, 0x1a, 0x12, 0xae, 0x4b, 0x05, 0x4b} },
-{ 0x05f6,	16,	{0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x15, 0xae, 0x4b} },
-{ 0x0606,	16,	{0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2} },
-{ 0x0616,	16,	{0x0f, 0x02, 0x07, 0xf2, 0xc2, 0x21, 0x02, 0x07, 0xf2, 0x20, 0x0f, 0x03, 0x02, 0x06, 0xd1, 0xe5} },
-{ 0x0626,	16,	{0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x3e, 0x20, 0x11, 0x36, 0x20, 0x0a, 0x33, 0x90, 0x7f, 0x9a, 0xe0} },
-{ 0x0636,	16,	{0x20, 0xe5, 0x03, 0x20, 0x1b, 0x29, 0x30, 0x1a, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e} },
-{ 0x0646,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x15, 0xae, 0x4b, 0x05, 0x4b, 0x74} },
-{ 0x0656,	16,	{0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0x02, 0x07, 0xf2, 0xc2} },
-{ 0x0666,	16,	{0x0f, 0x02, 0x07, 0xf2, 0x90, 0x7f, 0xcd, 0xe4, 0xf0, 0xd2, 0x03, 0x30, 0x13, 0x0c, 0xc2, 0x13} },
-{ 0x0676,	16,	{0x90, 0x7f, 0xc1, 0x04, 0xf0, 0xc2, 0x0f, 0x02, 0x07, 0xf2, 0x90, 0x7f, 0xca, 0xe0, 0x30, 0xe1} },
-{ 0x0686,	16,	{0x05, 0xc2, 0x0f, 0x02, 0x07, 0xf2, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0x90, 0x7d, 0x40, 0xe0} },
-{ 0x0696,	16,	{0x13, 0x92, 0x13, 0x20, 0x11, 0x2d, 0x20, 0x0a, 0x2a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03} },
-{ 0x06a6,	16,	{0x20, 0x1b, 0x20, 0x30, 0x1a, 0x11, 0x90, 0x7d, 0x41, 0xe0, 0x13, 0x92, 0x15, 0xa3, 0xe0, 0xf5} },
-{ 0x06b6,	16,	{0x47, 0x75, 0x4b, 0x03, 0x02, 0x07, 0xf2, 0x75, 0x4b, 0x02, 0x90, 0x7d, 0x41, 0xe0, 0xf5, 0x47} },
-{ 0x06c6,	16,	{0x02, 0x07, 0xf2, 0x75, 0x4b, 0x01, 0xc2, 0x0f, 0x02, 0x07, 0xf2, 0xe5, 0x4b, 0xc3, 0x95, 0x7d} },
-{ 0x06d6,	16,	{0x50, 0x03, 0x02, 0x07, 0x73, 0x90, 0x7f, 0xcc, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x21, 0xd2, 0x1f} },
-{ 0x06e6,	16,	{0x02, 0x07, 0xf2, 0x90, 0x7f, 0xcd, 0xe0, 0xf5, 0x7d, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x13} },
-{ 0x06f6,	16,	{0x20, 0x11, 0x72, 0x20, 0x0a, 0x6f, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1b, 0x65} },
-{ 0x0706,	16,	{0x30, 0x1a, 0x10, 0x90, 0x7c, 0xc1, 0xe0, 0x13, 0x92, 0xc3, 0xa3, 0xe0, 0xf5, 0xc1, 0x75, 0x4b} },
-{ 0x0716,	16,	{0x03, 0x80, 0x09, 0x90, 0x7c, 0xc1, 0xe0, 0xf5, 0xc1, 0x75, 0x4b, 0x02, 0xe5, 0x4b, 0xc3, 0x95} },
-{ 0x0726,	16,	{0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcd, 0xe4, 0xf0, 0xd2, 0x03, 0x20, 0x13, 0x03, 0x02, 0x07, 0xf2} },
-{ 0x0736,	16,	{0xc2, 0x13, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x07, 0xf2, 0x30, 0x1a, 0x12, 0xae, 0x4b, 0x05} },
-{ 0x0746,	16,	{0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x15, 0xae} },
-{ 0x0756,	16,	{0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47} },
-{ 0x0766,	16,	{0xd2, 0x0f, 0x02, 0x07, 0xf2, 0x75, 0x4b, 0x01, 0xc2, 0x21, 0x02, 0x07, 0xf2, 0x30, 0x11, 0x03} },
-{ 0x0776,	16,	{0x02, 0x07, 0xf0, 0x20, 0x0a, 0x74, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1b, 0x6a} },
-{ 0x0786,	16,	{0x30, 0x1a, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5} },
-{ 0x0796,	16,	{0x83, 0xe0, 0x13, 0x92, 0xc3, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x07a6,	16,	{0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0xc1, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x40, 0x13, 0x90, 0x7f, 0xcd} },
-{ 0x07b6,	16,	{0xe4, 0xf0, 0xd2, 0x03, 0x30, 0x13, 0x35, 0xc2, 0x13, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x80, 0x2c} },
-{ 0x07c6,	16,	{0x30, 0x1a, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5} },
-{ 0x07d6,	16,	{0x83, 0xe0, 0x13, 0x92, 0x15, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x07e6,	16,	{0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x0f, 0x80, 0x02, 0xc2, 0x21, 0xd2, 0x24, 0x20, 0x98} },
-{ 0x07f6,	16,	{0x03, 0x02, 0x09, 0x26, 0xc2, 0x98, 0x20, 0x00, 0x03, 0x02, 0x08, 0x98, 0x20, 0x22, 0x27, 0xae} },
-{ 0x0806,	16,	{0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0} },
-{ 0x0816,	16,	{0x30, 0x18, 0x49, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5} },
-{ 0x0826,	16,	{0x83, 0xe5, 0x98, 0xf0, 0x80, 0x36, 0xaf, 0x99, 0xef, 0xb5, 0x58, 0x04, 0xd2, 0x08, 0x80, 0x2c} },
-{ 0x0836,	3,	{0xef, 0xb5, 0x57} },
-{ 0x0839,	16,	{0x04, 0xc2, 0x08, 0x80, 0x24, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x0849,	16,	{0x7e, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x18, 0x11, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5} },
-{ 0x0859,	16,	{0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x16, 0xe5, 0x48, 0xc3, 0x95, 0x54} },
-{ 0x0869,	16,	{0x50, 0x03, 0x02, 0x09, 0x24, 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x15, 0xe5, 0x48, 0xc3, 0x94} },
-{ 0x0879,	16,	{0x40, 0x50, 0x03, 0x02, 0x09, 0x24, 0x15, 0x48, 0x15, 0x48, 0x05, 0x2d, 0xd2, 0x09, 0x02, 0x09} },
-{ 0x0889,	16,	{0x24, 0x90, 0x7f, 0xb7, 0xe5, 0x48, 0xf0, 0x75, 0x48, 0x00, 0xc2, 0x00, 0x02, 0x09, 0x24, 0x20} },
-{ 0x0899,	16,	{0x22, 0x27, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83} },
-{ 0x08a9,	16,	{0xe5, 0x99, 0xf0, 0x30, 0x18, 0x49, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4} },
-{ 0x08b9,	16,	{0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x36, 0xaf, 0x99, 0xef, 0xb5, 0x58, 0x04, 0xd2} },
-{ 0x08c9,	16,	{0x08, 0x80, 0x2c, 0xef, 0xb5, 0x57, 0x04, 0xc2, 0x08, 0x80, 0x24, 0xae, 0x48, 0x05, 0x48, 0x74} },
-{ 0x08d9,	16,	{0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x18, 0x11, 0xae, 0x48} },
-{ 0x08e9,	16,	{0x05, 0x48, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2} },
-{ 0x08f9,	16,	{0x16, 0xe5, 0x48, 0xc3, 0x95, 0x54, 0x40, 0x23, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x11, 0xe5} },
-{ 0x0909,	16,	{0x48, 0xc3, 0x94, 0x40, 0x40, 0x15, 0x15, 0x48, 0x15, 0x48, 0x05, 0x2d, 0xd2, 0x09, 0x80, 0x0b} },
-{ 0x0919,	16,	{0x90, 0x7f, 0xb9, 0xe5, 0x48, 0xf0, 0x75, 0x48, 0x00, 0xd2, 0x00, 0xd2, 0x24, 0x20, 0xc0, 0x03} },
-{ 0x0929,	16,	{0x02, 0x0a, 0x58, 0xc2, 0xc0, 0x20, 0x01, 0x03, 0x02, 0x09, 0xca, 0x20, 0x23, 0x27, 0xae, 0x49} },
-{ 0x0939,	16,	{0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc1, 0xf0, 0x30} },
-{ 0x0949,	16,	{0x1a, 0x49, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83} },
-{ 0x0959,	16,	{0xe5, 0xc0, 0xf0, 0x80, 0x36, 0xaf, 0xc1, 0xef, 0xb5, 0x70, 0x04, 0xd2, 0x0a, 0x80, 0x2c, 0xef} },
-{ 0x0969,	16,	{0xb5, 0x6f, 0x04, 0xc2, 0x0a, 0x80, 0x24, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, 0x82} },
-{ 0x0979,	16,	{0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x1a, 0x11, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80} },
-{ 0x0989,	16,	{0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0xd2, 0x17, 0xe5, 0x49, 0xc3} },
-{ 0x0999,	16,	{0x95, 0x6c, 0x50, 0x03, 0x02, 0x0a, 0x56, 0x90, 0x7f, 0xbc, 0xe0, 0x30, 0xe1, 0x15, 0xe5, 0x49} },
-{ 0x09a9,	16,	{0xc3, 0x94, 0x40, 0x50, 0x03, 0x02, 0x0a, 0x56, 0x15, 0x49, 0x15, 0x49, 0x05, 0x39, 0xd2, 0x0b} },
-{ 0x09b9,	16,	{0x02, 0x0a, 0x56, 0x90, 0x7f, 0xbb, 0xe5, 0x49, 0xf0, 0x75, 0x49, 0x00, 0xc2, 0x01, 0x02, 0x0a} },
-{ 0x09c9,	16,	{0x56, 0x20, 0x23, 0x27, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d} },
-{ 0x09d9,	16,	{0xf5, 0x83, 0xe5, 0xc1, 0xf0, 0x30, 0x1a, 0x49, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5} },
-{ 0x09e9,	16,	{0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0x80, 0x36, 0xaf, 0xc1, 0xef, 0xb5, 0x70} },
-{ 0x09f9,	16,	{0x04, 0xd2, 0x0a, 0x80, 0x2c, 0xef, 0xb5, 0x6f, 0x04, 0xc2, 0x0a, 0x80, 0x24, 0xae, 0x49, 0x05} },
-{ 0x0a09,	16,	{0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x1a, 0x11} },
-{ 0x0a19,	16,	{0xae, 0x49, 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc0} },
-{ 0x0a29,	16,	{0xf0, 0xd2, 0x17, 0xe5, 0x49, 0xc3, 0x95, 0x6c, 0x40, 0x23, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1} },
-{ 0x0a39,	16,	{0x11, 0xe5, 0x49, 0xc3, 0x94, 0x40, 0x40, 0x15, 0x15, 0x49, 0x15, 0x49, 0x05, 0x39, 0xd2, 0x0b} },
-{ 0x0a49,	16,	{0x80, 0x0b, 0x90, 0x7f, 0xbd, 0xe5, 0x49, 0xf0, 0x75, 0x49, 0x00, 0xd2, 0x01, 0xd2, 0x24, 0x30} },
-{ 0x0a59,	7,	{0x24, 0x05, 0xc2, 0x24, 0x02, 0x00, 0x56} },
-{ 0x0a60,	11,	{0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0a6b,	16,	{0x90, 0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x0b, 0x93, 0xe4, 0xf5, 0x12, 0x74, 0x40, 0x25} },
-{ 0x0a7b,	16,	{0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x12, 0x7c, 0x00, 0x7b, 0x00} },
-{ 0x0a8b,	16,	{0x24, 0x4c, 0xf9, 0xec, 0x34, 0x00, 0xfa, 0xef, 0x12, 0x15, 0x55, 0x05, 0x12, 0xe5, 0x12, 0xb4} },
-{ 0x0a9b,	16,	{0x18, 0xdb, 0xe5, 0x4c, 0x60, 0x0c, 0x75, 0xc9, 0x20, 0x75, 0xc8, 0x36, 0x85, 0x4d, 0xca, 0x85} },
-{ 0x0aab,	16,	{0x4e, 0xcb, 0xe5, 0x4f, 0x13, 0x92, 0x18, 0x92, 0x9f, 0xe5, 0x50, 0x13, 0x92, 0x19, 0xe5, 0x51} },
-{ 0x0abb,	16,	{0x13, 0x92, 0x22, 0xe5, 0x52, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07} },
-{ 0x0acb,	16,	{0x90, 0x7f, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x53, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54} },
-{ 0x0adb,	16,	{0x7f, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x59, 0x60, 0x0b, 0xc2} },
-{ 0x0aeb,	16,	{0x10, 0xc2, 0x08, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x5a, 0x60, 0x0b, 0xd2, 0x08} },
-{ 0x0afb,	16,	{0xd2, 0x09, 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x5b, 0x60, 0x17, 0xc2, 0xaf, 0xe4} },
-{ 0x0b0b,	16,	{0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0xc2, 0x0e, 0xd2, 0x02, 0xc2, 0x12, 0xf5, 0x7c} },
-{ 0x0b1b,	16,	{0xf5, 0x4a, 0xd2, 0xaf, 0xe5, 0x5c, 0x60, 0x05, 0x30, 0x22, 0x02, 0xd2, 0x08, 0xe5, 0x5d, 0x60} },
-{ 0x0b2b,	16,	{0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9e, 0xe0, 0x44, 0x02, 0xf0, 0x90} },
-{ 0x0b3b,	16,	{0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x5e, 0x60, 0x0a, 0xd2, 0x9c, 0xc2, 0x98, 0x75, 0x2e} },
-{ 0x0b4b,	16,	{0x01, 0x75, 0x40, 0x28, 0xe5, 0x5f, 0x60, 0x07, 0xc2, 0x9c, 0xe4, 0xf5, 0x48, 0xf5, 0x2e, 0xe5} },
-{ 0x0b5b,	16,	{0x60, 0x60, 0x03, 0xe4, 0xf5, 0x48, 0xe5, 0x61, 0x60, 0x02, 0xd2, 0x04, 0xe5, 0x62, 0x60, 0x08} },
-{ 0x0b6b,	16,	{0xe5, 0x5e, 0x70, 0x02, 0xf5, 0x40, 0xd2, 0x09, 0xe5, 0x63, 0x60, 0x15, 0x90, 0x7f, 0xd7, 0x74} },
-{ 0x0b7b,	16,	{0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0, 0x74, 0x32, 0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35} },
-{ 0x0b8b,	16,	{0xf0, 0xd2, 0x06, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x65, 0x2b, 0x60} },
-{ 0x0b9b,	16,	{0x04, 0x8f, 0x2b, 0xd2, 0x09, 0xa2, 0x08, 0xe4, 0x33, 0xff, 0x65, 0x2c, 0x60, 0x04, 0x8f, 0x2c} },
-{ 0x0bab,	16,	{0xd2, 0x09, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x08, 0x65, 0x27, 0x60, 0x07, 0xe0, 0x54, 0x08, 0xf5} },
-{ 0x0bbb,	16,	{0x27, 0xd2, 0x09, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x40, 0xb5, 0x29, 0x09, 0xe0, 0x54, 0x40, 0x64} },
-{ 0x0bcb,	16,	{0x40, 0xf5, 0x29, 0xd2, 0x09, 0x30, 0x04, 0x35, 0xc2, 0xaf, 0x30, 0x00, 0x18, 0x90, 0x7f, 0xb8} },
-{ 0x0bdb,	16,	{0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x48, 0x60, 0x09, 0x90, 0x7f, 0xb7, 0xf0, 0xe4, 0xf5, 0x48, 0xc2} },
-{ 0x0beb,	16,	{0x00, 0xc2, 0x04, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x48, 0x60, 0x09} },
-{ 0x0bfb,	16,	{0x90, 0x7f, 0xb9, 0xf0, 0xe4, 0xf5, 0x48, 0xd2, 0x00, 0xc2, 0x04, 0xd2, 0xaf, 0x30, 0x1e, 0x37} },
-{ 0x0c0b,	16,	{0x30, 0x02, 0x1b, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92} },
-{ 0x0c1b,	16,	{0x12, 0x75, 0x4a, 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x7c, 0xc2, 0x1e, 0x80, 0x19, 0x90, 0x7f} },
-{ 0x0c2b,	16,	{0xc8, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x12, 0x75, 0x4a, 0x01, 0x90} },
-{ 0x0c3b,	16,	{0x7f, 0xc9, 0xe0, 0xf5, 0x7c, 0xc2, 0x1e, 0x30, 0x20, 0x03, 0x02, 0x0d, 0x4a, 0x30, 0x1e, 0x03} },
-{ 0x0c4b,	16,	{0x02, 0x0d, 0x4a, 0x30, 0x19, 0x0a, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x02, 0x0d, 0x4a} },
-{ 0x0c5b,	16,	{0x30, 0x08, 0x03, 0x02, 0x0d, 0x4a, 0x30, 0x10, 0x03, 0x02, 0x0d, 0x4a, 0x30, 0x02, 0x62, 0x30} },
-{ 0x0c6b,	16,	{0x18, 0x12, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83} },
-{ 0x0c7b,	16,	{0xe0, 0x13, 0x92, 0x2c, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e} },
-{ 0x0c8b,	16,	{0xf5, 0x83, 0xe0, 0xf5, 0x13, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x2a, 0x30, 0x18, 0x12, 0xaf} },
-{ 0x0c9b,	16,	{0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92} },
-{ 0x0cab,	16,	{0x14, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0} },
-{ 0x0cbb,	16,	{0xf5, 0x46, 0xd2, 0x0e, 0x80, 0x6b, 0xc2, 0x0e, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x02, 0x80} },
-{ 0x0ccb,	16,	{0x60, 0x30, 0x18, 0x12, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d} },
-{ 0x0cdb,	16,	{0xf5, 0x83, 0xe0, 0x13, 0x92, 0x2c, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4} },
-{ 0x0ceb,	16,	{0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x13, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x2a, 0x30, 0x18} },
-{ 0x0cfb,	16,	{0x12, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0} },
-{ 0x0d0b,	16,	{0x13, 0x92, 0x14, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5} },
-{ 0x0d1b,	16,	{0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x0e, 0x80, 0x09, 0xc2, 0x0e, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2} },
-{ 0x0d2b,	16,	{0x02, 0x30, 0x18, 0x04, 0xa2, 0x2c, 0x92, 0x9b, 0xd2, 0x20, 0xc2, 0xaf, 0x85, 0x13, 0x99, 0x20} },
-{ 0x0d3b,	16,	{0x0e, 0x0b, 0x30, 0x12, 0x08, 0xc2, 0x12, 0x90, 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90} },
-{ 0x0d4b,	16,	{0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x0e, 0x71, 0xe4, 0xf5, 0x12, 0x74, 0xc0, 0x25, 0x12} },
-{ 0x0d5b,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x12, 0x7c, 0x00, 0x7b, 0x00, 0x24} },
-{ 0x0d6b,	16,	{0x64, 0xf9, 0xec, 0x34, 0x00, 0xfa, 0xef, 0x12, 0x15, 0x55, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x18} },
-{ 0x0d7b,	16,	{0xdb, 0xe5, 0x64, 0x60, 0x0b, 0x75, 0x89, 0x60, 0x75, 0x88, 0x40, 0xd2, 0xdf, 0x85, 0x65, 0x8d} },
-{ 0x0d8b,	16,	{0xe5, 0x67, 0x13, 0x92, 0x1a, 0x92, 0xc7, 0xe5, 0x68, 0x13, 0x92, 0x1b, 0xe5, 0x69, 0x13, 0x92} },
-{ 0x0d9b,	16,	{0x23, 0xe5, 0x6a, 0x60, 0x09, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0x7f} },
-{ 0x0dab,	16,	{0x97, 0xe0, 0x44, 0x10, 0xf0, 0xe5, 0x6b, 0x60, 0x09, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0x7f, 0xf0} },
-{ 0x0dbb,	16,	{0x80, 0x07, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x71, 0x60, 0x0b, 0xc2, 0x11, 0xc2} },
-{ 0x0dcb,	16,	{0x0a, 0x90, 0x7f, 0x94, 0xe0, 0x44, 0x08, 0xf0, 0xe5, 0x72, 0x60, 0x0b, 0xd2, 0x0a, 0xd2, 0x0b} },
-{ 0x0ddb,	16,	{0x90, 0x7f, 0x94, 0xe0, 0x44, 0x08, 0xf0, 0xe5, 0x73, 0x60, 0x17, 0xc2, 0xaf, 0xe4, 0x90, 0x7f} },
-{ 0x0deb,	16,	{0xcb, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0xc2, 0x0f, 0xd2, 0x03, 0xc2, 0x13, 0xf5, 0x7d, 0xf5, 0x4b} },
-{ 0x0dfb,	16,	{0xd2, 0xaf, 0xe5, 0x74, 0x60, 0x05, 0x30, 0x23, 0x02, 0xd2, 0x0a, 0xe5, 0x75, 0x60, 0x15, 0x90} },
-{ 0x0e0b,	16,	{0x7f, 0x94, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f, 0x97} },
-{ 0x0e1b,	16,	{0xe0, 0x54, 0xf7, 0xf0, 0xe5, 0x76, 0x60, 0x0a, 0xd2, 0xc4, 0xc2, 0xc0, 0x75, 0x3a, 0x01, 0x75} },
-{ 0x0e2b,	16,	{0x41, 0x28, 0xe5, 0x77, 0x60, 0x07, 0xc2, 0xc4, 0xe4, 0xf5, 0x49, 0xf5, 0x3a, 0xe5, 0x78, 0x60} },
-{ 0x0e3b,	16,	{0x03, 0xe4, 0xf5, 0x49, 0xe5, 0x79, 0x60, 0x02, 0xd2, 0x05, 0xe5, 0x7a, 0x60, 0x08, 0xe5, 0x76} },
-{ 0x0e4b,	16,	{0x70, 0x02, 0xf5, 0x41, 0xd2, 0x0b, 0xe5, 0x7b, 0x60, 0x15, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0} },
-{ 0x0e5b,	16,	{0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0, 0x74, 0x16, 0xf0, 0x74, 0x36, 0xf0, 0xd2} },
-{ 0x0e6b,	16,	{0x07, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0xa2, 0x11, 0xe4, 0x33, 0xff, 0x65, 0x37, 0x60, 0x04, 0x8f} },
-{ 0x0e7b,	16,	{0x37, 0xd2, 0x0b, 0xa2, 0x0a, 0xe4, 0x33, 0xff, 0x65, 0x38, 0x60, 0x04, 0x8f, 0x38, 0xd2, 0x0b} },
-{ 0x0e8b,	16,	{0x90, 0x7f, 0x9a, 0xe0, 0x54, 0x20, 0x65, 0x33, 0x60, 0x07, 0xe0, 0x54, 0x20, 0xf5, 0x33, 0xd2} },
-{ 0x0e9b,	16,	{0x0b, 0x90, 0x7f, 0x9a, 0xe0, 0x54, 0x40, 0xb5, 0x35, 0x09, 0xe0, 0x54, 0x40, 0x64, 0x40, 0xf5} },
-{ 0x0eab,	16,	{0x35, 0xd2, 0x0b, 0x30, 0x05, 0x35, 0xc2, 0xaf, 0x30, 0x01, 0x18, 0x90, 0x7f, 0xbc, 0xe0, 0x20} },
-{ 0x0ebb,	16,	{0xe1, 0x27, 0xe5, 0x49, 0x60, 0x09, 0x90, 0x7f, 0xbb, 0xf0, 0xe4, 0xf5, 0x49, 0xc2, 0x01, 0xc2} },
-{ 0x0ecb,	16,	{0x05, 0x80, 0x16, 0x90, 0x7f, 0xba, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x49, 0x60, 0x09, 0x90, 0x7f} },
-{ 0x0edb,	16,	{0xbd, 0xf0, 0xe4, 0xf5, 0x49, 0xd2, 0x01, 0xc2, 0x05, 0xd2, 0xaf, 0x30, 0x1f, 0x37, 0x30, 0x03} },
-{ 0x0eeb,	16,	{0x1b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x13, 0x75} },
-{ 0x0efb,	16,	{0x4b, 0x01, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0xc2, 0x1f, 0x80, 0x19, 0x90, 0x7f, 0xcc, 0xe0} },
-{ 0x0f0b,	16,	{0x20, 0xe1, 0x12, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x13, 0x75, 0x4b, 0x01, 0x90, 0x7f, 0xcd} },
-{ 0x0f1b,	16,	{0xe0, 0xf5, 0x7d, 0xc2, 0x1f, 0x30, 0x21, 0x03, 0x02, 0x10, 0x28, 0x30, 0x1f, 0x03, 0x02, 0x10} },
-{ 0x0f2b,	16,	{0x28, 0x30, 0x1b, 0x0a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x02, 0x10, 0x28, 0x30, 0x0a} },
-{ 0x0f3b,	16,	{0x03, 0x02, 0x10, 0x28, 0x30, 0x11, 0x03, 0x02, 0x10, 0x28, 0x30, 0x03, 0x62, 0x30, 0x1a, 0x12} },
-{ 0x0f4b,	16,	{0xaf, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13} },
-{ 0x0f5b,	16,	{0x92, 0x2c, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83} },
-{ 0x0f6b,	16,	{0xe0, 0xf5, 0x13, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x2a, 0x30, 0x1a, 0x12, 0xaf, 0x4b, 0x05} },
-{ 0x0f7b,	16,	{0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x15, 0xaf} },
-{ 0x0f8b,	16,	{0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47} },
-{ 0x0f9b,	16,	{0xd2, 0x0f, 0x80, 0x6b, 0xc2, 0x0f, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0xc2, 0x03, 0x80, 0x60, 0x30} },
-{ 0x0fab,	16,	{0x1a, 0x12, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83} },
-{ 0x0fbb,	16,	{0xe0, 0x13, 0x92, 0x2c, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c} },
-{ 0x0fcb,	16,	{0xf5, 0x83, 0xe0, 0xf5, 0x13, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x2a, 0x30, 0x1a, 0x12, 0xaf} },
-{ 0x0fdb,	16,	{0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92} },
-{ 0x0feb,	16,	{0x15, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0} },
-{ 0x0ffb,	16,	{0xf5, 0x47, 0xd2, 0x0f, 0x80, 0x09, 0xc2, 0x0f, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0xd2, 0x03, 0x30} },
-{ 0x100b,	16,	{0x1a, 0x04, 0xa2, 0x2c, 0x92, 0xc3, 0xd2, 0x21, 0xc2, 0xaf, 0x85, 0x13, 0xc1, 0x20, 0x0f, 0x0b} },
-{ 0x101b,	16,	{0x30, 0x13, 0x08, 0xc2, 0x13, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90, 0x7f, 0xc2} },
-{ 0x102b,	16,	{0xe0, 0x30, 0xe1, 0x03, 0x02, 0x10, 0xfe, 0xe5, 0x1a, 0x70, 0x46, 0x30, 0x09, 0x3f, 0xe5, 0x40} },
-{ 0x103b,	16,	{0x70, 0x3b, 0xa2, 0x06, 0x33, 0xf5, 0x31, 0xc2, 0x06, 0xc2, 0x09, 0xe4, 0xf5, 0x12, 0x7e, 0x00} },
-{ 0x104b,	16,	{0x7b, 0x00, 0x74, 0x26, 0x25, 0x12, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x15, 0x0f, 0xff, 0x74} },
-{ 0x105b,	16,	{0x80, 0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12} },
-{ 0x106b,	16,	{0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x0c, 0xf0, 0x75, 0x40, 0x10, 0x22, 0x75, 0x1a, 0x01} },
-{ 0x107b,	16,	{0x22, 0xe5, 0x1a, 0x64, 0x01, 0x70, 0x45, 0x30, 0x0b, 0x3e, 0xe5, 0x41, 0x70, 0x3a, 0xa2, 0x07} },
-{ 0x108b,	16,	{0x33, 0xf5, 0x3d, 0xc2, 0x07, 0xc2, 0x0b, 0xe4, 0xf5, 0x12, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x32} },
-{ 0x109b,	16,	{0x25, 0x12, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x15, 0x0f, 0xff, 0x74, 0x80, 0x25, 0x12, 0xf5} },
-{ 0x10ab,	16,	{0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x0c, 0xdb, 0x90} },
-{ 0x10bb,	16,	{0x7f, 0xc3, 0x74, 0x0c, 0xf0, 0x75, 0x41, 0x10, 0x75, 0x1a, 0x02, 0x22, 0xe5, 0x1c, 0x60, 0x30} },
-{ 0x10cb,	16,	{0x15, 0x1c, 0xe4, 0xf5, 0x12, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x1b, 0x25, 0x12, 0xf9, 0xee, 0x34} },
-{ 0x10db,	16,	{0x00, 0xfa, 0x12, 0x15, 0x0f, 0xff, 0x74, 0x80, 0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5} },
-{ 0x10eb,	16,	{0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0} },
-{ 0x10fb,	3,	{0xe4, 0xf5, 0x1a} },
-{ 0x10fe,	1,	{0x22} },
-{ 0x10ff,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x15, 0x9f, 0x11, 0xc4, 0x00, 0x12, 0x38, 0x01, 0x12, 0xa4, 0x03} },
-{ 0x110f,	16,	{0x11, 0x22, 0x06, 0x11, 0xb7, 0x08, 0x11, 0xb1, 0x09, 0x11, 0xa4, 0x0a, 0x12, 0xfa, 0x0b, 0x00} },
-{ 0x111f,	16,	{0x00, 0x12, 0xf3, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x40, 0x24, 0x02} },
-{ 0x112f,	16,	{0x70, 0x69, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x12} },
-{ 0x113f,	16,	{0xfa, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x16, 0xd3, 0x8b, 0x12, 0x8a, 0x13, 0x89, 0x14, 0xea} },
-{ 0x114f,	16,	{0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5} },
-{ 0x115f,	16,	{0xf0, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x12, 0xfa, 0x90, 0x7f} },
-{ 0x116f,	16,	{0xea, 0xe0, 0xff, 0x12, 0x17, 0x22, 0x8b, 0x12, 0x8a, 0x13, 0x89, 0x14, 0xea, 0x49, 0x60, 0x11} },
-{ 0x117f,	16,	{0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x12} },
-{ 0x118f,	16,	{0xfa, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0xb4, 0xe0, 0x44} },
-{ 0x119f,	16,	{0x01, 0xf0, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02} },
-{ 0x11af,	16,	{0x12, 0xfa, 0x12, 0x14, 0x47, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f} },
-{ 0x11bf,	16,	{0xb5, 0xf0, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31} },
-{ 0x11cf,	16,	{0x24, 0x02, 0x70, 0x5b, 0xa2, 0x25, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x29, 0xe4, 0x33} },
-{ 0x11df,	16,	{0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x12} },
-{ 0x11ef,	16,	{0xfa, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x12} },
-{ 0x11ff,	16,	{0xfa, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07} },
-{ 0x120f,	16,	{0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90} },
-{ 0x121f,	16,	{0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x12, 0xfa, 0x90} },
-{ 0x122f,	16,	{0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60} },
-{ 0x123f,	16,	{0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2} },
-{ 0x124f,	16,	{0x25, 0x02, 0x12, 0xfa, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x12, 0xfa, 0x90, 0x7f} },
-{ 0x125f,	16,	{0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff} },
-{ 0x126f,	16,	{0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4} },
-{ 0x127f,	16,	{0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54} },
-{ 0x128f,	16,	{0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0} },
-{ 0x129f,	16,	{0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70} },
-{ 0x12af,	16,	{0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x25, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0} },
-{ 0x12bf,	16,	{0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4} },
-{ 0x12cf,	16,	{0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5} },
-{ 0x12df,	16,	{0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44} },
-{ 0x12ef,	16,	{0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44} },
-{ 0x12ff,	2,	{0x02, 0xf0} },
-{ 0x1301,	1,	{0x22} },
-{ 0x1302,	16,	{0x20, 0x27, 0x03, 0x02, 0x14, 0x46, 0xe5, 0x40, 0x60, 0x02, 0x15, 0x40, 0xe5, 0x48, 0x60, 0x4f} },
-{ 0x1312,	16,	{0x65, 0x44, 0x70, 0x45, 0xe5, 0x42, 0xf4, 0x60, 0x02, 0x05, 0x42, 0xe5, 0x42, 0xc3, 0x95, 0x55} },
-{ 0x1322,	16,	{0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x00, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f} },
-{ 0x1332,	16,	{0xb7, 0xe5, 0x48, 0xf0, 0xc2, 0x00, 0xe4, 0xf5, 0x48, 0xf5, 0x42, 0xf5, 0x44, 0x80, 0x16, 0x90} },
-{ 0x1342,	16,	{0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0x90, 0x7f, 0xb9, 0xe5, 0x48, 0xf0, 0xd2, 0x00, 0xe4, 0xf5} },
-{ 0x1352,	16,	{0x48, 0xf5, 0x42, 0xf5, 0x44, 0xd2, 0xaf, 0x80, 0x06, 0x85, 0x48, 0x44, 0xe4, 0xf5, 0x42, 0xe5} },
-{ 0x1362,	16,	{0x2e, 0x60, 0x2d, 0x20, 0x16, 0x07, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe0, 0x0e, 0xe5, 0x2f, 0x60} },
-{ 0x1372,	16,	{0x05, 0xe4, 0xf5, 0x2f, 0xd2, 0x09, 0xe4, 0xf5, 0x3e, 0x80, 0x13, 0xe5, 0x3e, 0xd3, 0x95, 0x56} },
-{ 0x1382,	16,	{0x50, 0x0c, 0xe5, 0x3e, 0xb5, 0x56, 0x05, 0x75, 0x2f, 0x01, 0xd2, 0x09, 0x05, 0x3e, 0xc2, 0x16} },
-{ 0x1392,	16,	{0xe5, 0x41, 0x60, 0x02, 0x15, 0x41, 0xe5, 0x49, 0x60, 0x4f, 0x65, 0x45, 0x70, 0x45, 0xe5, 0x43} },
-{ 0x13a2,	16,	{0xf4, 0x60, 0x02, 0x05, 0x43, 0xe5, 0x43, 0xc3, 0x95, 0x6d, 0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x01} },
-{ 0x13b2,	16,	{0x18, 0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f, 0xbb, 0xe5, 0x49, 0xf0, 0xc2, 0x01} },
-{ 0x13c2,	16,	{0xe4, 0xf5, 0x49, 0xf5, 0x43, 0xf5, 0x45, 0x80, 0x16, 0x90, 0x7f, 0xba, 0xe0, 0x20, 0xe1, 0x0f} },
-{ 0x13d2,	16,	{0x90, 0x7f, 0xbd, 0xe5, 0x49, 0xf0, 0xd2, 0x01, 0xe4, 0xf5, 0x49, 0xf5, 0x43, 0xf5, 0x45, 0xd2} },
-{ 0x13e2,	16,	{0xaf, 0x80, 0x06, 0x85, 0x49, 0x45, 0xe4, 0xf5, 0x43, 0xe5, 0x3a, 0x60, 0x2d, 0x20, 0x17, 0x07} },
-{ 0x13f2,	16,	{0x90, 0x7f, 0x9a, 0xe0, 0x30, 0xe2, 0x0e, 0xe5, 0x3b, 0x60, 0x05, 0xe4, 0xf5, 0x3b, 0xd2, 0x0b} },
-{ 0x1402,	16,	{0xe4, 0xf5, 0x3f, 0x80, 0x13, 0xe5, 0x3f, 0xd3, 0x95, 0x6e, 0x50, 0x0c, 0xe5, 0x3f, 0xb5, 0x6e} },
-{ 0x1412,	16,	{0x05, 0x75, 0x3b, 0x01, 0xd2, 0x0b, 0x05, 0x3f, 0xc2, 0x17, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1} },
-{ 0x1422,	16,	{0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x1c, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x1d} },
-{ 0x1432,	16,	{0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4} },
-{ 0x1442,	5,	{0x90, 0x7f, 0xd3, 0xf0, 0x22} },
-{ 0x1447,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x96, 0xe0, 0x44} },
-{ 0x1457,	16,	{0x10, 0xf0, 0x90, 0x7f, 0x94, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x9a, 0xf0, 0x90, 0x7f} },
-{ 0x1467,	16,	{0x97, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x23, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x84} },
-{ 0x1477,	16,	{0xf0, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f, 0xcf, 0xf0, 0x75, 0x98} },
-{ 0x1487,	16,	{0x40, 0x43, 0xa8, 0x10, 0xc2, 0x18, 0xc2, 0x20, 0xc2, 0x08, 0xc2, 0x10, 0xf5, 0x7c, 0xf5, 0x4a} },
-{ 0x1497,	16,	{0xc2, 0x0e, 0xc2, 0x12, 0xf5, 0x42, 0xc2, 0x16, 0xf5, 0x44, 0xf5, 0x48, 0xc2, 0x22, 0xc2, 0x19} },
-{ 0x14a7,	16,	{0xf5, 0x2d, 0xf5, 0x2f, 0xc2, 0x04, 0xc2, 0x1c, 0xf5, 0x3e, 0xc2, 0x06, 0xd2, 0x00, 0xd2, 0x02} },
-{ 0x14b7,	16,	{0xd2, 0x09, 0xd2, 0x1e, 0xf5, 0x26, 0x90, 0x7f, 0xcb, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f} },
-{ 0x14c7,	16,	{0xd1, 0xf0, 0x75, 0xc0, 0x40, 0x43, 0xa8, 0x40, 0xc2, 0x1a, 0xc2, 0x21, 0xc2, 0x0a, 0xc2, 0x11} },
-{ 0x14d7,	16,	{0xf5, 0x7d, 0xf5, 0x4b, 0xc2, 0x0f, 0xc2, 0x13, 0xf5, 0x43, 0xc2, 0x17, 0xf5, 0x45, 0xf5, 0x49} },
-{ 0x14e7,	16,	{0xc2, 0x23, 0xc2, 0x1b, 0xf5, 0x39, 0xf5, 0x3b, 0xc2, 0x05, 0xc2, 0x1d, 0xf5, 0x3f, 0xc2, 0x07} },
-{ 0x14f7,	16,	{0xd2, 0x01, 0xd2, 0x03, 0xd2, 0x0b, 0xd2, 0x1f, 0x75, 0x32, 0x01, 0x90, 0x7f, 0xdf, 0x74, 0xff} },
-{ 0x1507,	8,	{0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xd2, 0x27, 0x22} },
-{ 0x150f,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x151f,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x1528,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x1538,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x1548,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x1555,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} },
-{ 0x1565,	2,	{0xf3, 0x22} },
-{ 0x1567,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0x1577,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0x1587,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0x1597,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0x159f,	16,	{0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} },
-{ 0x15af,	16,	{0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} },
-{ 0x15bf,	6,	{0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} },
-{ 0x15c5,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x7d, 0x02, 0x16, 0x0c} },
-{ 0x15d1,	16,	{0x02, 0x16, 0x51, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x15e1,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x15f1,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x1601,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x18, 0x9e, 0xe4, 0x7e} },
-{ 0x1611,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x1621,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x1631,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x1641,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x1651,	16,	{0x75, 0x11, 0x01, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3} },
-{ 0x1661,	16,	{0x92, 0x25, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde} },
-{ 0x1671,	16,	{0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9} },
-{ 0x1681,	16,	{0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90} },
-{ 0x1691,	16,	{0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2, 0xbe, 0xd2, 0x2c, 0x12, 0x18} },
-{ 0x16a1,	16,	{0x58, 0xc2, 0x26, 0xc2, 0x24, 0xc2, 0x27, 0x30, 0x27, 0x03, 0x12, 0x0a, 0x6b, 0x90, 0x7f, 0xd8} },
-{ 0x16b1,	16,	{0xe0, 0x65, 0x10, 0x60, 0x08, 0xe0, 0xf5, 0x10, 0x12, 0x13, 0x02, 0x80, 0xea, 0x30, 0x26, 0x07} },
-{ 0x16c1,	16,	{0xc2, 0x26, 0x12, 0x10, 0xff, 0x80, 0xe0, 0x30, 0x2a, 0xdd, 0xc2, 0x2a, 0x12, 0x00, 0x26, 0x80} },
-{ 0x16d1,	1,	{0xd6} },
-{ 0x16d2,	1,	{0x22} },
-{ 0x16d3,	16,	{0xe4, 0xfe, 0x75, 0x17, 0xff, 0x75, 0x18, 0x19, 0x75, 0x19, 0x12, 0xab, 0x17, 0xaa, 0x18, 0xa9} },
-{ 0x16e3,	16,	{0x19, 0x90, 0x00, 0x01, 0x12, 0x15, 0x28, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x16f3,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x15, 0x67, 0x85, 0xf0, 0x15, 0xf5, 0x16, 0x62, 0x15} },
-{ 0x1703,	16,	{0xe5, 0x15, 0x62, 0x16, 0xe5, 0x16, 0x62, 0x15, 0x29, 0xfd, 0xe5, 0x15, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x1713,	14,	{0x17, 0xff, 0xf5, 0x18, 0x89, 0x19, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x1721,	1,	{0x22} },
-{ 0x1722,	2,	{0x8f, 0x15} },
-{ 0x1724,	16,	{0xe4, 0xf5, 0x16, 0x75, 0x17, 0xff, 0x75, 0x18, 0x19, 0x75, 0x19, 0x86, 0xab, 0x17, 0xaa, 0x18} },
-{ 0x1734,	16,	{0xa9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x15, 0x28, 0xb4, 0x03, 0x1d, 0xaf, 0x16, 0x05, 0x16, 0xef} },
-{ 0x1744,	16,	{0xb5, 0x15, 0x01, 0x22, 0x12, 0x15, 0x0f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x1754,	14,	{0x17, 0xff, 0xf5, 0x18, 0x89, 0x19, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x1762,	1,	{0x22} },
-{ 0x1763,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} },
-{ 0x1773,	16,	{0x2b, 0x04, 0xc2, 0x2b, 0x80, 0x02, 0xd2, 0x2a, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} },
-{ 0x1783,	14,	{0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1791,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d} },
-{ 0x17a1,	16,	{0x74, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xf0, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74} },
-{ 0x17b1,	12,	{0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9d, 0xf0, 0x22} },
-{ 0x17bd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} },
-{ 0x17cd,	16,	{0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} },
-{ 0x17dd,	10,	{0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x17e7,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} },
-{ 0x17f7,	16,	{0x26, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} },
-{ 0x1807,	7,	{0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x180e,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x181e,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x182e,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1833,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x1843,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x1853,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1858,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x2c, 0x04, 0xe0, 0x44} },
-{ 0x1868,	16,	{0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, 0x06, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x1878,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x187d,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x188d,	1,	{0x22} },
-{ 0x188e,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x189e,	16,	{0x01, 0x1a, 0x00, 0x03, 0x1b, 0x03, 0x00, 0x00, 0xc1, 0x26, 0xc1, 0x2a, 0xc1, 0x25, 0xc1, 0xa9} },
-{ 0x18ae,	2,	{0xc1, 0xab} },
-{ 0x18b0,	1,	{0x00} },
-{ 0x1900,	16,	{0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x0f, 0x01, 0x00, 0x00, 0x01, 0x02} },
-{ 0x1910,	16,	{0x00, 0x01, 0x09, 0x02, 0x74, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e} },
-{ 0x1920,	16,	{0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} },
-{ 0x1930,	16,	{0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00} },
-{ 0x1940,	16,	{0x07, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} },
-{ 0x1950,	16,	{0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02} },
-{ 0x1960,	16,	{0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00} },
-{ 0x1970,	16,	{0x00, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07} },
-{ 0x1980,	16,	{0x05, 0x87, 0x02, 0x40, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00} },
-{ 0x1990,	16,	{0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00} },
-{ 0x19a0,	16,	{0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00} },
-{ 0x19b0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00} },
-{ 0x19c0,	16,	{0x6f, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} },
-{ 0x19d0,	16,	{0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00} },
-{ 0x19e0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00} },
-{ 0x19f0,	16,	{0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00} },
-{ 0x1a00,	10,	{0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00} },
-{ 0x1b00,	16,	{0x02, 0x17, 0xe7, 0x00, 0x02, 0x18, 0x0e, 0x00, 0x02, 0x17, 0xbd, 0x00, 0x02, 0x17, 0x63, 0x00} },
-{ 0x1b10,	3,	{0x02, 0x18, 0x33} },
+ {0x0026, 10, { 0x12, 0x18, 0x09, 0x12, 0x18, 0xbc, 0x12, 0x14, 0xbb, 0x22}},
+ {0x0033,  3, { 0x02, 0x00, 0x1d}},
+ {0x001d,  4, { 0x53, 0xd8, 0xef, 0x32}},
+ {0x0006, 16, { 0x8e, 0x12, 0x8f, 0x13, 0xe5, 0x13, 0x15, 0x13, 0xae, 0x12, 0x70, 0x02, 0x15, 0x12, 0x4e, 0x60}},
+ {0x0016,  7, { 0x05, 0x12, 0x18, 0xab, 0x80, 0xee, 0x22}},
+ {0x0003,  3, { 0x02, 0x00, 0x46}},
+ {0x0046, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08}},
+ {0x0056, 16, { 0x30, 0x99, 0x0e, 0x30, 0x11, 0x07, 0xa2, 0x17, 0x92, 0x9b, 0x85, 0x46, 0x99, 0xc2, 0x99, 0xd2}},
+ {0x0066, 16, { 0x1f, 0x30, 0xc1, 0x0e, 0x30, 0x12, 0x07, 0xa2, 0x18, 0x92, 0xc3, 0x85, 0x47, 0xc1, 0xc2, 0xc1}},
+ {0x0076, 16, { 0xd2, 0x20, 0x20, 0x1f, 0x03, 0x02, 0x04, 0x42, 0xc2, 0x1f, 0x20, 0x03, 0x03, 0x02, 0x02, 0x67}},
+ {0x0086, 16, { 0x20, 0x11, 0x03, 0x02, 0x01, 0x38, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x3e, 0x20, 0x13, 0x36}},
+ {0x0096, 16, { 0x20, 0x0b, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x29, 0x30, 0x1b, 0x12}},
+ {0x00a6, 16, { 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13}},
+ {0x00b6, 16, { 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83}},
+ {0x00c6, 16, { 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc7, 0xe4, 0xf0}},
+ {0x00d6, 16, { 0xc2, 0x03, 0x30, 0x15, 0x0c, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0xc2, 0x11, 0x02, 0x04}},
+ {0x00e6, 16, { 0x40, 0x90, 0x7f, 0xc8, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc9}},
+ {0x00f6, 16, { 0xe0, 0xf5, 0x7c, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x15, 0x20, 0x13, 0x2d, 0x20, 0x0b, 0x2a}},
+ {0x0043,  3, { 0x02, 0x1b, 0x00}},
+ {0x0023,  3, { 0x02, 0x00, 0x46}},
+ {0x003b,  3, { 0x02, 0x00, 0x46}},
+ {0x0000,  3, { 0x02, 0x16, 0x3d}},
+ {0x0106, 64, { 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x20, 0x30, 0x1b, 0x11, 0x90, 0x7d, 0xc1, 0xe0,
+  0x13, 0x92, 0x17, 0xa3, 0xe0, 0xf5, 0x46, 0x75, 0x4a, 0x03, 0x02, 0x04, 0x40, 0x75, 0x4a, 0x02,
+  0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0x75, 0x4a, 0x01, 0xc2, 0x11, 0x02, 0x04,
+  0x40, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x03, 0x02, 0x01, 0xe0, 0x90, 0x7f, 0xc6, 0xe0}},
+ {0x0146, 64, { 0x30, 0xe1, 0x07, 0xc2, 0x21, 0xc2, 0x05, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x7c, 0x90,
+  0x7e, 0x40, 0xe0, 0x13, 0x92, 0x15, 0x30, 0x13, 0x03, 0x02, 0x01, 0xd8, 0x20, 0x0b, 0x72, 0x20,
+  0x00, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x65, 0x30, 0x1b, 0x10, 0x90,
+  0x7e, 0x41, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x03, 0x80, 0x09}},
+ {0x0186, 64, { 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x02, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x17, 0x90,
+  0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x03, 0x20, 0x15, 0x03, 0x02, 0x04, 0x40, 0xc2, 0x15, 0x90, 0x7f,
+  0xbf, 0x04, 0xf0, 0x02, 0x04, 0x40, 0x30, 0x1b, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e,
+  0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a}},
+ {0x01c6, 64, { 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x02, 0x04,
+  0x40, 0x75, 0x4a, 0x01, 0xc2, 0x21, 0x02, 0x04, 0x40, 0x30, 0x13, 0x03, 0x02, 0x02, 0x62, 0x20,
+  0x0b, 0x79, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x6f, 0x30, 0x1b, 0x12, 0xae,
+  0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13}},
+ {0x0206, 64, { 0x92, 0x9b, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0,
+  0xf5, 0x99, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x17, 0x90, 0x7f, 0xc7, 0xe4, 0xf0, 0xc2, 0x03,
+  0x20, 0x15, 0x03, 0x02, 0x04, 0x40, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x02, 0x04, 0x40,
+  0x30, 0x1b, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e}},
+ {0x0246, 64, { 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34,
+  0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x02, 0x04, 0x40, 0xc2, 0x21, 0x02, 0x04, 0x40,
+  0x20, 0x11, 0x03, 0x02, 0x03, 0x19, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x3e, 0x20, 0x13, 0x36,
+  0x20, 0x0b, 0x33, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x29, 0x30, 0x1b}},
+ {0x0286, 64, { 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13,
+  0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83,
+  0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc9, 0xe4, 0xf0,
+  0xd2, 0x03, 0x30, 0x15, 0x0c, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0xc2, 0x11, 0x02}},
+ {0x02c6, 64, { 0x04, 0x40, 0x90, 0x7f, 0xc6, 0xe0, 0x30, 0xe1, 0x05, 0xc2, 0x11, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc7,
+  0xe0, 0xf5, 0x7c, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x15, 0x20, 0x13, 0x2d, 0x20, 0x0b, 0x2a,
+  0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x20, 0x30, 0x1b, 0x11, 0x90, 0x7e, 0x41,
+  0xe0, 0x13, 0x92, 0x17, 0xa3, 0xe0, 0xf5, 0x46, 0x75, 0x4a, 0x03, 0x02, 0x04, 0x40, 0x75}},
+ {0x0306, 64, { 0x4a, 0x02, 0x90, 0x7e, 0x41, 0xe0, 0xf5, 0x46, 0x02, 0x04, 0x40, 0x75, 0x4a, 0x01, 0xc2, 0x11, 0x02,
+  0x04, 0x40, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x03, 0x02, 0x03, 0xc1, 0x90, 0x7f, 0xc8, 0xe0,
+  0x30, 0xe1, 0x07, 0xc2, 0x21, 0xc2, 0x05, 0x02, 0x04, 0x40, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x7c,
+  0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x15, 0x30, 0x13, 0x03, 0x02, 0x03, 0xb9, 0x20, 0x0b}},
+ {0x0346, 64, { 0x72, 0x20, 0x00, 0x6f, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x65, 0x30, 0x1b, 0x10,
+  0x90, 0x7d, 0xc1, 0xe0, 0x13, 0x92, 0x9b, 0xa3, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x03, 0x80, 0x09,
+  0x90, 0x7d, 0xc1, 0xe0, 0xf5, 0x99, 0x75, 0x4a, 0x02, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x17,
+  0x90, 0x7f, 0xc9, 0xe4, 0xf0, 0xd2, 0x03, 0x20, 0x15, 0x03, 0x02, 0x04, 0x40, 0xc2, 0x15}},
+ {0x0386, 64, { 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x02, 0x04, 0x40, 0x30, 0x1b, 0x12, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0,
+  0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a,
+  0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x02,
+  0x04, 0x40, 0x75, 0x4a, 0x01, 0xc2, 0x21, 0x02, 0x04, 0x40, 0x30, 0x13, 0x03, 0x02, 0x04}},
+ {0x03c6, 64, { 0x3e, 0x20, 0x0b, 0x74, 0x90, 0x7f, 0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x20, 0x1c, 0x6a, 0x30, 0x1b, 0x12,
+  0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13,
+  0x92, 0x9b, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83,
+  0xe0, 0xf5, 0x99, 0xe5, 0x4a, 0xc3, 0x95, 0x7c, 0x40, 0x13, 0x90, 0x7f, 0xc9, 0xe4, 0xf0}},
+ {0x0406, 64, { 0xd2, 0x03, 0x30, 0x15, 0x35, 0xc2, 0x15, 0x90, 0x7f, 0xbf, 0x04, 0xf0, 0x80, 0x2c, 0x30, 0x1b, 0x12,
+  0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13,
+  0x92, 0x17, 0xae, 0x4a, 0x05, 0x4a, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83,
+  0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x80, 0x02, 0xc2, 0x21, 0xd2, 0x25, 0x20, 0x20, 0x03, 0x02}},
+ {0x0446, 64, { 0x08, 0x0c, 0xc2, 0x20, 0x20, 0x04, 0x03, 0x02, 0x06, 0x31, 0x20, 0x12, 0x03, 0x02, 0x05, 0x02, 0xe5,
+  0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x3e, 0x20, 0x14, 0x36, 0x20, 0x0d, 0x33, 0x90, 0x7f, 0x9a, 0xe0,
+  0x20, 0xe5, 0x03, 0x20, 0x1e, 0x29, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e,
+  0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b}},
+ {0x0486, 64, { 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0x02, 0x08, 0x0a, 0xc2,
+  0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x04, 0x30, 0x16, 0x0c, 0xc2, 0x16,
+  0x90, 0x7f, 0xc1, 0x04, 0xf0, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcc, 0xe0, 0x30, 0xe1,
+  0x05, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0xf5, 0x7d, 0x90, 0x7c, 0xc0}},
+ {0x04c6, 64, { 0xe0, 0x13, 0x92, 0x16, 0x20, 0x14, 0x2d, 0x20, 0x0d, 0x2a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5, 0x03,
+  0x20, 0x1e, 0x20, 0x30, 0x1d, 0x11, 0x90, 0x7c, 0xc1, 0xe0, 0x13, 0x92, 0x18, 0xa3, 0xe0, 0xf5,
+  0x47, 0x75, 0x4b, 0x03, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x02, 0x90, 0x7c, 0xc1, 0xe0, 0xf5, 0x47,
+  0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0xe5, 0x4b, 0xc3, 0x95}},
+ {0x0506, 64, { 0x7d, 0x50, 0x03, 0x02, 0x05, 0xaa, 0x90, 0x7f, 0xca, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x22, 0xc2, 0x06,
+  0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x16,
+  0x30, 0x14, 0x03, 0x02, 0x05, 0xa2, 0x20, 0x0d, 0x72, 0x20, 0x00, 0x6f, 0x90, 0x7f, 0x9a, 0xe0,
+  0x20, 0xe5, 0x03, 0x20, 0x1e, 0x65, 0x30, 0x1d, 0x10, 0x90, 0x7d, 0x41, 0xe0, 0x13, 0x92}},
+ {0x0546, 64, { 0xc3, 0xa3, 0xe0, 0xf5, 0xc1, 0x75, 0x4b, 0x03, 0x80, 0x09, 0x90, 0x7d, 0x41, 0xe0, 0xf5, 0xc1, 0x75,
+  0x4b, 0x02, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x04,
+  0x20, 0x16, 0x03, 0x02, 0x08, 0x0a, 0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x08, 0x0a,
+  0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d}},
+ {0x0586, 64, { 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34,
+  0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01, 0xc2, 0x22,
+  0x02, 0x08, 0x0a, 0x30, 0x14, 0x03, 0x02, 0x06, 0x2c, 0x20, 0x0d, 0x79, 0x90, 0x7f, 0x9a, 0xe0,
+  0x20, 0xe5, 0x03, 0x20, 0x1e, 0x6f, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0x40}},
+ {0x05c6, 64, { 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0xc3, 0xae, 0x4b, 0x05, 0x4b, 0x74,
+  0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0xc1, 0xe5, 0x4b, 0xc3, 0x95,
+  0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcb, 0xe4, 0xf0, 0xc2, 0x04, 0x20, 0x16, 0x03, 0x02, 0x08, 0x0a,
+  0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x08, 0x0a, 0x30, 0x1d, 0x12, 0xae, 0x4b}},
+ {0x0606, 64, { 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae,
+  0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47,
+  0xd2, 0x12, 0x02, 0x08, 0x0a, 0xc2, 0x22, 0x02, 0x08, 0x0a, 0x20, 0x12, 0x03, 0x02, 0x06, 0xe3,
+  0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x3e, 0x20, 0x14, 0x36, 0x20, 0x0d, 0x33, 0x90, 0x7f}},
+ {0x0646, 64, { 0x9a, 0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x29, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0,
+  0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b,
+  0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0x02, 0x08, 0x0a,
+  0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcd, 0xe4, 0xf0, 0xd2, 0x04, 0x30, 0x16, 0x0c}},
+ {0x0686, 64, { 0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xca, 0xe0, 0x30,
+  0xe1, 0x05, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0x90, 0x7d, 0x40,
+  0xe0, 0x13, 0x92, 0x16, 0x20, 0x14, 0x2d, 0x20, 0x0d, 0x2a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5,
+  0x03, 0x20, 0x1e, 0x20, 0x30, 0x1d, 0x11, 0x90, 0x7d, 0x41, 0xe0, 0x13, 0x92, 0x18, 0xa3}},
+ {0x06c6, 64, { 0xe0, 0xf5, 0x47, 0x75, 0x4b, 0x03, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x02, 0x90, 0x7d, 0x41, 0xe0, 0xf5,
+  0x47, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01, 0xc2, 0x12, 0x02, 0x08, 0x0a, 0xe5, 0x4b, 0xc3, 0x95,
+  0x7d, 0x50, 0x03, 0x02, 0x07, 0x8b, 0x90, 0x7f, 0xcc, 0xe0, 0x30, 0xe1, 0x07, 0xc2, 0x22, 0xc2,
+  0x06, 0x02, 0x08, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0xf5, 0x7d, 0x90, 0x7c, 0xc0, 0xe0, 0x13}},
+ {0x0706, 64, { 0x92, 0x16, 0x30, 0x14, 0x03, 0x02, 0x07, 0x83, 0x20, 0x0d, 0x72, 0x20, 0x00, 0x6f, 0x90, 0x7f, 0x9a,
+  0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x65, 0x30, 0x1d, 0x10, 0x90, 0x7c, 0xc1, 0xe0, 0x13, 0x92,
+  0xc3, 0xa3, 0xe0, 0xf5, 0xc1, 0x75, 0x4b, 0x03, 0x80, 0x09, 0x90, 0x7c, 0xc1, 0xe0, 0xf5, 0xc1,
+  0x75, 0x4b, 0x02, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x40, 0x17, 0x90, 0x7f, 0xcd, 0xe4, 0xf0}},
+ {0x0746, 64, { 0xd2, 0x04, 0x20, 0x16, 0x03, 0x02, 0x08, 0x0a, 0xc2, 0x16, 0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x02, 0x08,
+  0x0a, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c,
+  0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4,
+  0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12, 0x02, 0x08, 0x0a, 0x75, 0x4b, 0x01}},
+ {0x0786, 64, { 0xc2, 0x22, 0x02, 0x08, 0x0a, 0x30, 0x14, 0x03, 0x02, 0x08, 0x08, 0x20, 0x0d, 0x74, 0x90, 0x7f, 0x9a,
+  0xe0, 0x20, 0xe5, 0x03, 0x20, 0x1e, 0x6a, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0,
+  0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0xc3, 0xae, 0x4b, 0x05, 0x4b,
+  0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0xc1, 0xe5, 0x4b}},
+ {0x07c6, 64, { 0xc3, 0x95, 0x7d, 0x40, 0x13, 0x90, 0x7f, 0xcd, 0xe4, 0xf0, 0xd2, 0x04, 0x30, 0x16, 0x35, 0xc2, 0x16,
+  0x90, 0x7f, 0xc1, 0x04, 0xf0, 0x80, 0x2c, 0x30, 0x1d, 0x12, 0xae, 0x4b, 0x05, 0x4b, 0x74, 0xc0,
+  0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xae, 0x4b, 0x05, 0x4b,
+  0x74, 0xc0, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12}},
+ {0x0806, 64, { 0x80, 0x02, 0xc2, 0x22, 0xd2, 0x25, 0x20, 0x98, 0x03, 0x02, 0x09, 0x3e, 0xc2, 0x98, 0x20, 0x01, 0x03,
+  0x02, 0x08, 0xb0, 0x20, 0x23, 0x27, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4,
+  0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x1b, 0x49, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80,
+  0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0x80, 0x36, 0xaf, 0x99}},
+ {0x0846, 64, { 0xef, 0xb5, 0x58, 0x04, 0xd2, 0x0b, 0x80, 0x2c, 0xef, 0xb5, 0x57, 0x04, 0xc2, 0x0b, 0x80, 0x24, 0xae,
+  0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xef, 0xf0, 0x30,
+  0x1b, 0x11, 0xae, 0x48, 0x05, 0x48, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83,
+  0xe5, 0x98, 0xf0, 0xd2, 0x19, 0xe5, 0x48, 0xc3, 0x95, 0x54, 0x50, 0x03, 0x02, 0x09, 0x3c}},
+ {0x0886, 64, { 0x90, 0x7f, 0xb8, 0xe0, 0x30, 0xe1, 0x15, 0xe5, 0x48, 0xc3, 0x94, 0x40, 0x50, 0x03, 0x02, 0x09, 0x3c,
+  0x15, 0x48, 0x15, 0x48, 0x05, 0x2d, 0xd2, 0x0c, 0x02, 0x09, 0x3c, 0x90, 0x7f, 0xb7, 0xe5, 0x48,
+  0xf0, 0x75, 0x48, 0x00, 0xc2, 0x01, 0x02, 0x09, 0x3c, 0x20, 0x23, 0x27, 0xae, 0x48, 0x05, 0x48,
+  0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x99, 0xf0, 0x30, 0x1b}},
+ {0x08c6, 64, { 0x49, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98,
+  0xf0, 0x80, 0x36, 0xaf, 0x99, 0xef, 0xb5, 0x58, 0x04, 0xd2, 0x0b, 0x80, 0x2c, 0xef, 0xb5, 0x57,
+  0x04, 0xc2, 0x0b, 0x80, 0x24, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34,
+  0x7e, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x1b, 0x11, 0xae, 0x48, 0x05, 0x48, 0x74, 0x00, 0x2e}},
+ {0x0906, 64, { 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe5, 0x98, 0xf0, 0xd2, 0x19, 0xe5, 0x48, 0xc3, 0x95, 0x54,
+  0x40, 0x23, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x11, 0xe5, 0x48, 0xc3, 0x94, 0x40, 0x40, 0x15,
+  0x15, 0x48, 0x15, 0x48, 0x05, 0x2d, 0xd2, 0x0c, 0x80, 0x0b, 0x90, 0x7f, 0xb9, 0xe5, 0x48, 0xf0,
+  0x75, 0x48, 0x00, 0xd2, 0x01, 0xd2, 0x25, 0x20, 0xc0, 0x03, 0x02, 0x0a, 0x70, 0xc2, 0xc0}},
+ {0x0946, 64, { 0x20, 0x02, 0x03, 0x02, 0x09, 0xe2, 0x20, 0x24, 0x27, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5,
+  0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc1, 0xf0, 0x30, 0x1d, 0x49, 0xae, 0x49, 0x05, 0x49,
+  0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0x80, 0x36, 0xaf,
+  0xc1, 0xef, 0xb5, 0x70, 0x04, 0xd2, 0x0d, 0x80, 0x2c, 0xef, 0xb5, 0x6f, 0x04, 0xc2, 0x0d}},
+ {0x0986, 64, { 0x80, 0x24, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef,
+  0xf0, 0x30, 0x1d, 0x11, 0xae, 0x49, 0x05, 0x49, 0x74, 0x80, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d,
+  0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0xd2, 0x1a, 0xe5, 0x49, 0xc3, 0x95, 0x6c, 0x50, 0x03, 0x02, 0x0a,
+  0x6e, 0x90, 0x7f, 0xbc, 0xe0, 0x30, 0xe1, 0x15, 0xe5, 0x49, 0xc3, 0x94, 0x40, 0x50, 0x03}},
+ {0x09c6, 64, { 0x02, 0x0a, 0x6e, 0x15, 0x49, 0x15, 0x49, 0x05, 0x39, 0xd2, 0x0e, 0x02, 0x0a, 0x6e, 0x90, 0x7f, 0xbb,
+  0xe5, 0x49, 0xf0, 0x75, 0x49, 0x00, 0xc2, 0x02, 0x02, 0x0a, 0x6e, 0x20, 0x24, 0x27, 0xae, 0x49,
+  0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc1, 0xf0, 0x30,
+  0x1d, 0x49, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5}},
+ {0x0a06, 64, { 0x83, 0xe5, 0xc0, 0xf0, 0x80, 0x36, 0xaf, 0xc1, 0xef, 0xb5, 0x70, 0x04, 0xd2, 0x0d, 0x80, 0x2c, 0xef,
+  0xb5, 0x6f, 0x04, 0xc2, 0x0d, 0x80, 0x24, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00, 0x2e, 0xf5, 0x82,
+  0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x1d, 0x11, 0xae, 0x49, 0x05, 0x49, 0x74, 0x00,
+  0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe5, 0xc0, 0xf0, 0xd2, 0x1a, 0xe5, 0x49}},
+ {0x0a46, 64, { 0xc3, 0x95, 0x6c, 0x40, 0x23, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x11, 0xe5, 0x49, 0xc3, 0x94, 0x40,
+  0x40, 0x15, 0x15, 0x49, 0x15, 0x49, 0x05, 0x39, 0xd2, 0x0e, 0x80, 0x0b, 0x90, 0x7f, 0xbd, 0xe5,
+  0x49, 0xf0, 0x75, 0x49, 0x00, 0xd2, 0x02, 0xd2, 0x25, 0x30, 0x25, 0x05, 0xc2, 0x25, 0x02, 0x00,
+  0x56, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0xce}},
+ {0x0a86, 64, { 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x0b, 0xa1, 0xe4, 0xf5, 0x12, 0x74, 0x40, 0x25, 0x12, 0xf5, 0x82, 0xe4,
+  0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x12, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x4c, 0xf9, 0xec,
+  0x34, 0x00, 0xfa, 0xef, 0x12, 0x15, 0xcd, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x18, 0xdb, 0xe5, 0x4c,
+  0x60, 0x0c, 0x75, 0xc9, 0x20, 0x75, 0xc8, 0x36, 0x85, 0x4d, 0xca, 0x85, 0x4e, 0xcb, 0xe5}},
+ {0x0ac6, 64, { 0x4f, 0x13, 0x92, 0x1b, 0x92, 0x9f, 0xe5, 0x50, 0x13, 0x92, 0x1c, 0xe5, 0x51, 0x13, 0x92, 0x23, 0xe5,
+  0x52, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x98, 0xe0,
+  0x44, 0x04, 0xf0, 0xe5, 0x53, 0x60, 0x09, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x07,
+  0x90, 0x7f, 0x98, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x59, 0x60, 0x0b, 0xc2, 0x13, 0xc2, 0x0b}},
+ {0x0b06, 64, { 0x90, 0x7f, 0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x5a, 0x60, 0x0b, 0xd2, 0x0b, 0xd2, 0x0c, 0x90, 0x7f,
+  0x95, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x5b, 0x60, 0x0d, 0xc2, 0xaf, 0xc2, 0x11, 0xd2, 0x00, 0xe4,
+  0xf5, 0x7c, 0xf5, 0x4a, 0xd2, 0xaf, 0xe5, 0x5c, 0x60, 0x05, 0x30, 0x23, 0x02, 0xd2, 0x0b, 0xe5,
+  0x5d, 0x60, 0x15, 0x90, 0x7f, 0x95, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x9e, 0xe0, 0x44}},
+ {0x0b46, 64, { 0x02, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x5e, 0x60, 0x0a, 0xd2, 0x9c, 0xc2, 0x98,
+  0x75, 0x2e, 0x01, 0x75, 0x40, 0x28, 0xe5, 0x5f, 0x60, 0x07, 0xc2, 0x9c, 0xe4, 0xf5, 0x48, 0xf5,
+  0x2e, 0xe5, 0x60, 0x60, 0x03, 0xe4, 0xf5, 0x48, 0xe5, 0x61, 0x60, 0x02, 0xd2, 0x07, 0xe5, 0x62,
+  0x60, 0x08, 0xe5, 0x5e, 0x70, 0x02, 0xf5, 0x40, 0xd2, 0x0c, 0xe5, 0x63, 0x60, 0x15, 0x90}},
+ {0x0b86, 64, { 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x12, 0xf0, 0x74, 0x32, 0xf0, 0x74, 0x15, 0xf0,
+  0x74, 0x35, 0xf0, 0xd2, 0x09, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0xa2, 0x13, 0xe4, 0x33, 0xff, 0x65,
+  0x2b, 0x60, 0x04, 0x8f, 0x2b, 0xd2, 0x0c, 0xa2, 0x0b, 0xe4, 0x33, 0xff, 0x65, 0x2c, 0x60, 0x04,
+  0x8f, 0x2c, 0xd2, 0x0c, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x08, 0x65, 0x27, 0x60, 0x07, 0xe0}},
+ {0x0bc6, 64, { 0x54, 0x08, 0xf5, 0x27, 0xd2, 0x0c, 0x90, 0x7f, 0x9b, 0xe0, 0x54, 0x40, 0xb5, 0x29, 0x09, 0xe0, 0x54,
+  0x40, 0x64, 0x40, 0xf5, 0x29, 0xd2, 0x0c, 0x30, 0x07, 0x35, 0xc2, 0xaf, 0x30, 0x01, 0x18, 0x90,
+  0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0xe5, 0x48, 0x60, 0x09, 0x90, 0x7f, 0xb7, 0xf0, 0xe4, 0xf5,
+  0x48, 0xc2, 0x01, 0xc2, 0x07, 0x80, 0x16, 0x90, 0x7f, 0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0xe5}},
+ {0x0c06, 64, { 0x48, 0x60, 0x09, 0x90, 0x7f, 0xb9, 0xf0, 0xe4, 0xf5, 0x48, 0xd2, 0x01, 0xc2, 0x07, 0xd2, 0xaf, 0x20,
+  0x05, 0x37, 0x30, 0x03, 0x1b, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7e, 0x40, 0xe0,
+  0x13, 0x92, 0x15, 0x75, 0x4a, 0x01, 0x90, 0x7f, 0xc7, 0xe0, 0xf5, 0x7c, 0xd2, 0x05, 0x80, 0x19,
+  0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x15, 0x75}},
+ {0x0c46, 64, { 0x4a, 0x01, 0x90, 0x7f, 0xc9, 0xe0, 0xf5, 0x7c, 0xd2, 0x05, 0x20, 0x21, 0x33, 0x20, 0x00, 0x06, 0xe5,
+  0x4a, 0x65, 0x7c, 0x70, 0x2a, 0x30, 0x05, 0x1a, 0x30, 0x03, 0x09, 0xe4, 0x90, 0x7f, 0xc7, 0xf0,
+  0xc2, 0x03, 0x80, 0x07, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0xc2, 0x05, 0xe4, 0xf5, 0x7c,
+  0xf5, 0x4a, 0x30, 0x15, 0x0a, 0xc2, 0x15, 0xc2, 0x00, 0x90, 0x7f, 0xbf, 0x74, 0x01, 0xf0}},
+ {0x0c86, 64, { 0x30, 0x21, 0x03, 0x02, 0x0d, 0x90, 0x20, 0x05, 0x03, 0x02, 0x0d, 0x90, 0x30, 0x1c, 0x0a, 0x90, 0x7f,
+  0x9b, 0xe0, 0x20, 0xe3, 0x03, 0x02, 0x0d, 0x90, 0x30, 0x0b, 0x03, 0x02, 0x0d, 0x90, 0x30, 0x13,
+  0x03, 0x02, 0x0d, 0x90, 0x30, 0x03, 0x62, 0x30, 0x1b, 0x12, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0x40,
+  0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x2d, 0xaf, 0x4a, 0x05}},
+ {0x0cc6, 64, { 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x13, 0xe5, 0x4a, 0xc3,
+  0x95, 0x7c, 0x50, 0x2a, 0x30, 0x1b, 0x12, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2f, 0xf5, 0x82,
+  0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0x40, 0x2f,
+  0xf5, 0x82, 0xe4, 0x34, 0x7e, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x80, 0x6b, 0xc2}},
+ {0x0d06, 64, { 0x11, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0xc2, 0x03, 0x80, 0x60, 0x30, 0x1b, 0x12, 0xaf, 0x4a, 0x05, 0x4a,
+  0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x2d, 0xaf, 0x4a,
+  0x05, 0x4a, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x13, 0xe5,
+  0x4a, 0xc3, 0x95, 0x7c, 0x50, 0x2a, 0x30, 0x1b, 0x12, 0xaf, 0x4a, 0x05, 0x4a, 0x74, 0xc0}},
+ {0x0d46, 64, { 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x17, 0xaf, 0x4a, 0x05, 0x4a, 0x74,
+  0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x46, 0xd2, 0x11, 0x80, 0x09,
+  0xc2, 0x11, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x03, 0x30, 0x1b, 0x04, 0xa2, 0x2d, 0x92, 0x9b,
+  0xd2, 0x21, 0xc2, 0xaf, 0x85, 0x13, 0x99, 0x20, 0x11, 0x0d, 0x30, 0x15, 0x0a, 0xc2, 0x15}},
+ {0x0d86, 64, { 0xc2, 0x00, 0x90, 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90, 0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x03,
+  0x02, 0x0e, 0xad, 0xe4, 0xf5, 0x12, 0x74, 0xc0, 0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5,
+  0x83, 0xe0, 0xff, 0xe5, 0x12, 0x7c, 0x00, 0x7b, 0x00, 0x24, 0x64, 0xf9, 0xec, 0x34, 0x00, 0xfa,
+  0xef, 0x12, 0x15, 0xcd, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x18, 0xdb, 0xe5, 0x64, 0x60, 0x0b}},
+ {0x0dc6, 64, { 0x75, 0x89, 0x60, 0x75, 0x88, 0x40, 0xd2, 0xdf, 0x85, 0x65, 0x8d, 0xe5, 0x67, 0x13, 0x92, 0x1d, 0x92,
+  0xc7, 0xe5, 0x68, 0x13, 0x92, 0x1e, 0xe5, 0x69, 0x13, 0x92, 0x24, 0xe5, 0x6a, 0x60, 0x09, 0x90,
+  0x7f, 0x97, 0xe0, 0x54, 0xef, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x97, 0xe0, 0x44, 0x10, 0xf0, 0xe5,
+  0x6b, 0x60, 0x09, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0x7f, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0x97}},
+ {0x0e06, 64, { 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x71, 0x60, 0x0b, 0xc2, 0x14, 0xc2, 0x0d, 0x90, 0x7f, 0x94, 0xe0, 0x44,
+  0x08, 0xf0, 0xe5, 0x72, 0x60, 0x0b, 0xd2, 0x0d, 0xd2, 0x0e, 0x90, 0x7f, 0x94, 0xe0, 0x44, 0x08,
+  0xf0, 0xe5, 0x73, 0x60, 0x0d, 0xc2, 0xaf, 0xc2, 0x12, 0xd2, 0x00, 0xe4, 0xf5, 0x7d, 0xf5, 0x4b,
+  0xd2, 0xaf, 0xe5, 0x74, 0x60, 0x05, 0x30, 0x24, 0x02, 0xd2, 0x0d, 0xe5, 0x75, 0x60, 0x15}},
+ {0x0e46, 64, { 0x90, 0x7f, 0x94, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x9d, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f, 0x97,
+  0xe0, 0x54, 0xf7, 0xf0, 0xe5, 0x76, 0x60, 0x0a, 0xd2, 0xc4, 0xc2, 0xc0, 0x75, 0x3a, 0x01, 0x75,
+  0x41, 0x28, 0xe5, 0x77, 0x60, 0x07, 0xc2, 0xc4, 0xe4, 0xf5, 0x49, 0xf5, 0x3a, 0xe5, 0x78, 0x60,
+  0x03, 0xe4, 0xf5, 0x49, 0xe5, 0x79, 0x60, 0x02, 0xd2, 0x08, 0xe5, 0x7a, 0x60, 0x08, 0xe5}},
+ {0x0e86, 64, { 0x76, 0x70, 0x02, 0xf5, 0x41, 0xd2, 0x0e, 0xe5, 0x7b, 0x60, 0x15, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0,
+  0x74, 0x33, 0xf0, 0x74, 0x14, 0xf0, 0x74, 0x34, 0xf0, 0x74, 0x16, 0xf0, 0x74, 0x36, 0xf0, 0xd2,
+  0x0a, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0xa2, 0x14, 0xe4, 0x33, 0xff, 0x65, 0x37, 0x60, 0x04, 0x8f,
+  0x37, 0xd2, 0x0e, 0xa2, 0x0d, 0xe4, 0x33, 0xff, 0x65, 0x38, 0x60, 0x04, 0x8f, 0x38, 0xd2}},
+ {0x0ec6, 64, { 0x0e, 0x90, 0x7f, 0x9a, 0xe0, 0x54, 0x20, 0x65, 0x33, 0x60, 0x07, 0xe0, 0x54, 0x20, 0xf5, 0x33, 0xd2,
+  0x0e, 0x90, 0x7f, 0x9a, 0xe0, 0x54, 0x40, 0xb5, 0x35, 0x09, 0xe0, 0x54, 0x40, 0x64, 0x40, 0xf5,
+  0x35, 0xd2, 0x0e, 0x30, 0x08, 0x35, 0xc2, 0xaf, 0x30, 0x02, 0x18, 0x90, 0x7f, 0xbc, 0xe0, 0x20,
+  0xe1, 0x27, 0xe5, 0x49, 0x60, 0x09, 0x90, 0x7f, 0xbb, 0xf0, 0xe4, 0xf5, 0x49, 0xc2, 0x02}},
+ {0x0f06, 64, { 0xc2, 0x08, 0x80, 0x16, 0x90, 0x7f, 0xba, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x49, 0x60, 0x09, 0x90, 0x7f,
+  0xbd, 0xf0, 0xe4, 0xf5, 0x49, 0xd2, 0x02, 0xc2, 0x08, 0xd2, 0xaf, 0x20, 0x06, 0x37, 0x30, 0x04,
+  0x1b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x2d, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x16, 0x75,
+  0x4b, 0x01, 0x90, 0x7f, 0xcb, 0xe0, 0xf5, 0x7d, 0xd2, 0x06, 0x80, 0x19, 0x90, 0x7f, 0xcc}},
+ {0x0f46, 64, { 0xe0, 0x20, 0xe1, 0x12, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x16, 0x75, 0x4b, 0x01, 0x90, 0x7f, 0xcd,
+  0xe0, 0xf5, 0x7d, 0xd2, 0x06, 0x20, 0x22, 0x33, 0x20, 0x00, 0x06, 0xe5, 0x4b, 0x65, 0x7d, 0x70,
+  0x2a, 0x30, 0x06, 0x1a, 0x30, 0x04, 0x09, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0xc2, 0x04, 0x80, 0x07,
+  0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0xd2, 0x04, 0xc2, 0x06, 0xe4, 0xf5, 0x7d, 0xf5, 0x4b, 0x30}},
+ {0x0f86, 64, { 0x16, 0x0a, 0xc2, 0x16, 0xc2, 0x00, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0x30, 0x22, 0x03, 0x02, 0x10,
+  0x9c, 0x20, 0x06, 0x03, 0x02, 0x10, 0x9c, 0x30, 0x1e, 0x0a, 0x90, 0x7f, 0x9a, 0xe0, 0x20, 0xe5,
+  0x03, 0x02, 0x10, 0x9c, 0x30, 0x0d, 0x03, 0x02, 0x10, 0x9c, 0x30, 0x14, 0x03, 0x02, 0x10, 0x9c,
+  0x30, 0x04, 0x62, 0x30, 0x1d, 0x12, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82}},
+ {0x0fc6, 64, { 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x2d, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5,
+  0x82, 0xe4, 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x13, 0xe5, 0x4b, 0xc3, 0x95, 0x7d, 0x50, 0x2a,
+  0x30, 0x1d, 0x12, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7d, 0xf5,
+  0x83, 0xe0, 0x13, 0x92, 0x18, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4}},
+ {0x1006, 64, { 0x34, 0x7d, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12, 0x80, 0x6b, 0xc2, 0x12, 0xe4, 0x90, 0x7f, 0xcb,
+  0xf0, 0xc2, 0x04, 0x80, 0x60, 0x30, 0x1d, 0x12, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5,
+  0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x2d, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0,
+  0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x13, 0xe5, 0x4b, 0xc3, 0x95}},
+ {0x1046, 64, { 0x7d, 0x50, 0x2a, 0x30, 0x1d, 0x12, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82, 0xe4, 0x34,
+  0x7c, 0xf5, 0x83, 0xe0, 0x13, 0x92, 0x18, 0xaf, 0x4b, 0x05, 0x4b, 0x74, 0xc0, 0x2f, 0xf5, 0x82,
+  0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xf5, 0x47, 0xd2, 0x12, 0x80, 0x09, 0xc2, 0x12, 0xe4, 0x90,
+  0x7f, 0xcd, 0xf0, 0xd2, 0x04, 0x30, 0x1d, 0x04, 0xa2, 0x2d, 0x92, 0xc3, 0xd2, 0x22, 0xc2}},
+ {0x1086, 64, { 0xaf, 0x85, 0x13, 0xc1, 0x20, 0x12, 0x0d, 0x30, 0x16, 0x0a, 0xc2, 0x16, 0xc2, 0x00, 0x90, 0x7f, 0xc1,
+  0x74, 0x01, 0xf0, 0xd2, 0xaf, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0x72, 0xe5,
+  0x1a, 0x70, 0x46, 0x30, 0x0c, 0x3f, 0xe5, 0x40, 0x70, 0x3b, 0xa2, 0x09, 0x33, 0xf5, 0x31, 0xc2,
+  0x09, 0xc2, 0x0c, 0xe4, 0xf5, 0x12, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x26, 0x25, 0x12, 0xf9}},
+ {0x10c6, 64, { 0xee, 0x34, 0x00, 0xfa, 0x12, 0x15, 0x87, 0xff, 0x74, 0x80, 0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b,
+  0xf5, 0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12, 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x0c,
+  0xf0, 0x75, 0x40, 0x10, 0x22, 0x75, 0x1a, 0x01, 0x22, 0xe5, 0x1a, 0x64, 0x01, 0x70, 0x45, 0x30,
+  0x0e, 0x3e, 0xe5, 0x41, 0x70, 0x3a, 0xa2, 0x0a, 0x33, 0xf5, 0x3d, 0xc2, 0x0a, 0xc2, 0x0e}},
+ {0x1106, 64, { 0xe4, 0xf5, 0x12, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x32, 0x25, 0x12, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12,
+  0x15, 0x87, 0xff, 0x74, 0x80, 0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0,
+  0x05, 0x12, 0xe5, 0x12, 0xb4, 0x0c, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x0c, 0xf0, 0x75, 0x41, 0x10,
+  0x75, 0x1a, 0x02, 0x22, 0xe5, 0x1c, 0x60, 0x30, 0x15, 0x1c, 0xe4, 0xf5, 0x12, 0x7e, 0x00}},
+ {0x1146, 64, { 0x7b, 0x00, 0x74, 0x1b, 0x25, 0x12, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x15, 0x87, 0xff, 0x74, 0x80,
+  0x25, 0x12, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x12, 0xe5, 0x12, 0xb4,
+  0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x1a, 0x22, 0x90, 0x7f, 0xe9, 0xe0,
+  0x12, 0x16, 0x17, 0x12, 0x38, 0x00, 0x12, 0xac, 0x01, 0x13, 0x18, 0x03, 0x11, 0x96, 0x06}},
+ {0x1186, 64, { 0x12, 0x2b, 0x08, 0x12, 0x25, 0x09, 0x12, 0x18, 0x0a, 0x13, 0x6e, 0x0b, 0x00, 0x00, 0x13, 0x67, 0x90,
+  0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x40, 0x24, 0x02, 0x70, 0x69, 0x74, 0x19,
+  0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xea,
+  0xe0, 0xff, 0x12, 0x17, 0x4b, 0x8b, 0x12, 0x8a, 0x13, 0x89, 0x14, 0xea, 0x49, 0x60, 0x11}},
+ {0x11c6, 64, { 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x13, 0x6e,
+  0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12,
+  0x17, 0x9a, 0x8b, 0x12, 0x8a, 0x13, 0x89, 0x14, 0xea, 0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90,
+  0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f}},
+ {0x1206, 64, { 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x13,
+  0x6e, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x13, 0x6e, 0x12, 0x14,
+  0xbb, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x13,
+  0x6e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70}},
+ {0x1246, 64, { 0x5b, 0xa2, 0x26, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x2b, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00,
+  0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x13, 0x6e, 0xe4, 0x90, 0x7f,
+  0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xec,
+  0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0}},
+ {0x1286, 64, { 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4,
+  0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xb4, 0xe0, 0x44,
+  0x01, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60,
+  0x03, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x26, 0x02, 0x13}},
+ {0x12c6, 64, { 0x6e, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x13, 0x6e, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38,
+  0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f,
+  0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec,
+  0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90}},
+ {0x1306, 64, { 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80,
+  0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea,
+  0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x26, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80,
+  0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff}},
+ {0x1346, 64, { 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f,
+  0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07,
+  0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x20,
+  0x28, 0x03, 0x02, 0x14, 0xba, 0xe5, 0x40, 0x60, 0x02, 0x15, 0x40, 0xe5, 0x48, 0x60, 0x4f}},
+ {0x1386, 64, { 0x65, 0x44, 0x70, 0x45, 0xe5, 0x42, 0xf4, 0x60, 0x02, 0x05, 0x42, 0xe5, 0x42, 0xc3, 0x95, 0x55, 0x40,
+  0x3d, 0xc2, 0xaf, 0x30, 0x01, 0x18, 0x90, 0x7f, 0xb8, 0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f, 0xb7,
+  0xe5, 0x48, 0xf0, 0xc2, 0x01, 0xe4, 0xf5, 0x48, 0xf5, 0x42, 0xf5, 0x44, 0x80, 0x16, 0x90, 0x7f,
+  0xb6, 0xe0, 0x20, 0xe1, 0x0f, 0x90, 0x7f, 0xb9, 0xe5, 0x48, 0xf0, 0xd2, 0x01, 0xe4, 0xf5}},
+ {0x13c6, 64, { 0x48, 0xf5, 0x42, 0xf5, 0x44, 0xd2, 0xaf, 0x80, 0x06, 0x85, 0x48, 0x44, 0xe4, 0xf5, 0x42, 0xe5, 0x2e,
+  0x60, 0x2d, 0x20, 0x19, 0x07, 0x90, 0x7f, 0x9b, 0xe0, 0x30, 0xe0, 0x0e, 0xe5, 0x2f, 0x60, 0x05,
+  0xe4, 0xf5, 0x2f, 0xd2, 0x0c, 0xe4, 0xf5, 0x3e, 0x80, 0x13, 0xe5, 0x3e, 0xd3, 0x95, 0x56, 0x50,
+  0x0c, 0xe5, 0x3e, 0xb5, 0x56, 0x05, 0x75, 0x2f, 0x01, 0xd2, 0x0c, 0x05, 0x3e, 0xc2, 0x19}},
+ {0x1406, 64, { 0xe5, 0x41, 0x60, 0x02, 0x15, 0x41, 0xe5, 0x49, 0x60, 0x4f, 0x65, 0x45, 0x70, 0x45, 0xe5, 0x43, 0xf4,
+  0x60, 0x02, 0x05, 0x43, 0xe5, 0x43, 0xc3, 0x95, 0x6d, 0x40, 0x3d, 0xc2, 0xaf, 0x30, 0x02, 0x18,
+  0x90, 0x7f, 0xbc, 0xe0, 0x20, 0xe1, 0x27, 0x90, 0x7f, 0xbb, 0xe5, 0x49, 0xf0, 0xc2, 0x02, 0xe4,
+  0xf5, 0x49, 0xf5, 0x43, 0xf5, 0x45, 0x80, 0x16, 0x90, 0x7f, 0xba, 0xe0, 0x20, 0xe1, 0x0f}},
+ {0x1446, 64, { 0x90, 0x7f, 0xbd, 0xe5, 0x49, 0xf0, 0xd2, 0x02, 0xe4, 0xf5, 0x49, 0xf5, 0x43, 0xf5, 0x45, 0xd2, 0xaf,
+  0x80, 0x06, 0x85, 0x49, 0x45, 0xe4, 0xf5, 0x43, 0xe5, 0x3a, 0x60, 0x2d, 0x20, 0x1a, 0x07, 0x90,
+  0x7f, 0x9a, 0xe0, 0x30, 0xe2, 0x0e, 0xe5, 0x3b, 0x60, 0x05, 0xe4, 0xf5, 0x3b, 0xd2, 0x0e, 0xe4,
+  0xf5, 0x3f, 0x80, 0x13, 0xe5, 0x3f, 0xd3, 0x95, 0x6e, 0x50, 0x0c, 0xe5, 0x3f, 0xb5, 0x6e}},
+ {0x1486, 64, { 0x05, 0x75, 0x3b, 0x01, 0xd2, 0x0e, 0x05, 0x3f, 0xc2, 0x1a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23,
+  0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5, 0x1c, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x1d, 0x90,
+  0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90,
+  0x7f, 0xd3, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0}},
+ {0x14c6, 64, { 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x10, 0xf0, 0x90, 0x7f, 0x94, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0x9d, 0x74,
+  0x9a, 0xf0, 0x90, 0x7f, 0x97, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0x23, 0xf0, 0x90,
+  0x7f, 0x9e, 0x74, 0x84, 0xf0, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x90, 0x7f,
+  0xcf, 0xf0, 0x75, 0x98, 0x40, 0x43, 0xa8, 0x10, 0xc2, 0x1b, 0xc2, 0x05, 0xc2, 0x21, 0xc2}},
+ {0x1506, 64, { 0x0b, 0xc2, 0x13, 0xf5, 0x7c, 0xf5, 0x4a, 0xc2, 0x11, 0xc2, 0x15, 0xf5, 0x42, 0xc2, 0x19, 0xf5, 0x44,
+  0xf5, 0x48, 0xc2, 0x23, 0xc2, 0x1c, 0xf5, 0x2d, 0xf5, 0x2f, 0xc2, 0x07, 0xc2, 0x00, 0xc2, 0x1f,
+  0xf5, 0x3e, 0xc2, 0x09, 0xd2, 0x01, 0xd2, 0x03, 0xd2, 0x0c, 0xf5, 0x26, 0x90, 0x7f, 0xcb, 0xf0,
+  0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xd1, 0xf0, 0x75, 0xc0, 0x40, 0x43, 0xa8, 0x40, 0xc2}},
+ {0x1546, 64, { 0x1d, 0xc2, 0x06, 0xc2, 0x22, 0xc2, 0x0d, 0xc2, 0x14, 0xf5, 0x7d, 0xf5, 0x4b, 0xc2, 0x12, 0xc2, 0x16,
+  0xf5, 0x43, 0xc2, 0x1a, 0xf5, 0x45, 0xf5, 0x49, 0xc2, 0x24, 0xc2, 0x1e, 0xf5, 0x39, 0xf5, 0x3b,
+  0xc2, 0x08, 0xc2, 0x00, 0xc2, 0x20, 0xf5, 0x3f, 0xc2, 0x0a, 0xd2, 0x02, 0xd2, 0x04, 0xd2, 0x0e,
+  0x75, 0x32, 0x01, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xd2, 0x28}},
+ {0x1586, 64, { 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}},
+ {0x15c6, 64, { 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, 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}},
+ {0x1606, 64, { 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83, 0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 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, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x7d}},
+ {0x1646, 64, { 0x02, 0x16, 0x84, 0x02, 0x16, 0xc9, 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, 0x18}},
+ {0x1686, 64, { 0xcc, 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}},
+ {0x16c6, 64, { 0xe7, 0x80, 0xbe, 0x75, 0x11, 0x01, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xae, 0xe0,
+  0xff, 0xd3, 0x92, 0x26, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90,
+  0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90,
+  0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44}},
+ {0x1706, 64, { 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0xbc, 0xd2, 0xbe, 0xd2, 0x2d,
+  0x12, 0x18, 0x86, 0xc2, 0x27, 0xc2, 0x25, 0xc2, 0x28, 0x30, 0x28, 0x03, 0x12, 0x0a, 0x83, 0x90,
+  0x7f, 0xd8, 0xe0, 0x65, 0x10, 0x60, 0x08, 0xe0, 0xf5, 0x10, 0x12, 0x13, 0x76, 0x80, 0xea, 0x30,
+  0x27, 0x07, 0xc2, 0x27, 0x12, 0x11, 0x73, 0x80, 0xe0, 0x30, 0x2c, 0xdd, 0xc2, 0x2c, 0x12}},
+ {0x1746, 64, { 0x00, 0x26, 0x80, 0xd6, 0x22, 0xe4, 0xfe, 0x75, 0x17, 0xff, 0x75, 0x18, 0x19, 0x75, 0x19, 0x12, 0xab,
+  0x17, 0xaa, 0x18, 0xa9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x15, 0xa0, 0x64, 0x02, 0x70, 0x2d, 0xad,
+  0x06, 0x0e, 0xed, 0xb5, 0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x15, 0xdf, 0x85, 0xf0, 0x15,
+  0xf5, 0x16, 0x62, 0x15, 0xe5, 0x15, 0x62, 0x16, 0xe5, 0x16, 0x62, 0x15, 0x29, 0xfd, 0xe5}},
+ {0x1786, 64, { 0x15, 0x3a, 0xa9, 0x05, 0x75, 0x17, 0xff, 0xf5, 0x18, 0x89, 0x19, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00,
+  0x79, 0x00, 0x22, 0x8f, 0x15, 0xe4, 0xf5, 0x16, 0x75, 0x17, 0xff, 0x75, 0x18, 0x19, 0x75, 0x19,
+  0x86, 0xab, 0x17, 0xaa, 0x18, 0xa9, 0x19, 0x90, 0x00, 0x01, 0x12, 0x15, 0xa0, 0xb4, 0x03, 0x1d,
+  0xaf, 0x16, 0x05, 0x16, 0xef, 0xb5, 0x15, 0x01, 0x22, 0x12, 0x15, 0x87, 0x7e, 0x00, 0x29}},
+ {0x17c6, 64, { 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x17, 0xff, 0xf5, 0x18, 0x89, 0x19, 0x80, 0xd4, 0x7b, 0x00, 0x7a,
+  0x00, 0x79, 0x00, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86,
+  0x75, 0x86, 0x00, 0x30, 0x2a, 0x04, 0xc2, 0x2a, 0x80, 0x02, 0xd2, 0x2c, 0x53, 0x91, 0xef, 0x90,
+  0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83}},
+ {0x1806, 64, { 0xd0, 0xe0, 0x32, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90,
+  0x7f, 0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0x97, 0xf0, 0xe4, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f,
+  0x9e, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9d, 0xf0, 0x22, 0xc0, 0xe0,
+  0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f}},
+ {0x1846, 64, { 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0,
+  0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85,
+  0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x27, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74,
+  0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32}},
+ {0x1886, 64, { 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x2d, 0x04, 0xe0, 0x44, 0x02,
+  0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x00, 0x06, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0,
+  0x44, 0x04, 0xf0, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82,
+  0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01}},
+ {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xc1, 0xaa, 0x01, 0x1a, 0x00, 0x03, 0x1b, 0x03, 0x00, 0x00, 0xc1,
+  0x27, 0xc1, 0x2c, 0xc1, 0x26, 0xc1, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x01, 0xff, 0x00}},
+ {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x0f, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x00, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x00, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x00}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65,
+  0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53,
+  0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c,
+  0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}},
+ {0x1a06, 64, { 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1a46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1a86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1ac6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 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, 0x18, 0x5f, 0x00, 0x02, 0x1b}},
+ {0x1b06,  9, { 0x04, 0x00, 0x02, 0x18, 0x35, 0x00, 0x02, 0x17, 0xdb}},
 { 0xffff,	0,	{0x00} }
 };
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa28msg.h linux/drivers/usb/serial/keyspan_usa28msg.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa28msg.h	Thu Dec  7 16:13:38 2000
+++ linux/drivers/usb/serial/keyspan_usa28msg.h	Tue Oct  9 15:15:02 2001
@@ -113,7 +113,8 @@
 			hardly more trouble to do them than to check whether to do them):
 	*/
 	u8	parity,			// 1=use parity, 0=don't
-		ctsFlowControl,	// 1=use CTS flow control, 0=don't
+		ctsFlowControl,	        // all except 19Q: 1=use CTS flow control, 0=don't
+					// 19Q: 0x08:CTSflowControl 0x10:DSRflowControl
 		xonFlowControl,	// 1=use XON/XOFF flow control, 0=don't
 		rts,			// 1=on, 0=off
 		dtr;			// 1=on, 0=off
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa28x_fw.h linux/drivers/usb/serial/keyspan_usa28x_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa28x_fw.h	Mon Jul 10 14:33:04 2000
+++ linux/drivers/usb/serial/keyspan_usa28x_fw.h	Tue Oct  9 15:15:02 2001
@@ -1,10 +1,10 @@
 /* keyspan_usa28x_fw.h
   
-   Generated from Keyspan firmware image Wed Jul  5 09:18:29 2000 EST
+   Generated from Keyspan firmware image usa26code.h Sat Oct  6 12:08:55 EST 2001
    This firmware is for the Keyspan USA-28X Serial Adaptor
 
    "The firmware contained herein as keyspan_usa28x_fw.h is
-   Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
    ("Keyspan"), as an unpublished work.  This notice does not imply
    unrestricted or public access to this firmware which is a trade secret of
    Keyspan, and which may not be reproduced, used, sold or transferred to any
@@ -18,389 +18,425 @@
 */
 
 static const struct ezusb_hex_record keyspan_usa28x_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x0e, 0x9b} },
-{ 0x0003,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
-{ 0x0013,	16,	{0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90} },
-{ 0x0023,	15,	{0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22} },
-{ 0x0033,	3,	{0x02, 0x13, 0xfc} },
-{ 0x0036,	12,	{0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0043,	3,	{0x02, 0x14, 0x00} },
-{ 0x0046,	16,	{0x30, 0x08, 0x13, 0x12, 0x13, 0xc0, 0xef, 0xc3, 0x95, 0x3c, 0x50, 0x73, 0x90, 0x7f, 0xbf, 0x74} },
-{ 0x0056,	16,	{0x01, 0xf0, 0xc2, 0x08, 0x80, 0x69, 0x30, 0x02, 0x34, 0x90, 0x7f, 0xc6, 0xe0, 0x20, 0xe1, 0x5f} },
-{ 0x0066,	16,	{0x12, 0x13, 0xc0, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x56, 0x90, 0x7e, 0x40, 0xe0, 0x13, 0x92, 0x08} },
-{ 0x0076,	16,	{0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d} },
-{ 0x0086,	16,	{0x41, 0x12, 0x0d, 0x55, 0xc2, 0x02, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x32, 0x90, 0x7f, 0xc8} },
-{ 0x0096,	16,	{0xe0, 0x20, 0xe1, 0x2b, 0x12, 0x13, 0xc0, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x22, 0x90, 0x7d, 0xc0} },
-{ 0x00a6,	16,	{0xe0, 0x13, 0x92, 0x08, 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0xc1, 0x75} },
-{ 0x00b6,	16,	{0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x55, 0xd2, 0x02, 0xe4, 0x90, 0x7f, 0xc9, 0xf0, 0x90} },
-{ 0x00c6,	16,	{0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x53, 0x53, 0x36, 0x80, 0x12, 0x13, 0xcc, 0xef} },
-{ 0x00d6,	16,	{0x42, 0x36, 0x12, 0x12, 0x49, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3a, 0x50, 0x0f, 0x12, 0x13, 0xa8} },
-{ 0x00e6,	16,	{0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0a, 0x61, 0xc2, 0x0a, 0xe5, 0x19} },
-{ 0x00f6,	16,	{0x70, 0x04, 0xf5, 0x36, 0x80, 0x57, 0x12, 0x13, 0xcc, 0xef, 0x42, 0x36, 0xe5, 0x36, 0x30, 0xe7} },
-{ 0x0106,	16,	{0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7e} },
-{ 0x0116,	16,	{0x7f, 0x80, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0xb7, 0xe5, 0x19, 0x25} },
-{ 0x0126,	16,	{0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19} },
-{ 0x0136,	16,	{0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75, 0x0c, 0x7e} },
-{ 0x0146,	16,	{0x75, 0x0d, 0x81, 0x12, 0x0d, 0x7a, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90, 0x7f, 0xce} },
-{ 0x0156,	16,	{0xe0, 0x30, 0xe1, 0x06, 0x20, 0x04, 0x03, 0x02, 0x03, 0xbd, 0xc2, 0x04, 0xe4, 0xf5, 0x18, 0x74} },
-{ 0x0166,	16,	{0x40, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00} },
-{ 0x0176,	16,	{0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0c} },
-{ 0x0186,	16,	{0xe5, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68, 0x90, 0x7e} },
-{ 0x0196,	16,	{0x03, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x24, 0x7f, 0x03, 0x7d, 0xcd, 0x12} },
-{ 0x01a6,	16,	{0x12, 0x24, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46} },
-{ 0x01b6,	16,	{0xf0, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x10, 0xa8} },
-{ 0x01c6,	16,	{0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x10, 0xce, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12} },
-{ 0x01d6,	16,	{0x12, 0x24, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x24, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x01e6,	16,	{0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40} },
-{ 0x01f6,	16,	{0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x13, 0xe0} },
-{ 0x0206,	16,	{0x70, 0x08, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12} },
-{ 0x0216,	16,	{0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5} },
-{ 0x0226,	16,	{0x44, 0xf0, 0x90, 0x7e, 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x42, 0x80, 0x80} },
-{ 0x0236,	16,	{0x03, 0x53, 0x42, 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x42, 0x02} },
-{ 0x0246,	16,	{0xa3, 0xe0, 0xff, 0x12, 0x11, 0x1a, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x11, 0x40, 0xaf, 0x42} },
-{ 0x0256,	16,	{0x12, 0x10, 0xf4, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42, 0x12, 0x10} },
-{ 0x0266,	16,	{0xf4, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x02, 0x80, 0x03} },
-{ 0x0276,	16,	{0x53, 0x46, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90} },
-{ 0x0286,	16,	{0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03, 0x53, 0x46} },
-{ 0x0296,	16,	{0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x12} },
-{ 0x02a6,	16,	{0xe0, 0xf5, 0x3a, 0xa3, 0xe0, 0x13, 0x92, 0x0c, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3, 0xe0, 0x60, 0x05} },
-{ 0x02b6,	16,	{0x43, 0x46, 0x10, 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0} },
-{ 0x02c6,	16,	{0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90, 0x7f, 0x98} },
-{ 0x02d6,	16,	{0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11} },
-{ 0x02e6,	16,	{0xf0, 0x12, 0x13, 0x9c, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e, 0xfd, 0xe4, 0xff} },
-{ 0x02f6,	16,	{0xad, 0x3e, 0x12, 0x12, 0x24, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x06, 0x90, 0x7e, 0x17, 0xe0} },
-{ 0x0306,	16,	{0x60, 0x0f, 0x43, 0x3e, 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x12, 0x24, 0x75, 0x29, 0x01, 0xd2} },
-{ 0x0316,	16,	{0x06, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x1b, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44} },
-{ 0x0326,	16,	{0x04, 0x90, 0xc0, 0x00, 0xf0, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0xd2, 0x02} },
-{ 0x0336,	16,	{0xc2, 0x08, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13} },
-{ 0x0346,	16,	{0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53} },
-{ 0x0356,	16,	{0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x12, 0x24, 0x75, 0x2b, 0x01, 0xd2, 0x06, 0x90, 0x7e} },
-{ 0x0366,	16,	{0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x12, 0x24, 0xe4, 0xf5} },
-{ 0x0376,	16,	{0x2b, 0xd2, 0x06, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5} },
-{ 0x0386,	16,	{0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0a, 0x90} },
-{ 0x0396,	16,	{0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4, 0xf5, 0x38, 0xd2, 0x06, 0x90, 0x7e, 0x1f} },
-{ 0x03a6,	16,	{0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74} },
-{ 0x03b6,	16,	{0x35, 0xf0, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30, 0x18, 0x52, 0xe5, 0x38, 0x60, 0x02, 0x15, 0x38} },
-{ 0x03c6,	16,	{0x20, 0x12, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13} },
-{ 0x03d6,	16,	{0x0a, 0x30, 0x19, 0x02, 0xd2, 0x12, 0x12, 0x13, 0x9c, 0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x2a} },
-{ 0x03e6,	16,	{0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x06, 0x12, 0x13, 0xd8, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65} },
-{ 0x03f6,	16,	{0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x06, 0x30, 0x0c, 0x11, 0x12, 0x13, 0xd8, 0xef, 0x54} },
-{ 0x0406,	16,	{0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19, 0x25, 0xd2, 0x06, 0x20, 0x19, 0x03, 0x02} },
-{ 0x0416,	16,	{0x07, 0xe4, 0x30, 0x09, 0x13, 0x12, 0x14, 0x2b, 0xef, 0xc3, 0x95, 0x3d, 0x50, 0x73, 0x90, 0x7f} },
-{ 0x0426,	16,	{0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0x80, 0x69, 0x30, 0x03, 0x34, 0x90, 0x7f, 0xca, 0xe0, 0x20} },
-{ 0x0436,	16,	{0xe1, 0x5f, 0x12, 0x14, 0x2b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x56, 0x90, 0x7d, 0x40, 0xe0, 0x13} },
-{ 0x0446,	16,	{0x92, 0x09, 0x90, 0x7f, 0xcb, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41, 0x75, 0x0c, 0x7d} },
-{ 0x0456,	16,	{0x75, 0x0d, 0x41, 0x12, 0x0d, 0x9f, 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x32, 0x90} },
-{ 0x0466,	16,	{0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x2b, 0x12, 0x14, 0x2b, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x22, 0x90} },
-{ 0x0476,	16,	{0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x08, 0x7e, 0x7c, 0x7f} },
-{ 0x0486,	16,	{0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x9f, 0xd2, 0x03, 0xe4, 0x90, 0x7f, 0xcd} },
-{ 0x0496,	16,	{0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, 0x25, 0x53, 0x37, 0x80, 0x12, 0x14} },
-{ 0x04a6,	16,	{0x37, 0xef, 0x42, 0x37, 0x12, 0x12, 0x93, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3b, 0x50, 0x0f, 0x12} },
-{ 0x04b6,	16,	{0x14, 0x13, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x61, 0xc2, 0x0b} },
-{ 0x04c6,	16,	{0xe5, 0x19, 0x70, 0x04, 0xf5, 0x37, 0x80, 0x57, 0x12, 0x14, 0x37, 0xef, 0x42, 0x37, 0xe5, 0x37} },
-{ 0x04d6,	16,	{0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08} },
-{ 0x04e6,	16,	{0x7e, 0x7d, 0x7f, 0x80, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0xf0, 0xe5} },
-{ 0x04f6,	16,	{0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03} },
-{ 0x0506,	16,	{0x75, 0x19, 0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7d, 0x80, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75} },
-{ 0x0516,	16,	{0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12, 0x0d, 0xc4, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90} },
-{ 0x0526,	16,	{0x7f, 0xd0, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x05, 0x03, 0x02, 0x07, 0x8f, 0xc2, 0x05, 0xe4, 0xf5} },
-{ 0x0536,	16,	{0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18} },
-{ 0x0546,	16,	{0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef} },
-{ 0x0556,	16,	{0x12, 0x0c, 0xe5, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68} },
-{ 0x0566,	16,	{0x90, 0x7e, 0x23, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x6e, 0x7f, 0x03, 0x7d} },
-{ 0x0576,	16,	{0xcd, 0x12, 0x12, 0x6e, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00} },
-{ 0x0586,	16,	{0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12} },
-{ 0x0596,	16,	{0x11, 0x8c, 0x90, 0x7e, 0x22, 0xe0, 0xff, 0x12, 0x11, 0xb2, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0} },
-{ 0x05a6,	16,	{0xfd, 0x12, 0x12, 0x6e, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x6e, 0x43, 0x47, 0x80, 0x90, 0x7f} },
-{ 0x05b6,	16,	{0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0} },
-{ 0x05c6,	16,	{0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e} },
-{ 0x05d6,	16,	{0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0} },
-{ 0x05e6,	16,	{0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0} },
-{ 0x05f6,	16,	{0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e, 0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43} },
-{ 0x0606,	16,	{0x80, 0x80, 0x03, 0x53, 0x43, 0x7f, 0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43} },
-{ 0x0616,	16,	{0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x11, 0xd8, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0xfe} },
-{ 0x0626,	16,	{0xaf, 0x43, 0x12, 0x11, 0x66, 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf, 0x43} },
-{ 0x0636,	16,	{0x12, 0x11, 0x66, 0x90, 0x7e, 0x2c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02} },
-{ 0x0646,	16,	{0x80, 0x03, 0x53, 0x47, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47} },
-{ 0x0656,	16,	{0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03} },
-{ 0x0666,	16,	{0x53, 0x47, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90} },
-{ 0x0676,	16,	{0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3, 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0} },
-{ 0x0686,	16,	{0x60, 0x05, 0x43, 0x47, 0x10, 0x80, 0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0} },
-{ 0x0696,	16,	{0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90} },
-{ 0x06a6,	16,	{0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98} },
-{ 0x06b6,	16,	{0x74, 0x09, 0xf0, 0x12, 0x13, 0xf0, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd} },
-{ 0x06c6,	16,	{0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x07, 0x90, 0x7e} },
-{ 0x06d6,	16,	{0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e, 0x75, 0x32} },
-{ 0x06e6,	16,	{0x01, 0xd2, 0x07, 0x90, 0x7e, 0x38, 0xe0, 0x60, 0x1b, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5} },
-{ 0x06f6,	16,	{0x41, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xe4, 0x90, 0x7f, 0xcb, 0xf0, 0x90, 0x7f, 0xcd, 0xf0} },
-{ 0x0706,	16,	{0xd2, 0x03, 0xc2, 0x09, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, 0x45, 0x40, 0x90, 0x7f, 0x98} },
-{ 0x0716,	16,	{0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3a, 0xe0, 0x60} },
-{ 0x0726,	16,	{0x0f, 0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e, 0x75, 0x34, 0x01, 0xd2, 0x07} },
-{ 0x0736,	16,	{0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x6e} },
-{ 0x0746,	16,	{0xe4, 0xf5, 0x34, 0xd2, 0x07, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x0a} },
-{ 0x0756,	16,	{0xf0, 0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3d, 0xe0, 0x60, 0x02, 0xd2} },
-{ 0x0766,	16,	{0x0b, 0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, 0xf5, 0x39, 0xd2, 0x07, 0x90} },
-{ 0x0776,	16,	{0x7e, 0x3f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16} },
-{ 0x0786,	16,	{0xf0, 0x74, 0x36, 0xf0, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0x30, 0x18, 0x52, 0xe5, 0x39, 0x60, 0x02} },
-{ 0x0796,	16,	{0x15, 0x39, 0x30, 0x12, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e} },
-{ 0x07a6,	16,	{0x75, 0x13, 0x0a, 0x30, 0x19, 0x02, 0xc2, 0x12, 0x12, 0x13, 0xf0, 0xef, 0x54, 0x01, 0xf5, 0x19} },
-{ 0x07b6,	16,	{0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2, 0x07, 0x12, 0x14, 0x43, 0xef, 0x54, 0x80, 0xf5} },
-{ 0x07c6,	16,	{0x19, 0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, 0x07, 0x30, 0x0d, 0x11, 0x12, 0x14, 0x43} },
-{ 0x07d6,	16,	{0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, 0x85, 0x19, 0x2e, 0xd2, 0x07, 0x30, 0x18} },
-{ 0x07e6,	16,	{0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5} },
-{ 0x07f6,	16,	{0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7} },
-{ 0x0806,	16,	{0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30} },
-{ 0x0816,	16,	{0xe1, 0x03, 0x02, 0x09, 0x18, 0xe5, 0x0a, 0x70, 0x40, 0x30, 0x06, 0x39, 0xe5, 0x38, 0x70, 0x35} },
-{ 0x0826,	16,	{0xc2, 0x06, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00} },
-{ 0x0836,	16,	{0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83} },
-{ 0x0846,	16,	{0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75} },
-{ 0x0856,	16,	{0x38, 0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30} },
-{ 0x0866,	16,	{0x07, 0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d} },
-{ 0x0876,	16,	{0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5} },
-{ 0x0886,	16,	{0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90} },
-{ 0x0896,	16,	{0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5} },
-{ 0x08a6,	16,	{0x0a, 0x64, 0x02, 0x70, 0x36, 0x30, 0x13, 0x2f, 0xc2, 0x13, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00} },
-{ 0x08b6,	16,	{0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25} },
-{ 0x08c6,	16,	{0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05} },
-{ 0x08d6,	16,	{0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15} },
-{ 0x08e6,	16,	{0x15, 0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00} },
-{ 0x08f6,	16,	{0xfa, 0x12, 0x0c, 0x9f, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83} },
-{ 0x0906,	16,	{0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4} },
-{ 0x0916,	2,	{0xf5, 0x0a} },
-{ 0x0918,	1,	{0x22} },
-{ 0x0919,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0d, 0x2f, 0x09, 0xe9, 0x00, 0x0a, 0x5d, 0x01, 0x0a, 0xc9, 0x03} },
-{ 0x0929,	16,	{0x09, 0x3c, 0x06, 0x09, 0xdc, 0x08, 0x09, 0xd6, 0x09, 0x09, 0xbe, 0x0a, 0x09, 0xcd, 0x0b, 0x00} },
-{ 0x0939,	16,	{0x00, 0x0b, 0x18, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x40, 0x24, 0x02} },
-{ 0x0949,	16,	{0x70, 0x69, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b} },
-{ 0x0959,	16,	{0x1f, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, 0x27, 0x8b, 0x18, 0x8a, 0x19, 0x89, 0x1a, 0xea} },
-{ 0x0969,	16,	{0x49, 0x60, 0x11, 0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5} },
-{ 0x0979,	16,	{0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f} },
-{ 0x0989,	16,	{0xea, 0xe0, 0xff, 0x12, 0x0f, 0x76, 0x8b, 0x18, 0x8a, 0x19, 0x89, 0x1a, 0xea, 0x49, 0x60, 0x11} },
-{ 0x0999,	16,	{0xae, 0x02, 0xee, 0x90, 0x7f, 0xd4, 0xf0, 0xaf, 0x01, 0xef, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b} },
-{ 0x09a9,	16,	{0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44} },
-{ 0x09b9,	16,	{0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01} },
-{ 0x09c9,	16,	{0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x1f, 0x12, 0x0b, 0x27} },
-{ 0x09d9,	16,	{0x02, 0x0b, 0x1f, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x0b, 0x1f} },
-{ 0x09e9,	16,	{0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2} },
-{ 0x09f9,	16,	{0x0f, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x14, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0} },
-{ 0x0a09,	16,	{0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x1f, 0xe4, 0x90, 0x7f, 0x00} },
-{ 0x0a19,	16,	{0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xec, 0xe0} },
-{ 0x0a29,	16,	{0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} },
-{ 0x0a39,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3} },
-{ 0x0a49,	16,	{0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01} },
-{ 0x0a59,	16,	{0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03} },
-{ 0x0a69,	16,	{0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x0f, 0x02, 0x0b, 0x1f, 0x90} },
-{ 0x0a79,	16,	{0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x1f, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90} },
-{ 0x0a89,	16,	{0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25} },
-{ 0x0a99,	16,	{0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0} },
-{ 0x0aa9,	16,	{0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7} },
-{ 0x0ab9,	16,	{0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56} },
-{ 0x0ac9,	16,	{0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0} },
-{ 0x0ad9,	16,	{0xb4, 0x01, 0x04, 0xd2, 0x0f, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36} },
-{ 0x0ae9,	16,	{0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54} },
-{ 0x0af9,	16,	{0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
-{ 0x0b09,	16,	{0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90} },
-{ 0x0b19,	13,	{0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
-{ 0x0b26,	1,	{0x22} },
-{ 0x0b27,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x18, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
-{ 0x0b37,	16,	{0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x0b47,	16,	{0x18, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4} },
-{ 0x0b57,	16,	{0xf5, 0x24, 0x75, 0x1b, 0x01, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x1b, 0xf9, 0xe4, 0x34, 0x00, 0xfa} },
-{ 0x0b67,	16,	{0xe4, 0x12, 0x0c, 0xe5, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, 0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5} },
-{ 0x0b77,	16,	{0x38, 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x06, 0xc2, 0x0a, 0xc2, 0x04, 0xc2, 0x08, 0xc2, 0x12, 0xd2} },
-{ 0x0b87,	16,	{0x02, 0xd2, 0x00, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74} },
-{ 0x0b97,	16,	{0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12, 0x24, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0xf4} },
-{ 0x0ba7,	16,	{0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00} },
-{ 0x0bb7,	16,	{0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0} },
-{ 0x0bc7,	16,	{0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x24, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x12} },
-{ 0x0bd7,	16,	{0x24, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f} },
-{ 0x0be7,	16,	{0x12, 0x12, 0x24, 0x7f, 0x01, 0x12, 0x13, 0x27, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x24, 0x20} },
-{ 0x0bf7,	16,	{0x19, 0x03, 0x02, 0x0c, 0x9c, 0x75, 0x2d, 0x01, 0x75, 0x1b, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25} },
-{ 0x0c07,	16,	{0x1b, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0c, 0xe5, 0x05, 0x1b, 0xe5, 0x1b, 0xb4, 0x09} },
-{ 0x0c17,	16,	{0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5, 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x07, 0xc2, 0x0b, 0xc2} },
-{ 0x0c27,	16,	{0x05, 0xc2, 0x09, 0xc2, 0x12, 0xd2, 0x03, 0xd2, 0x01, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75} },
-{ 0x0c37,	16,	{0x45, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12, 0x6e, 0x7f} },
-{ 0x0c47,	16,	{0x10, 0x8f, 0x43, 0x12, 0x11, 0x66, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41} },
-{ 0x0c57,	16,	{0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80} },
-{ 0x0c67,	16,	{0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x6e, 0xe4, 0xff, 0x7e, 0xa3} },
-{ 0x0c77,	16,	{0xad, 0x06, 0x8d, 0x3f, 0x12, 0x12, 0x6e, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00} },
-{ 0x0c87,	16,	{0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x12, 0x6e, 0x7f, 0x01, 0x12, 0x13, 0x48, 0x7f, 0x03} },
-{ 0x0c97,	7,	{0x7d, 0x07, 0x12, 0x12, 0x6e, 0xd2, 0x11} },
-{ 0x0c9e,	1,	{0x22} },
-{ 0x0c9f,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x0caf,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x0cb8,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x0cc8,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x0cd8,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x0ce5,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} },
-{ 0x0cf5,	2,	{0xf3, 0x22} },
-{ 0x0cf7,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0x0d07,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0x0d17,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0x0d27,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0x0d2f,	16,	{0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} },
-{ 0x0d3f,	16,	{0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} },
-{ 0x0d4f,	6,	{0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} },
-{ 0x0d55,	16,	{0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83} },
-{ 0x0d65,	16,	{0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86} },
-{ 0x0d75,	16,	{0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5} },
-{ 0x0d85,	16,	{0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0} },
-{ 0x0d95,	16,	{0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0} },
-{ 0x0da5,	16,	{0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0} },
-{ 0x0db5,	16,	{0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90} },
-{ 0x0dc5,	16,	{0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2} },
-{ 0x0dd5,	16,	{0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05} },
-{ 0x0de5,	4,	{0x86, 0xd2, 0xaf, 0x22} },
-{ 0x0de9,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x0df9,	1,	{0x22} },
-{ 0x0dfa,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x0e0a,	16,	{0xd2, 0x17, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92} },
-{ 0x0e1a,	16,	{0x0f, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74} },
-{ 0x0e2a,	16,	{0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0} },
-{ 0x0e3a,	16,	{0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f} },
-{ 0x0e4a,	16,	{0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x18, 0x12, 0x13, 0x02, 0xc2, 0x10, 0xe4, 0xf5} },
-{ 0x0e5a,	16,	{0x0b, 0xf5, 0x13, 0xc2, 0x15, 0xc2, 0x11, 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0} },
-{ 0x0e6a,	16,	{0x65, 0x17, 0x60, 0x10, 0x30, 0x11, 0x05, 0xd2, 0x18, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0} },
-{ 0x0e7a,	16,	{0xf5, 0x17, 0x80, 0x08, 0x30, 0x11, 0x05, 0xc2, 0x18, 0x12, 0x00, 0x46, 0x30, 0x10, 0x07, 0xc2} },
-{ 0x0e8a,	16,	{0x10, 0x12, 0x09, 0x19, 0x80, 0xd6, 0x30, 0x16, 0xd3, 0xc2, 0x16, 0x12, 0x14, 0x4f, 0x80, 0xcc} },
-{ 0x0e9a,	1,	{0x22} },
-{ 0x0e9b,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x47, 0x02, 0x0e, 0xe2} },
-{ 0x0ea7,	16,	{0x02, 0x0e, 0x0a, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x0eb7,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x0ec7,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x0ed7,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x13, 0x69, 0xe4, 0x7e} },
-{ 0x0ee7,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x0ef7,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x0f07,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x0f17,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x0f27,	16,	{0xe4, 0xfe, 0x75, 0x1d, 0xff, 0x75, 0x1e, 0x19, 0x75, 0x1f, 0x12, 0xab, 0x1d, 0xaa, 0x1e, 0xa9} },
-{ 0x0f37,	16,	{0x1f, 0x90, 0x00, 0x01, 0x12, 0x0c, 0xb8, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x0f47,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x0c, 0xf7, 0x85, 0xf0, 0x1b, 0xf5, 0x1c, 0x62, 0x1b} },
-{ 0x0f57,	16,	{0xe5, 0x1b, 0x62, 0x1c, 0xe5, 0x1c, 0x62, 0x1b, 0x29, 0xfd, 0xe5, 0x1b, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x0f67,	14,	{0x1d, 0xff, 0xf5, 0x1e, 0x89, 0x1f, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0f75,	1,	{0x22} },
-{ 0x0f76,	2,	{0x8f, 0x1b} },
-{ 0x0f78,	16,	{0xe4, 0xf5, 0x1c, 0x75, 0x1d, 0xff, 0x75, 0x1e, 0x19, 0x75, 0x1f, 0x86, 0xab, 0x1d, 0xaa, 0x1e} },
-{ 0x0f88,	16,	{0xa9, 0x1f, 0x90, 0x00, 0x01, 0x12, 0x0c, 0xb8, 0xb4, 0x03, 0x1d, 0xaf, 0x1c, 0x05, 0x1c, 0xef} },
-{ 0x0f98,	16,	{0xb5, 0x1b, 0x01, 0x22, 0x12, 0x0c, 0x9f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0fa8,	14,	{0x1d, 0xff, 0xf5, 0x1e, 0x89, 0x1f, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0fb6,	1,	{0x22} },
-{ 0x0fb7,	16,	{0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e} },
-{ 0x0fc7,	16,	{0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05} },
-{ 0x0fd7,	16,	{0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13} },
-{ 0x0fe7,	9,	{0xcc, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22} },
-{ 0x0ff0,	16,	{0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e} },
-{ 0x1000,	16,	{0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x13, 0xe4, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05} },
-{ 0x1010,	16,	{0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x14} },
-{ 0x1020,	9,	{0x37, 0x8f, 0x1a, 0xef, 0x42, 0x37, 0x80, 0xca, 0x22} },
-{ 0x1029,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} },
-{ 0x1039,	16,	{0x1a, 0x04, 0xc2, 0x1a, 0x80, 0x02, 0xd2, 0x16, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} },
-{ 0x1049,	14,	{0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1057,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} },
-{ 0x1067,	16,	{0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} },
-{ 0x1077,	10,	{0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1081,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} },
-{ 0x1091,	16,	{0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} },
-{ 0x10a1,	7,	{0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x10a8,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x10b8,	16,	{0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x10c8,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x10ce,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x10de,	16,	{0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x10ee,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x10f4,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1104,	16,	{0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x1114,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x111a,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x112a,	16,	{0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x113a,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x1140,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1150,	16,	{0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54} },
-{ 0x1160,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x1166,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1176,	16,	{0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x1186,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x118c,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x119c,	16,	{0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x11ac,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x11b2,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x11c2,	16,	{0x09, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x11d2,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x11d8,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x11e8,	16,	{0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x11f8,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x11fe,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x120e,	16,	{0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54} },
-{ 0x121e,	6,	{0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x1224,	16,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f} },
-{ 0x1234,	16,	{0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90} },
-{ 0x1244,	5,	{0xc0, 0x00, 0xed, 0xf0, 0x22} },
-{ 0x1249,	16,	{0x12, 0x13, 0xb4, 0x8f, 0x1a, 0x12, 0x13, 0xb4, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12} },
-{ 0x1259,	16,	{0x12, 0x13, 0xb4, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0xb4, 0x8f, 0x1b} },
-{ 0x1269,	4,	{0x80, 0xe8, 0xaf, 0x1a} },
-{ 0x126d,	1,	{0x22} },
-{ 0x126e,	16,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f} },
-{ 0x127e,	16,	{0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90} },
-{ 0x128e,	5,	{0xc0, 0x00, 0xed, 0xf0, 0x22} },
-{ 0x1293,	16,	{0x12, 0x14, 0x1f, 0x8f, 0x1a, 0x12, 0x14, 0x1f, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12} },
-{ 0x12a3,	16,	{0x12, 0x14, 0x1f, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x14, 0x1f, 0x8f, 0x1b} },
-{ 0x12b3,	4,	{0x80, 0xe8, 0xaf, 0x1a} },
-{ 0x12b7,	1,	{0x22} },
-{ 0x12b8,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x12c8,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x12d8,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x12dd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x53} },
-{ 0x12ed,	16,	{0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82} },
-{ 0x12fd,	5,	{0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1302,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x18, 0x04, 0xe0, 0x44} },
-{ 0x1312,	16,	{0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x13, 0x85, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x1322,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x1327,	16,	{0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x24, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1337,	16,	{0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80, 0xfd, 0x12, 0x12, 0x24} },
-{ 0x1347,	1,	{0x22} },
-{ 0x1348,	16,	{0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x6e, 0x90, 0x7f, 0x98, 0x74} },
-{ 0x1358,	16,	{0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, 0xfd, 0x12, 0x12, 0x6e} },
-{ 0x1368,	1,	{0x22} },
-{ 0x1369,	16,	{0x05, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, 0x00, 0xc1, 0x10, 0xc1, 0x16} },
-{ 0x1379,	7,	{0xc1, 0x0f, 0xc1, 0x94, 0x01, 0x0a, 0x00} },
-{ 0x1380,	2,	{0xc1, 0x99} },
-{ 0x1382,	2,	{0xc1, 0x9a} },
-{ 0x1384,	1,	{0x00} },
-{ 0x1385,	16,	{0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, 0x60} },
-{ 0x1395,	7,	{0x05, 0x12, 0x0d, 0xe9, 0x80, 0xee, 0x22} },
-{ 0x139c,	12,	{0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13a8,	12,	{0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13b4,	12,	{0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13c0,	12,	{0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13cc,	12,	{0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13d8,	12,	{0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13e4,	12,	{0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13f0,	12,	{0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x13fc,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x1400,	16,	{0x02, 0x10, 0x81, 0x00, 0x02, 0x12, 0xb8, 0x00, 0x02, 0x10, 0x57, 0x00, 0x02, 0x10, 0x29, 0x00} },
-{ 0x1410,	3,	{0x02, 0x12, 0xdd} },
-{ 0x1413,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x141f,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x142b,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x1437,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x1443,	12,	{0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x144f,	10,	{0x12, 0x00, 0x03, 0x12, 0x0d, 0xfa, 0x12, 0x0b, 0x27, 0x22} },
-{ 0x1900,	16,	{0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x10, 0x01, 0x00, 0x00, 0x01, 0x02} },
-{ 0x1910,	16,	{0x00, 0x01, 0x09, 0x02, 0x74, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e} },
-{ 0x1920,	16,	{0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} },
-{ 0x1930,	16,	{0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00} },
-{ 0x1940,	16,	{0x07, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} },
-{ 0x1950,	16,	{0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02} },
-{ 0x1960,	16,	{0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00} },
-{ 0x1970,	16,	{0x00, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07} },
-{ 0x1980,	16,	{0x05, 0x87, 0x02, 0x40, 0x00, 0x00, 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00} },
-{ 0x1990,	16,	{0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00} },
-{ 0x19a0,	16,	{0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00} },
-{ 0x19b0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00} },
-{ 0x19c0,	16,	{0x6f, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} },
-{ 0x19d0,	16,	{0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00} },
-{ 0x19e0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00} },
-{ 0x19f0,	16,	{0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00} },
-{ 0x1a00,	10,	{0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00} },
+ {0x0033,  3, { 0x02, 0x13, 0xab}},
+ {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}},
+ {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}},
+ {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}},
+ {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x33, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}},
+ {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}},
+ {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x33, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}},
+ {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}},
+ {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xca}},
+ {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}},
+ {0x00a6, 16, { 0x12, 0x13, 0x33, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}},
+ {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}},
+ {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xca, 0xd2, 0x03, 0xe4, 0x90, 0x7f}},
+ {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x66, 0x53, 0x36, 0x80, 0x12}},
+ {0x00e6, 16, { 0x13, 0x3f, 0xef, 0x42, 0x36, 0x12, 0x11, 0xed, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3a, 0x50, 0x0f}},
+ {0x00f6, 16, { 0x12, 0x13, 0x1b, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x61, 0xc2}},
+ {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}},
+ {0x0043,  3, { 0x02, 0x13, 0x00}},
+ {0x0000,  3, { 0x02, 0x0e, 0x10}},
+ {0x0106, 64, { 0x0b, 0xe5, 0x19, 0x70, 0x04, 0xf5, 0x36, 0x80, 0x57, 0x12, 0x13, 0x3f, 0xef, 0x42, 0x36, 0xe5, 0x36,
+  0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08,
+  0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x5b, 0xe5,
+  0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40}},
+ {0x0146, 64, { 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75,
+  0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, 0x0c, 0xef, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90,
+  0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x05, 0x03, 0x02, 0x03, 0xc5, 0xc2, 0x05, 0xe4, 0xf5,
+  0x18, 0x74, 0x40, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5}},
+ {0x0186, 64, { 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef,
+  0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68,
+  0x90, 0x7e, 0x03, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xc8, 0x7f, 0x03, 0x7d,
+  0xcd, 0x12, 0x11, 0xc8, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0}},
+ {0x01c6, 64, { 0x00, 0xe5, 0x46, 0xf0, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12,
+  0x10, 0x4c, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x10, 0x72, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0,
+  0xfd, 0x12, 0x11, 0xc8, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xc8, 0x43, 0x46, 0x80, 0x90, 0x7f,
+  0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12}},
+ {0x0206, 64, { 0xf0, 0xe5, 0x40, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e,
+  0x13, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0,
+  0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x44, 0xf0, 0x90, 0x7e, 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43}},
+ {0x0246, 64, { 0x42, 0x80, 0x80, 0x03, 0x53, 0x42, 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43,
+  0x42, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x10, 0xbe, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xe4,
+  0xaf, 0x42, 0x12, 0x10, 0x98, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42,
+  0x12, 0x10, 0x98, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46}},
+ {0x0286, 64, { 0x02, 0x80, 0x03, 0x53, 0x46, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46,
+  0xf0, 0x90, 0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03,
+  0x53, 0x46, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90,
+  0x7e, 0x12, 0xe0, 0xf5, 0x3a, 0xa3, 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3}},
+ {0x02c6, 64, { 0xe0, 0x60, 0x05, 0x43, 0x46, 0x10, 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0,
+  0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90,
+  0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x11, 0xf0, 0x12, 0x13, 0x0f, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e}},
+ {0x0306, 64, { 0xfd, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xc8, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e,
+  0x17, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xc8, 0x75, 0x29,
+  0x01, 0xd2, 0x07, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5,
+  0x40, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11}},
+ {0x0346, 64, { 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0,
+  0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53, 0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xc8,
+  0x75, 0x2b, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff,
+  0xad, 0x3e, 0x12, 0x11, 0xc8, 0xe4, 0xf5, 0x2b, 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60}},
+ {0x0386, 64, { 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e,
+  0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0b, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4,
+  0xf5, 0x38, 0xd2, 0x07, 0x90, 0x7e, 0x1f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0,
+  0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35, 0xf0, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30}},
+ {0x03c6, 64, { 0x1a, 0x52, 0xe5, 0x38, 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40,
+  0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x13, 0x0f,
+  0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13,
+  0x4b, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x07}},
+ {0x0406, 64, { 0x30, 0x0d, 0x11, 0x12, 0x13, 0x4b, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19,
+  0x25, 0xd2, 0x07, 0x20, 0x1b, 0x03, 0x02, 0x07, 0xf4, 0x30, 0x0a, 0x18, 0x12, 0x13, 0x87, 0xef,
+  0xc3, 0x95, 0x3d, 0x40, 0x03, 0x02, 0x04, 0xb2, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x0a,
+  0xc2, 0x00, 0x80, 0x77, 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x6d, 0x12}},
+ {0x0446, 64, { 0x13, 0x87, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f,
+  0xcb, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41,
+  0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x41, 0x12, 0x0d, 0x14, 0xc2, 0x04, 0xe4, 0x90, 0x7f, 0xcb, 0xf0,
+  0x80, 0x39, 0x90, 0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x87, 0xef, 0xc3, 0x94}},
+ {0x0486, 64, { 0x40, 0x50, 0x29, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x19,
+  0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d,
+  0xc1, 0x12, 0x0d, 0x14, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30,
+  0xe1, 0x03, 0x02, 0x05, 0x40, 0x53, 0x37, 0x80, 0x12, 0x13, 0x93, 0xef, 0x42, 0x37, 0x12}},
+ {0x04c6, 64, { 0x12, 0x37, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x6f, 0xef, 0x30, 0xe0, 0x08,
+  0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0c, 0x61, 0xc2, 0x0c, 0xe5, 0x19, 0x70, 0x04, 0xf5, 0x37,
+  0x80, 0x57, 0x12, 0x13, 0x93, 0xef, 0x42, 0x37, 0xe5, 0x37, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3,
+  0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7d, 0x7f, 0x80, 0x75}},
+ {0x0506, 64, { 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0x94, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb,
+  0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08,
+  0xe4, 0x90, 0x7d, 0x80, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12,
+  0x0d, 0x39, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90, 0x7f, 0xd0, 0xe0, 0x30, 0xe1}},
+ {0x0546, 64, { 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0x9f, 0xc2, 0x06, 0xe4, 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5,
+  0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e,
+  0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5,
+  0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x23, 0xe0, 0x60}},
+ {0x0586, 64, { 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x12, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x12, 0x12, 0x43, 0x47,
+  0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e,
+  0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, 0x11, 0x30, 0x90, 0x7e, 0x22, 0xe0,
+  0xff, 0x12, 0x11, 0x56, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, 0xfd, 0x12, 0x12, 0x12, 0x7f}},
+ {0x05c6, 64, { 0x03, 0x7d, 0x07, 0x12, 0x12, 0x12, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0,
+  0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90,
+  0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54}},
+ {0x0606, 64, { 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e,
+  0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f,
+  0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12,
+  0x11, 0x7c, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0xa2, 0xaf, 0x43, 0x12, 0x11, 0x0a}},
+ {0x0646, 64, { 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf, 0x43, 0x12, 0x11, 0x0a, 0x90, 0x7e, 0x2c,
+  0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90,
+  0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60,
+  0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, 0x53, 0x47, 0xfe, 0x90, 0x7f}},
+ {0x0686, 64, { 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3,
+  0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x10, 0x80,
+  0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0,
+  0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0}},
+ {0x06c6, 64, { 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x63,
+  0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12,
+  0x12, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f,
+  0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x12, 0x75, 0x32, 0x01, 0xd2, 0x08, 0x90, 0x7e}},
+ {0x0706, 64, { 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00,
+  0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74,
+  0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f,
+  0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x12, 0x75, 0x34, 0x01, 0xd2, 0x08}},
+ {0x0746, 64, { 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x12, 0xe4,
+  0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0,
+  0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c,
+  0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, 0xf5, 0x39, 0xd2, 0x08, 0x90}},
+ {0x0786, 64, { 0x7e, 0x3f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0,
+  0x74, 0x36, 0xf0, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0x30, 0x1a, 0x52, 0xe5, 0x39, 0x60, 0x02, 0x15,
+  0x39, 0x30, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75,
+  0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, 0x13, 0x12, 0x13, 0x63, 0xef, 0x54, 0x01, 0xf5, 0x19}},
+ {0x07c6, 64, { 0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2, 0x08, 0x12, 0x13, 0x9f, 0xef, 0x54, 0x80, 0xf5, 0x19,
+  0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, 0x08, 0x30, 0x0e, 0x11, 0x12, 0x13, 0x9f, 0xef,
+  0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, 0x85, 0x19, 0x2e, 0xd2, 0x08, 0x30, 0x1a, 0x2a,
+  0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5}},
+ {0x0806, 64, { 0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74,
+  0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1,
+  0x03, 0x02, 0x09, 0x28, 0xe5, 0x0a, 0x70, 0x40, 0x30, 0x07, 0x39, 0xe5, 0x38, 0x70, 0x35, 0xc2,
+  0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}},
+ {0x0846, 64, { 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef,
+  0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x38,
+  0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30, 0x08,
+  0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x08, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d}},
+ {0x0886, 64, { 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82,
+  0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f,
+  0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5, 0x0a,
+  0x64, 0x02, 0x70, 0x36, 0x30, 0x14, 0x2f, 0xc2, 0x14, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00}},
+ {0x08c6, 64, { 0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18,
+  0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05, 0xdb,
+  0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15, 0x15,
+  0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}},
+ {0x0906, 64, { 0xfa, 0x12, 0x0e, 0x9c, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef,
+  0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5,
+  0x0a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0e, 0xf4, 0x0a, 0x10, 0x00, 0x0a, 0x84, 0x01, 0x0a,
+  0xf0, 0x03, 0x09, 0x4c, 0x06, 0x0a, 0x03, 0x08, 0x09, 0xfd, 0x09, 0x09, 0xe5, 0x0a, 0x09}},
+ {0x0946, 64, { 0xf4, 0x0b, 0x00, 0x00, 0x0b, 0x3f, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x61,
+  0x24, 0x02, 0x60, 0x03, 0x02, 0x09, 0xdb, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90,
+  0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02,
+  0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x7b, 0x75, 0x83}},
+ {0x0986, 64, { 0x19, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75,
+  0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83,
+  0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b,
+  0x46, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, 0x1a, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90}},
+ {0x09c6, 64, { 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01,
+  0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f,
+  0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea,
+  0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x46, 0x12, 0x0b, 0x4e, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0x00}},
+ {0x0a06, 64, { 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60,
+  0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff,
+  0xa2, 0x16, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74,
+  0x02, 0xf0, 0x02, 0x0b, 0x46, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5}},
+ {0x0a46, 64, { 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f,
+  0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83,
+  0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0,
+  0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f}},
+ {0x0a86, 64, { 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0,
+  0xb4, 0x01, 0x05, 0xc2, 0x10, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02,
+  0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff,
+  0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4}},
+ {0x0ac6, 64, { 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54,
+  0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f,
+  0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60,
+  0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x10, 0x80}},
+ {0x0b06, 64, { 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90,
+  0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25,
+  0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90,
+  0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}},
+ {0x0b46, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74,
+  0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e,
+  0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74,
+  0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, 0x24, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74}},
+ {0x0b86, 64, { 0x24, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5, 0x18, 0xb4,
+  0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5, 0x38, 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x07, 0xc2, 0x0b,
+  0xc2, 0x05, 0xc2, 0x00, 0xc2, 0x09, 0xc2, 0x13, 0xd2, 0x03, 0xd2, 0x01, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd}},
+ {0x0bc6, 64, { 0x12, 0x11, 0xc8, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0x98, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x7f,
+  0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0,
+  0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x11, 0xc8, 0xe4,
+  0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x11, 0xc8, 0x90, 0x7f, 0x98, 0x74, 0x11}},
+ {0x0c06, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x11, 0xc8, 0x7f, 0x01, 0x12, 0x12,
+  0x81, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xc8, 0x20, 0x1b, 0x03, 0x02, 0x0c, 0xc7, 0x75, 0x2d,
+  0x01, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4,
+  0x12, 0x0e, 0xe2, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5}},
+ {0x0c46, 64, { 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x08, 0xc2, 0x0c, 0xc2, 0x06, 0xc2, 0x00, 0xc2, 0x0a, 0xc2, 0x13,
+  0xd2, 0x04, 0xd2, 0x02, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00,
+  0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12, 0x12, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x11,
+  0x0a, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90}},
+ {0x0c86, 64, { 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80,
+  0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x12, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12,
+  0x12, 0x12, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d,
+  0x7f, 0x12, 0x12, 0x12, 0x7f, 0x01, 0x12, 0x12, 0xa2, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12}},
+ {0x0cc6, 64, { 0x12, 0xd2, 0x12, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5,
+  0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86,
+  0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08,
+  0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00}},
+ {0x0d06, 64, { 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05,
+  0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2,
+  0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5}},
+ {0x0d46, 64, { 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86,
+  0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05,
+  0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43,
+  0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92, 0xe0, 0x44}},
+ {0x0d86, 64, { 0x02, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2,
+  0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f,
+  0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90,
+  0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf}},
+ {0x0dc6, 64, { 0xd2, 0x1a, 0x12, 0x12, 0x5c, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2, 0x12, 0x90,
+  0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12, 0x05, 0xd2,
+  0x1a, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30, 0x12, 0x05, 0xc2,
+  0x1a, 0x12, 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x29, 0x80, 0xd6, 0x30}},
+ {0x0e06, 64, { 0x18, 0xd3, 0xc2, 0x18, 0x12, 0x12, 0xf6, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75,
+  0x81, 0x47, 0x02, 0x0e, 0x57, 0x02, 0x0d, 0x7f, 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}},
+ {0x0e46, 64, { 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+  0x90, 0x12, 0xc3, 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}},
+ {0x0e86, 64, { 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf,
+  0xe9, 0xde, 0xe7, 0x80, 0xbe, 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}},
+ {0x0ec6, 64, { 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, 0xd0, 0x83, 0xd0,
+  0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8}},
+ {0x0f06, 64, { 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3,
+  0xa3, 0x80, 0xdf, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19, 0x75, 0x1c,
+  0x86, 0xab, 0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xb5, 0xb4, 0x03, 0x1d,
+  0xaf, 0x19, 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0x9c, 0x7e, 0x00, 0x29}},
+ {0x0f46, 64, { 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b, 0x00, 0x7a,
+  0x00, 0x79, 0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c,
+  0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac,
+  0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5}},
+ {0x0f86, 64, { 0x08, 0x60, 0x0a, 0x12, 0x13, 0x3f, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f, 0x1a, 0x05,
+  0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a,
+  0xf0, 0x12, 0x13, 0x57, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5,
+  0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x93, 0x8f}},
+ {0x0fc6, 64, { 0x1a, 0xef, 0x42, 0x37, 0x80, 0xca, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84,
+  0xc0, 0x86, 0x75, 0x86, 0x00, 0x30, 0x15, 0x04, 0xc2, 0x15, 0x80, 0x02, 0xd2, 0x18, 0x53, 0x91,
+  0xef, 0x90, 0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0,
+  0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0}},
+ {0x1006, 64, { 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04,
+  0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0,
+  0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x11, 0x53,
+  0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0}},
+ {0x1046, 64, { 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf,
+  0xf0, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13,
+  0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0}},
+ {0x1086, 64, { 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0,
+  0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44,
+  0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0}},
+ {0x10c6, 64, { 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f,
+  0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90,
+  0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90}},
+ {0x1106, 64, { 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90,
+  0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0,
+  0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90,
+  0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef}},
+ {0x1146, 64, { 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90,
+  0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09,
+  0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f,
+  0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74}},
+ {0x1186, 64, { 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74,
+  0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b,
+  0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00,
+  0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00}},
+ {0x11c6, 64, { 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90,
+  0x7f, 0x98, 0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0,
+  0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x27, 0x8f, 0x1a, 0x12, 0x13, 0x27, 0x8f, 0x1b,
+  0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x27, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b}},
+ {0x1206, 64, { 0x60, 0x07, 0x12, 0x13, 0x27, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b,
+  0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90,
+  0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22,
+  0x12, 0x13, 0x7b, 0x8f, 0x1a, 0x12, 0x13, 0x7b, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60}},
+ {0x1246, 64, { 0x12, 0x12, 0x13, 0x7b, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x7b, 0x8f, 0x1b,
+  0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0,
+  0x30, 0x1a, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x12, 0xdf, 0x90, 0x7f,
+  0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5}},
+ {0x1286, 64, { 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x11, 0xc8, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee,
+  0xf0, 0xe4, 0xe5, 0x3e, 0x44, 0x80, 0xfd, 0x12, 0x11, 0xc8, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5,
+  0x3f, 0x54, 0x7f, 0xfd, 0x12, 0x12, 0x12, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00,
+  0xee, 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, 0xfd, 0x12, 0x12, 0x12, 0x22, 0x05, 0x0e, 0x02}},
+ {0x12c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x03, 0x14, 0x03, 0x00, 0x00, 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10,
+  0xc1, 0x16, 0x01, 0x0a, 0x00, 0xc1, 0x9b, 0x00, 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19,
+  0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e, 0x60, 0x05, 0x12, 0x0d, 0x5e, 0x80, 0xee, 0x22, 0x12,
+  0x00, 0x03, 0x12, 0x0d, 0x6f, 0x12, 0x0b, 0x4e, 0x22, 0x02, 0x10, 0x25, 0x00, 0x02, 0x13}},
+ {0x1306, 64, { 0x04, 0x00, 0x02, 0x0f, 0xfb, 0x00, 0x02, 0x0f, 0xcd, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0,
+  0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22,
+  0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90}},
+ {0x1346, 64, { 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22,
+  0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x90, 0xc0,
+  0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff}},
+ {0x1386, 64, { 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0,
+  0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1406, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x01, 0xff, 0x00}},
+ {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x10, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65,
+  0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53,
+  0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c,
+  0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}},
+ {0x1a06,  4, { 0x72, 0x00, 0x00, 0x00}},
 { 0xffff,	0,	{0x00} }
 };
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa28xa_fw.h linux/drivers/usb/serial/keyspan_usa28xa_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa28xa_fw.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/keyspan_usa28xa_fw.h	Tue Oct  9 15:15:03 2001
@@ -0,0 +1,446 @@
+/* keyspan_usa28xa_fw.h
+
+   Generated from Keyspan firmware image usa44code.h Sat Oct  6 12:08:02 EST 2001
+   This firmware is for the Keyspan USA-28XA Serial Adaptor
+
+   "The firmware contained herein as keyspan_usa28xa_fw.h is
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
+   ("Keyspan"), as an unpublished work.  This notice does not imply
+   unrestricted or public access to this firmware which is a trade secret of
+   Keyspan, and which may not be reproduced, used, sold or transferred to any
+   third party without Keyspan's prior written consent.  All Rights Reserved.
+
+   Permission is hereby granted for the distribution of this firmware image
+   as part of a Linux or other Open Source operating system kernel in 
+   text or binary form as required.
+
+   This firmware may not be modified and may only be used with the Keyspan 
+   USA-28XA Serial Adapter.  Distribution and/or Modification of the
+   keyspan.c driver which includes this firmware, in whole or in part,
+   requires the inclusion of this statement."
+
+*/
+
+static const struct ezusb_hex_record keyspan_usa28xa_firmware[] = {
+ {0x0033,  3, { 0x02, 0x13, 0xaa}},
+ {0x0003, 16, { 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0}},
+ {0x0013, 16, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90}},
+ {0x0023, 15, { 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x22}},
+ {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x28, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}},
+ {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}},
+ {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x28, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}},
+ {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}},
+ {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xd8}},
+ {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}},
+ {0x00a6, 16, { 0x12, 0x13, 0x28, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}},
+ {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}},
+ {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xd8, 0xd2, 0x03, 0xe4, 0x90, 0x7f}},
+ {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x66, 0x53, 0x36, 0x80, 0x12}},
+ {0x00e6, 16, { 0x13, 0x34, 0xef, 0x42, 0x36, 0x12, 0x11, 0xfb, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3a, 0x50, 0x0f}},
+ {0x00f6, 16, { 0x12, 0x13, 0x10, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x61, 0xc2}},
+ {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}},
+ {0x0043,  3, { 0x02, 0x14, 0x00}},
+ {0x0000,  3, { 0x02, 0x0e, 0x1e}},
+ {0x0106, 64, { 0x0b, 0xe5, 0x19, 0x70, 0x04, 0xf5, 0x36, 0x80, 0x57, 0x12, 0x13, 0x34, 0xef, 0x42, 0x36, 0xe5, 0x36,
+  0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08,
+  0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x69, 0xe5,
+  0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40}},
+ {0x0146, 64, { 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75,
+  0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, 0x0c, 0xfd, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90,
+  0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x05, 0x03, 0x02, 0x03, 0xc5, 0xc2, 0x05, 0xe4, 0xf5,
+  0x18, 0x74, 0x40, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5}},
+ {0x0186, 64, { 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef,
+  0x12, 0x0e, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68,
+  0x90, 0x7e, 0x03, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xd6, 0x7f, 0x03, 0x7d,
+  0xcd, 0x12, 0x11, 0xd6, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0}},
+ {0x01c6, 64, { 0x00, 0xe5, 0x46, 0xf0, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12,
+  0x10, 0x5a, 0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x10, 0x80, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0,
+  0xfd, 0x12, 0x11, 0xd6, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xd6, 0x43, 0x46, 0x80, 0x90, 0x7f,
+  0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12}},
+ {0x0206, 64, { 0xf0, 0xe5, 0x40, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e,
+  0x13, 0xe0, 0x70, 0x08, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0,
+  0x60, 0x12, 0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x44, 0xf0, 0x90, 0x7e, 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43}},
+ {0x0246, 64, { 0x42, 0x80, 0x80, 0x03, 0x53, 0x42, 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43,
+  0x42, 0x02, 0xa3, 0xe0, 0xff, 0x12, 0x10, 0xcc, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xf2,
+  0xaf, 0x42, 0x12, 0x10, 0xa6, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42,
+  0x12, 0x10, 0xa6, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46}},
+ {0x0286, 64, { 0x02, 0x80, 0x03, 0x53, 0x46, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46,
+  0xf0, 0x90, 0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03,
+  0x53, 0x46, 0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90,
+  0x7e, 0x12, 0xe0, 0xf5, 0x3a, 0xa3, 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3}},
+ {0x02c6, 64, { 0xe0, 0x60, 0x05, 0x43, 0x46, 0x10, 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0,
+  0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90,
+  0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x11, 0xf0, 0x12, 0x13, 0x04, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e}},
+ {0x0306, 64, { 0xfd, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xd6, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e,
+  0x17, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xd6, 0x75, 0x29,
+  0x01, 0xd2, 0x07, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5,
+  0x40, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11}},
+ {0x0346, 64, { 0x43, 0x44, 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0,
+  0x90, 0x7e, 0x1a, 0xe0, 0x60, 0x0f, 0x53, 0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xd6,
+  0x75, 0x2b, 0x01, 0xd2, 0x07, 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff,
+  0xad, 0x3e, 0x12, 0x11, 0xd6, 0xe4, 0xf5, 0x2b, 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60}},
+ {0x0386, 64, { 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e,
+  0x1d, 0xe0, 0x60, 0x02, 0xd2, 0x0b, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4,
+  0xf5, 0x38, 0xd2, 0x07, 0x90, 0x7e, 0x1f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0,
+  0x74, 0x31, 0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35, 0xf0, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30}},
+ {0x03c6, 64, { 0x1a, 0x52, 0xe5, 0x38, 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40,
+  0x04, 0x15, 0x13, 0x80, 0x3e, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x13, 0x04,
+  0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13,
+  0x40, 0xef, 0x54, 0x80, 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26, 0xd2, 0x07}},
+ {0x0406, 64, { 0x30, 0x0d, 0x11, 0x12, 0x13, 0x40, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05, 0x85, 0x19,
+  0x25, 0xd2, 0x07, 0x20, 0x1b, 0x03, 0x02, 0x07, 0xf4, 0x30, 0x0a, 0x18, 0x12, 0x13, 0x7c, 0xef,
+  0xc3, 0x95, 0x3d, 0x40, 0x03, 0x02, 0x04, 0xb2, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0, 0xc2, 0x0a,
+  0xc2, 0x00, 0x80, 0x77, 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1, 0x6d, 0x12}},
+ {0x0446, 64, { 0x13, 0x7c, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f,
+  0xcb, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d, 0x7f, 0x41,
+  0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x41, 0x12, 0x0d, 0x22, 0xc2, 0x04, 0xe4, 0x90, 0x7f, 0xcb, 0xf0,
+  0x80, 0x39, 0x90, 0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x7c, 0xef, 0xc3, 0x94}},
+ {0x0486, 64, { 0x40, 0x50, 0x29, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14, 0xf5, 0x19,
+  0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c, 0x75, 0x0d,
+  0xc1, 0x12, 0x0d, 0x22, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba, 0xe0, 0x30,
+  0xe1, 0x03, 0x02, 0x05, 0x40, 0x53, 0x37, 0x80, 0x12, 0x13, 0x88, 0xef, 0x42, 0x37, 0x12}},
+ {0x04c6, 64, { 0x12, 0x45, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x64, 0xef, 0x30, 0xe0, 0x08,
+  0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0c, 0x61, 0xc2, 0x0c, 0xe5, 0x19, 0x70, 0x04, 0xf5, 0x37,
+  0x80, 0x57, 0x12, 0x13, 0x88, 0xef, 0x42, 0x37, 0xe5, 0x37, 0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3,
+  0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7d, 0x7f, 0x80, 0x75}},
+ {0x0506, 64, { 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0xa2, 0xe5, 0x19, 0x25, 0xe0, 0x90, 0x7f, 0xbb,
+  0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08,
+  0xe4, 0x90, 0x7d, 0x80, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x81, 0x12,
+  0x0d, 0x47, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90, 0x7f, 0xd0, 0xe0, 0x30, 0xe1}},
+ {0x0546, 64, { 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0x9f, 0xc2, 0x06, 0xe4, 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5,
+  0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e,
+  0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xf0, 0x05, 0x18, 0xe5,
+  0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x23, 0xe0, 0x60}},
+ {0x0586, 64, { 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x20, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x12, 0x20, 0x43, 0x47,
+  0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e,
+  0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, 0x11, 0x3e, 0x90, 0x7e, 0x22, 0xe0,
+  0xff, 0x12, 0x11, 0x64, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, 0xfd, 0x12, 0x12, 0x20, 0x7f}},
+ {0x05c6, 64, { 0x03, 0x7d, 0x07, 0x12, 0x12, 0x20, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0,
+  0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90,
+  0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54}},
+ {0x0606, 64, { 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e,
+  0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f,
+  0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12,
+  0x11, 0x8a, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0xb0, 0xaf, 0x43, 0x12, 0x11, 0x18}},
+ {0x0646, 64, { 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf, 0x43, 0x12, 0x11, 0x18, 0x90, 0x7e, 0x2c,
+  0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90,
+  0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60,
+  0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, 0x53, 0x47, 0xfe, 0x90, 0x7f}},
+ {0x0686, 64, { 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3,
+  0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x10, 0x80,
+  0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0,
+  0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0}},
+ {0x06c6, 64, { 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x58,
+  0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12,
+  0x20, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f,
+  0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x20, 0x75, 0x32, 0x01, 0xd2, 0x08, 0x90, 0x7e}},
+ {0x0706, 64, { 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00,
+  0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74,
+  0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f,
+  0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x20, 0x75, 0x34, 0x01, 0xd2, 0x08}},
+ {0x0746, 64, { 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x20, 0xe4,
+  0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0,
+  0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c,
+  0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, 0xf5, 0x39, 0xd2, 0x08, 0x90}},
+ {0x0786, 64, { 0x7e, 0x3f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0,
+  0x74, 0x36, 0xf0, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0x30, 0x1a, 0x52, 0xe5, 0x39, 0x60, 0x02, 0x15,
+  0x39, 0x30, 0x13, 0x49, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80, 0x3e, 0x75,
+  0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, 0x13, 0x12, 0x13, 0x58, 0xef, 0x54, 0x01, 0xf5, 0x19}},
+ {0x07c6, 64, { 0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2, 0x08, 0x12, 0x13, 0x94, 0xef, 0x54, 0x80, 0xf5, 0x19,
+  0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, 0x08, 0x30, 0x0e, 0x11, 0x12, 0x13, 0x94, 0xef,
+  0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, 0x85, 0x19, 0x2e, 0xd2, 0x08, 0x30, 0x1a, 0x2a,
+  0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0, 0x60, 0x09, 0xe0, 0xf5}},
+ {0x0806, 64, { 0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74,
+  0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1,
+  0x03, 0x02, 0x09, 0x28, 0xe5, 0x0a, 0x70, 0x40, 0x30, 0x07, 0x39, 0xe5, 0x38, 0x70, 0x35, 0xc2,
+  0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}},
+ {0x0846, 64, { 0xfa, 0x12, 0x0e, 0xaa, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef,
+  0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x38,
+  0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, 0xe5, 0x0a, 0x64, 0x01, 0x70, 0x40, 0x30, 0x08,
+  0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x08, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x2d}},
+ {0x0886, 64, { 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0xaa, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82,
+  0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f,
+  0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, 0xf5, 0x35, 0x75, 0x0a, 0x02, 0x22, 0xe5, 0x0a,
+  0x64, 0x02, 0x70, 0x36, 0x30, 0x14, 0x2f, 0xc2, 0x14, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00}},
+ {0x08c6, 64, { 0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0xaa, 0xff, 0x74, 0x80, 0x25, 0x18,
+  0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x05, 0xdb,
+  0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, 0x03, 0x22, 0xe5, 0x15, 0x60, 0x30, 0x15, 0x15,
+  0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x14, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00}},
+ {0x0906, 64, { 0xfa, 0x12, 0x0e, 0xaa, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef,
+  0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5,
+  0x0a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0f, 0x02, 0x0a, 0x10, 0x00, 0x0a, 0x84, 0x01, 0x0a,
+  0xf0, 0x03, 0x09, 0x4c, 0x06, 0x0a, 0x03, 0x08, 0x09, 0xfd, 0x09, 0x09, 0xe5, 0x0a, 0x09}},
+ {0x0946, 64, { 0xf4, 0x0b, 0x00, 0x00, 0x0b, 0x3f, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x61,
+  0x24, 0x02, 0x60, 0x03, 0x02, 0x09, 0xdb, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90,
+  0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04, 0x7f, 0x02, 0x80, 0x02,
+  0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x7b, 0x75, 0x83}},
+ {0x0986, 64, { 0x19, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75,
+  0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83,
+  0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b,
+  0x46, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, 0x28, 0xea, 0x49, 0x60, 0x0d, 0xea, 0x90}},
+ {0x09c6, 64, { 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01,
+  0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f,
+  0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea,
+  0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x46, 0x12, 0x0b, 0x4e, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0x00}},
+ {0x0a06, 64, { 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60,
+  0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x10, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff,
+  0xa2, 0x16, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74,
+  0x02, 0xf0, 0x02, 0x0b, 0x46, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90, 0x7f, 0xb5}},
+ {0x0a46, 64, { 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f,
+  0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83,
+  0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0,
+  0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x46, 0x90, 0x7f}},
+ {0x0a86, 64, { 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0,
+  0xb4, 0x01, 0x05, 0xc2, 0x10, 0x02, 0x0b, 0x46, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02,
+  0x0b, 0x46, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff,
+  0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4}},
+ {0x0ac6, 64, { 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff, 0x13, 0x13, 0x13, 0x54,
+  0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20, 0xf0, 0x80, 0x5f,
+  0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60,
+  0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2, 0x10, 0x80}},
+ {0x0b06, 64, { 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x20, 0x90,
+  0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25,
+  0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x80, 0x10, 0x90,
+  0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0}},
+ {0x0b46, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74,
+  0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e,
+  0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, 0xf0, 0xe4, 0xf5, 0x8e, 0x90, 0x7f, 0xdf, 0x74,
+  0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, 0x24, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74}},
+ {0x0b86, 64, { 0x24, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4,
+  0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5, 0x38, 0xf5, 0x13, 0xf5, 0x36, 0xc2, 0x07, 0xc2, 0x0b,
+  0xc2, 0x05, 0xc2, 0x00, 0xc2, 0x09, 0xc2, 0x13, 0xd2, 0x03, 0xd2, 0x01, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd}},
+ {0x0bc6, 64, { 0x12, 0x11, 0xd6, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0xa6, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x7f,
+  0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0,
+  0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x11, 0xd6, 0xe4,
+  0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x11, 0xd6, 0x90, 0x7f, 0x98, 0x74, 0x11}},
+ {0x0c06, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x11, 0xd6, 0x7f, 0x01, 0x12, 0x12,
+  0x8f, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xd6, 0x7f, 0x13, 0x7d, 0x01, 0x12, 0x11, 0xd6, 0x20,
+  0x1b, 0x03, 0x02, 0x0c, 0xd5, 0x75, 0x2d, 0x01, 0x75, 0x18, 0x01, 0x7b, 0x00, 0x74, 0x2d, 0x25,
+  0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4}},
+ {0x0c46, 64, { 0x09, 0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5, 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2, 0x08, 0xc2, 0x0c, 0xc2,
+  0x06, 0xc2, 0x00, 0xc2, 0x0a, 0xc2, 0x13, 0xd2, 0x04, 0xd2, 0x02, 0x90, 0x7f, 0x98, 0x74, 0x0b,
+  0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x12,
+  0x20, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x11, 0x18, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0x7f}},
+ {0x0c86, 64, { 0x01, 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x75,
+  0x47, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12, 0x12, 0x20, 0xe4, 0xff,
+  0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12, 0x12, 0x20, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90,
+  0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x12, 0x20, 0x7f, 0x01, 0x12, 0x12}},
+ {0x0cc6, 64, { 0xb0, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x20, 0x7f, 0x13, 0x7d, 0x01, 0x12, 0x12, 0x20, 0xd2, 0x12,
+  0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5,
+  0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05,
+  0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5}},
+ {0x0d06, 64, { 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86,
+  0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08,
+  0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90,
+  0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf}},
+ {0x0d46, 64, { 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83,
+  0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7,
+  0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5,
+  0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87}},
+ {0x0d86, 64, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x90,
+  0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43,
+  0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74,
+  0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f}},
+ {0x0dc6, 64, { 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x1a, 0x12,
+  0x12, 0x6a, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2, 0x12, 0x90, 0x7f, 0xa1,
+  0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12, 0x05, 0xd2, 0x1a, 0x12,
+  0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30, 0x12, 0x05, 0xc2, 0x1a}},
+ {0x0e06, 64, { 0x12, 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x29, 0x80, 0xd6, 0x30, 0x18, 0xd3, 0xc2,
+  0x18, 0x12, 0x13, 0xa0, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x47,
+  0x02, 0x0e, 0x65, 0x02, 0x0d, 0x8d, 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}},
+ {0x0e46, 64, { 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, 0x12,
+  0xd1, 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}},
+ {0x0e86, 64, { 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, 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}},
+ {0x0ec6, 64, { 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, 0xd0, 0x83, 0xd0, 0x82}},
+ {0x0f06, 64, { 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, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19, 0x75, 0x1c, 0x86, 0xab,
+  0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xc3, 0xb4, 0x03, 0x1d, 0xaf}},
+ {0x0f46, 64, { 0x19, 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0xaa, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a,
+  0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79,
+  0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5,
+  0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c}},
+ {0x0f86, 64, { 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a,
+  0x12, 0x13, 0x34, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5,
+  0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12,
+  0x13, 0x4c, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82}},
+ {0x0fc6, 64, { 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x88, 0x8f, 0x1a, 0xef, 0x42,
+  0x37, 0x80, 0xca, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86,
+  0x75, 0x86, 0x00, 0x30, 0x15, 0x04, 0xc2, 0x15, 0x80, 0x02, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90,
+  0x7f, 0xab, 0x74, 0x08, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83}},
+ {0x1006, 64, { 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86,
+  0x00, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0,
+  0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83,
+  0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x11, 0x53, 0x91}},
+ {0x1046, 64, { 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83,
+  0xd0, 0xe0, 0x32, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90,
+  0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0,
+  0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0}},
+ {0x1086, 64, { 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0,
+  0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90,
+  0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12,
+  0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54}},
+ {0x10c6, 64, { 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf,
+  0xf0, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13,
+  0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0}},
+ {0x1106, 64, { 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0,
+  0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45,
+  0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0}},
+ {0x1146, 64, { 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f,
+  0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90,
+  0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90}},
+ {0x1186, 64, { 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90,
+  0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0,
+  0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90,
+  0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef}},
+ {0x11c6, 64, { 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90,
+  0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x17, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0,
+  0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x1c, 0x8f, 0x1a, 0x12, 0x13, 0x1c, 0x8f, 0x1b, 0xe5}},
+ {0x1206, 64, { 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x1c, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12,
+  0x13, 0x1c, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5,
+  0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00,
+  0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12}},
+ {0x1246, 64, { 0x13, 0x70, 0x8f, 0x1a, 0x12, 0x13, 0x70, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13,
+  0x70, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x70, 0x8f, 0x1b, 0x80, 0xe8,
+  0xaf, 0x1a, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x1a,
+  0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x12, 0xed, 0x90, 0x7f, 0xd6}},
+ {0x1286, 64, { 0xe0, 0x54, 0xf7, 0xf0, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f,
+  0xfd, 0x12, 0x11, 0xd6, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4,
+  0xe5, 0x3e, 0x44, 0x80, 0xfd, 0x12, 0x11, 0xd6, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54,
+  0x7f, 0xfd, 0x12, 0x12, 0x20, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee}},
+ {0x12c6, 64, { 0xf0, 0xe4, 0xe5, 0x3f, 0x44, 0x80, 0xfd, 0x12, 0x12, 0x20, 0x22, 0x05, 0x0e, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x03, 0x14, 0x03, 0x00, 0x00, 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10, 0xc1, 0x16,
+  0x01, 0x0a, 0x00, 0xc1, 0x9b, 0x00, 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18,
+  0x70, 0x02, 0x15, 0x18, 0x4e, 0x60, 0x05, 0x12, 0x0d, 0x6c, 0x80, 0xee, 0x22, 0x90, 0x7f}},
+ {0x1306, 64, { 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90,
+  0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff,
+  0x22, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0}},
+ {0x1346, 64, { 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff,
+  0x22, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x0a, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90,
+  0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0}},
+ {0x1386, 64, { 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98,
+  0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x12, 0x00, 0x03, 0x12, 0x0d, 0x7d, 0x12,
+  0x0b, 0x4e, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 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, 0x10, 0x33, 0x00, 0x02, 0x14}},
+ {0x1406, 64, { 0x04, 0x00, 0x02, 0x10, 0x09, 0x00, 0x02, 0x0f, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x01, 0xff, 0x00}},
+ {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x15, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65,
+  0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53,
+  0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c,
+  0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}},
+ {0x1a06,  4, { 0x72, 0x00, 0x00, 0x00}},
+ { 0xffff,	0,	{0x00} }
+};
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa28xb_fw.h linux/drivers/usb/serial/keyspan_usa28xb_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa28xb_fw.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/serial/keyspan_usa28xb_fw.h	Tue Oct  9 15:15:03 2001
@@ -0,0 +1,447 @@
+/* keyspan_usa28xb_fw.h
+
+   Generated from Keyspan firmware image usacode36.h Sat Oct  6 12:07:38 EST 2001
+   This firmware is for the Keyspan USA-28XA Serial Adaptor
+
+   "The firmware contained herein as keyspan_usa28xb_fw.h is
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
+   ("Keyspan"), as an unpublished work.  This notice does not imply
+   unrestricted or public access to the source code from which this 
+   firmware image is derived.  Except as noted below this firmware image
+   may not be reproduced, used, sold or transferred to any third party
+   without Keyspan's prior written consent.  All Rights Reserved.
+
+   Permission is hereby granted for the distribution of this firmware image
+   as part of a Linux or other Open Source operating system kernel in 
+   text or binary form as required.
+
+   This firmware may not be modified and may only be used with the Keyspan 
+   USA-28 Serial Adapter.  Distribution and/or Modification of the
+   keyspan.c driver which includes this firmware, in whole or in part,
+   requires the inclusion of this statement."
+
+*/
+
+static const struct ezusb_hex_record keyspan_usa28xb_firmware[] = {
+ {0x0033,  3, { 0x02, 0x13, 0xb7}},
+ {0x0046, 16, { 0x30, 0x09, 0x18, 0x12, 0x13, 0x35, 0xef, 0xc3, 0x95, 0x3c, 0x40, 0x03, 0x02, 0x00, 0xd8, 0x90}},
+ {0x0056, 16, { 0x7f, 0xbf, 0x74, 0x01, 0xf0, 0xc2, 0x09, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x03, 0x3b, 0x90, 0x7f}},
+ {0x0066, 16, { 0xc6, 0xe0, 0x20, 0xe1, 0x6d, 0x12, 0x13, 0x35, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7e}},
+ {0x0076, 16, { 0x40, 0xe0, 0x13, 0x92, 0x09, 0x90, 0x7f, 0xc7, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60}},
+ {0x0086, 16, { 0x0f, 0xf5, 0x08, 0x7e, 0x7e, 0x7f, 0x41, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x41, 0x12, 0x0c, 0xdc}},
+ {0x0096, 16, { 0xc2, 0x03, 0xe4, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xc8, 0xe0, 0x20, 0xe1, 0x32}},
+ {0x00a6, 16, { 0x12, 0x13, 0x35, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7d, 0xc0, 0xe0, 0x13, 0x92, 0x09}},
+ {0x00b6, 16, { 0x90, 0x7f, 0xc9, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d}},
+ {0x00c6, 16, { 0x7f, 0xc1, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0xc1, 0x12, 0x0c, 0xdc, 0xd2, 0x03, 0xe4, 0x90, 0x7f}},
+ {0x00d6, 16, { 0xc9, 0xf0, 0x90, 0x7f, 0xb6, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x01, 0x66, 0x53, 0x36, 0x80, 0x12}},
+ {0x00e6, 16, { 0x13, 0x41, 0xef, 0x42, 0x36, 0x12, 0x12, 0x08, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3a, 0x50, 0x0f}},
+ {0x00f6, 16, { 0x12, 0x13, 0x1d, 0xef, 0x30, 0xe0, 0x08, 0xe5, 0x36, 0x20, 0xe7, 0x03, 0x30, 0x0b, 0x61, 0xc2}},
+ {0x0036, 12, { 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}},
+ {0x0043,  3, { 0x02, 0x14, 0x00}},
+ {0x0003, 16, { 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30}},
+ {0x0013, 16, { 0x15, 0x04, 0xc2, 0x15, 0x80, 0x02, 0xd2, 0x18, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08}},
+ {0x0023, 14, { 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32}},
+ {0x0000,  3, { 0x02, 0x0e, 0x22}},
+ {0x0106, 64, { 0x0b, 0xe5, 0x19, 0x70, 0x04, 0xf5, 0x36, 0x80, 0x57, 0x12, 0x13, 0x41, 0xef, 0x42, 0x36, 0xe5, 0x36,
+  0x30, 0xe7, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08,
+  0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x0c, 0x7e, 0x75, 0x0d, 0x80, 0xaf, 0x36, 0x12, 0x0f, 0x6d, 0xe5,
+  0x19, 0x25, 0xe0, 0x90, 0x7f, 0xb7, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40}},
+ {0x0146, 64, { 0x03, 0x75, 0x19, 0x3f, 0x85, 0x19, 0x08, 0xe4, 0x90, 0x7e, 0x80, 0xf0, 0x7e, 0x7e, 0x7f, 0x81, 0x75,
+  0x0c, 0x7e, 0x75, 0x0d, 0x81, 0x12, 0x0d, 0x01, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xb7, 0xf0, 0x90,
+  0x7f, 0xce, 0xe0, 0x30, 0xe1, 0x06, 0x20, 0x05, 0x03, 0x02, 0x03, 0xc5, 0xe4, 0xf5, 0x18, 0x74,
+  0x40, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7c, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c}},
+ {0x0186, 64, { 0x00, 0x7b, 0x01, 0x7a, 0x7e, 0x79, 0x00, 0x24, 0x00, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e,
+  0xf4, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x00, 0xe0, 0x60, 0x68, 0x90, 0x7e,
+  0x03, 0xe0, 0x60, 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x11, 0xe3, 0x7f, 0x03, 0x7d, 0xcd, 0x12,
+  0x11, 0xe3, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5}},
+ {0x01c6, 64, { 0x46, 0xf0, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x01, 0xe0, 0xff, 0x12, 0x10, 0x67,
+  0x90, 0x7e, 0x02, 0xe0, 0xff, 0x12, 0x10, 0x8d, 0x7f, 0x01, 0x90, 0x7e, 0x11, 0xe0, 0xfd, 0x12,
+  0x11, 0xe3, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xe3, 0x43, 0x46, 0x80, 0x90, 0x7f, 0x98, 0x74,
+  0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5}},
+ {0x0206, 64, { 0x40, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x03, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x13, 0xe0,
+  0x70, 0x08, 0xe4, 0x90, 0x7e, 0x13, 0xf0, 0x75, 0x25, 0xff, 0x90, 0x7e, 0x05, 0xe0, 0x60, 0x12,
+  0xa3, 0xe0, 0x54, 0x3f, 0xf5, 0x44, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe5,
+  0x44, 0xf0, 0x90, 0x7e, 0x07, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x42, 0x80}},
+ {0x0246, 64, { 0x80, 0x03, 0x53, 0x42, 0x7f, 0x53, 0x42, 0xfc, 0x90, 0x7e, 0x09, 0xe0, 0x60, 0x11, 0x43, 0x42, 0x02,
+  0xa3, 0xe0, 0xff, 0x12, 0x10, 0xd9, 0x90, 0x7e, 0x0b, 0xe0, 0xff, 0x12, 0x10, 0xff, 0xaf, 0x42,
+  0x12, 0x10, 0xb3, 0x90, 0x7e, 0x03, 0xe0, 0x60, 0x08, 0x53, 0x42, 0x7f, 0xaf, 0x42, 0x12, 0x10,
+  0xb3, 0x90, 0x7e, 0x0c, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x02, 0x80}},
+ {0x0286, 64, { 0x03, 0x53, 0x46, 0xfd, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90,
+  0x7e, 0x0e, 0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x46, 0x01, 0x80, 0x03, 0x53, 0x46,
+  0xfe, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x12,
+  0xe0, 0xf5, 0x3a, 0xa3, 0xe0, 0x13, 0x92, 0x0d, 0xa3, 0xe0, 0xf5, 0x3c, 0xa3, 0xe0, 0x60}},
+ {0x02c6, 64, { 0x05, 0x43, 0x46, 0x10, 0x80, 0x03, 0x53, 0x46, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x46, 0xf0, 0x90, 0x7e, 0x16, 0xe0, 0x60, 0x32, 0x53, 0x44, 0xbf, 0x90, 0x7f, 0x98,
+  0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11,
+  0xf0, 0x12, 0x13, 0x11, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3e, 0xfd, 0xe4}},
+ {0x0306, 64, { 0xff, 0xad, 0x3e, 0x12, 0x11, 0xe3, 0xe4, 0xf5, 0x2a, 0xf5, 0x29, 0xd2, 0x07, 0x90, 0x7e, 0x17, 0xe0,
+  0x60, 0x0f, 0x43, 0x3e, 0x02, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xe3, 0x75, 0x29, 0x01, 0xd2,
+  0x07, 0x90, 0x7e, 0x18, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44,
+  0x04, 0x90, 0xc0, 0x00, 0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x19, 0xe0, 0x60, 0x11, 0x43, 0x44}},
+ {0x0346, 64, { 0x40, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e,
+  0x1a, 0xe0, 0x60, 0x0f, 0x53, 0x3e, 0xfe, 0xe4, 0xff, 0xad, 0x3e, 0x12, 0x11, 0xe3, 0x75, 0x2b,
+  0x01, 0xd2, 0x07, 0x90, 0x7e, 0x1b, 0xe0, 0x60, 0x0f, 0x43, 0x3e, 0x01, 0xe4, 0xff, 0xad, 0x3e,
+  0x12, 0x11, 0xe3, 0xe4, 0xf5, 0x2b, 0xd2, 0x07, 0x90, 0x7e, 0x1c, 0xe0, 0x60, 0x0e, 0x90}},
+ {0x0386, 64, { 0x7f, 0x98, 0x74, 0x12, 0xf0, 0xe5, 0x40, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x1d, 0xe0,
+  0x60, 0x02, 0xd2, 0x0b, 0x90, 0x7e, 0x1e, 0xe0, 0x60, 0x08, 0x75, 0x2c, 0x01, 0xe4, 0xf5, 0x38,
+  0xd2, 0x07, 0x90, 0x7e, 0x1f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x11, 0xf0, 0x74, 0x31,
+  0xf0, 0x74, 0x15, 0xf0, 0x74, 0x35, 0xf0, 0xc2, 0x05, 0xe4, 0x90, 0x7f, 0xcf, 0xf0, 0x30}},
+ {0x03c6, 64, { 0x1a, 0x54, 0xe5, 0x38, 0x60, 0x02, 0x15, 0x38, 0x20, 0x13, 0x4b, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40,
+  0x04, 0x15, 0x13, 0x80, 0x40, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xd2, 0x13, 0x12, 0x13, 0x11,
+  0xef, 0x54, 0x01, 0xf5, 0x19, 0x65, 0x2a, 0x60, 0x05, 0x85, 0x19, 0x2a, 0xd2, 0x07, 0x12, 0x13,
+  0x4d, 0xef, 0x54, 0x80, 0x64, 0x80, 0xf5, 0x19, 0x65, 0x26, 0x60, 0x05, 0x85, 0x19, 0x26}},
+ {0x0406, 64, { 0xd2, 0x07, 0x30, 0x0d, 0x11, 0x12, 0x13, 0x4d, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x25, 0x60, 0x05,
+  0x85, 0x19, 0x25, 0xd2, 0x07, 0x20, 0x1b, 0x03, 0x02, 0x07, 0xf8, 0x30, 0x0a, 0x18, 0x12, 0x13,
+  0x89, 0xef, 0xc3, 0x95, 0x3d, 0x40, 0x03, 0x02, 0x04, 0xb4, 0x90, 0x7f, 0xc1, 0x74, 0x01, 0xf0,
+  0xc2, 0x0a, 0xc2, 0x00, 0x80, 0x77, 0x30, 0x04, 0x3b, 0x90, 0x7f, 0xca, 0xe0, 0x20, 0xe1}},
+ {0x0446, 64, { 0x6d, 0x12, 0x13, 0x89, 0xef, 0xc3, 0x94, 0x40, 0x50, 0x64, 0x90, 0x7d, 0x40, 0xe0, 0x13, 0x92, 0x0a,
+  0x90, 0x7f, 0xcb, 0xe0, 0x14, 0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7d,
+  0x7f, 0x41, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x41, 0x12, 0x0d, 0x26, 0xc2, 0x04, 0xe4, 0x90, 0x7f,
+  0xcb, 0xf0, 0x80, 0x39, 0x90, 0x7f, 0xcc, 0xe0, 0x20, 0xe1, 0x32, 0x12, 0x13, 0x89, 0xef}},
+ {0x0486, 64, { 0xc3, 0x94, 0x40, 0x50, 0x29, 0x90, 0x7c, 0xc0, 0xe0, 0x13, 0x92, 0x0a, 0x90, 0x7f, 0xcd, 0xe0, 0x14,
+  0xf5, 0x19, 0x20, 0x00, 0x11, 0x60, 0x0f, 0xf5, 0x08, 0x7e, 0x7c, 0x7f, 0xc1, 0x75, 0x0c, 0x7c,
+  0x75, 0x0d, 0xc1, 0x12, 0x0d, 0x26, 0xd2, 0x04, 0xe4, 0x90, 0x7f, 0xcd, 0xf0, 0x90, 0x7f, 0xba,
+  0xe0, 0x30, 0xe1, 0x03, 0x02, 0x05, 0x42, 0x53, 0x37, 0x80, 0x12, 0x13, 0x95, 0xef, 0x42}},
+ {0x04c6, 64, { 0x37, 0x12, 0x12, 0x52, 0x8f, 0x19, 0xef, 0xc3, 0x95, 0x3b, 0x50, 0x0f, 0x12, 0x13, 0x71, 0xef, 0x30,
+  0xe0, 0x08, 0xe5, 0x37, 0x20, 0xe7, 0x03, 0x30, 0x0c, 0x61, 0xc2, 0x0c, 0xe5, 0x19, 0x70, 0x04,
+  0xf5, 0x37, 0x80, 0x57, 0x12, 0x13, 0x95, 0xef, 0x42, 0x37, 0xe5, 0x37, 0x30, 0xe7, 0x26, 0xe5,
+  0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x08, 0x7e, 0x7d, 0x7f}},
+ {0x0506, 64, { 0x80, 0x75, 0x0c, 0x7d, 0x75, 0x0d, 0x80, 0xaf, 0x37, 0x12, 0x0f, 0xa6, 0xe5, 0x19, 0x25, 0xe0, 0x90,
+  0x7f, 0xbb, 0xf0, 0x80, 0x26, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03, 0x75, 0x19, 0x3f, 0x85,
+  0x19, 0x08, 0xe4, 0x90, 0x7d, 0x80, 0xf0, 0x7e, 0x7d, 0x7f, 0x81, 0x75, 0x0c, 0x7d, 0x75, 0x0d,
+  0x81, 0x12, 0x0d, 0x4b, 0xe5, 0x19, 0x04, 0x90, 0x7f, 0xbb, 0xf0, 0x90, 0x7f, 0xd0, 0xe0}},
+ {0x0546, 64, { 0x30, 0xe1, 0x06, 0x20, 0x06, 0x03, 0x02, 0x07, 0xa1, 0xe4, 0xf5, 0x18, 0x74, 0xc0, 0x25, 0x18, 0xf5,
+  0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x18, 0x7c, 0x00, 0x7b, 0x01, 0x7a, 0x7e,
+  0x79, 0x20, 0x24, 0x20, 0xf9, 0xec, 0x34, 0x7e, 0xfa, 0xef, 0x12, 0x0e, 0xf4, 0x05, 0x18, 0xe5,
+  0x18, 0xb4, 0x20, 0xd7, 0x90, 0x7e, 0x20, 0xe0, 0x60, 0x68, 0x90, 0x7e, 0x23, 0xe0, 0x60}},
+ {0x0586, 64, { 0x24, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x12, 0x2d, 0x7f, 0x03, 0x7d, 0xcd, 0x12, 0x12, 0x2d, 0x43, 0x47,
+  0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0xe4, 0x90, 0x7e,
+  0x33, 0xf0, 0x80, 0x30, 0x90, 0x7e, 0x21, 0xe0, 0xff, 0x12, 0x11, 0x4b, 0x90, 0x7e, 0x22, 0xe0,
+  0xff, 0x12, 0x11, 0x71, 0x7f, 0x01, 0x90, 0x7e, 0x31, 0xe0, 0xfd, 0x12, 0x12, 0x2d, 0x7f}},
+ {0x05c6, 64, { 0x03, 0x7d, 0x07, 0x12, 0x12, 0x2d, 0x43, 0x47, 0x80, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0,
+  0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x06, 0x90, 0xc0,
+  0x00, 0xf0, 0x90, 0x7e, 0x23, 0xe0, 0x70, 0x06, 0x90, 0x7e, 0x33, 0xe0, 0x70, 0x08, 0xe4, 0x90,
+  0x7e, 0x33, 0xf0, 0x75, 0x2e, 0xff, 0x90, 0x7e, 0x25, 0xe0, 0x60, 0x12, 0xa3, 0xe0, 0x54}},
+ {0x0606, 64, { 0x3f, 0xf5, 0x45, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x45, 0xf0, 0x90, 0x7e,
+  0x27, 0xe0, 0x60, 0x2b, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x43, 0x80, 0x80, 0x03, 0x53, 0x43, 0x7f,
+  0x53, 0x43, 0xfc, 0x90, 0x7e, 0x29, 0xe0, 0x60, 0x11, 0x43, 0x43, 0x02, 0xa3, 0xe0, 0xff, 0x12,
+  0x11, 0x97, 0x90, 0x7e, 0x2b, 0xe0, 0xff, 0x12, 0x11, 0xbd, 0xaf, 0x43, 0x12, 0x11, 0x25}},
+ {0x0646, 64, { 0x90, 0x7e, 0x23, 0xe0, 0x60, 0x08, 0x53, 0x43, 0x7f, 0xaf, 0x43, 0x12, 0x11, 0x25, 0x90, 0x7e, 0x2c,
+  0xe0, 0x60, 0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x02, 0x80, 0x03, 0x53, 0x47, 0xfd, 0x90,
+  0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x2e, 0xe0, 0x60,
+  0x18, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x01, 0x80, 0x03, 0x53, 0x47, 0xfe, 0x90, 0x7f}},
+ {0x0686, 64, { 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0, 0x90, 0x7e, 0x32, 0xe0, 0xf5, 0x3b, 0xa3,
+  0xe0, 0x13, 0x92, 0x0e, 0xa3, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, 0x60, 0x05, 0x43, 0x47, 0x10, 0x80,
+  0x03, 0x53, 0x47, 0xef, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe5, 0x47, 0xf0,
+  0x90, 0x7e, 0x36, 0xe0, 0x60, 0x32, 0x53, 0x45, 0xbf, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0}},
+ {0x06c6, 64, { 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x12, 0x13, 0x65,
+  0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0x53, 0x3f, 0xfd, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12,
+  0x2d, 0xe4, 0xf5, 0x33, 0xf5, 0x32, 0xd2, 0x08, 0x90, 0x7e, 0x37, 0xe0, 0x60, 0x0f, 0x43, 0x3f,
+  0x02, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x2d, 0x75, 0x32, 0x01, 0xd2, 0x08, 0x90, 0x7e}},
+ {0x0706, 64, { 0x38, 0xe0, 0x60, 0x10, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0, 0xe5, 0x41, 0x44, 0x04, 0x90, 0xc0, 0x00,
+  0xf0, 0xd2, 0x00, 0x90, 0x7e, 0x39, 0xe0, 0x60, 0x11, 0x43, 0x45, 0x40, 0x90, 0x7f, 0x98, 0x74,
+  0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3a, 0xe0, 0x60, 0x0f,
+  0x53, 0x3f, 0xfe, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x2d, 0x75, 0x34, 0x01, 0xd2, 0x08}},
+ {0x0746, 64, { 0x90, 0x7e, 0x3b, 0xe0, 0x60, 0x0f, 0x43, 0x3f, 0x01, 0xe4, 0xff, 0xad, 0x3f, 0x12, 0x12, 0x2d, 0xe4,
+  0xf5, 0x34, 0xd2, 0x08, 0x90, 0x7e, 0x3c, 0xe0, 0x60, 0x0e, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0,
+  0xe5, 0x41, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7e, 0x3d, 0xe0, 0x60, 0x02, 0xd2, 0x0c,
+  0x90, 0x7e, 0x3e, 0xe0, 0x60, 0x08, 0x75, 0x35, 0x01, 0xe4, 0xf5, 0x39, 0xd2, 0x08, 0x90}},
+ {0x0786, 64, { 0x7e, 0x3f, 0xe0, 0x60, 0x0f, 0x90, 0x7f, 0xd7, 0x74, 0x13, 0xf0, 0x74, 0x33, 0xf0, 0x74, 0x16, 0xf0,
+  0x74, 0x36, 0xf0, 0xc2, 0x06, 0xe4, 0x90, 0x7f, 0xd1, 0xf0, 0x30, 0x1a, 0x54, 0xe5, 0x39, 0x60,
+  0x02, 0x15, 0x39, 0x30, 0x13, 0x4b, 0xe5, 0x13, 0xd3, 0x94, 0x00, 0x40, 0x04, 0x15, 0x13, 0x80,
+  0x40, 0x75, 0x13, 0x0a, 0x30, 0x1b, 0x02, 0xc2, 0x13, 0x12, 0x13, 0x65, 0xef, 0x54, 0x01}},
+ {0x07c6, 64, { 0xf5, 0x19, 0x65, 0x33, 0x60, 0x05, 0x85, 0x19, 0x33, 0xd2, 0x08, 0x12, 0x13, 0xa1, 0xef, 0x54, 0x80,
+  0x64, 0x80, 0xf5, 0x19, 0x65, 0x2f, 0x60, 0x05, 0x85, 0x19, 0x2f, 0xd2, 0x08, 0x30, 0x0e, 0x11,
+  0x12, 0x13, 0xa1, 0xef, 0x54, 0x10, 0xf5, 0x19, 0x65, 0x2e, 0x60, 0x05, 0x85, 0x19, 0x2e, 0xd2,
+  0x08, 0x30, 0x1a, 0x2a, 0x90, 0x7f, 0xd2, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x7b, 0x40, 0xe0}},
+ {0x0806, 64, { 0x60, 0x09, 0xe0, 0xf5, 0x15, 0x90, 0x7b, 0x42, 0xe0, 0xf5, 0x16, 0x90, 0x7b, 0x41, 0xe0, 0x60, 0x09,
+  0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x7f,
+  0xc2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x09, 0x2c, 0xe5, 0x0a, 0x70, 0x40, 0x30, 0x07, 0x39, 0xe5,
+  0x38, 0x70, 0x35, 0xc2, 0x07, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18}},
+ {0x0846, 64, { 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0xae, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34,
+  0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74,
+  0x09, 0xf0, 0x75, 0x38, 0x10, 0xe4, 0xf5, 0x2c, 0x75, 0x0a, 0x01, 0x22, 0xe5, 0x0a, 0x64, 0x01,
+  0x70, 0x40, 0x30, 0x08, 0x39, 0xe5, 0x39, 0x70, 0x35, 0xc2, 0x08, 0xf5, 0x18, 0x7e, 0x00}},
+ {0x0886, 64, { 0x7b, 0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0xae, 0xff, 0x74, 0x80,
+  0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4,
+  0x09, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x09, 0xf0, 0x75, 0x39, 0x10, 0xe4, 0xf5, 0x35, 0x75, 0x0a,
+  0x02, 0x22, 0xe5, 0x0a, 0x64, 0x02, 0x70, 0x36, 0x30, 0x14, 0x2f, 0xc2, 0x14, 0xf5, 0x18}},
+ {0x08c6, 64, { 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x0e, 0x25, 0x18, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0xae, 0xff,
+  0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5,
+  0x18, 0xb4, 0x05, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x05, 0xf0, 0x75, 0x0a, 0x03, 0x22, 0xe5, 0x15,
+  0x60, 0x30, 0x15, 0x15, 0xe4, 0xf5, 0x18, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x14, 0x25, 0x18}},
+ {0x0906, 64, { 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x0e, 0xae, 0xff, 0x74, 0x80, 0x25, 0x18, 0xf5, 0x82, 0xe4, 0x34,
+  0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x18, 0xe5, 0x18, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74,
+  0x03, 0xf0, 0xe4, 0xf5, 0x0a, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x0f, 0x06, 0x0a, 0x14, 0x00,
+  0x0a, 0x88, 0x01, 0x0a, 0xf4, 0x03, 0x09, 0x50, 0x06, 0x0a, 0x07, 0x08, 0x0a, 0x01, 0x09}},
+ {0x0946, 64, { 0x09, 0xe9, 0x0a, 0x09, 0xf8, 0x0b, 0x00, 0x00, 0x0b, 0x43, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60,
+  0x19, 0x14, 0x60, 0x61, 0x24, 0x02, 0x60, 0x03, 0x02, 0x09, 0xdf, 0x74, 0x19, 0x90, 0x7f, 0xd4,
+  0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x04,
+  0x7f, 0x02, 0x80, 0x02, 0x7f, 0x03, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75}},
+ {0x0986, 64, { 0x82, 0x7b, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x74, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75,
+  0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75,
+  0x82, 0x17, 0x75, 0x83, 0x19, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f,
+  0xd5, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0f, 0x2c, 0xea, 0x49}},
+ {0x09c6, 64, { 0x60, 0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f,
+  0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02,
+  0x0b, 0x4a, 0x90, 0x7f, 0x00, 0xe5, 0x09, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x0b,
+  0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x09, 0x02, 0x0b, 0x4a, 0x12, 0x0b, 0x52, 0x02, 0x0b}},
+ {0x0a06, 64, { 0x4a, 0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xe8,
+  0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x10, 0xe4, 0x33,
+  0xff, 0x25, 0xe0, 0xff, 0xa2, 0x16, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0,
+  0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x4a, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3}},
+ {0x0a46, 64, { 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80,
+  0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4,
+  0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f,
+  0xb5, 0x74, 0x02, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02}},
+ {0x0a86, 64, { 0x0b, 0x4a, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x0b, 0x4a,
+  0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x10, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xb4, 0xe0,
+  0x44, 0x01, 0xf0, 0x02, 0x0b, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0,
+  0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24}},
+ {0x0ac6, 64, { 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff,
+  0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44,
+  0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8,
+  0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01}},
+ {0x0b06, 64, { 0x04, 0xd2, 0x10, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea,
+  0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0,
+  0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01,
+  0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4}},
+ {0x0b46, 64, { 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0,
+  0x90, 0x7f, 0x9c, 0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc0,
+  0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x18, 0xf0, 0xe4, 0xf5, 0x8e,
+  0x90, 0x7f, 0xdf, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0xe4, 0xf5, 0x24, 0x75, 0x18}},
+ {0x0b86, 64, { 0x01, 0x7b, 0x00, 0x74, 0x24, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xf4, 0x05,
+  0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3a, 0x01, 0xe4, 0xf5, 0x38, 0xf5, 0x13, 0xf5, 0x36,
+  0xc2, 0x07, 0xc2, 0x0b, 0xc2, 0x05, 0xc2, 0x00, 0xc2, 0x09, 0xc2, 0x13, 0xd2, 0x03, 0xd2, 0x01,
+  0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x75, 0x44, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0}},
+ {0x0bc6, 64, { 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x11, 0xe3, 0x7f, 0x10, 0x8f, 0x42, 0x12, 0x10, 0xb3, 0x90, 0x7f, 0x98,
+  0x74, 0x12, 0xf0, 0x7f, 0x01, 0x8f, 0x40, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f,
+  0x98, 0x74, 0x14, 0xf0, 0x75, 0x46, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd,
+  0x12, 0x11, 0xe3, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3e, 0x12, 0x11, 0xe3, 0x90}},
+ {0x0c06, 64, { 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x11, 0xe3,
+  0x7f, 0x01, 0x12, 0x12, 0x9c, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x11, 0xe3, 0x7f, 0x13, 0x7d, 0x09,
+  0x12, 0x11, 0xe3, 0x20, 0x1b, 0x03, 0x02, 0x0c, 0xd9, 0x75, 0x2d, 0x01, 0x75, 0x18, 0x01, 0x7b,
+  0x00, 0x74, 0x2d, 0x25, 0x18, 0xf9, 0xe4, 0x34, 0x00, 0xfa, 0xe4, 0x12, 0x0e, 0xf4, 0x05}},
+ {0x0c46, 64, { 0x18, 0xe5, 0x18, 0xb4, 0x09, 0xea, 0x75, 0x3b, 0x01, 0xe4, 0xf5, 0x39, 0xf5, 0x13, 0xf5, 0x37, 0xc2,
+  0x08, 0xc2, 0x0c, 0xc2, 0x06, 0xc2, 0x00, 0xc2, 0x0a, 0xc2, 0x13, 0xd2, 0x04, 0xd2, 0x02, 0x90,
+  0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x75, 0x45, 0x03, 0x90, 0xc0, 0x00, 0x74, 0x03, 0xf0, 0x7f, 0x0c,
+  0xe4, 0xfd, 0x12, 0x12, 0x2d, 0x7f, 0x10, 0x8f, 0x43, 0x12, 0x11, 0x25, 0x90, 0x7f, 0x98}},
+ {0x0c86, 64, { 0x74, 0x0a, 0xf0, 0x7f, 0x01, 0x8f, 0x41, 0xef, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x0c, 0xf0, 0x75, 0x47, 0x80, 0x90, 0xc0, 0x00, 0x74, 0x80, 0xf0, 0x0f, 0xe4, 0xfd, 0x12,
+  0x12, 0x2d, 0xe4, 0xff, 0x7e, 0xa3, 0xad, 0x06, 0x8d, 0x3f, 0x12, 0x12, 0x2d, 0x90, 0x7f, 0x98,
+  0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x12, 0x2d}},
+ {0x0cc6, 64, { 0x7f, 0x01, 0x12, 0x12, 0xbd, 0x7f, 0x03, 0x7d, 0x07, 0x12, 0x12, 0x2d, 0x7f, 0x13, 0x7d, 0x09, 0x12,
+  0x12, 0x2d, 0xd2, 0x12, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5,
+  0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3,
+  0x05, 0x86, 0xf0, 0x05, 0x86, 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x10}},
+ {0x0d06, 64, { 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0,
+  0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3, 0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x90,
+  0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82, 0xe5, 0x0c, 0xf5, 0x83, 0xc2,
+  0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0x05, 0x86, 0xe0, 0xa3, 0x05, 0x86, 0xf0, 0x05, 0x86}},
+ {0x0d46, 64, { 0xdf, 0xf7, 0xd2, 0xaf, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0xaf, 0x08, 0xe5, 0x0d, 0xf5, 0x82,
+  0xe5, 0x0c, 0xf5, 0x83, 0xc2, 0xaf, 0x05, 0x86, 0x90, 0xc0, 0x00, 0xe0, 0x05, 0x86, 0xf0, 0xa3,
+  0x05, 0x86, 0xdf, 0xf7, 0x05, 0x86, 0xd2, 0xaf, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5,
+  0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44}},
+ {0x0d86, 64, { 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd2, 0x19, 0x90, 0x7f, 0x92, 0xe0,
+  0x44, 0x02, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x10, 0xe4, 0x33, 0xfe, 0xef, 0x4e,
+  0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0,
+  0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53}},
+ {0x0dc6, 64, { 0x91, 0xef, 0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x0d, 0xf0, 0xd2,
+  0xaf, 0xd2, 0x1a, 0x12, 0x12, 0x77, 0xc2, 0x11, 0xe4, 0xf5, 0x0b, 0xf5, 0x13, 0xc2, 0x17, 0xc2,
+  0x12, 0x90, 0x7f, 0xa1, 0x04, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x17, 0x60, 0x10, 0x30, 0x12,
+  0x05, 0xd2, 0x1a, 0x12, 0x00, 0x46, 0x90, 0x7f, 0xd8, 0xe0, 0xf5, 0x17, 0x80, 0x08, 0x30}},
+ {0x0e06, 64, { 0x12, 0x05, 0xc2, 0x1a, 0x12, 0x00, 0x46, 0x30, 0x11, 0x07, 0xc2, 0x11, 0x12, 0x09, 0x2d, 0x80, 0xd6,
+  0x30, 0x18, 0xd3, 0xc2, 0x18, 0x12, 0x13, 0xad, 0x80, 0xcc, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8,
+  0xfd, 0x75, 0x81, 0x47, 0x02, 0x0e, 0x69, 0x02, 0x0d, 0x91, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93,
+  0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3}},
+ {0x0e46, 64, { 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, 0x12, 0xde, 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}},
+ {0x0e86, 64, { 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, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22,
+  0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93}},
+ {0x0ec6, 64, { 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}},
+ {0x0f06, 64, { 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, 0x8f, 0x18, 0xe4, 0xf5, 0x19, 0x75, 0x1a, 0xff, 0x75, 0x1b, 0x19,
+  0x75, 0x1c, 0x86, 0xab, 0x1a, 0xaa, 0x1b, 0xa9, 0x1c, 0x90, 0x00, 0x01, 0x12, 0x0e, 0xc7}},
+ {0x0f46, 64, { 0xb4, 0x03, 0x1d, 0xaf, 0x19, 0x05, 0x19, 0xef, 0xb5, 0x18, 0x01, 0x22, 0x12, 0x0e, 0xae, 0x7e, 0x00,
+  0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1a, 0xff, 0xf5, 0x1b, 0x89, 0x1c, 0x80, 0xd4, 0x7b,
+  0x00, 0x7a, 0x00, 0x79, 0x00, 0x22, 0x8f, 0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02,
+  0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12, 0x00, 0x36, 0x05, 0x0d}},
+ {0x0f86, 64, { 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08,
+  0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x41, 0x8f, 0x1a, 0xef, 0x42, 0x36, 0x80, 0xca, 0x22, 0x8f,
+  0x1a, 0x05, 0x0d, 0xe5, 0x0d, 0xae, 0x0c, 0x70, 0x02, 0x05, 0x0c, 0x14, 0xf5, 0x82, 0x8e, 0x83,
+  0xe5, 0x1a, 0xf0, 0x12, 0x13, 0x59, 0x05, 0x0d, 0xe5, 0x0d, 0xac, 0x0c, 0x70, 0x02, 0x05}},
+ {0x0fc6, 64, { 0x0c, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x0a, 0x12, 0x13, 0x95,
+  0x8f, 0x1a, 0xef, 0x42, 0x37, 0x80, 0xca, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c,
+  0x74, 0x30, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74,
+  0x27, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x20, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x07, 0xf0, 0xe4}},
+ {0x1006, 64, { 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x22, 0xc0,
+  0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f,
+  0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84,
+  0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82}},
+ {0x1046, 64, { 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2, 0x11, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab,
+  0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32,
+  0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74,
+  0x10, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44}},
+ {0x1086, 64, { 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74,
+  0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90}},
+ {0x10c6, 64, { 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00,
+  0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f,
+  0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5,
+  0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90}},
+ {0x1106, 64, { 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90,
+  0x7f, 0x98, 0x74, 0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f,
+  0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0,
+  0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f}},
+ {0x1146, 64, { 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0,
+  0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b,
+  0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0,
+  0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00}},
+ {0x1186, 64, { 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22,
+  0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74,
+  0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54,
+  0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00}},
+ {0x11c6, 64, { 0x74, 0xbf, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x7f, 0x98, 0x74,
+  0x13, 0xf0, 0xe5, 0x44, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x17, 0xf0,
+  0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x15, 0xf0, 0x90, 0xc0, 0x00, 0xed}},
+ {0x1206, 64, { 0xf0, 0x22, 0x12, 0x13, 0x29, 0x8f, 0x1a, 0x12, 0x13, 0x29, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60,
+  0x12, 0x12, 0x13, 0x29, 0x8f, 0x1a, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x29, 0x8f,
+  0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0xe5, 0x45, 0x54, 0x7f,
+  0x90, 0xc0, 0x00, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x0f, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0}},
+ {0x1246, 64, { 0x90, 0x7f, 0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22, 0x12, 0x13, 0x7d, 0x8f, 0x1a,
+  0x12, 0x13, 0x7d, 0x8f, 0x1b, 0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x12, 0x12, 0x13, 0x7d, 0x8f, 0x1a,
+  0xe5, 0x1a, 0x65, 0x1b, 0x60, 0x07, 0x12, 0x13, 0x7d, 0x8f, 0x1b, 0x80, 0xe8, 0xaf, 0x1a, 0x22,
+  0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x1a, 0x04, 0xe0}},
+ {0x1286, 64, { 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x12, 0xfa, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0,
+  0xe0, 0x44, 0x04, 0xf0, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3e, 0x54, 0x7f, 0xfd, 0x12, 0x11,
+  0xe3, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3e, 0x44,
+  0x80, 0xfd, 0x12, 0x11, 0xe3, 0x22, 0xae, 0x07, 0xe4, 0xff, 0xe5, 0x3f, 0x54, 0x7f, 0xfd}},
+ {0x12c6, 64, { 0x12, 0x12, 0x2d, 0x90, 0x7f, 0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5, 0x3f,
+  0x44, 0x80, 0xfd, 0x12, 0x12, 0x2d, 0x22, 0x05, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x14,
+  0x03, 0x00, 0x00, 0xc1, 0x11, 0xc1, 0x18, 0xc1, 0x95, 0xc1, 0x10, 0xc1, 0x16, 0x01, 0x0a, 0x00,
+  0xc1, 0x9b, 0x00, 0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02}},
+ {0x1306, 64, { 0x15, 0x18, 0x4e, 0x60, 0x05, 0x12, 0x0d, 0x70, 0x80, 0xee, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x11, 0xf0,
+  0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x12, 0xf0, 0x90, 0xc0, 0x00, 0xe0,
+  0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x13, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f,
+  0x98, 0x74, 0x14, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x15}},
+ {0x1346, 64, { 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x16, 0xf0, 0x90, 0xc0, 0x00, 0xe0,
+  0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x08, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f,
+  0x98, 0x74, 0x09, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0a, 0xf0,
+  0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0b, 0xf0, 0x90, 0xc0, 0x00}},
+ {0x1386, 64, { 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0c, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f,
+  0x98, 0x74, 0x0d, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0x98, 0x74, 0x0e, 0xf0,
+  0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x12, 0x0f, 0xdf, 0x12, 0x0d, 0x81, 0x12, 0x0b, 0x52, 0x22,
+  0x53, 0xd8, 0xef, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x13c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 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, 0x10, 0x40, 0x00, 0x02, 0x14}},
+ {0x1406, 64, { 0x04, 0x00, 0x02, 0x10, 0x16, 0x00, 0x02, 0x00, 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}},
+ {0x1446, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1486, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x14c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1506, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1546, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1586, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x15c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1606, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1646, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1686, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x16c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1706, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1746, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1786, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x17c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1806, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1846, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1886, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x18c6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x01, 0xff, 0x00}},
+ {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x10, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65,
+  0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53,
+  0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c,
+  0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00}},
+ {0x1a06,  4, { 0x72, 0x00, 0x00, 0x00}},
+ {0xffff,	0,	{0x00} }
+};
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa49msg.h linux/drivers/usb/serial/keyspan_usa49msg.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa49msg.h	Thu Dec  7 16:13:38 2000
+++ linux/drivers/usb/serial/keyspan_usa49msg.h	Tue Oct  9 15:15:03 2001
@@ -189,13 +189,26 @@
 #define	PARITY_1			0x28
 #define	PARITY_0			0x38
 
+/*
+	during normal operation, status messages are returned 
+	to the host whenever the board detects changes.  In some
+	circumstances (e.g. Windows), status messages from the
+	device cause problems; to shut them off, the host issues
+	a control message with the disableStatusMessages flags
+	set (to any non-zero value).  The device will respond to
+	this message, and then suppress further status messages;
+	it will resume sending status messages any time the host
+	sends any control message (either global or port-specific).
+*/
+
 typedef struct keyspan_usa49_globalControlMessage
 {
 	u8	portNumber,			// 0x80
 		sendGlobalStatus,	// 1/2=number of status responses requested
 		resetStatusToggle,	// 1=reset global status toggle
 		resetStatusCount,	// a cycling value
-		remoteWakeupEnable;	// 0x10=P1, 0x20=P2, 0x40=P3, 0x80=P3
+		remoteWakeupEnable,		// 0x10=P1, 0x20=P2, 0x40=P3, 0x80=P4
+		disableStatusMessages;	// 1=send no status until host talks
 } keyspan_usa49_globalControlMessage;
 
 /*
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/keyspan_usa49w_fw.h linux/drivers/usb/serial/keyspan_usa49w_fw.h
--- v2.4.10/linux/drivers/usb/serial/keyspan_usa49w_fw.h	Thu Dec  7 16:13:38 2000
+++ linux/drivers/usb/serial/keyspan_usa49w_fw.h	Tue Oct  9 15:15:03 2001
@@ -1,10 +1,10 @@
 /* keyspan_usa49w_fw.h
   
-   Generated from Keyspan firmware image Thu Sep 28 09:13:26 2000 EST
+   Generated from Keyspan firmware image usa49code.h Sat Oct  6 12:06:59 EST 2001
    This firmware is for the Keyspan USA-49W Serial Adaptor
 
    "The firmware contained herein as keyspan_usa49w_fw.h is
-   Copyright (C) 1999-2000 Keyspan, A division of InnoSys Incorporated
+   Copyright (C) 1999-2001 Keyspan, A division of InnoSys Incorporated
    ("Keyspan"), as an unpublished work.  This notice does not imply
    unrestricted or public access to this firmware which is a trade secret of
    Keyspan, and which may not be reproduced, used, sold or transferred to any
@@ -18,440 +18,443 @@
 */
 
 static const struct ezusb_hex_record keyspan_usa49w_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x10, 0x36} },
-{ 0x0003,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
-{ 0x0013,	16,	{0x01, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
-{ 0x0023,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x0033,	3,	{0x02, 0x17, 0xf0} },
-{ 0x0036,	12,	{0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x0043,	3,	{0x02, 0x18, 0x00} },
-{ 0x0046,	16,	{0xe4, 0xff, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x27} },
-{ 0x0056,	16,	{0x24, 0x04, 0xfd, 0xe4, 0x35, 0x26, 0xfa, 0xa9, 0x05, 0x7b, 0x01, 0xef, 0x7c, 0x00, 0x29, 0xf9} },
-{ 0x0066,	16,	{0xec, 0x3a, 0xfa, 0xee, 0x12, 0x11, 0x90, 0x0f, 0xbf, 0x22, 0xd7, 0xe5, 0x27, 0x24, 0x05, 0xf5} },
-{ 0x0076,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x01, 0x4f, 0x7f, 0x01, 0xe5, 0x27} },
-{ 0x0086,	16,	{0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x15, 0x3d, 0xe5, 0x27} },
-{ 0x0096,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0x6c, 0xe5, 0x27} },
-{ 0x00a6,	16,	{0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x00, 0x03, 0xe5, 0x27} },
-{ 0x00b6,	16,	{0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x30, 0xf0, 0x7d, 0x04, 0x44} },
-{ 0x00c6,	16,	{0x20, 0xf0, 0xe5, 0x27, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x12} },
-{ 0x00d6,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xdf, 0xf0, 0x43} },
-{ 0x00e6,	16,	{0x05, 0xc0, 0xe5, 0x27, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x14} },
-{ 0x00f6,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xdf, 0xf0, 0x43} },
-{ 0x0106,	16,	{0x05, 0x0b, 0x80, 0x03, 0x43, 0x05, 0x02, 0x7f, 0x03, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x39} },
-{ 0x0116,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04} },
-{ 0x0126,	16,	{0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00} },
-{ 0x0136,	16,	{0xf0, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0146,	16,	{0xf5, 0x83, 0xe0, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
-{ 0x0156,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x32, 0xe5, 0x27, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0166,	16,	{0xf5, 0x83, 0xe0, 0x54, 0x3f, 0xff, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x0176,	16,	{0x83, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4} },
-{ 0x0186,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x0d, 0xf5, 0x82, 0xe4} },
-{ 0x0196,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x02, 0x6a, 0xe5, 0x27, 0x24, 0x17, 0xf5, 0x82} },
-{ 0x01a6,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x01b6,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4} },
-{ 0x01c6,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfb, 0xf0, 0xe4, 0xff, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82} },
-{ 0x01d6,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x0e, 0xf5, 0x82} },
-{ 0x01e6,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x01f6,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4} },
-{ 0x0206,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x0216,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x27, 0x24, 0x0f, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0226,	16,	{0xf5, 0x83, 0xe0, 0x60, 0x2f, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
-{ 0x0236,	16,	{0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x0246,	16,	{0xff, 0x12, 0x14, 0xdd, 0xe5, 0x27, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x0256,	16,	{0xff, 0x12, 0x15, 0x0d, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x0266,	16,	{0xff, 0x12, 0x14, 0xad, 0xe5, 0x27, 0x24, 0x14, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x0276,	16,	{0x60, 0x44, 0xe5, 0x27, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11} },
-{ 0x0286,	16,	{0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x80} },
-{ 0x0296,	16,	{0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xf0} },
-{ 0x02a6,	16,	{0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x02b6,	16,	{0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x12, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x02c6,	16,	{0x83, 0xe0, 0x60, 0x44, 0xe5, 0x27, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x02d6,	16,	{0x60, 0x11, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x02} },
-{ 0x02e6,	16,	{0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x02f6,	16,	{0xfd, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x0306,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x16, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x0316,	16,	{0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x27, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
-{ 0x0326,	16,	{0xef, 0xf0, 0xe5, 0x27, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe0} },
-{ 0x0336,	16,	{0x11, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x40, 0xf0} },
-{ 0x0346,	16,	{0x80, 0x0f, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xbf} },
-{ 0x0356,	16,	{0xf0, 0xe5, 0x27, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x27} },
-{ 0x0366,	16,	{0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x27, 0x24, 0x19, 0xf5} },
-{ 0x0376,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4} },
-{ 0x0386,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0f, 0xe5, 0x27, 0x24, 0x39, 0xf5, 0x82} },
-{ 0x0396,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5} },
-{ 0x03a6,	16,	{0x27, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5} },
-{ 0x03b6,	16,	{0x27, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x6b, 0xe5, 0x27, 0x24} },
-{ 0x03c6,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
-{ 0x03d6,	16,	{0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f} },
-{ 0x03e6,	16,	{0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0xfe} },
-{ 0x03f6,	16,	{0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x0406,	16,	{0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x2c, 0xf5, 0x82} },
-{ 0x0416,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x27, 0x24, 0x2b, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0426,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x0436,	16,	{0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x0446,	16,	{0x83, 0xe0, 0x60, 0x28, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x0456,	16,	{0x44, 0x02, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24, 0x2b, 0xf5, 0x82} },
-{ 0x0466,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x1c} },
-{ 0x0476,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82} },
-{ 0x0486,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x2c, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27} },
-{ 0x0496,	16,	{0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0} },
-{ 0x04a6,	16,	{0xe4, 0xff, 0x12, 0x14, 0x0c, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
-{ 0x04b6,	16,	{0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x04c6,	16,	{0x60, 0x27, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x40} },
-{ 0x04d6,	16,	{0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x04e6,	16,	{0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x1e, 0xf5, 0x82, 0xe4} },
-{ 0x04f6,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0506,	16,	{0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15, 0x3d, 0xe5, 0x27, 0x24} },
-{ 0x0516,	16,	{0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5} },
-{ 0x0526,	16,	{0x27, 0x24, 0x1f, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x27, 0x24} },
-{ 0x0536,	16,	{0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x27, 0x24, 0x32, 0xf5} },
-{ 0x0546,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x15} },
-{ 0x0556,	16,	{0x3d, 0xe5, 0x27, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28} },
-{ 0x0566,	16,	{0x42, 0x25, 0xe5, 0x27, 0x24, 0x20, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x70, 0x0e} },
-{ 0x0576,	16,	{0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x18, 0x90, 0x78} },
-{ 0x0586,	16,	{0x41, 0x74, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x0596,	16,	{0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x27, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x05a6,	16,	{0x83, 0xe0, 0x60, 0x0f, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x05b6,	16,	{0x44, 0x02, 0xf0, 0xe5, 0x27, 0x24, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60} },
-{ 0x05c6,	16,	{0x1f, 0xe5, 0x27, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5} },
-{ 0x05d6,	16,	{0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
-{ 0x05e6,	16,	{0xe5, 0x27, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x12, 0x17} },
-{ 0x05f6,	16,	{0x4e, 0xe5, 0x27, 0x24, 0x24, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x1b, 0xe5} },
-{ 0x0606,	16,	{0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f} },
-{ 0x0616,	16,	{0x98, 0xe0, 0xff, 0xe5, 0x28, 0xf4, 0xfe, 0xef, 0x5e, 0xf0, 0xe5, 0x27, 0x24, 0x25, 0xf5, 0x82} },
-{ 0x0626,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x60, 0x16, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x0636,	14,	{0x26, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x28, 0xf0} },
-{ 0x0644,	1,	{0x22} },
-{ 0x0645,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x11, 0xa2, 0x07, 0x42, 0x00, 0x07, 0xb6, 0x01, 0x08, 0x22, 0x03} },
-{ 0x0655,	16,	{0x06, 0x68, 0x06, 0x07, 0x35, 0x08, 0x07, 0x2f, 0x09, 0x07, 0x17, 0x0a, 0x07, 0x26, 0x0b, 0x00} },
-{ 0x0665,	16,	{0x00, 0x08, 0x71, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x19, 0x14, 0x60, 0x77, 0x24, 0x02} },
-{ 0x0675,	16,	{0x60, 0x03, 0x02, 0x07, 0x0d, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} },
-{ 0x0685,	16,	{0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82, 0x17, 0x75, 0x83, 0x19, 0xf0} },
-{ 0x0695,	16,	{0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe0, 0x04, 0x7f, 0x03, 0x80, 0x02, 0x7f, 0x02, 0x75, 0x82, 0x82} },
-{ 0x06a5,	16,	{0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x6d, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x66, 0x75} },
-{ 0x06b5,	16,	{0x83, 0x19, 0xf0, 0x75, 0x82, 0x5f, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x58, 0x75, 0x83, 0x19} },
-{ 0x06c5,	16,	{0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe1, 0x04, 0x7f, 0x64, 0x80, 0x02, 0x7f, 0x32, 0x75, 0x82} },
-{ 0x06d5,	16,	{0x1a, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x12, 0x90, 0x7f} },
-{ 0x06e5,	16,	{0xd5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x13, 0x54, 0xea, 0x49, 0x60} },
-{ 0x06f5,	16,	{0x0d, 0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f} },
-{ 0x0705,	16,	{0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02} },
-{ 0x0715,	16,	{0x08, 0x78, 0x90, 0x7f, 0x00, 0xe5, 0x0a, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08} },
-{ 0x0725,	16,	{0x78, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x0a, 0x02, 0x08, 0x78, 0x12, 0x0a, 0x6a, 0x02, 0x08, 0x78} },
-{ 0x0735,	16,	{0x90, 0x7f, 0x00, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xe8} },
-{ 0x0745,	16,	{0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33} },
-{ 0x0755,	16,	{0xff, 0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0} },
-{ 0x0765,	16,	{0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0} },
-{ 0x0775,	16,	{0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80} },
-{ 0x0785,	16,	{0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4} },
-{ 0x0795,	16,	{0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f} },
-{ 0x07a5,	16,	{0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08} },
-{ 0x07b5,	16,	{0x78, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x08, 0x78} },
-{ 0x07c5,	16,	{0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xb4, 0xe0} },
-{ 0x07d5,	16,	{0x44, 0x01, 0xf0, 0x02, 0x08, 0x78, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0} },
-{ 0x07e5,	16,	{0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4} },
-{ 0x07f5,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff} },
-{ 0x0805,	16,	{0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44} },
-{ 0x0815,	16,	{0x20, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8} },
-{ 0x0825,	16,	{0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04} },
-{ 0x0835,	16,	{0xd2, 0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea} },
-{ 0x0845,	16,	{0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0} },
-{ 0x0855,	16,	{0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01} },
-{ 0x0865,	16,	{0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0} },
-{ 0x0875,	10,	{0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
-{ 0x087f,	1,	{0x22} },
-{ 0x0880,	16,	{0xe5, 0x23, 0x54, 0x0f, 0x70, 0x03, 0x02, 0x09, 0x5f, 0x12, 0x15, 0x9b, 0xef, 0x20, 0xe1, 0x63} },
-{ 0x0890,	16,	{0x12, 0x15, 0xf9, 0xef, 0x14, 0xf5, 0x1a, 0x12, 0x17, 0xc1, 0xef, 0x25, 0x1a, 0xff, 0xe4, 0x33} },
-{ 0x08a0,	16,	{0xfe, 0xc3, 0xef, 0x94, 0x80, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x47, 0x85, 0x27, 0x82, 0x85} },
-{ 0x08b0,	16,	{0x26, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5} },
-{ 0x08c0,	16,	{0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f} },
-{ 0x08d0,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0x85} },
-{ 0x08e0,	16,	{0x1a, 0x08, 0xef, 0x24, 0x01, 0xf5, 0x10, 0xe4, 0x3e, 0xf5, 0x0f, 0x12, 0x13, 0xd6, 0xe4, 0xff} },
-{ 0x08f0,	16,	{0x12, 0x14, 0x0c, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30} },
-{ 0x0900,	16,	{0xe7, 0x5d, 0x12, 0x17, 0xc1, 0xe5, 0x27, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
-{ 0x0910,	16,	{0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x48, 0xe5, 0x27, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0920,	16,	{0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
-{ 0x0930,	16,	{0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4} },
-{ 0x0940,	16,	{0xf0, 0xe5, 0x28, 0x42, 0x25, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x10, 0xe5, 0x27, 0x24, 0x26} },
-{ 0x0950,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xf5, 0x09, 0x80, 0x03, 0x12, 0x12, 0x3d, 0x12} },
-{ 0x0960,	16,	{0x15, 0xca, 0xef, 0x30, 0xe1, 0x03, 0x02, 0x0a, 0x69, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4} },
-{ 0x0970,	16,	{0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x80, 0xf0, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x0980,	16,	{0x26, 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x17, 0xcd, 0xee, 0x4f, 0xd0, 0x82} },
-{ 0x0990,	16,	{0xd0, 0x83, 0xf0, 0x12, 0x16, 0xd1, 0x8f, 0x1a, 0xe5, 0x27, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x09a0,	16,	{0x26, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x28, 0x12, 0x17, 0xa9, 0xef, 0x30, 0xe0} },
-{ 0x09b0,	16,	{0x21, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x20, 0xe7, 0x12} },
-{ 0x09c0,	16,	{0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x03, 0x02} },
-{ 0x09d0,	16,	{0x0a, 0x69, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0xfd} },
-{ 0x09e0,	16,	{0xf0, 0xe5, 0x1a, 0x70, 0x0e, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
-{ 0x09f0,	16,	{0xe4, 0xf0, 0x22, 0xe5, 0x27, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff} },
-{ 0x0a00,	16,	{0x30, 0xe7, 0x29, 0xe5, 0x1a, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x1a, 0x20, 0x85, 0x1a, 0x08} },
-{ 0x0a10,	16,	{0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0x8c, 0x0f, 0xf5, 0x10} },
-{ 0x0a20,	16,	{0x12, 0x13, 0x06, 0xe5, 0x1a, 0x25, 0xe0, 0xff, 0x12, 0x14, 0x42, 0x22, 0xe5, 0x1a, 0xd3, 0x94} },
-{ 0x0a30,	16,	{0x3f, 0x40, 0x03, 0x75, 0x1a, 0x3f, 0x85, 0x1a, 0x08, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3} },
-{ 0x0a40,	16,	{0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x85, 0x27, 0x82, 0x85, 0x26} },
-{ 0x0a50,	16,	{0x83, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x24, 0x01, 0xf5, 0x10, 0xe4, 0x3e, 0xf5, 0x0f, 0x12} },
-{ 0x0a60,	9,	{0x13, 0x95, 0xe5, 0x1a, 0x04, 0xff, 0x12, 0x14, 0x42} },
-{ 0x0a69,	1,	{0x22} },
-{ 0x0a6a,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4} },
-{ 0x0a7a,	16,	{0x90, 0x7f, 0x94, 0xf0, 0x90, 0x78, 0x4a, 0x04, 0xf0, 0xf5, 0x8e, 0x90, 0x7f, 0x95, 0x74, 0xc0} },
-{ 0x0a8a,	16,	{0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98, 0x74, 0x1f, 0xf0, 0x90, 0x78, 0x43} },
-{ 0x0a9a,	16,	{0x74, 0xff, 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x7f, 0xdf, 0x74, 0x9f, 0xf0, 0x90, 0x7f} },
-{ 0x0aaa,	16,	{0xde, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b} },
-{ 0x0aba,	16,	{0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x0e, 0xb3, 0x7e} },
-{ 0x0aca,	16,	{0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75} },
-{ 0x0ada,	16,	{0x28, 0x01, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0, 0x7e} },
-{ 0x0aea,	16,	{0x7e, 0x7f, 0x40, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x40, 0xf0} },
-{ 0x0afa,	16,	{0x7e, 0x7e, 0x7f, 0x80, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3} },
-{ 0x0b0a,	16,	{0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x00, 0x90, 0x7f, 0x96} },
-{ 0x0b1a,	16,	{0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x0e, 0xb3, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c} },
-{ 0x0b2a,	16,	{0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0xe5, 0x27, 0x24, 0x26} },
-{ 0x0b3a,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x7e, 0x7d, 0x7f, 0xc0, 0x85, 0x27} },
-{ 0x0b4a,	16,	{0x82, 0x85, 0x26, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0xc0, 0xf0, 0x7e, 0x7e, 0x7f, 0x00, 0x85} },
-{ 0x0b5a,	16,	{0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0x7e, 0x7c} },
-{ 0x0b6a,	16,	{0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28} },
-{ 0x0b7a,	16,	{0x04, 0x12, 0x0e, 0xb3, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f} },
-{ 0x0b8a,	16,	{0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0b9a,	16,	{0xf5, 0x83, 0x74, 0x02, 0xf0, 0x7e, 0x7d, 0x7f, 0x40, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74} },
-{ 0x0baa,	16,	{0x7d, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7d, 0x7f, 0x80, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83} },
-{ 0x0bba,	16,	{0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c} },
-{ 0x0bca,	16,	{0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x0e, 0xb3, 0x7e} },
-{ 0x0bda,	16,	{0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75} },
-{ 0x0bea,	16,	{0x28, 0x08, 0xe5, 0x27, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x03, 0xf0} },
-{ 0x0bfa,	16,	{0x7e, 0x7c, 0x7f, 0xc0, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0x74, 0x7c, 0xf0, 0xa3, 0x74, 0xc0} },
-{ 0x0c0a,	16,	{0xf0, 0x7e, 0x7d, 0x7f, 0x00, 0x85, 0x27, 0x82, 0x85, 0x26, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0} },
-{ 0x0c1a,	7,	{0xa3, 0x74, 0x00, 0xf0, 0xd2, 0x02, 0x22} },
-{ 0x0c21,	16,	{0xe5, 0x22, 0x04, 0x54, 0x03, 0xf5, 0x22, 0x14, 0x60, 0x1f, 0x14, 0x60, 0x31, 0x14, 0x60, 0x43} },
-{ 0x0c31,	16,	{0x24, 0x03, 0x70, 0x52, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f} },
-{ 0x0c41,	16,	{0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x80, 0x3d, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c} },
-{ 0x0c51,	16,	{0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x80, 0x28, 0x7e, 0x7c} },
-{ 0x0c61,	16,	{0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28} },
-{ 0x0c71,	16,	{0x04, 0x80, 0x13, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96} },
-{ 0x0c81,	16,	{0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0xe5, 0x15, 0x55, 0x28, 0x70, 0x03, 0x02, 0x0d, 0xbf, 0xe5} },
-{ 0x0c91,	16,	{0x28, 0xf4, 0xff, 0x52, 0x15, 0xe5, 0x0b, 0x54, 0x7f, 0xfe, 0x70, 0x0f, 0xe5, 0x0d, 0x55, 0x28} },
-{ 0x0ca1,	16,	{0x60, 0x24, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x28, 0xf0, 0x80, 0x1b, 0xbe, 0x20, 0x18, 0xe5, 0x27} },
-{ 0x0cb1,	16,	{0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe3, 0x09, 0xe4, 0xf5, 0x0d} },
-{ 0x0cc1,	16,	{0x90, 0x7f, 0x98, 0xe0, 0x5f, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x0cd1,	16,	{0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe5, 0x27, 0x24, 0x34, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0ce1,	16,	{0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe0, 0x60, 0x03, 0x02, 0x0d, 0xbf, 0x74, 0x0a} },
-{ 0x0cf1,	16,	{0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0x01, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x2c, 0xf5, 0x82} },
-{ 0x0d01,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x1a, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
-{ 0x0d11,	16,	{0x12, 0x17, 0xd9, 0x8f, 0x1a, 0xe5, 0x27, 0x24, 0x27, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83} },
-{ 0x0d21,	16,	{0xe0, 0xff, 0xe5, 0x1a, 0x54, 0x10, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
-{ 0x0d31,	16,	{0xe5, 0x27, 0x24, 0x28, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1a, 0x54} },
-{ 0x0d41,	16,	{0x80, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x27, 0x24, 0x29, 0xf5} },
-{ 0x0d51,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x1a, 0x54, 0x20, 0xfe, 0x6f, 0x60, 0x15} },
-{ 0x0d61,	16,	{0xee, 0xf0, 0xe5, 0x27, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe4} },
-{ 0x0d71,	16,	{0x04, 0xe5, 0x28, 0x42, 0x25, 0xe5, 0x24, 0x55, 0x28, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x2a} },
-{ 0x0d81,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x16, 0xe5, 0x1a, 0xf0, 0xe5, 0x27} },
-{ 0x0d91,	16,	{0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x30, 0xe5, 0x04, 0xe5, 0x28, 0x42} },
-{ 0x0da1,	16,	{0x25, 0xe5, 0x29, 0x55, 0x28, 0xff, 0xf5, 0x1a, 0xe5, 0x27, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x0db1,	14,	{0x26, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x1a, 0xf0, 0xe5, 0x28, 0x42, 0x25} },
-{ 0x0dbf,	1,	{0x22} },
-{ 0x0dc0,	16,	{0xe5, 0x09, 0x14, 0x60, 0x2a, 0x14, 0x60, 0x41, 0x14, 0x60, 0x58, 0x14, 0x60, 0x6f, 0x24, 0x04} },
-{ 0x0dd0,	16,	{0x60, 0x03, 0x02, 0x0e, 0x77, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90} },
-{ 0x0de0,	16,	{0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x01, 0x22, 0x7e} },
-{ 0x0df0,	16,	{0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75} },
-{ 0x0e00,	16,	{0x28, 0x02, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x02, 0x22, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c} },
-{ 0x0e10,	16,	{0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0x12, 0x12, 0x3d, 0x75} },
-{ 0x0e20,	16,	{0x09, 0x03, 0x22, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96} },
-{ 0x0e30,	16,	{0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x12, 0x3d, 0x75, 0x09, 0x04, 0x22, 0x30, 0x04, 0x33} },
-{ 0x0e40,	16,	{0xc2, 0x04, 0x53, 0x25, 0xdf, 0xe4, 0xf5, 0x1a, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x11, 0x25, 0x1a} },
-{ 0x0e50,	16,	{0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0x4a, 0xff, 0x74, 0x80, 0x25, 0x1a, 0xf5, 0x82, 0xe4} },
-{ 0x0e60,	16,	{0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x1a, 0xe5, 0x1a, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3} },
-{ 0x0e70,	16,	{0x74, 0x03, 0xf0, 0x75, 0x09, 0x05, 0x22, 0xe5, 0x17, 0x60, 0x34, 0xd5, 0x17, 0x03, 0x53, 0x25} },
-{ 0x0e80,	16,	{0xef, 0xe4, 0xf5, 0x1a, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x16, 0x25, 0x1a, 0xf9, 0xee, 0x34, 0x00} },
-{ 0x0e90,	16,	{0xfa, 0x12, 0x11, 0x4a, 0xff, 0x74, 0x80, 0x25, 0x1a, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83} },
-{ 0x0ea0,	16,	{0xef, 0xf0, 0x05, 0x1a, 0xe5, 0x1a, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4} },
-{ 0x0eb0,	2,	{0xf5, 0x09} },
-{ 0x0eb2,	1,	{0x22} },
-{ 0x0eb3,	16,	{0xe4, 0xf5, 0x19, 0x7e, 0x00, 0x7b, 0x01, 0xe5, 0x27, 0x25, 0x19, 0xf9, 0xee, 0x35, 0x26, 0xfa} },
-{ 0x0ec3,	16,	{0xe4, 0x12, 0x11, 0x90, 0x05, 0x19, 0xe5, 0x19, 0xb4, 0x3c, 0xe8, 0xe5, 0x27, 0x24, 0x35, 0xf5} },
-{ 0x0ed3,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5} },
-{ 0x0ee3,	16,	{0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00} },
-{ 0x0ef3,	16,	{0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x15, 0x3d, 0x7f, 0x10, 0xe5, 0x27, 0x24, 0x33, 0xf5, 0x82} },
-{ 0x0f03,	16,	{0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0x12, 0x14, 0xad, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0} },
-{ 0x0f13,	16,	{0x7f, 0x01, 0xe5, 0x27, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xef, 0xf0, 0x44} },
-{ 0x0f23,	16,	{0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x27, 0x24, 0x39, 0xf5} },
-{ 0x0f33,	16,	{0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, 0xfd} },
-{ 0x0f43,	16,	{0x12, 0x15, 0x3d, 0xe4, 0xff, 0x7e, 0xa3, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26} },
-{ 0x0f53,	16,	{0xf5, 0x83, 0xee, 0xf0, 0xfd, 0x12, 0x15, 0x3d, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0} },
-{ 0x0f63,	16,	{0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x15, 0x3d, 0x7f, 0x01, 0x12, 0x14, 0x78, 0x7f} },
-{ 0x0f73,	6,	{0x03, 0x7d, 0x07, 0x12, 0x15, 0x3d} },
-{ 0x0f79,	1,	{0x22} },
-{ 0x0f7a,	16,	{0x53, 0x25, 0x3f, 0x90, 0x7b, 0xf1, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x26} },
-{ 0x0f8a,	16,	{0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x28, 0x01, 0x12, 0x08, 0x80} },
-{ 0x0f9a,	16,	{0x90, 0x7c, 0x31, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27} },
-{ 0x0faa,	16,	{0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x08, 0x80, 0x90, 0x7c, 0x71} },
-{ 0x0fba,	16,	{0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f} },
-{ 0x0fca,	16,	{0x96, 0x74, 0xbf, 0xf0, 0x75, 0x28, 0x04, 0x12, 0x08, 0x80, 0x90, 0x7c, 0xb1, 0xe0, 0x30, 0xe3} },
-{ 0x0fda,	16,	{0x16, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f} },
-{ 0x0fea,	16,	{0xf0, 0x75, 0x28, 0x08, 0x12, 0x08, 0x80, 0x05, 0x23, 0xe5, 0x23, 0x54, 0x0f, 0xf5, 0x19, 0x70} },
-{ 0x0ffa,	16,	{0x1f, 0x90, 0x78, 0x41, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf5, 0x29, 0x90, 0x78} },
-{ 0x100a,	16,	{0x41, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f, 0x99, 0xe0, 0xf4, 0xf5, 0x24, 0x12, 0x10, 0xc2, 0x22} },
-{ 0x101a,	16,	{0xe5, 0x19, 0xb4, 0x01, 0x04, 0x12, 0x0c, 0x21, 0x22, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x08} },
-{ 0x102a,	11,	{0xe5, 0x25, 0x60, 0x04, 0x12, 0x0d, 0xc0, 0x22, 0x12, 0x0c, 0x21} },
-{ 0x1035,	1,	{0x22} },
-{ 0x1036,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x29, 0x02, 0x10, 0x7d} },
-{ 0x1042,	16,	{0x02, 0x11, 0xc8, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x1052,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x1062,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x1072,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x17, 0x67, 0xe4, 0x7e} },
-{ 0x1082,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x1092,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x10a2,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x10b2,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x10c2,	16,	{0x90, 0x7f, 0xd2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0x49, 0x90, 0x7b, 0x40, 0xe0, 0x14, 0x60} },
-{ 0x10d2,	16,	{0x26, 0x14, 0x60, 0x3b, 0x14, 0x60, 0x50, 0x24, 0x83, 0x60, 0x64, 0x24, 0x80, 0x70, 0x63, 0x7e} },
-{ 0x10e2,	16,	{0x7b, 0x7f, 0xc0, 0x75, 0x26, 0x7b, 0x75, 0x27, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75} },
-{ 0x10f2,	16,	{0x28, 0x01, 0x12, 0x00, 0x46, 0x80, 0x4b, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x26, 0x7c, 0x75, 0x27} },
-{ 0x1102,	16,	{0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x28, 0x02, 0x12, 0x00, 0x46, 0x80, 0x33, 0x7e} },
-{ 0x1112,	16,	{0x7c, 0x7f, 0x40, 0x75, 0x26, 0x7c, 0x75, 0x27, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75} },
-{ 0x1122,	16,	{0x28, 0x04, 0x12, 0x00, 0x46, 0x80, 0x1b, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x26, 0x7c, 0x75, 0x27} },
-{ 0x1132,	16,	{0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x28, 0x08, 0x12, 0x00, 0x46, 0x80, 0x03, 0x12} },
-{ 0x1142,	8,	{0x16, 0x56, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x22} },
-{ 0x114a,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x115a,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x1163,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x1173,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x1183,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x1190,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01} },
-{ 0x11a0,	2,	{0xf3, 0x22} },
-{ 0x11a2,	16,	{0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3} },
-{ 0x11b2,	16,	{0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60} },
-{ 0x11c2,	6,	{0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf} },
-{ 0x11c8,	16,	{0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x00, 0xe4, 0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8} },
-{ 0x11d8,	16,	{0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab} },
-{ 0x11e8,	16,	{0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x11f8,	16,	{0xaf, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d, 0xf0, 0xd2, 0xaf, 0xd2, 0x09, 0x12, 0x17} },
-{ 0x1208,	16,	{0x13, 0xc2, 0x01, 0xe4, 0xf5, 0x0e, 0xf5, 0x14, 0xc2, 0x07, 0xc2, 0x02, 0x90, 0x7f, 0xd8, 0xe0} },
-{ 0x1218,	16,	{0x65, 0x0b, 0x60, 0x06, 0x75, 0x15, 0x0f, 0xe0, 0xf5, 0x0b, 0x30, 0x02, 0x03, 0x12, 0x0f, 0x7a} },
-{ 0x1228,	16,	{0x30, 0x01, 0x07, 0xc2, 0x01, 0x12, 0x06, 0x45, 0x80, 0xe2, 0x30, 0x08, 0xdf, 0xc2, 0x08, 0x12} },
-{ 0x1238,	5,	{0x17, 0x95, 0x80, 0xd8, 0x22} },
-{ 0x123d,	16,	{0xe5, 0x25, 0x55, 0x28, 0x60, 0x6a, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x124d,	16,	{0x83, 0xe0, 0x70, 0x5c, 0xe5, 0x28, 0xf4, 0x52, 0x25, 0xe5, 0x27, 0x24, 0x26, 0xff, 0xe4, 0x35} },
-{ 0x125d,	16,	{0x26, 0xfe, 0xe4, 0xfd, 0x0f, 0xef, 0xaa, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8a, 0x83} },
-{ 0x126d,	16,	{0xe0, 0xfc, 0x74, 0x80, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0xbd} },
-{ 0x127d,	16,	{0x0b, 0xe2, 0x90, 0x7f, 0xc3, 0x74, 0x0b, 0xf0, 0xe5, 0x27, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x128d,	16,	{0x26, 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xe5, 0x27, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x129d,	16,	{0x83, 0xe4, 0xf0, 0xe5, 0x27, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe4, 0xf0} },
-{ 0x12ad,	1,	{0x22} },
-{ 0x12ae,	16,	{0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4} },
-{ 0x12be,	16,	{0x90, 0x78, 0x4a, 0xf0, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90} },
-{ 0x12ce,	16,	{0x7f, 0x97, 0xf0, 0xe5, 0x0c, 0x54, 0xf0, 0x44, 0x08, 0x90, 0x78, 0x41, 0xf0, 0xe4, 0x90, 0x7f} },
-{ 0x12de,	16,	{0x98, 0xf0, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x98} },
-{ 0x12ee,	16,	{0xf0, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0xe4, 0x90, 0x7f, 0x96, 0xf0} },
-{ 0x12fe,	8,	{0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x22} },
-{ 0x1306,	16,	{0x8f, 0x1b, 0x05, 0x10, 0xe5, 0x10, 0xae, 0x0f, 0x70, 0x02, 0x05, 0x0f, 0x14, 0xf5, 0x82, 0x8e} },
-{ 0x1316,	16,	{0x83, 0xe5, 0x1b, 0xf0, 0x12, 0x17, 0xe5, 0x05, 0x10, 0xe5, 0x10, 0xac, 0x0f, 0x70, 0x02, 0x05} },
-{ 0x1326,	16,	{0x0f, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x08, 0xe5, 0x08, 0x60, 0x1f, 0xe5, 0x27} },
-{ 0x1336,	16,	{0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12} },
-{ 0x1346,	14,	{0x17, 0xcd, 0x8f, 0x1b, 0xee, 0x4f, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x80, 0xb5, 0x22} },
-{ 0x1354,	2,	{0x8f, 0x19} },
-{ 0x1356,	16,	{0xe4, 0xf5, 0x1a, 0x75, 0x1b, 0xff, 0x75, 0x1c, 0x19, 0x75, 0x1d, 0x86, 0xab, 0x1b, 0xaa, 0x1c} },
-{ 0x1366,	16,	{0xa9, 0x1d, 0x90, 0x00, 0x01, 0x12, 0x11, 0x63, 0xb4, 0x03, 0x1d, 0xaf, 0x1a, 0x05, 0x1a, 0xef} },
-{ 0x1376,	16,	{0xb5, 0x19, 0x01, 0x22, 0x12, 0x11, 0x4a, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x1386,	14,	{0x1b, 0xff, 0xf5, 0x1c, 0x89, 0x1d, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x1394,	1,	{0x22} },
-{ 0x1395,	16,	{0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x78, 0x4f, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x50, 0xf0} },
-{ 0x13a5,	16,	{0xe5, 0x0f, 0x90, 0x78, 0x51, 0xf0, 0xae, 0x0f, 0xe5, 0x10, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78} },
-{ 0x13b5,	16,	{0x54, 0xe5, 0x08, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x10} },
-{ 0x13c5,	16,	{0xf0, 0xe0, 0x54, 0xf7, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa} },
-{ 0x13d5,	1,	{0x22} },
-{ 0x13d6,	16,	{0xe4, 0x90, 0x78, 0x41, 0xf0, 0xe5, 0x0f, 0x90, 0x78, 0x4f, 0xf0, 0xae, 0x0f, 0xe5, 0x10, 0x90} },
-{ 0x13e6,	16,	{0x78, 0x50, 0xf0, 0x90, 0x78, 0x51, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78} },
-{ 0x13f6,	16,	{0x54, 0xe5, 0x08, 0xf0, 0x90, 0x78, 0x57, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90} },
-{ 0x1406,	6,	{0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22} },
-{ 0x140c,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14} },
-{ 0x141c,	16,	{0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f} },
-{ 0x142c,	16,	{0xc9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xcb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xcd, 0xef} },
-{ 0x143c,	6,	{0xf0, 0xe5, 0x28, 0x42, 0x0d, 0x22} },
-{ 0x1442,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14} },
-{ 0x1452,	16,	{0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xb7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f} },
-{ 0x1462,	16,	{0xb9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xbb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xbd, 0xef} },
-{ 0x1472,	6,	{0xf0, 0xe5, 0x28, 0x42, 0x0d, 0x22} },
-{ 0x1478,	16,	{0xae, 0x07, 0xe4, 0xff, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0} },
-{ 0x1488,	16,	{0x54, 0x7f, 0xfd, 0x12, 0x15, 0x3d, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xee} },
-{ 0x1498,	16,	{0xf0, 0xe4, 0xe5, 0x27, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x44, 0x80} },
-{ 0x14a8,	5,	{0xfd, 0x12, 0x15, 0x3d, 0x22} },
-{ 0x14ad,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
-{ 0x14bd,	16,	{0x02, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
-{ 0x14cd,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x14dd,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
-{ 0x14ed,	16,	{0x04, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
-{ 0x14fd,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x150d,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74} },
-{ 0x151d,	16,	{0x06, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24} },
-{ 0x152d,	16,	{0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x153d,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5} },
-{ 0x154d,	16,	{0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x07, 0xf0, 0x90, 0xc0} },
-{ 0x155d,	15,	{0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xed, 0xf0, 0x22} },
-{ 0x156c,	16,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0xe4, 0x90, 0x78, 0x41} },
-{ 0x157c,	16,	{0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x27, 0x24, 0x37} },
-{ 0x158c,	15,	{0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22} },
-{ 0x159b,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} },
-{ 0x15ab,	16,	{0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc8} },
-{ 0x15bb,	15,	{0xe0, 0xff, 0x22, 0x90, 0x7f, 0xca, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcc, 0xe0, 0xff, 0x22} },
-{ 0x15ca,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} },
-{ 0x15da,	16,	{0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xb6, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xb8} },
-{ 0x15ea,	15,	{0xe0, 0xff, 0x22, 0x90, 0x7f, 0xba, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xbc, 0xe0, 0xff, 0x22} },
-{ 0x15f9,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e, 0x14} },
-{ 0x1609,	16,	{0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xc9} },
-{ 0x1619,	15,	{0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcb, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcd, 0xe0, 0xff, 0x22} },
-{ 0x1628,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x30} },
-{ 0x1638,	16,	{0x05, 0x04, 0xc2, 0x05, 0x80, 0x02, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08} },
-{ 0x1648,	14,	{0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1656,	16,	{0x90, 0x7b, 0x41, 0xe0, 0xf5, 0x17, 0x43, 0x25, 0x10, 0xa3, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7} },
-{ 0x1666,	16,	{0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0x90, 0x7b, 0x43, 0xe0, 0xf5, 0x18, 0x30, 0x00, 0x07, 0xa3} },
-{ 0x1676,	10,	{0xe0, 0x54, 0xf0, 0xf5, 0x0c, 0x22, 0xe4, 0xf5, 0x0c, 0x22} },
-{ 0x1680,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90} },
-{ 0x1690,	16,	{0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0} },
-{ 0x16a0,	10,	{0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x16aa,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xd2} },
-{ 0x16ba,	16,	{0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85} },
-{ 0x16ca,	7,	{0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x16d1,	16,	{0x12, 0x17, 0xb5, 0xae, 0x07, 0x12, 0x17, 0xb5, 0xad, 0x07, 0xee, 0x6d, 0x60, 0x10, 0x12, 0x17} },
-{ 0x16e1,	16,	{0xb5, 0xae, 0x07, 0xee, 0x6d, 0x60, 0x07, 0x12, 0x17, 0xb5, 0xad, 0x07, 0x80, 0xec, 0xaf, 0x06} },
-{ 0x16f1,	1,	{0x22} },
-{ 0x16f2,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x1702,	1,	{0x22} },
-{ 0x1703,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x1713,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x04, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x09, 0x04, 0xe0, 0x44} },
-{ 0x1723,	16,	{0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x17, 0x34, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x1733,	1,	{0x22} },
-{ 0x1734,	16,	{0x8e, 0x19, 0x8f, 0x1a, 0xe5, 0x1a, 0x15, 0x1a, 0xae, 0x19, 0x70, 0x02, 0x15, 0x19, 0x4e, 0x60} },
-{ 0x1744,	10,	{0x08, 0x12, 0x16, 0xf2, 0x12, 0x16, 0xf2, 0x80, 0xeb, 0x22} },
-{ 0x174e,	16,	{0xe5, 0x27, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x26, 0xf5, 0x83, 0xe0, 0x04, 0xff, 0x44, 0x10} },
-{ 0x175e,	9,	{0x90, 0x7f, 0xd7, 0xf0, 0xef, 0x44, 0x30, 0xf0, 0x22} },
-{ 0x1767,	16,	{0x03, 0x16, 0x80, 0x00, 0x00, 0x03, 0x11, 0x81, 0x00, 0x00, 0xc1, 0x85, 0xc1, 0x81, 0xc1, 0x08} },
-{ 0x1777,	7,	{0xc1, 0x00, 0xc1, 0x86, 0x01, 0x09, 0x00} },
-{ 0x177e,	1,	{0x00} },
-{ 0x177f,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x17, 0x34, 0x90, 0x7f} },
-{ 0x178f,	6,	{0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22} },
-{ 0x1795,	16,	{0x12, 0x12, 0xae, 0x12, 0x17, 0x03, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x03, 0x12, 0x17, 0x7f} },
-{ 0x17a5,	4,	{0x12, 0x0a, 0x6a, 0x22} },
-{ 0x17a9,	12,	{0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x17b5,	12,	{0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x17c1,	12,	{0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x17cd,	12,	{0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x17d9,	12,	{0x90, 0x78, 0x41, 0x74, 0x06, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x17e5,	11,	{0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22} },
-{ 0x17f0,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x1800,	15,	{0x02, 0x16, 0xaa, 0x00, 0x02, 0x18, 0x04, 0x00, 0x02, 0x16, 0x80, 0x00, 0x02, 0x16, 0x28} },
-{ 0x1900,	16,	{0x12, 0x01, 0x01, 0x00, 0xff, 0x00, 0x00, 0x40, 0xcd, 0x06, 0x0a, 0x01, 0x00, 0x00, 0x01, 0x02} },
-{ 0x1910,	16,	{0x00, 0x04, 0x09, 0x02, 0x74, 0x00, 0x01, 0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e} },
-{ 0x1920,	16,	{0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40} },
-{ 0x1930,	16,	{0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00} },
-{ 0x1940,	16,	{0x07, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05} },
-{ 0x1950,	16,	{0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02} },
-{ 0x1960,	16,	{0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00} },
-{ 0x1970,	16,	{0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07} },
-{ 0x1980,	16,	{0x05, 0x87, 0x02, 0x40, 0x00, 0x01, 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00} },
-{ 0x1990,	16,	{0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00} },
-{ 0x19a0,	16,	{0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00} },
-{ 0x19b0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00} },
-{ 0x19c0,	16,	{0x6f, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00} },
-{ 0x19d0,	16,	{0x2e, 0x00, 0x36, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61, 0x00} },
-{ 0x19e0,	16,	{0x6e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00} },
-{ 0x19f0,	16,	{0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00} },
-{ 0x1a00,	10,	{0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00} },
+ {0x7f92,  1, { 0x01}},
+ {0x0033,  3, { 0x02, 0x18, 0xfc}},
+ {0x0036, 12, { 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22}},
+ {0x0046, 16, { 0xe4, 0xff, 0x74, 0x40, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xe0, 0xfe, 0xe5, 0x15}},
+ {0x0056, 16, { 0x24, 0x04, 0xfd, 0xe4, 0x35, 0x14, 0xfa, 0xa9, 0x05, 0x7b, 0x01, 0xef, 0x7c, 0x00, 0x29, 0xf9}},
+ {0x0066, 16, { 0xec, 0x3a, 0xfa, 0xee, 0x12, 0x11, 0xf6, 0x0f, 0xbf, 0x22, 0xd7, 0xe5, 0x15, 0x24, 0x05, 0xf5}},
+ {0x0076, 16, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x01, 0x34, 0xe5, 0x15, 0x24, 0x09}},
+ {0x0086, 16, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x0a, 0xf5, 0x82}},
+ {0x0096, 16, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x18, 0x7f, 0x01, 0xe4, 0xfd, 0x12, 0x16, 0x4c, 0xe5}},
+ {0x00a6, 16, { 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xcf, 0xf0, 0x80, 0x41}},
+ {0x00b6, 16, { 0xe5, 0x15, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x7b}},
+ {0x00c6, 16, { 0xe5, 0x15, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x00, 0x03}},
+ {0x00d6, 16, { 0x7f, 0x01, 0xe5, 0x15, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12}},
+ {0x00e6, 16, { 0x16, 0x4c, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x30}},
+ {0x00f6, 16, { 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0}},
+ {0x0003, 16, { 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74}},
+ {0x0013, 16, { 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24}},
+ {0x0023, 16, { 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22}},
+ {0x0043,  3, { 0x02, 0x1b, 0x00}},
+ {0x0000,  3, { 0x02, 0x10, 0x9a}},
+ {0x0106, 64, { 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24,
+  0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x32, 0xe5, 0x15, 0x24, 0x0c}},
+ {0x0146, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x3f, 0xff, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24,
+  0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24,
+  0x0d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02, 0x02, 0x4f, 0xe5}},
+ {0x0186, 64, { 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x32,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24,
+  0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfb, 0xf0, 0xe4, 0xff, 0xe5, 0x15,
+  0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfd, 0x12, 0x16, 0x4c, 0xe5}},
+ {0x01c6, 64, { 0x15, 0x24, 0x0e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x33,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24,
+  0x33, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x15, 0x24, 0x33,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x15, 0x24, 0x0f}},
+ {0x0206, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2f, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xec, 0xe5, 0x15, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x16, 0x1c, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82, 0xe4}},
+ {0x0246, 64, { 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x15, 0xbc, 0xe5, 0x15, 0x24, 0x14, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0,
+  0x44, 0x01, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}},
+ {0x0286, 64, { 0x83, 0xe0, 0x54, 0xfe, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x12, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x44, 0xe5, 0x15, 0x24, 0x13, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14}},
+ {0x02c6, 64, { 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x16,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82}},
+ {0x0306, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x15, 0x24, 0x17, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x44, 0x40, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x54, 0xbf, 0xf0, 0xe5, 0x15, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}},
+ {0x0346, 64, { 0x83, 0xe0, 0xff, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0xe5,
+  0x15, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x11, 0xe5, 0x15, 0x24,
+  0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x10, 0xf0, 0x80, 0x0f, 0xe5, 0x15,
+  0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x78}},
+ {0x0386, 64, { 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x90,
+  0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60,
+  0x6b, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xbf, 0xf0,
+  0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14}},
+ {0x03c6, 64, { 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x12, 0x00,
+  0x36, 0xef, 0x54, 0xfe, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x4c, 0xe5, 0x15,
+  0x24, 0x2c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x15, 0x24, 0x2b}},
+ {0x0406, 64, { 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1b,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x4c, 0xe5}},
+ {0x0446, 64, { 0x15, 0x24, 0x2b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5, 0x16, 0x42, 0x13,
+  0xe5, 0x15, 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x70, 0x0e, 0xe5,
+  0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x2a, 0x90, 0x78, 0x41,
+  0x74, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}},
+ {0x0486, 64, { 0x44, 0x04, 0x90, 0xc0, 0x00, 0xf0, 0xef, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x44, 0x40, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5}},
+ {0x04c6, 64, { 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x1e,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x28, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfe, 0xff, 0xf0, 0xfd, 0xe4, 0xff, 0x12, 0x16, 0x4c,
+  0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xe5}},
+ {0x0506, 64, { 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x1f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x70, 0x0e,
+  0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x27, 0xe5, 0x15,
+  0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xff, 0xf0, 0xfd, 0xe4,
+  0xff, 0x12, 0x16, 0x4c, 0xe5, 0x15, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83}},
+ {0x0546, 64, { 0xe4, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x20, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x70, 0x0e, 0xe5, 0x15, 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60,
+  0x18, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x44, 0x02, 0x90, 0xc0, 0x00, 0xf0, 0xe5, 0x15, 0x24, 0x21, 0xf5, 0x82}},
+ {0x0586, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x15, 0x24, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74,
+  0x01, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0}},
+ {0x05c6, 64, { 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60,
+  0x03, 0x12, 0x18, 0x91, 0xe5, 0x15, 0x24, 0x24, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0,
+  0x60, 0x1b, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x08,
+  0xf0, 0x90, 0x7f, 0x98, 0xe0, 0xff, 0xe5, 0x16, 0xf4, 0xfe, 0xef, 0x5e, 0xf0, 0xe5, 0x15}},
+ {0x0606, 64, { 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x60, 0x16, 0xe5, 0x15, 0x24, 0x31, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x16,
+  0xf0, 0x22, 0x90, 0x7f, 0xe9, 0xe0, 0x12, 0x12, 0x08, 0x07, 0x83, 0x00, 0x07, 0xf7, 0x01, 0x08,
+  0x63, 0x03, 0x06, 0x4c, 0x06, 0x07, 0x74, 0x08, 0x07, 0x68, 0x09, 0x07, 0x50, 0x0a, 0x07}},
+ {0x0646, 64, { 0x5f, 0x0b, 0x00, 0x00, 0x08, 0xb2, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x1c, 0x14, 0x70, 0x03,
+  0x02, 0x06, 0xfe, 0x24, 0x02, 0x60, 0x03, 0x02, 0x07, 0x46, 0x74, 0x19, 0x90, 0x7f, 0xd4, 0xf0,
+  0x74, 0x00, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0x04, 0x75, 0x82,
+  0x17, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe0, 0x04, 0x7f, 0x03, 0x80}},
+ {0x0686, 64, { 0x02, 0x7f, 0x02, 0x75, 0x82, 0x82, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x75, 0x82, 0x6d, 0x75, 0x83, 0x19,
+  0xf0, 0x75, 0x82, 0x66, 0x75, 0x83, 0x19, 0xf0, 0x75, 0x82, 0x5f, 0x75, 0x83, 0x19, 0xf0, 0x75,
+  0x82, 0x58, 0x75, 0x83, 0x19, 0xf0, 0x90, 0x7f, 0xea, 0xe0, 0x30, 0xe1, 0x04, 0x7f, 0x64, 0x80,
+  0x02, 0x7f, 0x32, 0x75, 0x82, 0x1a, 0x75, 0x83, 0x19, 0xef, 0xf0, 0x90, 0x7f, 0xef, 0xe0}},
+ {0x06c6, 64, { 0xfe, 0x90, 0x7f, 0xee, 0xe0, 0x7c, 0x00, 0x24, 0x00, 0xf5, 0x19, 0xec, 0x3e, 0xf5, 0x18, 0x75, 0x33,
+  0x19, 0x75, 0x34, 0x12, 0x75, 0x82, 0x14, 0x75, 0x83, 0x19, 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28,
+  0xd3, 0xe5, 0x28, 0x95, 0x19, 0xe5, 0x27, 0x95, 0x18, 0x40, 0x06, 0x85, 0x18, 0x27, 0x85, 0x19,
+  0x28, 0x12, 0x13, 0x17, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x14, 0x30}},
+ {0x0706, 64, { 0xea, 0x49, 0x60, 0x32, 0x90, 0x7f, 0xee, 0xe0, 0x75, 0x18, 0x00, 0xf5, 0x19, 0xae, 0x02, 0xaf, 0x01,
+  0x8e, 0x33, 0x8f, 0x34, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x27, 0xf5, 0x28,
+  0xd3, 0x95, 0x19, 0xe5, 0x27, 0x95, 0x18, 0x40, 0x06, 0x85, 0x18, 0x27, 0x85, 0x19, 0x28, 0x12,
+  0x13, 0x17, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xb9}},
+ {0x0746, 64, { 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0x00, 0xe5, 0x25, 0xf0, 0x90,
+  0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x25, 0x02, 0x08,
+  0xb9, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x22, 0x12, 0x0a, 0xbd, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0x00,
+  0xe5, 0x22, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xe8}},
+ {0x0786, 64, { 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02, 0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff,
+  0x25, 0xe0, 0xff, 0xa2, 0x06, 0xe4, 0x33, 0x4f, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90,
+  0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xb9, 0xe4, 0x90, 0x7f, 0x00, 0xf0, 0xa3, 0xf0, 0x90,
+  0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80}},
+ {0x07c6, 64, { 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34,
+  0x7f, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0x90, 0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5,
+  0x74, 0x02, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x08, 0xb9,
+  0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24, 0x02, 0x60, 0x03, 0x02, 0x08, 0xb9}},
+ {0x0806, 64, { 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xb4, 0xe0, 0x44,
+  0x01, 0xf0, 0x02, 0x08, 0xb9, 0x90, 0x7f, 0xea, 0xe0, 0x70, 0x38, 0x90, 0x7f, 0xec, 0xe0, 0xf4,
+  0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5,
+  0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x7f, 0xec, 0xe0, 0x54, 0x80, 0xff}},
+ {0x0846, 64, { 0x13, 0x13, 0x13, 0x54, 0x1f, 0xff, 0xe0, 0x54, 0x07, 0x2f, 0x90, 0x7f, 0xd7, 0xf0, 0xe0, 0x44, 0x20,
+  0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90, 0x7f, 0xe8, 0xe0,
+  0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x04, 0xd2,
+  0x00, 0x80, 0x3f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x36, 0x90, 0x7f, 0xea}},
+ {0x0886, 64, { 0xe0, 0x70, 0x20, 0x90, 0x7f, 0xec, 0xe0, 0xf4, 0x54, 0x80, 0xff, 0xc4, 0x54, 0x0f, 0xff, 0xe0, 0x54,
+  0x07, 0x2f, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74, 0x01, 0xf0,
+  0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f, 0xb4, 0xe0, 0x44,
+  0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe5, 0x11, 0x54, 0x0f, 0x70}},
+ {0x08c6, 64, { 0x03, 0x02, 0x09, 0xb2, 0x12, 0x16, 0xaa, 0xef, 0x20, 0xe1, 0x75, 0x12, 0x17, 0x08, 0xef, 0x14, 0xf5,
+  0x19, 0x12, 0x18, 0xd8, 0xef, 0x25, 0x19, 0xff, 0xe4, 0x33, 0xfe, 0xc3, 0xef, 0x94, 0x80, 0xee,
+  0x64, 0x80, 0x94, 0x80, 0x50, 0x59, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xe0, 0xfe, 0xa3, 0xe0,
+  0xff, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0x30, 0xe0, 0x11, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82}},
+ {0x0906, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x0f, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe2, 0x12, 0xe5, 0x19, 0x60, 0x0e, 0xf5, 0x23, 0xef, 0x24,
+  0x01, 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0xb2, 0xe4, 0xff, 0x12, 0x14, 0xe8}},
+ {0x0946, 64, { 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe7, 0x5d, 0x12, 0x18,
+  0xd8, 0xe5, 0x15, 0x24, 0x3b, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0xc3,
+  0x9e, 0x50, 0x48, 0xe5, 0x15, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01,
+  0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7b}},
+ {0x0986, 64, { 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x42,
+  0x13, 0x90, 0x7f, 0xc2, 0xe0, 0x30, 0xe1, 0x10, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0xf5, 0x24, 0x80, 0x03, 0x12, 0x12, 0xa6, 0x12, 0x16, 0xd9, 0xef, 0x30,
+  0xe1, 0x03, 0x02, 0x0a, 0xbc, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}},
+ {0x09c6, 64, { 0x83, 0xe0, 0x54, 0x80, 0xf0, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xc0,
+  0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x18, 0xe4, 0xee, 0x4f, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x12,
+  0x17, 0xde, 0x8f, 0x19, 0xe5, 0x15, 0x24, 0x35, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0,
+  0xfe, 0xef, 0xc3, 0x9e, 0x50, 0x28, 0x12, 0x18, 0xc0, 0xef, 0x30, 0xe0, 0x21, 0xe5, 0x15}},
+ {0x0a06, 64, { 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe7, 0x12, 0xe5, 0x15, 0x24, 0x31,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x03, 0x02, 0x0a, 0xbc, 0xe5, 0x15,
+  0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x19, 0x70,
+  0x0e, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x22}},
+ {0x0a46, 64, { 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe7, 0x29, 0xe5,
+  0x19, 0xd3, 0x94, 0x20, 0x40, 0x03, 0x75, 0x19, 0x20, 0x85, 0x19, 0x23, 0x85, 0x15, 0x82, 0x85,
+  0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0x8c, 0x2c, 0xf5, 0x2d, 0x12, 0x13, 0xe2, 0xe5,
+  0x19, 0x25, 0xe0, 0xff, 0x12, 0x15, 0x1e, 0x22, 0xe5, 0x19, 0xd3, 0x94, 0x3f, 0x40, 0x03}},
+ {0x0a86, 64, { 0x75, 0x19, 0x3f, 0x85, 0x19, 0x23, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3,
+  0xe0, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0xe0,
+  0xfe, 0xa3, 0xe0, 0x24, 0x01, 0xf5, 0x2d, 0xe4, 0x3e, 0xf5, 0x2c, 0x12, 0x14, 0x71, 0xe5, 0x19,
+  0x04, 0xff, 0x12, 0x15, 0x1e, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74}},
+ {0x0ac6, 64, { 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4, 0x90, 0x7f, 0x94, 0xf0, 0x90, 0x78, 0x4a, 0x04, 0xf0, 0xf5,
+  0x8e, 0x90, 0x7f, 0x95, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0x3f, 0xf0, 0x90, 0x7f, 0x98,
+  0x74, 0x1f, 0xf0, 0x90, 0x78, 0x43, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0x7f,
+  0xdf, 0x74, 0x9f, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x44, 0x02, 0xf0}},
+ {0x0b06, 64, { 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75,
+  0x16, 0x01, 0x12, 0x0f, 0x17, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90,
+  0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x16, 0x01, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x7e, 0x7e, 0x7f, 0x40, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83}},
+ {0x0b46, 64, { 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7e, 0x7f, 0x80, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83,
+  0xa3, 0xa3, 0x74, 0x7e, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c,
+  0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x0f, 0x17, 0x7e,
+  0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0}},
+ {0x0b86, 64, { 0x75, 0x16, 0x02, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0,
+  0x7e, 0x7d, 0x7f, 0xc0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0xc0,
+  0xf0, 0x7e, 0x7e, 0x7f, 0x00, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7e, 0xf0,
+  0xa3, 0x74, 0x00, 0xf0, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90}},
+ {0x0bc6, 64, { 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x0f, 0x17, 0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14,
+  0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0xe5, 0x15, 0x24,
+  0x26, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x02, 0xf0, 0x7e, 0x7d, 0x7f, 0x40, 0x85,
+  0x15, 0x82, 0x85, 0x14, 0x83, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x40, 0xf0, 0x7e, 0x7d, 0x7f}},
+ {0x0c06, 64, { 0x80, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x80, 0xf0, 0x7e,
+  0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75,
+  0x16, 0x08, 0x12, 0x0f, 0x17, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90,
+  0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0xe5, 0x15, 0x24, 0x26, 0xf5, 0x82, 0xe4}},
+ {0x0c46, 64, { 0x35, 0x14, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x7e, 0x7c, 0x7f, 0xc0, 0x85, 0x15, 0x82, 0x85, 0x14, 0x83,
+  0x74, 0x7c, 0xf0, 0xa3, 0x74, 0xc0, 0xf0, 0x7e, 0x7d, 0x7f, 0x00, 0x85, 0x15, 0x82, 0x85, 0x14,
+  0x83, 0xa3, 0xa3, 0x74, 0x7d, 0xf0, 0xa3, 0x74, 0x00, 0xf0, 0xc2, 0x0a, 0xc2, 0x09, 0xd2, 0x02,
+  0x22, 0xe5, 0x10, 0x04, 0x54, 0x03, 0xf5, 0x10, 0x14, 0x60, 0x1f, 0x14, 0x60, 0x31, 0x14}},
+ {0x0c86, 64, { 0x60, 0x43, 0x24, 0x03, 0x70, 0x52, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90,
+  0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x16, 0x01, 0x80, 0x3d, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14,
+  0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x80, 0x28, 0x7e,
+  0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0}},
+ {0x0cc6, 64, { 0x75, 0x16, 0x04, 0x80, 0x13, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f,
+  0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0xe5, 0x32, 0x55, 0x16, 0x70, 0x03, 0x02, 0x0e, 0x16,
+  0xe5, 0x16, 0xf4, 0xff, 0x52, 0x32, 0xe5, 0x26, 0x54, 0x7f, 0xfe, 0x70, 0x0f, 0xe5, 0x2a, 0x55,
+  0x16, 0x60, 0x24, 0x90, 0x7f, 0x98, 0xe0, 0x45, 0x16, 0xf0, 0x80, 0x1b, 0xbe, 0x20, 0x18}},
+ {0x0d06, 64, { 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe3, 0x09, 0xe4, 0xf5,
+  0x2a, 0x90, 0x7f, 0x98, 0xe0, 0x5f, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe5, 0x15, 0x24, 0x34, 0xf5, 0x82, 0xe4, 0x35,
+  0x14, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0xe0, 0x14, 0xf0, 0xe0, 0x60, 0x03, 0x02, 0x0e, 0x16}},
+ {0x0d46, 64, { 0x74, 0x0a, 0xf0, 0x12, 0x00, 0x36, 0xef, 0x54, 0x01, 0xff, 0xf5, 0x19, 0xe5, 0x15, 0x24, 0x2c, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x19, 0xf0, 0xe5, 0x16, 0x42,
+  0x13, 0x12, 0x18, 0xf0, 0x8f, 0x19, 0xe5, 0x15, 0x24, 0x27, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5,
+  0x83, 0xe0, 0xff, 0xe5, 0x19, 0x54, 0x10, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x16}},
+ {0x0d86, 64, { 0x42, 0x13, 0xe5, 0x15, 0x24, 0x28, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x19,
+  0x54, 0x80, 0xfe, 0x6f, 0x60, 0x06, 0xee, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x15, 0x24, 0x29,
+  0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x19, 0x54, 0x20, 0xfe, 0x6f, 0x60,
+  0x15, 0xee, 0xf0, 0xe5, 0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0}},
+ {0x0dc6, 64, { 0x30, 0xe4, 0x04, 0xe5, 0x16, 0x42, 0x13, 0xe5, 0x12, 0x55, 0x16, 0xff, 0xf5, 0x19, 0xe5, 0x15, 0x24,
+  0x2a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x16, 0xe5, 0x19, 0xf0, 0xe5,
+  0x15, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x30, 0xe5, 0x04, 0xe5, 0x16,
+  0x42, 0x13, 0xe5, 0x17, 0x55, 0x16, 0xff, 0xf5, 0x19, 0xe5, 0x15, 0x24, 0x30, 0xf5, 0x82}},
+ {0x0e06, 64, { 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x6f, 0x60, 0x07, 0xe5, 0x19, 0xf0, 0xe5, 0x16, 0x42, 0x13, 0x22,
+  0x30, 0x09, 0x03, 0x02, 0x0f, 0x16, 0xe5, 0x24, 0x14, 0x60, 0x2a, 0x14, 0x60, 0x41, 0x14, 0x60,
+  0x58, 0x14, 0x60, 0x6f, 0x24, 0x04, 0x60, 0x03, 0x02, 0x0e, 0xd4, 0x7e, 0x7b, 0x7f, 0xc0, 0x75,
+  0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0, 0x75, 0x16, 0x01, 0x12}},
+ {0x0e46, 64, { 0x12, 0xa6, 0x75, 0x24, 0x01, 0x22, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90,
+  0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x12, 0xa6, 0x75, 0x24, 0x02, 0x22, 0x7e,
+  0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75,
+  0x16, 0x04, 0x12, 0x12, 0xa6, 0x75, 0x24, 0x03, 0x22, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14}},
+ {0x0e86, 64, { 0x7c, 0x75, 0x15, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x12, 0xa6, 0x75,
+  0x24, 0x04, 0x22, 0x30, 0x04, 0x33, 0xc2, 0x04, 0x53, 0x13, 0xdf, 0xe4, 0xf5, 0x19, 0x7e, 0x00,
+  0x7b, 0x00, 0x74, 0x2e, 0x25, 0x19, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11, 0xb0, 0xff, 0x74,
+  0x80, 0x25, 0x19, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0, 0x05, 0x19, 0xe5}},
+ {0x0ec6, 64, { 0x19, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0x75, 0x24, 0x05, 0x22, 0xe5, 0x36, 0x60,
+  0x3b, 0xd5, 0x36, 0x0a, 0x53, 0x13, 0xef, 0x30, 0x0a, 0x04, 0xd2, 0x09, 0xc2, 0x0a, 0xe4, 0xf5,
+  0x19, 0x7e, 0x00, 0x7b, 0x00, 0x74, 0x35, 0x25, 0x19, 0xf9, 0xee, 0x34, 0x00, 0xfa, 0x12, 0x11,
+  0xb0, 0xff, 0x74, 0x80, 0x25, 0x19, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xef, 0xf0}},
+ {0x0f06, 64, { 0x05, 0x19, 0xe5, 0x19, 0xb4, 0x03, 0xdb, 0x90, 0x7f, 0xc3, 0x74, 0x03, 0xf0, 0xe4, 0xf5, 0x24, 0x22,
+  0xe4, 0xf5, 0x1a, 0x7e, 0x00, 0x7b, 0x01, 0xe5, 0x15, 0x25, 0x1a, 0xf9, 0xee, 0x35, 0x14, 0xfa,
+  0xe4, 0x12, 0x11, 0xf6, 0x05, 0x1a, 0xe5, 0x1a, 0xb4, 0x3c, 0xe8, 0xe5, 0x15, 0x24, 0x35, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0}},
+ {0x0f46, 64, { 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00,
+  0xf0, 0x7f, 0x0c, 0xe4, 0xfd, 0x12, 0x16, 0x4c, 0x7f, 0x10, 0xe5, 0x15, 0x24, 0x33, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0, 0x12, 0x15, 0xbc, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0,
+  0x7f, 0x01, 0xe5, 0x15, 0x24, 0x36, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xef, 0xf0}},
+ {0x0f86, 64, { 0x44, 0x06, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0xe5, 0x15, 0x24, 0x39, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0x74, 0x80, 0xf0, 0x90, 0xc0, 0x00, 0xf0, 0x0f, 0xe4, 0xfd,
+  0x12, 0x16, 0x4c, 0xe4, 0xff, 0x7e, 0xa3, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xee, 0xf0, 0xfd, 0x12, 0x16, 0x4c, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90}},
+ {0x0fc6, 64, { 0xc0, 0x00, 0xe4, 0xf0, 0x7f, 0x05, 0x7d, 0x7f, 0x12, 0x16, 0x4c, 0x7f, 0x01, 0x12, 0x15, 0x54, 0x7f,
+  0x03, 0x7d, 0x07, 0x12, 0x16, 0x4c, 0x22, 0x53, 0x13, 0x3f, 0x90, 0x7b, 0xf1, 0xe0, 0x30, 0xe3,
+  0x16, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef,
+  0xf0, 0x75, 0x16, 0x01, 0x12, 0x08, 0xc1, 0x90, 0x7c, 0x31, 0xe0, 0x30, 0xe3, 0x16, 0x7e}},
+ {0x1006, 64, { 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16,
+  0x02, 0x12, 0x08, 0xc1, 0x90, 0x7c, 0x71, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x40, 0x75,
+  0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf, 0xf0, 0x75, 0x16, 0x04, 0x12, 0x08,
+  0xc1, 0x90, 0x7c, 0xb1, 0xe0, 0x30, 0xe3, 0x16, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c}},
+ {0x1046, 64, { 0x75, 0x15, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x08, 0xc1, 0x05, 0x11,
+  0xe5, 0x11, 0x54, 0x0f, 0xf5, 0x18, 0x70, 0x1f, 0x90, 0x78, 0x41, 0xe0, 0x54, 0xf7, 0xf0, 0x90,
+  0x7f, 0x99, 0xe0, 0xf5, 0x17, 0x90, 0x78, 0x41, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x7f, 0x99, 0xe0,
+  0xf4, 0xf5, 0x12, 0x12, 0x11, 0x26, 0x22, 0xe5, 0x18, 0xb4, 0x01, 0x04, 0x12, 0x0c, 0x78}},
+ {0x1086, 64, { 0x22, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x08, 0xe5, 0x13, 0x60, 0x04, 0x12, 0x0e, 0x17, 0x22, 0x12,
+  0x0c, 0x78, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x37, 0x02, 0x10, 0xe1, 0x02,
+  0x12, 0x2e, 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}},
+ {0x10c6, 64, { 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, 0x18, 0x5c, 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}},
+ {0x1106, 64, { 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, 0x90,
+  0x7f, 0xd2, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x11, 0xaf, 0xc2, 0x09, 0x90, 0x7b, 0x40, 0xe0, 0x14,
+  0x60, 0x26, 0x14, 0x60, 0x3b, 0x14, 0x60, 0x50, 0x24, 0x83, 0x60, 0x64, 0x24, 0x80, 0x70}},
+ {0x1146, 64, { 0x63, 0x7e, 0x7b, 0x7f, 0xc0, 0x75, 0x14, 0x7b, 0x75, 0x15, 0xc0, 0x90, 0x7f, 0x96, 0x74, 0xef, 0xf0,
+  0x75, 0x16, 0x01, 0x12, 0x00, 0x46, 0x80, 0x4b, 0x7e, 0x7c, 0x7f, 0x00, 0x75, 0x14, 0x7c, 0x75,
+  0x15, 0x00, 0x90, 0x7f, 0x96, 0x74, 0xdf, 0xf0, 0x75, 0x16, 0x02, 0x12, 0x00, 0x46, 0x80, 0x33,
+  0x7e, 0x7c, 0x7f, 0x40, 0x75, 0x14, 0x7c, 0x75, 0x15, 0x40, 0x90, 0x7f, 0x96, 0x74, 0xbf}},
+ {0x1186, 64, { 0xf0, 0x75, 0x16, 0x04, 0x12, 0x00, 0x46, 0x80, 0x1b, 0x7e, 0x7c, 0x7f, 0x80, 0x75, 0x14, 0x7c, 0x75,
+  0x15, 0x80, 0x90, 0x7f, 0x96, 0x74, 0x7f, 0xf0, 0x75, 0x16, 0x08, 0x12, 0x00, 0x46, 0x80, 0x03,
+  0x12, 0x17, 0x8f, 0xe4, 0x90, 0x7f, 0xd3, 0xf0, 0x22, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83,
+  0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83}},
+ {0x11c6, 64, { 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}},
+ {0x1206, 64, { 0xf3, 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, 0x90, 0x7f, 0xae, 0xe0, 0xff, 0xd3, 0x92, 0x00, 0xe4,
+  0x33, 0xfe, 0xef, 0x4e, 0xf0, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xde, 0x74, 0x01}},
+ {0x1246, 64, { 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xa9, 0xf0, 0x90, 0x7f,
+  0xaa, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaf, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0x74, 0x0d,
+  0xf0, 0xd2, 0xaf, 0xd2, 0x0b, 0x12, 0x18, 0x20, 0xc2, 0x01, 0xe4, 0xf5, 0x2b, 0xf5, 0x31, 0xc2,
+  0x07, 0xc2, 0x02, 0x75, 0x29, 0xf0, 0x90, 0x7f, 0xd8, 0xe0, 0x65, 0x26, 0x60, 0x06, 0x75}},
+ {0x1286, 64, { 0x32, 0x0f, 0xe0, 0xf5, 0x26, 0x30, 0x02, 0x03, 0x12, 0x0f, 0xde, 0x30, 0x01, 0x07, 0xc2, 0x01, 0x12,
+  0x06, 0x29, 0x80, 0xe2, 0x30, 0x08, 0xdf, 0xc2, 0x08, 0x12, 0x18, 0x41, 0x80, 0xd8, 0x22, 0xe5,
+  0x13, 0x55, 0x16, 0x60, 0x6a, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83,
+  0xe0, 0x70, 0x5c, 0xe5, 0x16, 0xf4, 0x52, 0x13, 0xe5, 0x15, 0x24, 0x26, 0xff, 0xe4, 0x35}},
+ {0x12c6, 64, { 0x14, 0xfe, 0xe4, 0xfd, 0x0f, 0xef, 0xaa, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0,
+  0xfc, 0x74, 0x80, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7b, 0xf5, 0x83, 0xec, 0xf0, 0x0d, 0xbd, 0x0b,
+  0xe2, 0x90, 0x7f, 0xc3, 0x74, 0x0b, 0xf0, 0xe5, 0x15, 0x24, 0x3a, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0x74, 0x10, 0xf0, 0xe5, 0x15, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5}},
+ {0x1306, 64, { 0x83, 0xe4, 0xf0, 0xe5, 0x15, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe4, 0xf0, 0x22,
+  0xe5, 0x28, 0x45, 0x27, 0x60, 0x57, 0xae, 0x27, 0xaf, 0x28, 0xd3, 0xef, 0x94, 0x40, 0xee, 0x94,
+  0x00, 0x40, 0x04, 0x7e, 0x00, 0x7f, 0x40, 0xc3, 0xe5, 0x28, 0x9f, 0xf5, 0x28, 0xe5, 0x27, 0x9e,
+  0xf5, 0x27, 0xe4, 0xfd, 0xed, 0xc3, 0x9f, 0xe4, 0x9e, 0x50, 0x1f, 0x85, 0x34, 0x82, 0x85}},
+ {0x1346, 64, { 0x33, 0x83, 0xe0, 0xfc, 0x74, 0x00, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x0d,
+  0x05, 0x34, 0xe5, 0x34, 0x70, 0x02, 0x05, 0x33, 0x80, 0xda, 0x90, 0x7f, 0xa9, 0x74, 0x01, 0xf0,
+  0x90, 0x7f, 0xac, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb5, 0xef, 0xf0, 0x22, 0x90, 0x7f, 0xac,
+  0xe0, 0x54, 0xfe, 0xf0, 0xe4, 0x90, 0x7f, 0xb5, 0xf0, 0x22, 0xe4, 0x90, 0x7f, 0x93, 0xf0}},
+ {0x1386, 64, { 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0x90, 0x7f, 0x96, 0xf0, 0xe4, 0x90, 0x78, 0x4a, 0xf0, 0x90, 0x7f,
+  0x94, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x30, 0x00, 0x07,
+  0xe5, 0x29, 0x54, 0xf0, 0xff, 0x80, 0x02, 0x7f, 0x00, 0xef, 0x44, 0x08, 0x90, 0x78, 0x41, 0xf0,
+  0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x95, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xff, 0xf0}},
+ {0x13c6, 64, { 0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x93, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xf0, 0xf0, 0xe4, 0x90,
+  0x7f, 0x96, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x8f, 0x1a, 0x05, 0x2d, 0xe5,
+  0x2d, 0xae, 0x2c, 0x70, 0x02, 0x05, 0x2c, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x1a, 0xf0, 0x12,
+  0x1a, 0x08, 0x05, 0x2d, 0xe5, 0x2d, 0xac, 0x2c, 0x70, 0x02, 0x05, 0x2c, 0x14, 0xf5, 0x82}},
+ {0x1406, 64, { 0x8c, 0x83, 0xef, 0xf0, 0x15, 0x23, 0xe5, 0x23, 0x60, 0x1f, 0xe5, 0x15, 0x24, 0x38, 0xf5, 0x82, 0xe4,
+  0x35, 0x14, 0xf5, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0x12, 0x18, 0xe4, 0x8f, 0x1a, 0xee,
+  0x4f, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x80, 0xb5, 0x22, 0x8f, 0x1a, 0xe4, 0xf5, 0x1b, 0x75, 0x1c,
+  0xff, 0x75, 0x1d, 0x19, 0x75, 0x1e, 0x86, 0xab, 0x1c, 0xaa, 0x1d, 0xa9, 0x1e, 0x90, 0x00}},
+ {0x1446, 64, { 0x01, 0x12, 0x11, 0xc9, 0xb4, 0x03, 0x1d, 0xaf, 0x1b, 0x05, 0x1b, 0xef, 0xb5, 0x1a, 0x01, 0x22, 0x12,
+  0x11, 0xb0, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75, 0x1c, 0xff, 0xf5, 0x1d, 0x89,
+  0x1e, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00, 0x22, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90,
+  0x78, 0x4f, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x50, 0xf0, 0xe5, 0x2c, 0x90, 0x78, 0x51}},
+ {0x1486, 64, { 0xf0, 0xae, 0x2c, 0xe5, 0x2d, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90, 0x78,
+  0x57, 0x74, 0x04, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x10, 0xf0, 0xe0, 0x54, 0xf7, 0xf0, 0xe4,
+  0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa, 0x22, 0xe4, 0x90, 0x78, 0x41, 0xf0,
+  0xe5, 0x2c, 0x90, 0x78, 0x4f, 0xf0, 0xae, 0x2c, 0xe5, 0x2d, 0x90, 0x78, 0x50, 0xf0, 0x90}},
+ {0x14c6, 64, { 0x78, 0x51, 0x74, 0xc0, 0xf0, 0xe4, 0x90, 0x78, 0x52, 0xf0, 0x90, 0x78, 0x54, 0xe5, 0x23, 0xf0, 0x90,
+  0x78, 0x57, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x78, 0x55, 0xf0, 0x90, 0x78, 0x55, 0xe0, 0x60, 0xfa,
+  0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f,
+  0x14, 0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xef, 0xf0, 0x80, 0x13}},
+ {0x1506, 64, { 0x90, 0x7f, 0xc9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xcb, 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xcd,
+  0xef, 0xf0, 0xe5, 0x16, 0x42, 0x2a, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14,
+  0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0f, 0x14, 0x60, 0x13, 0x14, 0x60, 0x17, 0x80, 0x00, 0x90, 0x7f,
+  0xb7, 0xef, 0xf0, 0x80, 0x13, 0x90, 0x7f, 0xb9, 0xef, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xbb}},
+ {0x1546, 64, { 0xef, 0xf0, 0x80, 0x05, 0x90, 0x7f, 0xbd, 0xef, 0xf0, 0xe5, 0x16, 0x42, 0x2a, 0x22, 0xae, 0x07, 0xe4,
+  0xff, 0xe5, 0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0xfd,
+  0x12, 0x16, 0x4c, 0x90, 0x78, 0x41, 0x74, 0x01, 0xf0, 0x90, 0xc0, 0x00, 0xee, 0xf0, 0xe4, 0xe5,
+  0x15, 0x24, 0x32, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xfd, 0x12}},
+ {0x1586, 64, { 0x16, 0x4c, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86,
+  0x75, 0x86, 0x00, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x01,
+  0xf0, 0x12, 0x13, 0x17, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83,
+  0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74}},
+ {0x15c6, 64, { 0xbf, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74,
+  0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f,
+  0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf,
+  0xf0, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41}},
+ {0x1606, 64, { 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f,
+  0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf,
+  0xf0, 0x90, 0x78, 0x41, 0x74, 0x06, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74,
+  0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54}},
+ {0x1646, 64, { 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0xe5, 0x15, 0x24, 0x37, 0xf5,
+  0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0, 0x00, 0xf0, 0x90, 0x78, 0x41,
+  0x74, 0x07, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x05, 0xf0, 0x90, 0xc0,
+  0x00, 0xed, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0x74, 0xbf}},
+ {0x1686, 64, { 0xf0, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xef, 0xf0, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0,
+  0xe5, 0x15, 0x24, 0x37, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x54, 0x7f, 0x90, 0xc0,
+  0x00, 0xf0, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14,
+  0x60, 0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc6, 0xe0, 0xff}},
+ {0x16c6, 64, { 0x22, 0x90, 0x7f, 0xc8, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xca, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcc, 0xe0,
+  0xff, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60,
+  0x0e, 0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xb6, 0xe0, 0xff, 0x22, 0x90,
+  0x7f, 0xb8, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xba, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xbc, 0xe0}},
+ {0x1706, 64, { 0xff, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x14, 0x60, 0x0e,
+  0x14, 0x60, 0x11, 0x14, 0x60, 0x14, 0x80, 0x00, 0x90, 0x7f, 0xc7, 0xe0, 0xff, 0x22, 0x90, 0x7f,
+  0xc9, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcb, 0xe0, 0xff, 0x22, 0x90, 0x7f, 0xcd, 0xe0, 0xff, 0x22,
+  0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00}},
+ {0x1746, 64, { 0x30, 0x05, 0x04, 0xc2, 0x05, 0x80, 0x02, 0xd2, 0x08, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x08,
+  0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0xc0, 0xe0,
+  0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0x90, 0x7f, 0xc4,
+  0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x04, 0xf0, 0xd0, 0x86, 0xd0, 0x84}},
+ {0x1786, 64, { 0xd0, 0x85, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x7b, 0x41, 0xe0, 0xf5, 0x36, 0x43, 0x13,
+  0x10, 0xa3, 0xe0, 0x60, 0x09, 0x90, 0x7f, 0xd7, 0x74, 0x17, 0xf0, 0x74, 0x37, 0xf0, 0x90, 0x7b,
+  0x43, 0xe0, 0xf5, 0x37, 0xa3, 0xe0, 0x54, 0xf0, 0xf5, 0x29, 0xe0, 0x60, 0x02, 0xd2, 0x0a, 0x22,
+  0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00}},
+ {0x17c6, 64, { 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01, 0xf0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85,
+  0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x12, 0x18, 0xcc, 0xae, 0x07, 0x12, 0x18, 0xcc, 0xad,
+  0x07, 0xee, 0x6d, 0x60, 0x10, 0x12, 0x18, 0xcc, 0xae, 0x07, 0xee, 0x6d, 0x60, 0x07, 0x12, 0x18,
+  0xcc, 0xad, 0x07, 0x80, 0xec, 0xaf, 0x06, 0x22, 0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5}},
+ {0x1806, 64, { 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0,
+  0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x04, 0xf0,
+  0xe0, 0x44, 0x08, 0xf0, 0x30, 0x0b, 0x04, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12,
+  0x18, 0x77, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0, 0x22, 0x12, 0x13, 0x81, 0x12, 0x18}},
+ {0x1846, 64, { 0x10, 0x90, 0x7f, 0xd6, 0xe0, 0x30, 0xe7, 0x0a, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x18, 0x77, 0x12, 0x18,
+  0xaa, 0x12, 0x0a, 0xbd, 0x22, 0x03, 0x35, 0x80, 0x00, 0x00, 0x03, 0x2e, 0x81, 0x00, 0x00, 0xc1,
+  0x85, 0xc1, 0x81, 0xc1, 0x08, 0xc1, 0x00, 0xc1, 0x06, 0x01, 0x22, 0x00, 0x01, 0x24, 0x00, 0x00,
+  0x8e, 0x18, 0x8f, 0x19, 0xe5, 0x19, 0x15, 0x19, 0xae, 0x18, 0x70, 0x02, 0x15, 0x18, 0x4e}},
+ {0x1886, 64, { 0x60, 0x08, 0x12, 0x17, 0xff, 0x12, 0x17, 0xff, 0x80, 0xeb, 0x22, 0xe5, 0x15, 0x24, 0x04, 0xf5, 0x82,
+  0xe4, 0x35, 0x14, 0xf5, 0x83, 0xe0, 0x04, 0xff, 0x44, 0x10, 0x90, 0x7f, 0xd7, 0xf0, 0xef, 0x44,
+  0x30, 0xf0, 0x22, 0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x0d, 0x7e, 0x00, 0x12, 0x18,
+  0x77, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x78, 0x41, 0x74, 0x02, 0xf0}},
+ {0x18c6, 64, { 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41, 0x74, 0x03, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff,
+  0x22, 0x90, 0x78, 0x41, 0x74, 0x04, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41,
+  0x74, 0x05, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 0x22, 0x90, 0x78, 0x41, 0x74, 0x06, 0xf0, 0x90,
+  0xc0, 0x00, 0xe0, 0xff, 0x22, 0x53, 0xd8, 0xef, 0x32, 0x12, 0x01, 0x00, 0x01, 0xff, 0x00}},
+ {0x1906, 64, { 0x00, 0x40, 0xcd, 0x06, 0x0a, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x04, 0x09, 0x02, 0x74, 0x00, 0x01,
+  0x01, 0x00, 0xa0, 0x32, 0x09, 0x04, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x07, 0x05, 0x01,
+  0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x03, 0x02, 0x40,
+  0x00, 0x00, 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x05, 0x02, 0x40, 0x00}},
+ {0x1946, 64, { 0x00, 0x07, 0x05, 0x06, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x07, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05,
+  0x81, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x83, 0x02,
+  0x40, 0x00, 0x01, 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x85, 0x02, 0x40, 0x00,
+  0x01, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x87, 0x02, 0x40, 0x00, 0x01}},
+ {0x1986, 64, { 0x04, 0x03, 0x09, 0x04, 0x48, 0x03, 0x4b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x73, 0x00, 0x70, 0x00, 0x61,
+  0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x76,
+  0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66,
+  0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x53, 0x00, 0x79, 0x00}},
+ {0x19c6, 64, { 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x36, 0x03, 0x55, 0x00, 0x53,
+  0x00, 0x42, 0x00, 0x20, 0x00, 0x34, 0x00, 0x2d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x74,
+  0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20,
+  0x00, 0x41, 0x00, 0x64, 0x00, 0x61, 0x00, 0x70, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00}},
+ {0x1a06, 64, { 0x00, 0x00, 0xe4, 0x90, 0x78, 0x41, 0xf0, 0x90, 0xc0, 0x00, 0xe0, 0xff, 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}},
+ {0x1a46, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1a86, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {0x1ac6, 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 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, 0x17, 0xb7, 0x00, 0x02, 0x1b}},
+ {0x1b06, 21, { 0x04, 0x00, 0x02, 0x17, 0x65, 0x00, 0x02, 0x17, 0x37, 0x00, 0x02, 0x1b, 0x10, 0x00, 0x02, 0x1b, 0x14,
+  0x00, 0x02, 0x15, 0x89}},
 { 0xffff,	0,	{0x00} }
 };
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c
--- v2.4.10/linux/drivers/usb/serial/pl2303.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/pl2303.c	Tue Oct  9 15:15:02 2001
@@ -12,6 +12,12 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * 2001_Oct_06 gkh
+ *	Added RTS and DTR line control.  Thanks to joe@bndlg.de for parts of it.
+ *
+ * 2001_Sep_19 gkh
+ *	Added break support.
+ *
  * 2001_Aug_30 gkh
  *	fixed oops in write_bulk_callback.
  *
@@ -53,13 +59,15 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.7"
+#define DRIVER_VERSION "v0.9"
 #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
 
 
 
 static __devinitdata struct usb_device_id id_table [] = {
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
+	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
+	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
 	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
@@ -67,6 +75,28 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 
+#define SET_LINE_REQUEST_TYPE		0x21
+#define SET_LINE_REQUEST		0x20
+
+#define SET_CONTROL_REQUEST_TYPE	0x21
+#define SET_CONTROL_REQUEST		0x22
+#define CONTROL_DTR			0x01
+#define CONTROL_RTS			0x02
+
+#define BREAK_REQUEST_TYPE		0x21
+#define BREAK_REQUEST			0x23	
+#define BREAK_ON			0xffff
+#define BREAK_OFF			0x0000
+
+#define GET_LINE_REQUEST_TYPE		0xa1
+#define GET_LINE_REQUEST		0x21
+
+#define VENDOR_WRITE_REQUEST_TYPE	0x40
+#define VENDOR_WRITE_REQUEST		0x01
+
+#define VENDOR_READ_REQUEST_TYPE	0xc0
+#define VENDOR_READ_REQUEST		0x01
+
 /* function prototypes for a PL2303 serial converter */
 static int pl2303_open (struct usb_serial_port *port, struct file *filp);
 static void pl2303_close (struct usb_serial_port *port, struct file *filp);
@@ -80,6 +110,8 @@
 static int pl2303_write (struct usb_serial_port *port, int from_user,
 			 const unsigned char *buf, int count);
 static void pl2303_break_ctl(struct usb_serial_port *port,int break_state);
+static int pl2303_startup (struct usb_serial *serial);
+static void pl2303_shutdown (struct usb_serial *serial);
 
 
 /* All of the device info needed for the PL2303 SIO serial converter */
@@ -102,9 +134,40 @@
 	read_bulk_callback:	pl2303_read_bulk_callback,
 	read_int_callback:	pl2303_read_int_callback,
 	write_bulk_callback:	pl2303_write_bulk_callback,
+	startup:		pl2303_startup,
+	shutdown:		pl2303_shutdown,
 };
 
+struct pl2303_private { 
+	u8 line_control;
+};
+
+
+static int pl2303_startup (struct usb_serial *serial)
+{
+	struct pl2303_private *priv;
+	int i;
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		priv = kmalloc (sizeof (struct pl2303_private), GFP_KERNEL);
+		if (!priv)
+			return -ENOMEM;
+		memset (priv, 0x00, sizeof (struct pl2303_private));
+		serial->port[i].private = priv;
+	}
+	return 0;
+}
 
+static int set_control_lines (struct usb_device *dev, u8 value)
+{
+	int retval;
+	
+	retval = usb_control_msg (dev, usb_sndctrlpipe (dev, 0),
+				  SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
+				  value, 0, NULL, 0, 100);
+	dbg (__FUNCTION__" - value = %d, retval = %d", value, retval);
+	return retval;
+}
 
 static int pl2303_write (struct usb_serial_port *port, int from_user,  const unsigned char *buf, int count)
 {
@@ -145,58 +208,66 @@
 
 
 
-static void
-pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
-{				/* pl2303_set_termios */
+static void pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+{
 	struct usb_serial *serial = port->serial;
-	unsigned int cflag = port->tty->termios->c_cflag;
-	unsigned char buf[7] = { 0, 0, 0, 0, 0, 0, 0};
+	struct pl2303_private *priv;
+	unsigned int cflag;
+	unsigned char *buf;
 	int baud;
 	int i;
 
+	dbg (__FUNCTION__ " -  port %d", port->number);
 
-	dbg ("pl2303_set_termios port %d", port->number);
+	if ((!port->tty) || (!port->tty->termios)) {
+		dbg(__FUNCTION__" - no tty structures");
+		return;
+	}
 
+	cflag = port->tty->termios->c_cflag;
+	/* check that they really want us to change something */
+	if (old_termios) {
+		if ((cflag == old_termios->c_cflag) &&
+		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
+		    dbg(__FUNCTION__ " - nothing to change...");
+		    return;
+		}
+	}
 
+	buf = kmalloc (7, GFP_KERNEL);
+	if (!buf) {
+		err(__FUNCTION__ " - out of memory.");
+		return;
+	}
+	memset (buf, 0x00, 0x07);
+	
 	i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0),
-			     0x21, 0xa1, 0, 0, buf, 7, 100);
-
+			     GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
+			     0, 0, buf, 7, 100);
 	dbg ("0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x", i,
 	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
 
 
 	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-			     1, 0x40, 0, 1, NULL, 0, 100);
+			     VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE,
+			     0, 1, NULL, 0, 100);
 
 	dbg ("0x40:1:0:1  %d", i);
 
-
-
 	if (cflag & CSIZE) {
 		switch (cflag & CSIZE) {
-			case CS5:
-				buf[6] = 5;
-				dbg ("Setting CS5");
-				break;
-			case CS6:
-				buf[6] = 6;
-				dbg ("Setting CS6");
-				break;
-			case CS7:
-				buf[6] = 7;
-				dbg ("Setting CS7");
-				break;
-			case CS8:
-				buf[6] = 8;
-				dbg ("Setting CS8");
-				break;
+			case CS5:	buf[6] = 5;	break;
+			case CS6:	buf[6] = 6;	break;
+			case CS7:	buf[6] = 7;	break;
 			default:
-				err ("CSIZE was set but not CS5-CS8");
+			case CS8:	buf[6] = 8;	break;
 		}
+		dbg (__FUNCTION__ " - data bits = %d", buf[6]);
 	}
 
 	baud = 0;
 	switch (cflag & CBAUD) {
+		case B0:	baud = 0;	break;
 		case B75:	baud = 75;	break;
 		case B150:	baud = 150;	break;
 		case B300:	baud = 300;	break;
@@ -216,7 +287,7 @@
 			err ("pl2303 driver does not support the baudrate requested (fix it)");
 			break;
 	}
-
+	dbg (__FUNCTION__ " - baud = %d", baud);
 	if (baud) {
 		buf[0] = baud & 0xff;
 		buf[1] = (baud >> 8) & 0xff;
@@ -224,16 +295,17 @@
 		buf[3] = (baud >> 24) & 0xff;
 	}
 
-
 	/* For reference buf[4]=0 is 1 stop bits */
 	/* For reference buf[4]=1 is 1.5 stop bits */
 	/* For reference buf[4]=2 is 2 stop bits */
-
 	if (cflag & CSTOPB) {
 		buf[4] = 2;
+		dbg(__FUNCTION__ " - stop bits = 2");
+	} else {
+		buf[4] = 0;
+		dbg(__FUNCTION__ " - stop bits = 1");
 	}
 
-
 	if (cflag & PARENB) {
 		/* For reference buf[5]=0 is none parity */
 		/* For reference buf[5]=1 is odd parity */
@@ -242,45 +314,46 @@
 		/* For reference buf[5]=4 is space parity */
 		if (cflag & PARODD) {
 			buf[5] = 1;
+			dbg(__FUNCTION__ " - parity = odd");
 		} else {
 			buf[5] = 2;
+			dbg(__FUNCTION__ " - parity = even");
 		}
+	} else {
+		buf[5] = 0;
+		dbg(__FUNCTION__ " - parity = none");
 	}
 
 	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-			     0x20, 0x21, 0, 0, buf, 7, 100);
-
+			     SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE, 
+			     0, 0, buf, 7, 100);
 	dbg ("0x21:0x20:0:0  %d", i);
 
-	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-			     0x22, 0x21, 1, 0, NULL, 0, 100);
-
-	dbg ("0x21:0x22:1:0  %d", i);
-
-	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-			     0x22, 0x21, 3, 0, NULL, 0, 100);
-
-	dbg ("0x21:0x22:3:0  %d", i);
-
+	if (cflag && CBAUD) {
+		priv = port->private;
+		if ((cflag && CBAUD) == B0)
+			priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
+		else
+			priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
+		set_control_lines (serial->dev, priv->line_control);
+	}
+	
 	buf[0] = buf[1] = buf[2] = buf[3] = buf[4] = buf[5] = buf[6] = 0;
 
 	i = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0),
-			     0x21, 0xa1, 0, 0, buf, 7, 100);
-
+			     GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
+			     0, 0, buf, 7, 100);
 	dbg ("0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x", i,
 	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
 
 	if (cflag & CRTSCTS) {
-
 		i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-				     0x01, 0x40, 0x0, 0x41, NULL, 0, 100);
-
+				     VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST_TYPE,
+				     0x0, 0x41, NULL, 0, 100);
 		dbg ("0x40:0x1:0x0:0x41  %d", i);
-
 	}
 
-
-	return;
+	kfree (buf);
 }       
 
 
@@ -294,7 +367,7 @@
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
 		
-	dbg (__FUNCTION__ "-  port %d", port->number);
+	dbg (__FUNCTION__ " -  port %d", port->number);
 
 	down (&port->sem);
 
@@ -311,20 +384,20 @@
 
 #define SOUP(a,b,c,d)									\
 		result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0),	\
-				       b, a, c , d, NULL, 0, 100);			\
+				       b, a, c, d, NULL, 0, 100);			\
 		dbg("0x%x:0x%x:0x%x:0x%x  %d",a,b,c,d,result);
 
-		FISH (0xc0, 1, 0x8484, 0);
-		SOUP (0x40, 1, 0x0404, 0);
-		FISH (0xc0, 1, 0x8484, 0);
-		FISH (0xc0, 1, 0x8383, 0);
-		FISH (0xc0, 1, 0x8484, 0);
-		SOUP (0x40, 1, 0x0404, 1);
-		FISH (0xc0, 1, 0x8484, 0);
-		FISH (0xc0, 1, 0x8383, 0);
-		SOUP (0x40, 1, 0, 1);
-		SOUP (0x40, 1, 1, 0xc0);
-		SOUP (0x40, 1, 2, 4);
+		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 0);
+		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
+		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0x0404, 1);
+		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8484, 0);
+		FISH (VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, 0x8383, 0);
+		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 0, 1);
+		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 1, 0xc0);
+		SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4);
 
 		/* Setup termios */
 		*(port->tty->termios) = tty_std_termios;
@@ -334,6 +407,7 @@
 
 		//FIXME: need to assert RTS and DTR if CRTSCTS off
 
+		dbg (__FUNCTION__ " - submitting read urb");
 		port->read_urb->dev = serial->dev;
 		result = usb_submit_urb (port->read_urb);
 		if (result) {
@@ -343,6 +417,7 @@
 			return -EPROTO;
 		}
 
+		dbg (__FUNCTION__ " - submitting interrupt urb");
 		port->interrupt_in_urb->dev = serial->dev;
 		result = usb_submit_urb (port->interrupt_in_urb);
 		if (result) {
@@ -359,7 +434,9 @@
 
 static void pl2303_close (struct usb_serial_port *port, struct file *filp)
 {
+	struct pl2303_private *priv;
 	unsigned int c_cflag;
+	int result;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return;
@@ -372,74 +449,151 @@
 	if (port->open_count <= 0) {
 		c_cflag = port->tty->termios->c_cflag;
 		if (c_cflag & HUPCL) {
-			//FIXME: Do drop DTR
-			//FIXME: Do drop RTS
+			/* drop DTR and RTS */
+			priv = port->private;
+			priv->line_control = 0;
+			set_control_lines (port->serial->dev, priv->line_control);
 		}
 
 		/* shutdown our urbs */
-		usb_unlink_urb (port->write_urb);
-		usb_unlink_urb (port->read_urb);
-		usb_unlink_urb (port->interrupt_in_urb);
+		dbg (__FUNCTION__ " - shutting down urbs");
+		result = usb_unlink_urb (port->write_urb);
+		if (result)
+			dbg (__FUNCTION__ " - usb_unlink_urb (write_urb) failed with reason: %d", result);
+
+		result = usb_unlink_urb (port->read_urb);
+		if (result)
+			dbg (__FUNCTION__ " - usb_unlink_urb (read_urb) failed with reason: %d", result);
+
+		result = usb_unlink_urb (port->interrupt_in_urb);
+		if (result)
+			dbg (__FUNCTION__ " - usb_unlink_urb (interrupt_in_urb) failed with reason: %d", result);
 
 		port->active = 0;
 		port->open_count = 0;
 	}
 
 	up (&port->sem);
+	MOD_DEC_USE_COUNT;
 }
 
+static int set_modem_info (struct usb_serial_port *port, unsigned int cmd, unsigned int *value)
+{
+	struct pl2303_private *priv = port->private;
+	unsigned int arg;
+
+	if (copy_from_user(&arg, value, sizeof(int)))
+		return -EFAULT;
+
+	switch (cmd) {
+		case TIOCMBIS:
+			if (arg & TIOCM_RTS)
+				priv->line_control |= CONTROL_RTS;
+			if (arg & TIOCM_DTR)
+				priv->line_control |= CONTROL_DTR;
+			break;
+
+		case TIOCMBIC:
+			if (arg & TIOCM_RTS)
+				priv->line_control &= ~CONTROL_RTS;
+			if (arg & TIOCM_DTR)
+				priv->line_control &= ~CONTROL_DTR;
+			break;
+
+		case TIOCMSET:
+			/* turn off RTS and DTR and then only turn
+			   on what was asked to */
+			priv->line_control &= ~(CONTROL_RTS | CONTROL_DTR);
+			priv->line_control |= ((arg & TIOCM_RTS) ? CONTROL_RTS : 0);
+			priv->line_control |= ((arg & TIOCM_DTR) ? CONTROL_DTR : 0);
+			break;
+	}
+
+	return set_control_lines (port->serial->dev, priv->line_control);
+}
 
-static int
-pl2303_ioctl (struct usb_serial_port *port, struct file *file,
-	      unsigned int cmd, unsigned long arg)
+static int get_modem_info (struct usb_serial_port *port, unsigned int *value)
 {
-// struct usb_serial *serial = port->serial;
-// __u16 urb_value=0; /* Will hold the new flags */
-// char buf[1];
-// int  ret, mask;
+	struct pl2303_private *priv = port->private;
+	unsigned int mcr = priv->line_control;
+	unsigned int result;
 
+	result = ((mcr & CONTROL_DTR)		? TIOCM_DTR : 0)
+		  | ((mcr & CONTROL_RTS)	? TIOCM_RTS : 0);
 
-	dbg ("pl2303_sio ioctl 0x%04x", cmd);
+	dbg (__FUNCTION__ " - result = %x", result);
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+static int pl2303_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	dbg (__FUNCTION__" (%d) cmd = 0x%04x", port->number, cmd);
 
-	/* Based on code from acm.c and others */
 	switch (cmd) {
 		
 		case TIOCMGET:
-			dbg ("TIOCMGET");
+			dbg (__FUNCTION__" (%d) TIOCMGET", port->number);
+			return get_modem_info (port, (unsigned int *)arg);
 
-
-			return put_user (0, (unsigned long *) arg);
-			break;
 		case TIOCMBIS:
 		case TIOCMBIC:
 		case TIOCMSET:
-			return 0;
+			dbg(__FUNCTION__" (%d) TIOCMSET/TIOCMBIC/TIOCMSET",  port->number);
+			return set_modem_info(port, cmd, (unsigned int *) arg);
 
 		default:
-			/* This is not an error - turns out the higher layers will do 
-			 *  some ioctls itself (see comment above)
-			 */
-			dbg ("pl2303_sio ioctl arg not supported - it was 0x%04x", cmd);
-			return(-ENOIOCTLCMD);
+			dbg (__FUNCTION__" not supported = 0x%04x", cmd);
 			break;
 	}
-	dbg ("pl2303_ioctl returning 0");
 
-	return 0;
-}				/* pl2303_ioctl */
+	return -ENOIOCTLCMD;
+}
 
 
-static void pl2303_break_ctl(struct usb_serial_port *port,int break_state)
+static void pl2303_break_ctl (struct usb_serial_port *port, int break_state)
 {
-//FIXME
+	struct usb_serial *serial = port->serial;
+	u16 state;
+	int result;
+
+	dbg (__FUNCTION__ " - port %d", port->number);
+
+	if (break_state == 0)
+		state = BREAK_OFF;
+	else
+		state = BREAK_ON;
+	dbg (__FUNCTION__" - turning break %s", state==BREAK_OFF ? "off" : "on");
+
+	result = usb_control_msg (serial->dev, usb_rcvctrlpipe (serial->dev, 0),
+				  BREAK_REQUEST, BREAK_REQUEST_TYPE, state, 
+				  0, NULL, 0, 100);
+	if (result)
+		dbg (__FUNCTION__" - error sending break = %d", result);
+}
+
+
+static void pl2303_shutdown (struct usb_serial *serial)
+{
+	int i;
+
+	dbg (__FUNCTION__);
+
+	/* stop everything on all ports */
+	for (i = 0; i < serial->num_ports; ++i)
+		while (serial->port[i].open_count > 0) {
+			pl2303_close (&serial->port[i], NULL);
+			kfree (serial->port[i].private);
+		}
 }
 
 
-static void
-pl2303_read_int_callback (struct urb *urb)
+static void pl2303_read_int_callback (struct urb *urb)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
-	struct usb_serial *serial = get_usb_serial (port, "pl2303_read_int_callback");
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 	//unsigned char *data = urb->transfer_buffer;
 	//int i;
 
@@ -482,13 +636,23 @@
 		return;
 	}
 
-	/* PL2303 mysteriously fails with -EPROTO reschedule the read */
 	if (urb->status) {
-		urb->status = 0;
-		urb->dev = serial->dev;
-		result = usb_submit_urb(urb);
-		if (result)
-			err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+		dbg (__FUNCTION__ " - urb->status = %d", urb->status);
+		if (!port->active) {
+			dbg (__FUNCTION__ " - port is closed, exiting.");
+			return;
+		}
+		if (urb->status == -EPROTO) {
+			/* PL2303 mysteriously fails with -EPROTO reschedule the read */
+			dbg (__FUNCTION__ " - caught -EPROTO, resubmitting the urb");
+			urb->status = 0;
+			urb->dev = serial->dev;
+			result = usb_submit_urb(urb);
+			if (result)
+				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+			return;
+		}
+		dbg (__FUNCTION__ " - unable to handle the error, exiting.");
 		return;
 	}
 
@@ -505,11 +669,13 @@
 		tty_flip_buffer_push (tty);
 	}
 
-	/* Schedule the next read*/
-	urb->dev = serial->dev;
-	result = usb_submit_urb(urb);
-	if (result)
-		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+	/* Schedule the next read _if_ we are still open */
+	if (port->active) {
+		urb->dev = serial->dev;
+		result = usb_submit_urb(urb);
+		if (result)
+			err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+	}
 
 	return;
 }
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/pl2303.h linux/drivers/usb/serial/pl2303.h
--- v2.4.10/linux/drivers/usb/serial/pl2303.h	Tue Jul  3 17:08:21 2001
+++ linux/drivers/usb/serial/pl2303.h	Tue Oct  9 15:15:02 2001
@@ -9,7 +9,10 @@
  */
 #define PL2303_VENDOR_ID	0x067b
 #define PL2303_PRODUCT_ID	0x2303
+#define PL2303_PRODUCT_ID_RSAQ2	0x04bb
 
 #define ATEN_VENDOR_ID		0x0557
 #define ATEN_PRODUCT_ID		0x2008
 
+#define IODATA_VENDOR_ID	0x04bb
+#define IODATA_PRODUCT_ID	0x0a03
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- v2.4.10/linux/drivers/usb/serial/usbserial.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/usbserial.c	Mon Oct  1 13:45:47 2001
@@ -307,7 +307,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.3"
+#define DRIVER_VERSION "v1.4"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/"
 #define DRIVER_DESC "USB Serial Driver core"
 
@@ -343,6 +343,13 @@
 	num_ports:		1,
 	shutdown:		generic_shutdown,
 };
+
+#define if_generic_do(x)					\
+	if ((serial->dev->descriptor.idVendor == vendor) &&	\
+	    (serial->dev->descriptor.idProduct == product))	\
+	                x
+#else
+#define if_generic_do(x)
 #endif
 
 
@@ -505,8 +512,6 @@
 		return -ENODEV;
 	}
 
-	MOD_INC_USE_COUNT;
-	
 	/* set up our port structure making the tty driver remember our port object, and us it */
 	portNumber = MINOR(tty->device) - serial->minor;
 	port = &serial->port[portNumber];
@@ -544,8 +549,6 @@
 	} else {
 		generic_close(port, filp);
 	}
-
-	MOD_DEC_USE_COUNT;
 }	
 
 
@@ -768,7 +771,8 @@
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
 
-	MOD_INC_USE_COUNT;
+	/* only increment our usage count, if this device is _really_ a generic device */
+	if_generic_do(MOD_INC_USE_COUNT);
 
 	dbg(__FUNCTION__ " - port %d", port->number);
 
@@ -828,7 +832,9 @@
 	}
 
 	up (&port->sem);
-	MOD_DEC_USE_COUNT;
+
+	/* only decrement our usage count, if this device is _really_ a generic device */
+	if_generic_do(MOD_DEC_USE_COUNT);
 }
 
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/serial/xircom_pgs_fw.h linux/drivers/usb/serial/xircom_pgs_fw.h
--- v2.4.10/linux/drivers/usb/serial/xircom_pgs_fw.h	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/serial/xircom_pgs_fw.h	Mon Oct  1 13:45:43 2001
@@ -2,7 +2,7 @@
  * USB Xircom PGS Firmware
  *
  * Copyright (c) 1999, 2000 Brian Warner        <warner@lothar.com>
- * Copyright (c) 2001 Cristian M. Craciunescu
+ * Copyright (c) 2001 Cristian M. Craciunescu	<cristi@dnt.ro>
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/storage/datafab.c linux/drivers/usb/storage/datafab.c
--- v2.4.10/linux/drivers/usb/storage/datafab.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/storage/datafab.c	Tue Oct  9 15:15:02 2001
@@ -49,7 +49,7 @@
 
 #include <linux/sched.h>
 #include <linux/errno.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 
 extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
 			     unsigned int len, unsigned int *act_len);
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/uhci-debug.h linux/drivers/usb/uhci-debug.h
--- v2.4.10/linux/drivers/usb/uhci-debug.h	Tue Aug  7 12:52:07 2001
+++ linux/drivers/usb/uhci-debug.h	Tue Oct  9 15:25:55 2001
@@ -372,7 +372,9 @@
 				if (td->link != td->dma_handle)
 					out += sprintf(out, "    skel_term_td does not link to self\n");
 
-				out += uhci_show_td(td, out, len - (out - buf), 4);
+				/* Don't show it twice */
+				if (debug <= 1)
+					out += uhci_show_td(td, out, len - (out - buf), 4);
 			}
 
 			continue;
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.4.10/linux/drivers/usb/uhci.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/uhci.c	Sun Oct  7 16:51:39 2001
@@ -61,7 +61,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION ""
+#define DRIVER_VERSION "v1.1"
 #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber"
 #define DRIVER_DESC "USB Universal Host Controller Interface driver"
 
@@ -1258,21 +1258,38 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | ((pktsze - 1) << 21) |
+		uhci_fill_td(td, status, destination |
+			(((pktsze - 1) & UHCI_NULL_DATA_SIZE) << 21) |
 			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE),
 			data);
 
 		data += pktsze;
-		len -= maxsze;
-
-		if (len <= 0)
-			td->status |= TD_CTRL_IOC;
+		len -= pktsze;
 
 		usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			usb_pipeout(urb->pipe));
 	} while (len > 0);
 
+	if (usb_pipeout(urb->pipe) && (urb->transfer_flags & USB_ZERO_PACKET) &&
+	   urb->transfer_buffer_length) {
+		td = uhci_alloc_td(uhci, urb->dev);
+		if (!td)
+			return -ENOMEM;
+
+		uhci_add_td_to_urb(urb, td);
+		uhci_fill_td(td, status, destination | UHCI_NULL_DATA_SIZE |
+			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE),
+			data);
+
+		usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+			usb_pipeout(urb->pipe));
+	}
+
+	/* Set the flag on the last packet */
+	td->status |= TD_CTRL_IOC;
+
 	qh = uhci_alloc_qh(uhci, urb->dev);
 	if (!qh)
 		return -ENOMEM;
@@ -2343,11 +2360,11 @@
 
 	if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
 		if (status & USBSTS_HSE)
-			printk(KERN_ERR "uhci: host system error, PCI problems?\n");
+			err("%x: host system error, PCI problems?", io_addr);
 		if (status & USBSTS_HCPE)
-			printk(KERN_ERR "uhci: host controller process error. something bad happened\n");
+			err("%x: host controller process error. something bad happened", io_addr);
 		if ((status & USBSTS_HCH) && !uhci->is_suspended) {
-			printk(KERN_ERR "uhci: host controller halted. very bad\n");
+			err("%x: host controller halted. very bad", io_addr);
 			/* FIXME: Reset the controller, fix the offending TD */
 		}
 	}
@@ -2393,7 +2410,7 @@
 {
 	unsigned int io_addr = uhci->io_addr;
 
-	dbg("suspend_hc");
+	dbg("%x: suspend_hc", io_addr);
 
 	outw(USBCMD_EGSM, io_addr + USBCMD);
 
@@ -2405,7 +2422,7 @@
 	unsigned int io_addr = uhci->io_addr;
 	unsigned int status;
 
-	dbg("wakeup_hc");
+	dbg("%x: wakeup_hc", io_addr);
 
 	outw(0, io_addr + USBCMD);
 	
@@ -2463,37 +2480,74 @@
 	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
 }
 
-static int uhci_alloc_root_hub(struct uhci *uhci)
+#ifdef CONFIG_PROC_FS
+static int uhci_num = 0;
+#endif
+
+static void free_uhci(struct uhci *uhci)
 {
-	struct usb_device *dev;
+	kfree(uhci);
+}
 
-	dev = usb_alloc_dev(NULL, uhci->bus);
-	if (!dev)
-		return -1;
+/*
+ * De-allocate all resources..
+ */
+static void release_uhci(struct uhci *uhci)
+{
+	int i;
+#ifdef CONFIG_PROC_FS
+	char buf[8];
+#endif
 
-	uhci->bus->root_hub = dev;
-	uhci->rh.dev = dev;
+	if (uhci->irq >= 0) {
+		free_irq(uhci->irq, uhci);
+		uhci->irq = -1;
+	}
 
-	return 0;
-}
+	for (i = 0; i < UHCI_NUM_SKELQH; i++)
+		if (uhci->skelqh[i]) {
+			uhci_free_qh(uhci, uhci->skelqh[i]);
+			uhci->skelqh[i] = NULL;
+		}
 
-static int uhci_start_root_hub(struct uhci *uhci)
-{
-	usb_connect(uhci->rh.dev);
+	for (i = 0; i < UHCI_NUM_SKELTD; i++)
+		if (uhci->skeltd[i]) {
+			uhci_free_td(uhci, uhci->skeltd[i]);
+			uhci->skeltd[i] = NULL;
+		}
 
-	if (usb_new_device(uhci->rh.dev) != 0) {
-		usb_free_dev(uhci->rh.dev);
+	if (uhci->qh_pool) {
+		pci_pool_destroy(uhci->qh_pool);
+		uhci->qh_pool = NULL;
+	}
 
-		return -1;
+	if (uhci->td_pool) {
+		pci_pool_destroy(uhci->td_pool);
+		uhci->td_pool = NULL;
 	}
 
-	return 0;
-}
+	if (uhci->fl) {
+		pci_free_consistent(uhci->dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
+		uhci->fl = NULL;
+	}
+
+	if (uhci->bus) {
+		usb_free_bus(uhci->bus);
+		uhci->bus = NULL;
+	}
 
 #ifdef CONFIG_PROC_FS
-static int uhci_num = 0;
+	if (uhci->proc_entry) {
+		sprintf(buf, "hc%d", uhci->num);
+
+		remove_proc_entry(buf, uhci_proc_root);
+		uhci->proc_entry = NULL;
+	}
 #endif
 
+	free_uhci(uhci);
+}
+
 /*
  * Allocate a frame list, and then setup the skeleton
  *
@@ -2504,27 +2558,96 @@
  *  - any isochronous events handled before any
  *    of the queues. We don't do that here, because
  *    we'll create the actual TD entries on demand.
- *  - The first queue is the "interrupt queue".
- *  - The second queue is the "control queue", split into low and high speed
- *  - The third queue is "bulk data".
+ *  - The first queue is the interrupt queue.
+ *  - The second queue is the control queue, split into low and high speed
+ *  - The third queue is bulk queue.
+ *  - The fourth queue is the bandwidth reclamation queue, which loops back
+ *    to the high speed control queue.
  */
-static struct uhci *alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io_size)
+static int alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io_size)
 {
-	int i, port;
 	struct uhci *uhci;
+	int retval = -EBUSY;
+	char buf[8], *bufp = buf;
+	int i, port;
 	struct usb_bus *bus;
 	dma_addr_t dma_handle;
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *ent;
+#endif
 
-	uhci = kmalloc(sizeof(*uhci), GFP_KERNEL);
-	if (!uhci)
-		return NULL;
+	if (!request_region(io_addr, io_size, "usb-uhci")) {
+		err("couldn't allocate I/O range %x - %x", io_addr,
+			io_addr + io_size - 1);
+		goto err_request_region;
+	}
+
+	if (!dev->irq) {
+		err("found UHCI device with no IRQ assigned. check BIOS settings!");
+		retval = -EINVAL;
+		goto err_invalid_irq;
+	}
+
+	if (!pci_dma_supported(dev, 0xFFFFFFFF)) {
+		err("PCI subsystem doesn't support 32 bit addressing?");
+		retval = -ENODEV;
+		goto err_pci_dma_supported;
+	}
+
+	if (pci_enable_device(dev) < 0) {
+		err("couldn't enable PCI device");
+		goto err_enable_device;
+	}
+
+	pci_set_master(dev);
+
+#ifndef __sparc__
+	sprintf(buf, "%d", dev->irq);
+#else
+	bufp = __irq_itoa(dev->irq);
+#endif
+	printk(KERN_INFO __FILE__ ": USB UHCI at I/O 0x%x, IRQ %s\n",
+		io_addr, bufp);
 
-	memset(uhci, 0, sizeof(*uhci));
+	if (pci_set_dma_mask(dev, 0xFFFFFFFF)) {
+		err("couldn't set PCI dma mask");
+		retval = -ENODEV;
+		goto err_pci_set_dma_mask;
+	}
+
+	uhci = kmalloc(sizeof(*uhci), GFP_KERNEL);
+	if (!uhci) {
+		err("couldn't allocate uhci structure");
+		retval = -ENOMEM;
+		goto err_alloc_uhci;
+	}
 
 	uhci->dev = dev;
-	uhci->irq = -1;
 	uhci->io_addr = io_addr;
 	uhci->io_size = io_size;
+	dev->driver_data = uhci;
+
+#ifdef CONFIG_PROC_FS
+	uhci->num = uhci_num++;
+
+	sprintf(buf, "hc%d", uhci->num);
+
+	ent = create_proc_entry(buf, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
+	if (!ent) {
+		err("couldn't create uhci proc entry");
+		retval = -ENOMEM;
+		goto err_create_proc_entry;
+	}
+
+	ent->data = uhci;
+	ent->proc_fops = &uhci_proc_operations;
+	ent->size = 0;
+	uhci->proc_entry = ent;
+#endif
+
+	/* Reset here so we don't get any interrupts from an old setup */
+	/*  or broken setup */
+	reset_hc(uhci);
 
 	spin_lock_init(&uhci->qh_remove_list_lock);
 	INIT_LIST_HEAD(&uhci->qh_remove_list);
@@ -2542,10 +2665,13 @@
 
 	/* We need exactly one page (per UHCI specs), how convenient */
 	/* We assume that one page is atleast 4k (1024 frames * 4 bytes) */
+#if PAGE_SIZE < (4 * 1024)
+#error PAGE_SIZE is not atleast 4k
+#endif
 	uhci->fl = pci_alloc_consistent(uhci->dev, sizeof(*uhci->fl), &dma_handle);
 	if (!uhci->fl) {
-		printk(KERN_ERR "Unable to allocate consistent memory for frame list\n");
-		goto free_uhci;
+		err("unable to allocate consistent memory for frame list");
+		goto err_alloc_fl;
 	}
 
 	memset((void *)uhci->fl, 0, sizeof(*uhci->fl));
@@ -2555,34 +2681,38 @@
 	uhci->td_pool = pci_pool_create("uhci_td", uhci->dev,
 		sizeof(struct uhci_td), 16, 0, GFP_DMA | GFP_ATOMIC);
 	if (!uhci->td_pool) {
-		printk(KERN_ERR "Unable to create td pci_pool\n");
-		goto free_fl;
+		err("unable to create td pci_pool");
+		goto err_create_td_pool;
 	}
 
 	uhci->qh_pool = pci_pool_create("uhci_qh", uhci->dev,
 		sizeof(struct uhci_qh), 16, 0, GFP_DMA | GFP_ATOMIC);
 	if (!uhci->qh_pool) {
-		printk(KERN_ERR "Unable to create qh pci_pool\n");
-		goto free_td_pool;
+		err("unable to create qh pci_pool");
+		goto err_create_qh_pool;
 	}
 
 	bus = usb_alloc_bus(&uhci_device_operations);
-	if (!bus)
-		goto free_qh_pool;
+	if (!bus) {
+		err("unable to allocate bus");
+		goto err_alloc_bus;
+	}
 
 	uhci->bus = bus;
 	bus->hcpriv = uhci;
 
+	usb_register_bus(uhci->bus);
+
 	/* Initialize the root hub */
 
 	/* UHCI specs says devices must have 2 ports, but goes on to say */
 	/*  they may have more but give no way to determine how many they */
 	/*  have. However, according to the UHCI spec, Bit 7 is always set */
 	/*  to 1. So we try to use this to our advantage */
-	for (port = 0; port < (io_size - 0x10) / 2; port++) {
+	for (port = 0; port < (uhci->io_size - 0x10) / 2; port++) {
 		unsigned int portstatus;
 
-		portstatus = inw(io_addr + 0x10 + (port * 2));
+		portstatus = inw(uhci->io_addr + 0x10 + (port * 2));
 		if (!(portstatus & 0x0080))
 			break;
 	}
@@ -2598,15 +2728,16 @@
 
 	uhci->rh.numports = port;
 
-	if (uhci_alloc_root_hub(uhci)) {
+	uhci->bus->root_hub = uhci->rh.dev = usb_alloc_dev(NULL, uhci->bus);
+	if (!uhci->rh.dev) {
 		err("unable to allocate root hub");
-		goto free_fl;
+		goto err_alloc_root_hub;
 	}
 
 	uhci->skeltd[0] = uhci_alloc_td(uhci, uhci->rh.dev);
 	if (!uhci->skeltd[0]) {
 		err("unable to allocate TD 0");
-		goto free_fl;
+		goto err_alloc_skeltd;
 	}
 
 	/*
@@ -2619,7 +2750,7 @@
 		td = uhci->skeltd[i] = uhci_alloc_td(uhci, uhci->rh.dev);
 		if (!td) {
 			err("unable to allocate TD %d", i);
-			goto free_tds;
+			goto err_alloc_skeltd;
 		}
 
 		uhci_fill_td(td, 0, (UHCI_NULL_DATA_SIZE << 21) | (0x7f << 8) | USB_PID_IN, 0);
@@ -2628,15 +2759,15 @@
 
 	uhci->skel_term_td = uhci_alloc_td(uhci, uhci->rh.dev);
 	if (!uhci->skel_term_td) {
-		err("unable to allocate TD 0");
-		goto free_fl;
+		err("unable to allocate skel TD term");
+		goto err_alloc_skeltd;
 	}
 
 	for (i = 0; i < UHCI_NUM_SKELQH; i++) {
 		uhci->skelqh[i] = uhci_alloc_qh(uhci, uhci->rh.dev);
 		if (!uhci->skelqh[i]) {
 			err("unable to allocate QH %d", i);
-			goto free_qhs;
+			goto err_alloc_skelqh;
 		}
 	}
 
@@ -2695,157 +2826,88 @@
 		uhci->fl->frame[i] =  uhci->skeltd[irq]->dma_handle;
 	}
 
-	return uhci;
-
-/*
- * error exits:
- */
-free_qhs:
-	for (i = 0; i < UHCI_NUM_SKELQH; i++)
-		if (uhci->skelqh[i]) {
-			uhci_free_qh(uhci, uhci->skelqh[i]);
-			uhci->skelqh[i] = NULL;
-		}
+	start_hc(uhci);
 
-free_tds:
-	for (i = 0; i < UHCI_NUM_SKELTD; i++)
-		if (uhci->skeltd[i]) {
-			uhci_free_td(uhci, uhci->skeltd[i]);
-			uhci->skeltd[i] = NULL;
-		}
+	if (request_irq(dev->irq, uhci_interrupt, SA_SHIRQ, "usb-uhci", uhci))
+		goto err_request_irq;
 
-free_qh_pool:
-	pci_pool_destroy(uhci->qh_pool);
+	uhci->irq = dev->irq;
 
-free_td_pool:
-	pci_pool_destroy(uhci->td_pool);
+	/* disable legacy emulation */
+	pci_write_config_word(uhci->dev, USBLEGSUP, USBLEGSUP_DEFAULT);
 
-free_fl:
-	pci_free_consistent(uhci->dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
+	usb_connect(uhci->rh.dev);
 
-free_uhci:
-	kfree(uhci);
+	if (usb_new_device(uhci->rh.dev) != 0) {
+		err("unable to start root hub");
+		retval = -ENOMEM;
+		goto err_start_root_hub;
+	}
 
-	return NULL;
-}
+	return 0;
 
 /*
- * De-allocate all resources..
+ * error exits:
  */
-static void release_uhci(struct uhci *uhci)
-{
-	int i;
-#ifdef CONFIG_PROC_FS
-	char buf[8];
-#endif
-
-	if (uhci->irq >= 0) {
-		free_irq(uhci->irq, uhci);
-		uhci->irq = -1;
-	}
+err_start_root_hub:
+	free_irq(uhci->irq, uhci);
+	uhci->irq = -1;
 
+err_request_irq:
 	for (i = 0; i < UHCI_NUM_SKELQH; i++)
 		if (uhci->skelqh[i]) {
 			uhci_free_qh(uhci, uhci->skelqh[i]);
 			uhci->skelqh[i] = NULL;
 		}
 
+err_alloc_skelqh:
 	for (i = 0; i < UHCI_NUM_SKELTD; i++)
 		if (uhci->skeltd[i]) {
 			uhci_free_td(uhci, uhci->skeltd[i]);
 			uhci->skeltd[i] = NULL;
 		}
 
-	if (uhci->qh_pool) {
-		pci_pool_destroy(uhci->qh_pool);
-		uhci->qh_pool = NULL;
-	}
-
-	if (uhci->td_pool) {
-		pci_pool_destroy(uhci->td_pool);
-		uhci->td_pool = NULL;
-	}
-
-	if (uhci->fl) {
-		pci_free_consistent(uhci->dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
-		uhci->fl = NULL;
-	}
+err_alloc_skeltd:
+	usb_free_dev(uhci->rh.dev);
+	uhci->rh.dev = NULL;
 
+err_alloc_root_hub:
 	usb_free_bus(uhci->bus);
+	uhci->bus = NULL;
 
-#ifdef CONFIG_PROC_FS
-	sprintf(buf, "hc%d", uhci->num);
-
-	remove_proc_entry(buf, uhci_proc_root);
-	uhci->proc_entry = NULL;
-#endif
-
-	kfree(uhci);
-}
-
-/*
- * If we've successfully found a UHCI, now is the time to return success..
- */
-static int setup_uhci(struct pci_dev *dev, int irq, unsigned int io_addr, unsigned int io_size)
-{
-	int retval;
-	struct uhci *uhci;
-	char buf[8], *bufp = buf;
-#ifdef CONFIG_PROC_FS
-	struct proc_dir_entry *ent;
-#endif
-
-#ifndef __sparc__
-	sprintf(buf, "%d", irq);
-#else
-	bufp = __irq_itoa(irq);
-#endif
-	printk(KERN_INFO __FILE__ ": USB UHCI at I/O 0x%x, IRQ %s\n",
-		io_addr, bufp);
+err_alloc_bus:
+	pci_pool_destroy(uhci->qh_pool);
+	uhci->qh_pool = NULL;
 
-	uhci = alloc_uhci(dev, io_addr, io_size);
-	if (!uhci)
-		return -ENOMEM;
+err_create_qh_pool:
+	pci_pool_destroy(uhci->td_pool);
+	uhci->td_pool = NULL;
 
-	dev->driver_data = uhci;
+err_create_td_pool:
+	pci_free_consistent(uhci->dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
+	uhci->fl = NULL;
 
+err_alloc_fl:
 #ifdef CONFIG_PROC_FS
-	uhci->num = uhci_num++;
-
-	sprintf(buf, "hc%d", uhci->num);
-
-	ent = create_proc_entry(buf, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
-	if (!ent)
-		return -ENOMEM;
+	remove_proc_entry(buf, uhci_proc_root);
+	uhci->proc_entry = NULL;
 
-	ent->data = uhci;
-	ent->proc_fops = &uhci_proc_operations;
-	ent->size = 0;
-	uhci->proc_entry = ent;
+err_create_proc_entry:
+	free_uhci(uhci);
 #endif
 
-	request_region(uhci->io_addr, io_size, "usb-uhci");
-
-	reset_hc(uhci);
+err_alloc_uhci:
 
-	usb_register_bus(uhci->bus);
-	start_hc(uhci);
+err_pci_set_dma_mask:
 
-	retval = -EBUSY;
-	if (request_irq(irq, uhci_interrupt, SA_SHIRQ, "usb-uhci", uhci) == 0) {
-		uhci->irq = irq;
+err_enable_device:
 
-		pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
+err_pci_dma_supported:
+	release_region(io_addr, io_size);
 
-		if (!uhci_start_root_hub(uhci))
-			return 0;
-	}
+err_invalid_irq:
 
-	/* Couldn't allocate IRQ if we got here */
-
-	reset_hc(uhci);
-	release_region(uhci->io_addr, uhci->io_size);
-	release_uhci(uhci);
+err_request_region:
 
 	return retval;
 }
@@ -2854,23 +2916,6 @@
 {
 	int i;
 
-	if (!pci_dma_supported(dev, 0xFFFFFFFF)) {
-		err("PCI subsystem doesn't support 32 bit addressing?");
-		return -ENODEV;
-	}
-	dev->dma_mask = 0xFFFFFFFF;
-
-	/* disable legacy emulation */
-	pci_write_config_word(dev, USBLEGSUP, 0);
-
-	if (pci_enable_device(dev) < 0)
-		return -ENODEV;
-
-	if (!dev->irq) {
-		err("found UHCI device with no IRQ assigned. check BIOS settings!");
-		return -ENODEV;
-	}
-
 	/* Search for the IO base address.. */
 	for (i = 0; i < 6; i++) {
 		unsigned int io_addr = pci_resource_start(dev, i);
@@ -2880,12 +2925,7 @@
 		if (!(pci_resource_flags(dev, i) & IORESOURCE_IO))
 			continue;
 
-		/* Is it already in use? */
-		if (check_region(io_addr, io_size))
-			break;
-
-		pci_set_master(dev);
-		return setup_uhci(dev, dev->irq, io_addr, io_size);
+		return alloc_uhci(dev, io_addr, io_size);
 	}
 
 	return -ENODEV;
@@ -2918,7 +2958,7 @@
 #ifdef CONFIG_PM
 static int uhci_pci_suspend(struct pci_dev *dev, u32 state)
 {
-	reset_hc((struct uhci *) dev->driver_data);
+	suspend_hc((struct uhci *) dev->driver_data);
 	return 0;
 }
 
@@ -2945,11 +2985,11 @@
 	}, { /* end: all zeroes */ }
 };
 
-MODULE_DEVICE_TABLE (pci, uhci_pci_ids);
+MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
 
 static struct pci_driver uhci_pci_driver = {
 	name:		"usb-uhci",
-	id_table:	&uhci_pci_ids [0],
+	id_table:	uhci_pci_ids,
 
 	probe:		uhci_pci_probe,
 	remove:		uhci_pci_remove,
@@ -2965,6 +3005,8 @@
 {
 	int retval = -ENOMEM;
 
+	info(DRIVER_DESC " " DRIVER_VERSION);
+
 	if (debug) {
 		errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
 		if (!errbuf)
@@ -2986,8 +3028,6 @@
 	if (retval)
 		goto init_failed;
 
-	info(DRIVER_VERSION ":" DRIVER_DESC);
-
 	return 0;
 
 init_failed:
@@ -3009,7 +3049,7 @@
 	return retval;
 }
 
-static void __exit uhci_hcd_cleanup (void) 
+static void __exit uhci_hcd_cleanup(void) 
 {
 	pci_unregister_driver(&uhci_pci_driver);
 	
@@ -3027,6 +3067,6 @@
 module_init(uhci_hcd_init);
 module_exit(uhci_hcd_cleanup);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/uhci.h linux/drivers/usb/uhci.h
--- v2.4.10/linux/drivers/usb/uhci.h	Tue Aug  7 12:52:03 2001
+++ linux/drivers/usb/uhci.h	Tue Oct  9 15:25:52 2001
@@ -53,8 +53,8 @@
 #define   USBPORTSC_SUSP	0x1000	/* Suspend */
 
 /* Legacy support register */
-#define USBLEGSUP 0xc0
-#define USBLEGSUP_DEFAULT	0x2000	/* only PIRQ enable set */
+#define USBLEGSUP		0xc0
+#define   USBLEGSUP_DEFAULT	0x2000	/* only PIRQ enable set */
 
 #define UHCI_NULL_DATA_SIZE	0x7FF	/* for UHCI controller TD */
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/ultracam.c linux/drivers/usb/ultracam.c
--- v2.4.10/linux/drivers/usb/ultracam.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/ultracam.c	Fri Oct  5 12:04:51 2001
@@ -0,0 +1,710 @@
+/*
+ * USB NB Camera driver
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/wrapper.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "usbvideo.h"
+
+#define	ULTRACAM_VENDOR_ID	0x0461
+#define	ULTRACAM_PRODUCT_ID	0x0813
+
+#define MAX_CAMERAS		4	/* How many devices we allow to connect */
+
+/*
+ * This structure lives in uvd_t->user field.
+ */
+typedef struct {
+	int initialized;	/* Had we already sent init sequence? */
+	int camera_model;	/* What type of IBM camera we got? */
+        int has_hdr;
+} ultracam_t;
+#define	ULTRACAM_T(uvd)	((ultracam_t *)((uvd)->user_data))
+
+static usbvideo_t *cams = NULL;
+
+static int debug = 0;
+
+static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
+
+static const int min_canvasWidth  = 8;
+static const int min_canvasHeight = 4;
+
+//static int lighting = 1; /* Medium */
+
+#define SHARPNESS_MIN	0
+#define SHARPNESS_MAX	6
+//static int sharpness = 4; /* Low noise, good details */
+
+#define FRAMERATE_MIN	0
+#define FRAMERATE_MAX	6
+static int framerate = -1;
+
+/*
+ * Here we define several initialization variables. They may
+ * be used to automatically set color, hue, brightness and
+ * contrast to desired values. This is particularly useful in
+ * case of webcams (which have no controls and no on-screen
+ * output) and also when a client V4L software is used that
+ * does not have some of those controls. In any case it's
+ * good to have startup values as options.
+ *
+ * These values are all in [0..255] range. This simplifies
+ * operation. Note that actual values of V4L variables may
+ * be scaled up (as much as << 8). User can see that only
+ * on overlay output, however, or through a V4L client.
+ */
+static int init_brightness = 128;
+static int init_contrast = 192;
+static int init_color = 128;
+static int init_hue = 128;
+static int hue_correction = 128;
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
+MODULE_PARM(flags, "i");
+MODULE_PARM_DESC(flags,
+		"Bitfield: 0=VIDIOCSYNC, "
+		"1=B/W, "
+		"2=show hints, "
+		"3=show stats, "
+		"4=test pattern, "
+		"5=separate frames, "
+		"6=clean frames");
+MODULE_PARM(framerate, "i");
+MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
+MODULE_PARM(lighting, "i");
+MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light");
+MODULE_PARM(sharpness, "i");
+MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)");
+
+MODULE_PARM(init_brightness, "i");
+MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
+MODULE_PARM(init_contrast, "i");
+MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
+MODULE_PARM(init_color, "i");
+MODULE_PARM_DESC(init_color, "Color preconfiguration: 0-255 (default=128)");
+MODULE_PARM(init_hue, "i");
+MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
+MODULE_PARM(hue_correction, "i");
+MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
+
+/*
+ * ultracam_ProcessIsocData()
+ *
+ * Generic routine to parse the ring queue data. It employs either
+ * ultracam_find_header() or ultracam_parse_lines() to do most
+ * of work.
+ *
+ * 02-Nov-2000 First (mostly dummy) version.
+ * 06-Nov-2000 Rewrote to dump all data into frame.
+ */
+void ultracam_ProcessIsocData(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+	int n;
+
+	assert(uvd != NULL);
+	assert(frame != NULL);
+
+	/* Try to move data from queue into frame buffer */
+	n = RingQueue_GetLength(&uvd->dp);
+	if (n > 0) {
+		int m;
+		/* See how much spare we have left */
+		m = uvd->max_frame_size - frame->seqRead_Length;
+		if (n > m)
+			n = m;
+		/* Now move that much data into frame buffer */
+		RingQueue_Dequeue(
+			&uvd->dp,
+			frame->data + frame->seqRead_Length,
+			m);
+		frame->seqRead_Length += m;
+	}
+	/* See if we filled the frame */
+	if (frame->seqRead_Length >= uvd->max_frame_size) {
+		frame->frameState = FrameState_Done;
+		uvd->curframe = -1;
+		uvd->stats.frame_num++;
+	}
+}
+
+/*
+ * ultracam_veio()
+ *
+ * History:
+ * 1/27/00  Added check for dev == NULL; this happens if camera is unplugged.
+ */
+static int ultracam_veio(
+	uvd_t *uvd,
+	unsigned char req,
+	unsigned short value,
+	unsigned short index,
+	int is_out)
+{
+	static const char proc[] = "ultracam_veio";
+	unsigned char cp[8] /* = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } */;
+	int i;
+
+	if (!CAMERA_IS_OPERATIONAL(uvd))
+		return 0;
+
+	if (!is_out) {
+		i = usb_control_msg(
+			uvd->dev,
+			usb_rcvctrlpipe(uvd->dev, 0),
+			req,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value,
+			index,
+			cp,
+			sizeof(cp),
+			HZ);
+#if 1
+		info("USB => %02x%02x%02x%02x%02x%02x%02x%02x "
+		       "(req=$%02x val=$%04x ind=$%04x)",
+		       cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
+		       req, value, index);
+#endif
+	} else {
+		i = usb_control_msg(
+			uvd->dev,
+			usb_sndctrlpipe(uvd->dev, 0),
+			req,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value,
+			index,
+			NULL,
+			0,
+			HZ);
+	}
+	if (i < 0) {
+		err("%s: ERROR=%d. Camera stopped; Reconnect or reload driver.",
+		    proc, i);
+		uvd->last_error = i;
+	}
+	return i;
+}
+
+/*
+ * ultracam_calculate_fps()
+ */
+static int ultracam_calculate_fps(uvd_t *uvd)
+{
+	return 3 + framerate*4 + framerate/2;
+}
+
+/*
+ * ultracam_adjust_contrast()
+ */
+static void ultracam_adjust_contrast(uvd_t *uvd)
+{
+}
+
+/*
+ * ultracam_change_lighting_conditions()
+ */
+static void ultracam_change_lighting_conditions(uvd_t *uvd)
+{
+}
+
+/*
+ * ultracam_set_sharpness()
+ *
+ * Cameras model 1 have internal smoothing feature. It is controlled by value in
+ * range [0..6], where 0 is most smooth and 6 is most sharp (raw image, I guess).
+ * Recommended value is 4. Cameras model 2 do not have this feature at all.
+ */
+static void ultracam_set_sharpness(uvd_t *uvd)
+{
+}
+
+/*
+ * ultracam_set_brightness()
+ *
+ * This procedure changes brightness of the picture.
+ */
+static void ultracam_set_brightness(uvd_t *uvd)
+{
+}
+
+static void ultracam_set_hue(uvd_t *uvd)
+{
+}
+
+/*
+ * ultracam_adjust_picture()
+ *
+ * This procedure gets called from V4L interface to update picture settings.
+ * Here we change brightness and contrast.
+ */
+static void ultracam_adjust_picture(uvd_t *uvd)
+{
+	ultracam_adjust_contrast(uvd);
+	ultracam_set_brightness(uvd);
+	ultracam_set_hue(uvd);
+}
+
+/*
+ * ultracam_video_stop()
+ *
+ * This code tells camera to stop streaming. The interface remains
+ * configured and bandwidth - claimed.
+ */
+static void ultracam_video_stop(uvd_t *uvd)
+{
+}
+
+/*
+ * ultracam_reinit_iso()
+ *
+ * This procedure sends couple of commands to the camera and then
+ * resets the video pipe. This sequence was observed to reinit the
+ * camera or, at least, to initiate ISO data stream.
+ */
+static void ultracam_reinit_iso(uvd_t *uvd, int do_stop)
+{
+}
+
+static void ultracam_video_start(uvd_t *uvd)
+{
+	ultracam_change_lighting_conditions(uvd);
+	ultracam_set_sharpness(uvd);
+	ultracam_reinit_iso(uvd, 0);
+}
+
+static int ultracam_resetPipe(uvd_t *uvd)
+{
+	usb_clear_halt(uvd->dev, uvd->video_endp);
+	return 0;
+}
+
+static int ultracam_alternateSetting(uvd_t *uvd, int setting)
+{
+	static const char proc[] = "ultracam_alternateSetting";
+	int i;
+	i = usb_set_interface(uvd->dev, uvd->iface, setting);
+	if (i < 0) {
+		err("%s: usb_set_interface error", proc);
+		uvd->last_error = i;
+		return -EBUSY;
+	}
+	return 0;
+}
+
+/*
+ * Return negative code on failure, 0 on success.
+ */
+static int ultracam_setup_on_open(uvd_t *uvd)
+{
+	int setup_ok = 0; /* Success by default */
+	/* Send init sequence only once, it's large! */
+	if (!ULTRACAM_T(uvd)->initialized) {
+		ultracam_alternateSetting(uvd, 0x04);
+		ultracam_alternateSetting(uvd, 0x00);
+		ultracam_veio(uvd, 0x02, 0x0004, 0x000b, 1);
+		ultracam_veio(uvd, 0x02, 0x0001, 0x0005, 1);
+		ultracam_veio(uvd, 0x02, 0x8000, 0x0000, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
+		ultracam_veio(uvd, 0x00, 0x00b0, 0x0001, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x0002, 1);
+		ultracam_veio(uvd, 0x00, 0x000c, 0x0003, 1);
+		ultracam_veio(uvd, 0x00, 0x000b, 0x0004, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x0005, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x0006, 1);
+		ultracam_veio(uvd, 0x00, 0x0079, 0x0007, 1);
+		ultracam_veio(uvd, 0x00, 0x003b, 0x0008, 1);
+		ultracam_veio(uvd, 0x00, 0x0002, 0x000f, 1);
+		ultracam_veio(uvd, 0x00, 0x0001, 0x0010, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x0011, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00bf, 1);
+		ultracam_veio(uvd, 0x00, 0x0001, 0x00c0, 1);
+		ultracam_veio(uvd, 0x00, 0x0010, 0x00cb, 1);
+		ultracam_veio(uvd, 0x01, 0x00a4, 0x0001, 1);
+		ultracam_veio(uvd, 0x01, 0x0010, 0x0002, 1);
+		ultracam_veio(uvd, 0x01, 0x0066, 0x0007, 1);
+		ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
+		ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
+		ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
+		ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
+		ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
+		ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
+		ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
+		ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
+		ultracam_veio(uvd, 0x01, 0x000b, 0x0011, 1);
+		ultracam_veio(uvd, 0x01, 0x0001, 0x0012, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0013, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0014, 1);
+		ultracam_veio(uvd, 0x01, 0x0087, 0x0051, 1);
+		ultracam_veio(uvd, 0x01, 0x0040, 0x0052, 1);
+		ultracam_veio(uvd, 0x01, 0x0058, 0x0053, 1);
+		ultracam_veio(uvd, 0x01, 0x0040, 0x0054, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0040, 1);
+		ultracam_veio(uvd, 0x01, 0x0010, 0x0041, 1);
+		ultracam_veio(uvd, 0x01, 0x0020, 0x0042, 1);
+		ultracam_veio(uvd, 0x01, 0x0030, 0x0043, 1);
+		ultracam_veio(uvd, 0x01, 0x0040, 0x0044, 1);
+		ultracam_veio(uvd, 0x01, 0x0050, 0x0045, 1);
+		ultracam_veio(uvd, 0x01, 0x0060, 0x0046, 1);
+		ultracam_veio(uvd, 0x01, 0x0070, 0x0047, 1);
+		ultracam_veio(uvd, 0x01, 0x0080, 0x0048, 1);
+		ultracam_veio(uvd, 0x01, 0x0090, 0x0049, 1);
+		ultracam_veio(uvd, 0x01, 0x00a0, 0x004a, 1);
+		ultracam_veio(uvd, 0x01, 0x00b0, 0x004b, 1);
+		ultracam_veio(uvd, 0x01, 0x00c0, 0x004c, 1);
+		ultracam_veio(uvd, 0x01, 0x00d0, 0x004d, 1);
+		ultracam_veio(uvd, 0x01, 0x00e0, 0x004e, 1);
+		ultracam_veio(uvd, 0x01, 0x00f0, 0x004f, 1);
+		ultracam_veio(uvd, 0x01, 0x00ff, 0x0050, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0056, 1);
+		ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0080, 0x00c1, 1);
+		ultracam_veio(uvd, 0x00, 0x0004, 0x00c2, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0002, 0x00c1, 1);
+		ultracam_veio(uvd, 0x00, 0x0020, 0x00c2, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0040, 0x00c1, 1);
+		ultracam_veio(uvd, 0x00, 0x0017, 0x00c2, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c3, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c4, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c5, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c6, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c7, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c8, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c9, 1);
+		ultracam_veio(uvd, 0x00, 0x00c0, 0x00c1, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00c2, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
+		ultracam_veio(uvd, 0x02, 0xc040, 0x0001, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0008, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0009, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000b, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000c, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000d, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000e, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000f, 0);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0010, 0);
+		ultracam_veio(uvd, 0x01, 0x000b, 0x0008, 1);
+		ultracam_veio(uvd, 0x01, 0x0034, 0x0009, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x000a, 1);
+		ultracam_veio(uvd, 0x01, 0x002e, 0x000b, 1);
+		ultracam_veio(uvd, 0x01, 0x00d6, 0x000c, 1);
+		ultracam_veio(uvd, 0x01, 0x00fc, 0x000d, 1);
+		ultracam_veio(uvd, 0x01, 0x00f1, 0x000e, 1);
+		ultracam_veio(uvd, 0x01, 0x00da, 0x000f, 1);
+		ultracam_veio(uvd, 0x01, 0x0036, 0x0010, 1);
+		ultracam_veio(uvd, 0x01, 0x0000, 0x0001, 0);
+		ultracam_veio(uvd, 0x01, 0x0064, 0x0001, 1);
+		ultracam_veio(uvd, 0x01, 0x0059, 0x0051, 1);
+		ultracam_veio(uvd, 0x01, 0x003f, 0x0052, 1);
+		ultracam_veio(uvd, 0x01, 0x0094, 0x0053, 1);
+		ultracam_veio(uvd, 0x01, 0x00ff, 0x0011, 1);
+		ultracam_veio(uvd, 0x01, 0x0003, 0x0012, 1);
+		ultracam_veio(uvd, 0x01, 0x00f7, 0x0013, 1);
+		ultracam_veio(uvd, 0x00, 0x0009, 0x0011, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x0001, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x0000, 1);
+		ultracam_veio(uvd, 0x00, 0x0020, 0x00c1, 1);
+		ultracam_veio(uvd, 0x00, 0x0010, 0x00c2, 1);
+		ultracam_veio(uvd, 0x00, 0x0000, 0x00ca, 1);
+		ultracam_alternateSetting(uvd, 0x04);
+		ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
+		ultracam_veio(uvd, 0x02, 0x0000, 0x0001, 1);
+		ultracam_veio(uvd, 0x02, 0x0000, 0x0006, 1);
+		ultracam_veio(uvd, 0x02, 0x9000, 0x0007, 1);
+		ultracam_veio(uvd, 0x02, 0x0042, 0x0001, 1);
+		ultracam_veio(uvd, 0x02, 0x0000, 0x000b, 0);
+		ultracam_resetPipe(uvd);
+		ULTRACAM_T(uvd)->initialized = (setup_ok != 0);
+	}
+	return setup_ok;
+}
+
+static void ultracam_configure_video(uvd_t *uvd)
+{
+	if (uvd == NULL)
+		return;
+
+	RESTRICT_TO_RANGE(init_brightness, 0, 255);
+	RESTRICT_TO_RANGE(init_contrast, 0, 255);
+	RESTRICT_TO_RANGE(init_color, 0, 255);
+	RESTRICT_TO_RANGE(init_hue, 0, 255);
+	RESTRICT_TO_RANGE(hue_correction, 0, 255);
+
+	memset(&uvd->vpic, 0, sizeof(uvd->vpic));
+	memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
+
+	uvd->vpic.colour = init_color << 8;
+	uvd->vpic.hue = init_hue << 8;
+	uvd->vpic.brightness = init_brightness << 8;
+	uvd->vpic.contrast = init_contrast << 8;
+	uvd->vpic.whiteness = 105 << 8; /* This one isn't used */
+	uvd->vpic.depth = 24;
+	uvd->vpic.palette = VIDEO_PALETTE_RGB24;
+
+	memset(&uvd->vcap, 0, sizeof(uvd->vcap));
+	strcpy(uvd->vcap.name, "IBM Ultra Camera");
+	uvd->vcap.type = VID_TYPE_CAPTURE;
+	uvd->vcap.channels = 1;
+	uvd->vcap.audios = 0;
+	uvd->vcap.maxwidth = VIDEOSIZE_X(uvd->canvas);
+	uvd->vcap.maxheight = VIDEOSIZE_Y(uvd->canvas);
+	uvd->vcap.minwidth = min_canvasWidth;
+	uvd->vcap.minheight = min_canvasHeight;
+
+	memset(&uvd->vchan, 0, sizeof(uvd->vchan));
+	uvd->vchan.flags = 0;
+	uvd->vchan.tuners = 0;
+	uvd->vchan.channel = 0;
+	uvd->vchan.type = VIDEO_TYPE_CAMERA;
+	strcpy(uvd->vchan.name, "Camera");
+}
+
+/*
+ * ultracam_probe()
+ *
+ * This procedure queries device descriptor and accepts the interface
+ * if it looks like our camera.
+ *
+ * History:
+ * 12-Nov-2000 Reworked to comply with new probe() signature.
+ * 23-Jan-2001 Added compatibility with 2.2.x kernels.
+ */
+static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum
+#if defined(usb_device_id_ver)
+	,const struct usb_device_id *devid
+#endif
+	)
+{
+	uvd_t *uvd = NULL;
+	int i, nas;
+	int actInterface=-1, inactInterface=-1, maxPS=0;
+	unsigned char video_ep = 0;
+
+	if (debug >= 1)
+		info("ultracam_probe(%p,%u.)", dev, ifnum);
+
+	/* We don't handle multi-config cameras */
+	if (dev->descriptor.bNumConfigurations != 1)
+		return NULL;
+
+	/* Is it an IBM camera? */
+	if ((dev->descriptor.idVendor != ULTRACAM_VENDOR_ID) ||
+	    (dev->descriptor.idProduct != ULTRACAM_PRODUCT_ID))
+		return NULL;
+
+	info("IBM Ultra camera found (rev. 0x%04x)", dev->descriptor.bcdDevice);
+
+	/* Validate found interface: must have one ISO endpoint */
+	nas = dev->actconfig->interface[ifnum].num_altsetting;
+	if (debug > 0)
+		info("Number of alternate settings=%d.", nas);
+	if (nas < 8) {
+		err("Too few alternate settings for this camera!");
+		return NULL;
+	}
+	/* Validate all alternate settings */
+	for (i=0; i < nas; i++) {
+		const struct usb_interface_descriptor *interface;
+		const struct usb_endpoint_descriptor *endpoint;
+
+		interface = &dev->actconfig->interface[ifnum].altsetting[i];
+		if (interface->bNumEndpoints != 1) {
+			err("Interface %d. has %u. endpoints!",
+			    ifnum, (unsigned)(interface->bNumEndpoints));
+			return NULL;
+		}
+		endpoint = &interface->endpoint[0];
+		if (video_ep == 0)
+			video_ep = endpoint->bEndpointAddress;
+		else if (video_ep != endpoint->bEndpointAddress) {
+			err("Alternate settings have different endpoint addresses!");
+			return NULL;
+		}
+		if ((endpoint->bmAttributes & 0x03) != 0x01) {
+			err("Interface %d. has non-ISO endpoint!", ifnum);
+			return NULL;
+		}
+		if ((endpoint->bEndpointAddress & 0x80) == 0) {
+			err("Interface %d. has ISO OUT endpoint!", ifnum);
+			return NULL;
+		}
+		if (endpoint->wMaxPacketSize == 0) {
+			if (inactInterface < 0)
+				inactInterface = i;
+			else {
+				err("More than one inactive alt. setting!");
+				return NULL;
+			}
+		} else {
+			if (actInterface < 0) {
+				actInterface = i;
+				maxPS = endpoint->wMaxPacketSize;
+				if (debug > 0)
+					info("Active setting=%d. maxPS=%d.", i, maxPS);
+			} else {
+				/* Got another active alt. setting */
+				if (maxPS < endpoint->wMaxPacketSize) {
+					/* This one is better! */
+					actInterface = i;
+					maxPS = endpoint->wMaxPacketSize;
+					if (debug > 0) {
+						info("Even better ctive setting=%d. maxPS=%d.",
+						     i, maxPS);
+					}
+				}
+			}
+		}
+	}
+	if ((maxPS <= 0) || (actInterface < 0) || (inactInterface < 0)) {
+		err("Failed to recognize the camera!");
+		return NULL;
+	}
+
+	/* Code below may sleep, need to lock module while we are here */
+	MOD_INC_USE_COUNT;
+	uvd = usbvideo_AllocateDevice(cams);
+	if (uvd != NULL) {
+		/* Here uvd is a fully allocated uvd_t object */
+		uvd->flags = flags;
+		uvd->debug = debug;
+		uvd->dev = dev;
+		uvd->iface = ifnum;
+		uvd->ifaceAltInactive = inactInterface;
+		uvd->ifaceAltActive = actInterface;
+		uvd->video_endp = video_ep;
+		uvd->iso_packet_len = maxPS;
+		uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
+		uvd->defaultPalette = VIDEO_PALETTE_RGB24;
+		uvd->canvas = VIDEOSIZE(640, 480);	/* FIXME */
+		uvd->videosize = uvd->canvas; /* ultracam_size_to_videosize(size);*/
+
+		/* Initialize ibmcam-specific data */
+		assert(ULTRACAM_T(uvd) != NULL);
+		ULTRACAM_T(uvd)->camera_model = 0; /* Not used yet */
+		ULTRACAM_T(uvd)->initialized = 0;
+
+		ultracam_configure_video(uvd);
+
+		i = usbvideo_RegisterVideoDevice(uvd);
+		if (i != 0) {
+			err("usbvideo_RegisterVideoDevice() failed.");
+			uvd = NULL;
+		}
+	}
+	MOD_DEC_USE_COUNT;
+	return uvd;
+}
+
+/*
+ * ultracam_init()
+ *
+ * This code is run to initialize the driver.
+ */
+static int __init ultracam_init(void)
+{
+	usbvideo_cb_t cbTbl;
+	memset(&cbTbl, 0, sizeof(cbTbl));
+	cbTbl.probe = ultracam_probe;
+	cbTbl.setupOnOpen = ultracam_setup_on_open;
+	cbTbl.videoStart = ultracam_video_start;
+	cbTbl.videoStop = ultracam_video_stop;
+	cbTbl.processData = ultracam_ProcessIsocData;
+	cbTbl.postProcess = usbvideo_DeinterlaceFrame;
+	cbTbl.adjustPicture = ultracam_adjust_picture;
+	cbTbl.getFPS = ultracam_calculate_fps;
+	return usbvideo_register(
+		&cams,
+		MAX_CAMERAS,
+		sizeof(ultracam_t),
+		"ultracam",
+		&cbTbl,
+		THIS_MODULE);
+}
+
+static void __exit ultracam_cleanup(void)
+{
+	usbvideo_Deregister(&cams);
+}
+
+#if defined(usb_device_id_ver)
+
+static __devinitdata struct usb_device_id id_table[] = {
+	{ USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) },
+	{ }  /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+
+#endif /* defined(usb_device_id_ver) */
+MODULE_LICENSE("GPL");
+
+module_init(ultracam_init);
+module_exit(ultracam_cleanup);
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/usb-skeleton.c linux/drivers/usb/usb-skeleton.c
--- v2.4.10/linux/drivers/usb/usb-skeleton.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/usb-skeleton.c	Mon Oct  1 13:45:48 2001
@@ -1,5 +1,5 @@
 /*
- * USB Skeleton driver - 0.4
+ * USB Skeleton driver - 0.5
  *
  * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
  *
@@ -22,6 +22,7 @@
  *
  * History:
  *
+ * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux
  * 2001_08_21 - 0.4 - more small bug fixes.
  * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel
  * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people
@@ -598,6 +599,9 @@
 		
 	minor = dev->minor;
 
+	/* remove our devfs node */
+	devfs_unregister(dev->devfs);
+
 	/* if the device is not opened, then we clean up right now */
 	if (!dev->open_count) {
 		skel_delete (dev);
@@ -605,9 +609,6 @@
 		dev->udev = NULL;
 		up (&dev->sem);
 	}
-
-	/* remove our devfs node */
-	devfs_unregister(dev->devfs);
 
 	info("USB Skeleton #%d now disconnected", minor);
 	up (&minor_table_mutex);
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/usb-uhci.c linux/drivers/usb/usb-uhci.c
--- v2.4.10/linux/drivers/usb/usb-uhci.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/usb-uhci.c	Tue Oct  9 15:15:02 2001
@@ -71,9 +71,6 @@
 #define DEBUG_SYMBOLS
 #ifdef DEBUG_SYMBOLS
 	#define _static
-	#ifndef EXPORT_SYMTAB
-		#define EXPORT_SYMTAB
-	#endif
 #else
 	#define _static static
 #endif
@@ -2528,7 +2525,7 @@
 	int i;
 	int ret = 0;
 	urb_priv_t *urb_priv = urb->hcpriv;
-	struct list_head *p = urb_priv->desc_list.next;
+	struct list_head *p = urb_priv->desc_list.next, *p_tmp;
 	uhci_desc_t *desc = list_entry (urb_priv->desc_list.prev, uhci_desc_t, desc_list);
 
 	dbg("urb contains iso request");
@@ -2578,8 +2575,9 @@
 		dbg("process_iso: %i: len:%d %08x status:%x",
 		     i, urb->iso_frame_desc[i].actual_length, le32_to_cpu(desc->hw.td.status),urb->iso_frame_desc[i].status);
 
-		list_del (p);
+		p_tmp = p;
 		p = p->next;
+		list_del (p_tmp);
 		delete_desc (s, desc);
 	}
 	
@@ -3131,4 +3129,5 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
 
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.4.10/linux/drivers/usb/usb.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/usb.c	Tue Oct  9 15:15:02 2001
@@ -1042,15 +1042,11 @@
  *-------------------------------------------------------------------*/
 static void usb_api_blocking_completion(urb_t *urb)
 {
-	api_wrapper_data *awd = (api_wrapper_data *)urb->context;
+	struct usb_api_data *awd = (struct usb_api_data *)urb->context;
 
-	if (waitqueue_active(awd->wakeup))
-		wake_up(awd->wakeup);
-#if 0
-	else
-		dbg("(blocking_completion): waitqueue empty!"); 
-		// even occurs if urb was unlinked by timeout...
-#endif
+	awd->done = 1;
+	wmb();
+	wake_up(&awd->wqh);
 }
 
 /*-------------------------------------------------------------------*
@@ -1061,38 +1057,46 @@
 static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length)
 { 
 	DECLARE_WAITQUEUE(wait, current);
-	DECLARE_WAIT_QUEUE_HEAD(wqh);
-	api_wrapper_data awd;
+	struct usb_api_data awd;
 	int status;
-  
-	awd.wakeup = &wqh;
-	init_waitqueue_head(&wqh); 	
-	current->state = TASK_INTERRUPTIBLE;
-	add_wait_queue(&wqh, &wait);
+
+	init_waitqueue_head(&awd.wqh); 	
+	awd.done = 0;
+
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(&awd.wqh, &wait);
+
 	urb->context = &awd;
 	status = usb_submit_urb(urb);
 	if (status) {
 		// something went wrong
 		usb_free_urb(urb);
-		current->state = TASK_RUNNING;
-		remove_wait_queue(&wqh, &wait);
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&awd.wqh, &wait);
 		return status;
 	}
 
-	if (urb->status == -EINPROGRESS) {
-		while (timeout && urb->status == -EINPROGRESS)
-			status = timeout = schedule_timeout(timeout);
-	} else
-		status = 1;
-
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&wqh, &wait);
-
-	if (!status) {
-		// timeout
-		printk("usb_control/bulk_msg: timeout\n");
-		usb_unlink_urb(urb);  // remove urb safely
-		status = -ETIMEDOUT;
+	while (timeout && !awd.done)
+	{
+		timeout = schedule_timeout(timeout);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		rmb();
+	}
+
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&awd.wqh, &wait);
+
+	if (!timeout && !awd.done) {
+		if (urb->status != -EINPROGRESS) {	/* No callback?!! */
+			printk(KERN_ERR "usb: raced timeout, "
+			    "pipe 0x%x status %d time left %d\n",
+			    urb->pipe, urb->status, timeout);
+			status = urb->status;
+		} else {
+			printk("usb_control/bulk_msg: timeout\n");
+			usb_unlink_urb(urb);  // remove urb safely
+			status = -ETIMEDOUT;
+		}
 	} else
 		status = urb->status;
 
@@ -1116,15 +1120,14 @@
 	if (!urb)
 		return -ENOMEM;
   
-	FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len,    /* build urb */  
-		   (usb_complete_t)usb_api_blocking_completion,0);
+	FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len,
+		   usb_api_blocking_completion, 0);
 
 	retv = usb_start_wait_urb(urb, timeout, &length);
 	if (retv < 0)
 		return retv;
 	else
 		return length;
-	
 }
 
 /**
@@ -1205,8 +1208,8 @@
 	if (!urb)
 		return -ENOMEM;
 
-	FILL_BULK_URB(urb,usb_dev,pipe,(unsigned char*)data,len,   /* build urb */
-			(usb_complete_t)usb_api_blocking_completion,0);
+	FILL_BULK_URB(urb, usb_dev, pipe, data, len,
+		    usb_api_blocking_completion, 0);
 
 	return usb_start_wait_urb(urb,timeout,actual_length);
 }
@@ -1767,8 +1770,11 @@
  * These are the actual routines to send
  * and receive control messages.
  */
-
+#ifdef CONFIG_USB_LONG_TIMEOUT
+#define GET_TIMEOUT 4
+#else
 #define GET_TIMEOUT 3
+#endif
 #define SET_TIMEOUT 3
 
 int usb_set_address(struct usb_device *dev)
@@ -2397,6 +2403,7 @@
 EXPORT_SYMBOL(usb_set_interface);
 EXPORT_SYMBOL(usb_get_configuration);
 EXPORT_SYMBOL(usb_set_configuration);
+EXPORT_SYMBOL(usb_get_status);
 
 EXPORT_SYMBOL(usb_get_current_frame_number);
 
@@ -2409,3 +2416,4 @@
 EXPORT_SYMBOL(usb_bulk_msg);
 
 EXPORT_SYMBOL(usb_devfs_handle);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/usbvideo.c linux/drivers/usb/usbvideo.c
--- v2.4.10/linux/drivers/usb/usbvideo.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/usbvideo.c	Sun Sep 30 12:26:08 2001
@@ -1181,7 +1181,7 @@
 	assert(uvd->handle != NULL);
 	if (uvd->handle->uses_procfs) {
 		if (uvd->debug > 0) {
-			info("%s: Creating /proc/%s/ filesystem entries.",
+			info("%s: Creating /proc/video/%s/ filesystem entries.",
 			     proc, uvd->handle->drvName);
 		}
 		usbvideo_procfs_level2_create(uvd);
@@ -2472,3 +2472,4 @@
 }
 
 #endif /* USES_PROC_FS */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/usbvideo.h linux/drivers/usb/usbvideo.h
--- v2.4.10/linux/drivers/usb/usbvideo.h	Sun Sep 23 11:41:00 2001
+++ linux/drivers/usb/usbvideo.h	Fri Oct  5 12:04:51 2001
@@ -255,13 +255,7 @@
  * that default to usbvideo-provided methods.
  */
 typedef struct {
-#if defined(usb_device_id_ver)
-	/* New style probe (for 2.4.x kernels with hotplugging) */
 	void *(*probe)(struct usb_device *, unsigned int,const struct usb_device_id *);
-#else
-	/* Old style probe (for 2.2.x kernels) */
-	void *(*probe)(struct usb_device *, unsigned int);
-#endif
 	void (*userFree)(uvd_t *);
 	void (*disconnect)(struct usb_device *, void *);
 	int (*setupOnOpen)(uvd_t *);
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/uss720.c linux/drivers/usb/uss720.c
--- v2.4.10/linux/drivers/usb/uss720.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/usb/uss720.c	Tue Oct  9 15:15:02 2001
@@ -75,9 +75,10 @@
 	if (!usbdev)
 		return -1;
 	ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev,0), 3, 0xc0, ((unsigned int)reg) << 8, 0, priv->reg, 7, HZ);
-	if (ret) {
-		printk(KERN_DEBUG "uss720: get_1284_register(%d) failed, status 0x%x\n",
+	if (ret != 7) {
+		printk(KERN_DEBUG "uss720: get_1284_register(%d) failed, status 0x%x expected 7\n",
 		       (unsigned int)reg, ret);
+		ret = -1;
 	} else {
 #if 0
 		printk(KERN_DEBUG "uss720: get_1284_register(%d) return %02x %02x %02x %02x %02x %02x %02x\n",
@@ -88,6 +89,7 @@
 		/* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
 		if (priv->reg[2] & priv->reg[1] & 0x10)
 			parport_generic_irq(0, pp, NULL);
+		ret = 0;
 	}
 	if (val)
 		*val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
@@ -636,6 +638,7 @@
 	{ USB_DEVICE(0x047e, 0x1001) },
 	{ USB_DEVICE(0x0557, 0x2001) },
 	{ USB_DEVICE(0x0729, 0x1284) },
+	{ USB_DEVICE(0x1293, 0x0002) },
 	{ }						/* Terminating entry */
 };
 
@@ -653,6 +656,7 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
 
 static int __init uss720_init(void)
 {
diff -u --recursive --new-file v2.4.10/linux/drivers/video/clgenfb.c linux/drivers/video/clgenfb.c
--- v2.4.10/linux/drivers/video/clgenfb.c	Wed Jul 25 17:10:24 2001
+++ linux/drivers/video/clgenfb.c	Tue Oct  9 15:13:02 2001
@@ -31,7 +31,7 @@
  *
  */
 
-#define CLGEN_VERSION "1.9.8"
+#define CLGEN_VERSION "1.9.9"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -273,6 +273,7 @@
 	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_8 },
 	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_4 },
 	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5430 }, /* GD-5440 has identical id */
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7543 },
 	{ BT_GD5480, NULL, PCI_DEVICE_ID_CIRRUS_5480 }, /* MacPicasso probably */
 	{ BT_PICASSO4, NULL, PCI_DEVICE_ID_CIRRUS_5446 }, /* Picasso 4 is a GD5446 */
 	{ BT_LAGUNA, "CL Laguna", PCI_DEVICE_ID_CIRRUS_5462 },
@@ -2706,7 +2707,7 @@
 	}
 
 #elif defined(CONFIG_ZORRO)
-	/* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
+	/* FIXME: CONFIG_PCI and CONFIG_ZORRO may both be defined */
 	if (clgen_zorro_setup (fb_info, &btype)) {
 		DPRINTK ("EXIT, returning -ENXIO\n");
 		return -ENXIO;
diff -u --recursive --new-file v2.4.10/linux/drivers/video/controlfb.c linux/drivers/video/controlfb.c
--- v2.4.10/linux/drivers/video/controlfb.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/controlfb.c	Tue Oct  2 09:10:31 2001
@@ -51,6 +51,7 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pgtable.h>
+#include <asm/btext.h>
 
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
@@ -757,6 +758,12 @@
 		console_fb_info = &p->info;
 	}
 #endif /* CONFIG_FB_COMPAT_XPMAC */
+#ifdef CONFIG_BOOTX_TEXT
+	btext_update_display(p->frame_buffer_phys + CTRLFB_OFF,
+			     p->par.xres, p->par.yres,
+			     (cmode == CMODE_32? 32: cmode == CMODE_16? 16: 8),
+			     p->par.pitch);
+#endif /* CONFIG_BOOTX_TEXT */
 }
 
 
diff -u --recursive --new-file v2.4.10/linux/drivers/video/fbgen.c linux/drivers/video/fbgen.c
--- v2.4.10/linux/drivers/video/fbgen.c	Fri Mar  2 18:38:39 2001
+++ linux/drivers/video/fbgen.c	Sun Sep 30 12:26:08 2001
@@ -440,3 +440,4 @@
     } else
 	fbgen_install_cmap(currcon, info2);
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/video/matrox/i2c-matroxfb.c linux/drivers/video/matrox/i2c-matroxfb.c
--- v2.4.10/linux/drivers/video/matrox/i2c-matroxfb.c	Fri Mar 10 10:48:47 2000
+++ linux/drivers/video/matrox/i2c-matroxfb.c	Sun Sep 30 12:26:08 2001
@@ -349,3 +349,4 @@
 module_init(i2c_matroxfb_init);
 module_exit(i2c_matroxfb_exit);
 /* no __setup required */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/video/matrox/matroxfb_DAC1064.c linux/drivers/video/matrox/matroxfb_DAC1064.c
--- v2.4.10/linux/drivers/video/matrox/matroxfb_DAC1064.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/video/matrox/matroxfb_DAC1064.c	Sun Sep 30 12:26:08 2001
@@ -4,7 +4,7 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.53 2001/06/18
+ * Version: 1.54 2001/09/09
  *
  * See matroxfb_base.c for contributors.
  *
@@ -319,7 +319,7 @@
 	outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
 	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
 		outDAC1064(PMINFO 0x20, 0x04);
-		outDAC1064(PMINFO 0x1F, 0x00);
+		outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type));
 		if (ACCESS_FBINFO(devflags.g450dac)) {
 			outDAC1064(PMINFO M1064_X8B, 0xCC);	/* only matrox know... */
 			outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
@@ -851,6 +851,11 @@
 		}
 	}
 	DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
+	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
+		if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
+			ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
+		}
+	}
 	if (ACCESS_FBINFO(devflags.noinit))
 		return;
 	MGAG100_setPixClock(PMINFO 4, 25175);
@@ -929,3 +934,4 @@
 EXPORT_SYMBOL(DAC1064_global_init);
 EXPORT_SYMBOL(DAC1064_global_restore);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/video/matrox/matroxfb_Ti3026.c linux/drivers/video/matrox/matroxfb_Ti3026.c
--- v2.4.10/linux/drivers/video/matrox/matroxfb_Ti3026.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/video/matrox/matroxfb_Ti3026.c	Sun Sep 30 12:26:08 2001
@@ -863,3 +863,4 @@
 };
 EXPORT_SYMBOL(matrox_millennium);
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/video/matrox/matroxfb_accel.c linux/drivers/video/matrox/matroxfb_accel.c
--- v2.4.10/linux/drivers/video/matrox/matroxfb_accel.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/video/matrox/matroxfb_accel.c	Sun Sep 30 12:26:08 2001
@@ -1237,3 +1237,4 @@
 		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs;
 	}
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- v2.4.10/linux/drivers/video/matrox/matroxfb_base.c	Tue Jul  3 17:08:21 2001
+++ linux/drivers/video/matrox/matroxfb_base.c	Sun Sep 30 12:26:08 2001
@@ -4,7 +4,7 @@
  *
  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.53 2001/06/18
+ * Version: 1.54 2001/09/09
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -1326,6 +1326,7 @@
 static unsigned int fh;			/* "matrox:fh:xxxxxk" */
 static unsigned int maxclk;		/* "matrox:maxclk:xxxxM" */
 static int dfp;				/* "matrox:dfp */
+static int dfp_type = -1;		/* "matrox:dfp:xxx */
 static int memtype = -1;		/* "matrox:memtype:xxx" */
 static char fontname[64];		/* "matrox:font:xxxxx" */
 
@@ -1640,6 +1641,7 @@
 		if (dfp)
 			ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_DFP;
 	}
+	ACCESS_FBINFO(devflags.dfp_type) = dfp_type;
 	ACCESS_FBINFO(devflags.g450dac) = b->flags & DEVF_G450DAC;
 	ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode);
 	ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
@@ -2155,6 +2157,7 @@
 
 MODULE_DEVICE_TABLE(pci, matroxfb_devices);
 
+
 static struct pci_driver matroxfb_driver = {
 	name:		"matroxfb",
 	id_table:	matroxfb_devices,
@@ -2405,6 +2408,10 @@
 			mem = simple_strtoul(this_opt+4, NULL, 0);
 		else if (!strncmp(this_opt, "mode:", 5))
 			strncpy(videomode, this_opt+5, sizeof(videomode)-1);
+		else if (!strncmp(this_opt, "dfp:", 4)) {
+			dfp_type = simple_strtoul(this_opt+4, NULL, 0);
+			dfp = 1;
+		}	
 #ifdef CONFIG_PPC
 		else if (!strncmp(this_opt, "vmode:", 6)) {
 			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
@@ -2510,6 +2517,8 @@
 
 MODULE_AUTHOR("(c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>");
 MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(mem, "i");
 MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
 MODULE_PARM(disabled, "i");
@@ -2586,6 +2595,8 @@
 MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
 MODULE_PARM(dfp, "i");
 MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)");
+MODULE_PARM(dfp_type, "i");
+MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)");
 #ifdef CONFIG_PPC
 MODULE_PARM(vmode, "i");
 MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
diff -u --recursive --new-file v2.4.10/linux/drivers/video/matrox/matroxfb_base.h linux/drivers/video/matrox/matroxfb_base.h
--- v2.4.10/linux/drivers/video/matrox/matroxfb_base.h	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/matrox/matroxfb_base.h	Sun Sep 30 12:26:08 2001
@@ -1,8 +1,8 @@
 /*
  *
- * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450
  *
- * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
+ * (c) 1998,1999,2000,2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
  */
 #ifndef __MATROXFB_H__
@@ -533,6 +533,7 @@
 						/* 0 except for 6MB Millenium */
 		int		memtype;
 		int		g450dac;
+		int		dfp_type;
 			      } devflags;
 	struct display_switch	dispsw;
 	struct {
diff -u --recursive --new-file v2.4.10/linux/drivers/video/matrox/matroxfb_misc.c linux/drivers/video/matrox/matroxfb_misc.c
--- v2.4.10/linux/drivers/video/matrox/matroxfb_misc.c	Thu Aug 10 12:34:31 2000
+++ linux/drivers/video/matrox/matroxfb_misc.c	Sun Sep 30 12:26:08 2001
@@ -4,7 +4,7 @@
  *
  * (c) 1998,1999,2000 Petr Vandrovec <vandrove@vc.cvut.cz>
  *
- * Version: 1.50 2000/08/10
+ * Version: 1.54 2001/09/09
  *
  * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
  *
@@ -63,6 +63,9 @@
  *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
  *                     G400 support
  *
+ *               "David C. Hansen" <haveblue@us.ibm.com>
+ *                     Fixes
+ *
  * (following author is not in any relation with this code, but his code
  *  is included in this driver)
  *
@@ -654,7 +657,3 @@
 EXPORT_SYMBOL(matroxfb_fastfont_init);		/* DAC1064, Ti3026 */
 EXPORT_SYMBOL(matroxfb_vgaHWinit);		/* DAC1064, Ti3026 */
 EXPORT_SYMBOL(matroxfb_vgaHWrestore);		/* DAC1064, Ti3026 */
-#ifdef MATROXFB_USE_SPINLOCK
-spinlock_t matroxfb_spinlock = SPIN_LOCK_UNLOCKED;
-EXPORT_SYMBOL(matroxfb_spinlock);
-#endif
diff -u --recursive --new-file v2.4.10/linux/drivers/video/offb.c linux/drivers/video/offb.c
--- v2.4.10/linux/drivers/video/offb.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/offb.c	Tue Oct  2 09:10:31 2001
@@ -32,7 +32,9 @@
 #endif
 #include <asm/io.h>
 #include <asm/prom.h>
+#ifdef CONFIG_BOOTX_TEXT
 #include <asm/bootx.h>
+#endif
 
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
@@ -95,8 +97,9 @@
 			struct fb_info *info);
 static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 			struct fb_info *info);
-
+#ifdef CONFIG_BOOTX_TEXT
 extern boot_infos_t *boot_infos;
+#endif
 
 static void offb_init_nodriver(struct device_node *);
 static void offb_init_fb(const char *name, const char *full_name, int width,
@@ -253,6 +256,7 @@
 {
     struct device_node *dp;
     unsigned int dpy;
+#ifdef CONFIG_BOOTX_TEXT
     struct device_node *displays = find_type_devices("display");
     struct device_node *macos_display = NULL;
 
@@ -315,6 +319,7 @@
 		     boot_infos->dispDeviceDepth,
 		     boot_infos->dispDeviceRowBytes, addr, NULL);
     }
+#endif
 
     for (dpy = 0; dpy < prom_num_displays; dpy++) {
 	if ((dp = find_path_device(prom_display_paths[dpy])))
@@ -426,7 +431,8 @@
 		unsigned long regbase = dp->addrs[2].address;
 		info->cmap_adr = ioremap(regbase, 0x1FFF);
 		info->cmap_type = cmap_r128;
-	} else if (dp && !strncmp(name, "ATY,RageM3pA", 12)) {
+	} else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
+		|| !strncmp(name, "ATY,RageM3p12A", 14))) {
 		unsigned long regbase = dp->parent->addrs[2].address;
 		info->cmap_adr = ioremap(regbase, 0x1FFF);
 		info->cmap_type = cmap_M3A;
diff -u --recursive --new-file v2.4.10/linux/drivers/video/riva/fbdev.c linux/drivers/video/riva/fbdev.c
--- v2.4.10/linux/drivers/video/riva/fbdev.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/riva/fbdev.c	Sun Sep 30 12:26:08 2001
@@ -1111,6 +1111,7 @@
 #ifdef FBCON_HAS_CFB16
 	case 15:
 		rc = 15;	/* fix for 15 bpp depths on Riva 128 based cards */
+		break;
 	case 16:
 		rc = 16;	/* directcolor... 16 entries SW palette */
 		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
@@ -2131,3 +2132,4 @@
 
 MODULE_AUTHOR("Ani Joshi, maintainer");
 MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/drivers/video/sis/Makefile linux/drivers/video/sis/Makefile
--- v2.4.10/linux/drivers/video/sis/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/drivers/video/sis/Makefile	Mon Oct  8 10:46:49 2001
@@ -4,6 +4,8 @@
 
 O_TARGET := sisfb.o
 
+export-objs := sis_main.o
+
 obj-y  := sis_main.o sis_300.o sis_301.o
 obj-m  := $(O_TARGET)
 
diff -u --recursive --new-file v2.4.10/linux/drivers/video/sun3fb.c linux/drivers/video/sun3fb.c
--- v2.4.10/linux/drivers/video/sun3fb.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/sun3fb.c	Sun Sep 30 12:26:08 2001
@@ -521,7 +521,7 @@
     /*
      *  Initialisation
      */
-static void __init sun3fb_init_fb(int fbtype, unsigned long addr)
+static int __init sun3fb_init_fb(int fbtype, unsigned long addr)
 {
 	static struct linux_sbus_device sdb;
 	struct fb_fix_screeninfo *fix;
@@ -587,8 +587,8 @@
 	fb->cursor.hwsize.fby = 32;
 	
 	if (depth > 1 && !fb->color_map) {
-		fb->color_map = kmalloc(256 * 3, GFP_ATOMIC);
-		return -ENOMEM;
+		if((fb->color_map = kmalloc(256 * 3, GFP_ATOMIC))==NULL)
+			return -ENOMEM;
 	}
 			
 	switch(fbtype) {
@@ -605,7 +605,7 @@
 	
 	if (!p) {
 		kfree(fb);
-		-ENODEV;
+		return -ENODEV;
 	}
 	
 	if (p == SBUSFBINIT_SIZECHANGE)
diff -u --recursive --new-file v2.4.10/linux/drivers/video/tdfxfb.c linux/drivers/video/tdfxfb.c
--- v2.4.10/linux/drivers/video/tdfxfb.c	Sun Sep 23 11:41:00 2001
+++ linux/drivers/video/tdfxfb.c	Sun Sep 30 12:26:08 2001
@@ -2069,6 +2069,8 @@
 
 MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
 MODULE_DESCRIPTION("3Dfx framebuffer device driver");
+MODULE_LICENSE("GPL");
+
 
 #ifdef MODULE
 module_init(tdfxfb_init);
diff -u --recursive --new-file v2.4.10/linux/fs/Config.in linux/fs/Config.in
--- v2.4.10/linux/fs/Config.in	Tue Jul  3 17:08:21 2001
+++ linux/fs/Config.in	Thu Oct  4 15:13:18 2001
@@ -26,9 +26,14 @@
 dep_tristate '    UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
 dep_tristate '  VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS
 dep_tristate 'EFS file system support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS $CONFIG_EXPERIMENTAL
-dep_tristate 'Journalling Flash File System (JFFS) support (EXPERIMENTAL)' CONFIG_JFFS_FS $CONFIG_EXPERIMENTAL $CONFIG_MTD
+dep_tristate 'Journalling Flash File System (JFFS) support' CONFIG_JFFS_FS $CONFIG_MTD
 if [ "$CONFIG_JFFS_FS" = "y" -o "$CONFIG_JFFS_FS" = "m" ] ; then
    int 'JFFS debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_JFFS_FS_VERBOSE 0
+   bool 'JFFS stats available in /proc filesystem' CONFIG_JFFS_PROC_FS
+fi
+dep_tristate 'Journalling Flash File System v2 (JFFS2) support (EXPERIMENTAL)' CONFIG_JFFS2_FS $CONFIG_EXPERIMENTAL $CONFIG_MTD
+if [ "$CONFIG_JFFS2_FS" != "n" ] ; then
+        int 'JFFS2 debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_JFFS2_FS_DEBUG 0
 fi
 tristate 'Compressed ROM file system support' CONFIG_CRAMFS
 bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
diff -u --recursive --new-file v2.4.10/linux/fs/Makefile linux/fs/Makefile
--- v2.4.10/linux/fs/Makefile	Sun Sep 23 11:41:00 2001
+++ linux/fs/Makefile	Thu Oct  4 15:13:18 2001
@@ -14,7 +14,7 @@
 		super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \
 		fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
 		dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \
-		filesystems.o
+		filesystems.o namespace.o
 
 ifeq ($(CONFIG_QUOTA),y)
 obj-y += dquot.o
@@ -52,6 +52,7 @@
 subdir-$(CONFIG_UFS_FS)		+= ufs
 subdir-$(CONFIG_EFS_FS)		+= efs
 subdir-$(CONFIG_JFFS_FS)	+= jffs
+subdir-$(CONFIG_JFFS2_FS)	+= jffs2
 subdir-$(CONFIG_AFFS_FS)	+= affs
 subdir-$(CONFIG_ROMFS_FS)	+= romfs
 subdir-$(CONFIG_QNX4FS_FS)	+= qnx4
diff -u --recursive --new-file v2.4.10/linux/fs/adfs/inode.c linux/fs/adfs/inode.c
--- v2.4.10/linux/fs/adfs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/adfs/inode.c	Sun Sep 30 12:26:08 2001
@@ -17,6 +17,8 @@
 #include <linux/locks.h>
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
+#include <linux/module.h>
+
 
 #include "adfs.h"
 
@@ -373,3 +375,4 @@
 	adfs_dir_update(sb, &obj);
 	unlock_kernel();
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/affs/inode.c linux/fs/affs/inode.c
--- v2.4.10/linux/fs/affs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/affs/inode.c	Sun Sep 30 12:26:08 2001
@@ -29,6 +29,7 @@
 #include <linux/smp_lock.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <linux/module.h>
 
 extern struct inode_operations affs_symlink_inode_operations;
 extern struct timezone sys_tz;
@@ -300,7 +301,7 @@
 	u32			 block;
 	struct buffer_head	*bh;
 
-	if (!(inode = get_empty_inode()))
+	if (!(inode = new_inode(sb)))
 		goto err_inode;
 
 	if (!(block = affs_alloc_block(dir, dir->i_ino)))
@@ -312,8 +313,6 @@
 	mark_buffer_dirty_inode(bh, inode);
 	affs_brelse(bh);
 
-	inode->i_sb      = sb;
-	inode->i_dev     = sb->s_dev;
 	inode->i_uid     = current->fsuid;
 	inode->i_gid     = current->fsgid;
 	inode->i_ino     = block;
@@ -415,3 +414,4 @@
 	affs_unlock_link(inode);
 	goto done;
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/attr.c linux/fs/attr.c
--- v2.4.10/linux/fs/attr.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/attr.c	Fri Oct  5 12:23:53 2001
@@ -11,6 +11,7 @@
 #include <linux/smp_lock.h>
 #include <linux/dnotify.h>
 #include <linux/fcntl.h>
+#include <linux/quotaops.h>
 
 /* Taken over from the old code... */
 
@@ -131,8 +132,13 @@
 		error = inode->i_op->setattr(dentry, attr);
 	else {
 		error = inode_change_ok(inode, attr);
-		if (!error)
-			inode_setattr(inode, attr);
+		if (!error) {
+			if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+			    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
+				error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+			if (!error)
+				inode_setattr(inode, attr);
+		}
 	}
 	unlock_kernel();
 	if (!error) {
diff -u --recursive --new-file v2.4.10/linux/fs/autofs/init.c linux/fs/autofs/init.c
--- v2.4.10/linux/fs/autofs/init.c	Fri Mar 10 10:48:47 2000
+++ linux/fs/autofs/init.c	Sun Sep 30 12:26:08 2001
@@ -38,3 +38,4 @@
 	printk(")\n");
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/autofs4/init.c linux/fs/autofs4/init.c
--- v2.4.10/linux/fs/autofs4/init.c	Fri Apr 21 14:41:36 2000
+++ linux/fs/autofs4/init.c	Sun Sep 30 12:26:08 2001
@@ -28,3 +28,4 @@
 
 module_init(init_autofs4_fs) 
 module_exit(exit_autofs4_fs)
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/bfs/inode.c linux/fs/bfs/inode.c
--- v2.4.10/linux/fs/bfs/inode.c	Tue Apr 17 23:16:38 2001
+++ linux/fs/bfs/inode.c	Sun Sep 30 12:26:08 2001
@@ -19,6 +19,7 @@
 
 MODULE_AUTHOR("Tigran A. Aivazian <tigran@veritas.com>");
 MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
+MODULE_LICENSE("GPL");
 EXPORT_NO_SYMBOLS;
 
 #undef DEBUG
diff -u --recursive --new-file v2.4.10/linux/fs/binfmt_aout.c linux/fs/binfmt_aout.c
--- v2.4.10/linux/fs/binfmt_aout.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/binfmt_aout.c	Sun Sep 30 12:26:08 2001
@@ -513,3 +513,4 @@
 
 module_init(init_aout_binfmt);
 module_exit(exit_aout_binfmt);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.4.10/linux/fs/binfmt_elf.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/binfmt_elf.c	Fri Oct  5 12:19:45 2001
@@ -31,6 +31,8 @@
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/smp_lock.h>
+#include <linux/compiler.h>
+#include <linux/limits.h>
 
 #include <asm/uaccess.h>
 #include <asm/param.h>
@@ -75,6 +77,8 @@
 	NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
 };
 
+#define BAD_ADDR(x)	((unsigned long)(x) > TASK_SIZE)
+
 static void set_brk(unsigned long start, unsigned long end)
 {
 	start = ELF_PAGEALIGN(start);
@@ -297,6 +301,8 @@
 	    	elf_type |= MAP_FIXED;
 
 	    map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
+	    if (BAD_ADDR(map_addr))
+	    	goto out_close;
 
 	    if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
 		load_addr = map_addr - ELF_PAGESTART(vaddr);
@@ -408,7 +414,6 @@
 	char * elf_interpreter = NULL;
 	unsigned int interpreter_type = INTERPRETER_NONE;
 	unsigned char ibcs2_interpreter = 0;
-	mm_segment_t old_fs;
 	unsigned long error;
 	struct elf_phdr * elf_ppnt, *elf_phdata;
 	unsigned long elf_bss, k, elf_brk;
@@ -440,9 +445,11 @@
 	/* Now read in all of the header information */
 
 	retval = -ENOMEM;
-	size = ((unsigned int)elf_ex.e_phentsize) * elf_ex.e_phnum;
-	if (size > 65536)
+	if (elf_ex.e_phentsize != sizeof(struct elf_phdr))
+		goto out;
+	if (elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
 		goto out;
+	size = elf_ex.e_phnum * sizeof(struct elf_phdr);
 	elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
 	if (!elf_phdata)
 		goto out;
@@ -468,16 +475,14 @@
 
 	for (i = 0; i < elf_ex.e_phnum; i++) {
 		if (elf_ppnt->p_type == PT_INTERP) {
-			retval = -EINVAL;
-		  	if (elf_interpreter)
-				goto out_free_dentry;
-
 			/* This is the program interpreter used for
 			 * shared libraries - for now assume that this
 			 * is an a.out format binary
 			 */
 
 			retval = -ENOMEM;
+			if (elf_ppnt->p_filesz > PATH_MAX)
+				goto out_free_file;
 			elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
 							   GFP_KERNEL);
 			if (!elf_interpreter)
@@ -532,6 +537,7 @@
 			/* Get the exec headers */
 			interp_ex = *((struct exec *) bprm->buf);
 			interp_elf_ex = *((struct elfhdr *) bprm->buf);
+			break;
 		}
 		elf_ppnt++;
 	}
@@ -609,8 +615,6 @@
 	   the image should be loaded at fixed address, not at a variable
 	   address. */
 
-	old_fs = get_fs();
-	set_fs(get_ds());
 	for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
 		int elf_prot = 0, elf_flags;
 		unsigned long vaddr;
@@ -618,6 +622,22 @@
 		if (elf_ppnt->p_type != PT_LOAD)
 			continue;
 
+		if (unlikely (elf_brk > elf_bss)) {
+			unsigned long nbyte;
+	            
+			/* There was a PT_LOAD segment with p_memsz > p_filesz
+			   before this one. Map anonymous pages, if needed,
+			   and clear the area.  */
+			set_brk (elf_bss + load_bias, elf_brk + load_bias);
+			nbyte = ELF_PAGEOFFSET(elf_bss);
+			if (nbyte) {
+				nbyte = ELF_MIN_ALIGN - nbyte;
+				if (nbyte > elf_brk - elf_bss)
+					nbyte = elf_brk - elf_bss;
+				clear_user((void *) elf_bss + load_bias, nbyte);
+			}
+		}
+
 		if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
 		if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
 		if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
@@ -635,6 +655,8 @@
 		}
 
 		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
+		if (BAD_ADDR(error))
+			continue;
 
 		if (!load_addr_set) {
 			load_addr_set = 1;
@@ -661,7 +683,6 @@
 		if (k > elf_brk)
 			elf_brk = k;
 	}
-	set_fs(old_fs);
 
 	elf_entry += load_bias;
 	elf_bss += load_bias;
@@ -684,7 +705,7 @@
 		fput(interpreter);
 		kfree(elf_interpreter);
 
-		if (elf_entry == ~0UL) {
+		if (BAD_ADDR(elf_entry)) {
 			printk(KERN_ERR "Unable to load interpreter\n");
 			kfree(elf_phdata);
 			send_sig(SIGSEGV, current, 0);
@@ -786,7 +807,7 @@
 static int load_elf_library(struct file *file)
 {
 	struct elf_phdr *elf_phdata;
-	unsigned long elf_bss = 0, bss, len, k;
+	unsigned long elf_bss, bss, len;
 	int retval, error, i, j;
 	struct elfhdr elf_ex;
 
@@ -806,19 +827,18 @@
 	/* Now read in all of the header information */
 
 	j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
-	if (j > ELF_MIN_ALIGN)
-		goto out;
+	/* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */
 
 	error = -ENOMEM;
 	elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL);
 	if (!elf_phdata)
 		goto out;
 
-	/* N.B. check for error return?? */
-	retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata,
-			   sizeof(struct elf_phdr) * elf_ex.e_phnum);
-
 	error = -ENOEXEC;
+	retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata, j);
+	if (retval != j)
+		goto out_free_ph;
+
 	for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
 		if ((elf_phdata + i)->p_type == PT_LOAD) j++;
 	if (j != 1)
@@ -840,9 +860,7 @@
 	if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
 		goto out_free_ph;
 
-	k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
-	if (k > elf_bss)
-		elf_bss = k;
+	elf_bss = elf_phdata->p_vaddr + elf_phdata->p_filesz;
 	padzero(elf_bss);
 
 	len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1);
diff -u --recursive --new-file v2.4.10/linux/fs/block_dev.c linux/fs/block_dev.c
--- v2.4.10/linux/fs/block_dev.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/block_dev.c	Wed Oct  3 09:16:42 2001
@@ -22,291 +22,138 @@
 
 #include <asm/uaccess.h>
 
-static inline int blkdev_get_block(struct inode * inode, long iblock, struct buffer_head * bh_result)
-{
-	int err;
-
-	err = -EIO;
-	if (iblock >= buffered_blk_size(inode->i_rdev) >> (BUFFERED_BLOCKSIZE_BITS - BLOCK_SIZE_BITS))
-		goto out;
+#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
 
-	bh_result->b_blocknr = iblock;
-	bh_result->b_state |= 1UL << BH_Mapped;
-	err = 0;
-
- out:
-	return err;
+static inline unsigned int blksize_bits(unsigned int size)
+{
+	unsigned int bits = 8;
+	do {
+		bits++;
+		size >>= 1;
+	} while (size > 256);
+	return bits;
 }
 
-static int blkdev_direct_IO(int rw, struct inode * inode, struct kiobuf * iobuf, unsigned long blocknr, int blocksize)
+static inline unsigned int block_size(kdev_t dev)
 {
-	int i, nr_blocks, retval, dev = inode->i_rdev;
-	unsigned long * blocks = iobuf->blocks;
-
-	if (blocksize != BUFFERED_BLOCKSIZE)
-		BUG();
+	int retval = BLOCK_SIZE;
+	int major = MAJOR(dev);
 
-	nr_blocks = iobuf->length >> BUFFERED_BLOCKSIZE_BITS;
-	/* build the blocklist */
-	for (i = 0; i < nr_blocks; i++, blocknr++) {
-		struct buffer_head bh;
-
-		retval = blkdev_get_block(inode, blocknr, &bh);
-		if (retval)
-			goto out;
-
-		blocks[i] = bh.b_blocknr;
+	if (blksize_size[major]) {
+		int minor = MINOR(dev);
+		if (blksize_size[major][minor])
+			retval = blksize_size[major][minor];
 	}
-
-	retval = brw_kiovec(rw, 1, &iobuf, dev, iobuf->blocks, blocksize);
-
- out:
 	return retval;
 }
 
-static int blkdev_writepage(struct page * page)
+static unsigned long max_block(kdev_t dev)
 {
-	int err, i;
-	unsigned long block;
-	struct buffer_head *bh, *head;
-	struct inode *inode = page->mapping->host;
-
-	if (!PageLocked(page))
-		BUG();
-
-	if (!page->buffers)
-		create_empty_buffers(page, inode->i_rdev, BUFFERED_BLOCKSIZE);
-	head = page->buffers;
-
-	block = page->index << (PAGE_CACHE_SHIFT - BUFFERED_BLOCKSIZE_BITS);
-
-	bh = head;
-	i = 0;
+	unsigned int retval = ~0U;
+	int major = MAJOR(dev);
 
-	/* Stage 1: make sure we have all the buffers mapped! */
-	do {
-		/*
-		 * If the buffer isn't up-to-date, we can't be sure
-		 * that the buffer has been initialized with the proper
-		 * block number information etc..
-		 *
-		 * Leave it to the low-level FS to make all those
-		 * decisions (block #0 may actually be a valid block)
-		 */
-		if (!buffer_mapped(bh)) {
-			err = blkdev_get_block(inode, block, bh);
-			if (err)
-				goto out;
+	if (blk_size[major]) {
+		int minor = MINOR(dev);
+		unsigned int blocks = blk_size[major][minor];
+		if (blocks) {
+			unsigned int size = block_size(dev);
+			unsigned int sizebits = blksize_bits(size);
+			blocks += (size-1) >> BLOCK_SIZE_BITS;
+			retval = blocks << (BLOCK_SIZE_BITS - sizebits);
+			if (sizebits > BLOCK_SIZE_BITS)
+				retval = blocks >> (sizebits - BLOCK_SIZE_BITS);
 		}
-		bh = bh->b_this_page;
-		block++;
-	} while (bh != head);
-
-	/* Stage 2: lock the buffers, mark them clean */
-	do {
-		lock_buffer(bh);
-		set_buffer_async_io(bh);
-		set_bit(BH_Uptodate, &bh->b_state);
-		clear_bit(BH_Dirty, &bh->b_state);
-		bh = bh->b_this_page;
-	} while (bh != head);
-
-	/* Stage 3: submit the IO */
-	do {
-		submit_bh(WRITE, bh);
-		bh = bh->b_this_page;
-	} while (bh != head);
+	}
+	return retval;
+}
 
-	/* Done - end_buffer_io_async will unlock */
-	SetPageUptodate(page);
-	return 0;
+static loff_t blkdev_size(kdev_t dev)
+{
+	unsigned int blocks = ~0U;
+	int major = MAJOR(dev);
 
-out:
-	ClearPageUptodate(page);
-	UnlockPage(page);
-	return err;
+	if (blk_size[major]) {
+		int minor = MINOR(dev);
+		blocks = blk_size[major][minor];
+	}
+	return (loff_t) blocks << BLOCK_SIZE_BITS;
 }
 
-static int blkdev_readpage(struct file * file, struct page * page)
+/* Kill _all_ buffers, dirty or not.. */
+static void kill_bdev(struct block_device *bdev)
 {
-	struct inode *inode = page->mapping->host;
-	kdev_t dev = inode->i_rdev;
-	unsigned long iblock, lblock;
-	struct buffer_head *bh, *head, *arr[1 << (PAGE_CACHE_SHIFT - BUFFERED_BLOCKSIZE_BITS)];
-	unsigned int blocks;
-	int nr, i;
-
-	if (!PageLocked(page))
-		PAGE_BUG(page);
-	if (!page->buffers)
-		create_empty_buffers(page, dev, BUFFERED_BLOCKSIZE);
-	head = page->buffers;
-
-	blocks = PAGE_CACHE_SIZE >> BUFFERED_BLOCKSIZE_BITS;
-	iblock = page->index << (PAGE_CACHE_SHIFT - BUFFERED_BLOCKSIZE_BITS);
-	lblock = buffered_blk_size(dev) >> (BUFFERED_BLOCKSIZE_BITS - BLOCK_SIZE_BITS);
-	bh = head;
-	nr = 0;
-	i = 0;
+	invalidate_bdev(bdev, 1);
+	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
+}	
 
-	do {
-		if (buffer_uptodate(bh))
-			continue;
+int set_blocksize(kdev_t dev, int size)
+{
+	int oldsize;
+	struct block_device *bdev;
 
-		if (!buffer_mapped(bh)) {
-			if (iblock <= lblock) {
-				if (blkdev_get_block(inode, iblock, bh))
-					continue;
-			}
-			if (!buffer_mapped(bh)) {
-				memset(kmap(page) + i * BUFFERED_BLOCKSIZE, 0, BUFFERED_BLOCKSIZE);
-				flush_dcache_page(page);
-				kunmap(page);
-				set_bit(BH_Uptodate, &bh->b_state);
-				continue;
-			}
-			/* get_block() might have updated the buffer synchronously */
-			if (buffer_uptodate(bh))
-				continue;
-		}
+	/* Size must be a power of two, and between 512 and PAGE_SIZE */
+	if (size > PAGE_SIZE || size < 512 || (size & (size-1)))
+		return -EINVAL;
 
-		arr[nr] = bh;
-		nr++;
-	} while (i++, iblock++, (bh = bh->b_this_page) != head);
-
-	if (!nr) {
-		/*
-		 * all buffers are uptodate - we can set the page
-		 * uptodate as well.
-		 */
-		SetPageUptodate(page);
-		UnlockPage(page);
-		return 0;
-	}
+	/* Size cannot be smaller than the size supported by the device */
+	if (size < get_hardsect_size(dev))
+		return -EINVAL;
 
-	/* Stage two: lock the buffers */
-	for (i = 0; i < nr; i++) {
-		struct buffer_head * bh = arr[i];
-		lock_buffer(bh);
-		set_buffer_async_io(bh);
+	/* No blocksize array? Implies hardcoded BLOCK_SIZE */
+	if (!blksize_size[MAJOR(dev)]) {
+		if (size == BLOCK_SIZE)
+			return 0;
+		return -EINVAL;
 	}
 
-	/* Stage 3: start the IO */
-	for (i = 0; i < nr; i++)
-		submit_bh(READ, arr[i]);
+	oldsize = blksize_size[MAJOR(dev)][MINOR(dev)];
+	if (oldsize == size)
+		return 0;
+
+	if (!oldsize && size == BLOCK_SIZE) {
+		blksize_size[MAJOR(dev)][MINOR(dev)] = size;
+		return 0;
+	}
 
+	/* Ok, we're actually changing the blocksize.. */
+	bdev = bdget(dev);
+	sync_buffers(dev, 2);
+	blksize_size[MAJOR(dev)][MINOR(dev)] = size;
+	bdev->bd_inode->i_blkbits = blksize_bits(size);
+	kill_bdev(bdev);
+	bdput(bdev);
 	return 0;
 }
 
-static int __blkdev_prepare_write(struct inode *inode, struct page *page,
-				  unsigned from, unsigned to)
+static int blkdev_get_block(struct inode * inode, long iblock, struct buffer_head * bh, int create)
 {
-	kdev_t dev = inode->i_rdev;
-	unsigned block_start, block_end;
-	unsigned long block;
-	int err = 0;
-	struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
-	kmap(page);
-
-	if (!page->buffers)
-		create_empty_buffers(page, dev, BUFFERED_BLOCKSIZE);
-	head = page->buffers;
-
-	block = page->index << (PAGE_CACHE_SHIFT - BUFFERED_BLOCKSIZE_BITS);
-
-	for(bh = head, block_start = 0; bh != head || !block_start;
-	    block++, block_start=block_end, bh = bh->b_this_page) {
-		if (!bh)
-			BUG();
-		block_end = block_start + BUFFERED_BLOCKSIZE;
-		if (block_end <= from)
-			continue;
-		if (block_start >= to)
-			break;
-		if (!buffer_mapped(bh)) {
-			err = blkdev_get_block(inode, block, bh);
-			if (err)
-				goto out;
-		}
-		if (Page_Uptodate(page)) {
-			set_bit(BH_Uptodate, &bh->b_state);
-			continue; 
-		}
-		if (!buffer_uptodate(bh) &&
-		     (block_start < from || block_end > to)) {
-			ll_rw_block(READ, 1, &bh);
-			*wait_bh++=bh;
-		}
-	}
-	/*
-	 * If we issued read requests - let them complete.
-	 */
-	while(wait_bh > wait) {
-		wait_on_buffer(*--wait_bh);
-		err = -EIO;
-		if (!buffer_uptodate(*wait_bh))
-			goto out;
-	}
+	if (iblock >= max_block(inode->i_rdev))
+		return -EIO;
+
+	bh->b_dev = inode->i_rdev;
+	bh->b_blocknr = iblock;
+	bh->b_state |= 1UL << BH_Mapped;
 	return 0;
-out:
-	return err;
 }
 
-static int blkdev_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int blkdev_writepage(struct page * page)
 {
-	struct inode *inode = page->mapping->host;
-	int err = __blkdev_prepare_write(inode, page, from, to);
-	if (err) {
-		ClearPageUptodate(page);
-		kunmap(page);
-	}
-	return err;
-}
-
-static int __blkdev_commit_write(struct inode *inode, struct page *page,
-				 unsigned from, unsigned to)
-{
-	unsigned block_start, block_end;
-	int partial = 0, need_balance_dirty = 0;
-	struct buffer_head *bh, *head;
-
-	for(bh = head = page->buffers, block_start = 0;
-	    bh != head || !block_start;
-	    block_start=block_end, bh = bh->b_this_page) {
-		block_end = block_start + BUFFERED_BLOCKSIZE;
-		if (block_end <= from || block_start >= to) {
-			if (!buffer_uptodate(bh))
-				partial = 1;
-		} else {
-			set_bit(BH_Uptodate, &bh->b_state);
-			if (!atomic_set_buffer_dirty(bh)) {
-				__mark_dirty(bh);
-				buffer_insert_inode_data_queue(bh, inode);
-				need_balance_dirty = 1;
-			}
-		}
-	}
+	return block_write_full_page(page, blkdev_get_block);
+}
 
-	if (need_balance_dirty)
-		balance_dirty();
-	/*
-	 * is this a partial write that happened to make all buffers
-	 * uptodate then we can optimize away a bogus readpage() for
-	 * the next read(). Here we 'discover' wether the page went
-	 * uptodate as a result of this (potentially partial) write.
-	 */
-	if (!partial)
-		SetPageUptodate(page);
-	return 0;
+static int blkdev_readpage(struct file * file, struct page * page)
+{
+	return block_read_full_page(page, blkdev_get_block);
 }
 
-static int blkdev_commit_write(struct file *file, struct page *page,
-			       unsigned from, unsigned to)
+static int blkdev_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
 {
-	struct inode *inode = page->mapping->host;
-	__blkdev_commit_write(inode,page,from,to);
-	kunmap(page);
-	return 0;
+	return block_prepare_write(page, from, to, blkdev_get_block);
+}
+
+static int blkdev_commit_write(struct file *file, struct page *page, unsigned from, unsigned to)
+{
+	return block_commit_write(page, from, to);
 }
 
 /*
@@ -316,21 +163,19 @@
  */
 static loff_t block_llseek(struct file *file, loff_t offset, int origin)
 {
-	long long retval;
-	kdev_t dev;
+	/* ewww */
+	loff_t size = file->f_dentry->d_inode->i_bdev->bd_inode->i_size;
+	loff_t retval;
 
 	switch (origin) {
 		case 2:
-			dev = file->f_dentry->d_inode->i_rdev;
-			if (blk_size[MAJOR(dev)])
-				offset += (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
-			/* else?  return -EINVAL? */
+			offset += size;
 			break;
 		case 1:
 			offset += file->f_pos;
 	}
 	retval = -EINVAL;
-	if (offset >= 0) {
+	if (offset >= 0 && offset <= size) {
 		if (offset != file->f_pos) {
 			file->f_pos = offset;
 			file->f_reada = 0;
@@ -378,6 +223,7 @@
 	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
 	root->i_uid = root->i_gid = 0;
 	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
+	sb->s_maxbytes = ~0ULL;
 	sb->s_blocksize = 1024;
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = 0x62646576;
@@ -491,13 +337,16 @@
 	if (new_bdev) {
 		struct inode *inode = new_inode(bd_mnt->mnt_sb);
 		if (inode) {
+			kdev_t kdev = to_kdev_t(dev);
 			atomic_set(&new_bdev->bd_count,1);
 			new_bdev->bd_dev = dev;
 			new_bdev->bd_op = NULL;
 			new_bdev->bd_inode = inode;
-			inode->i_rdev = to_kdev_t(dev);
+			inode->i_rdev = kdev;
+			inode->i_dev = kdev;
 			inode->i_bdev = new_bdev;
 			inode->i_data.a_ops = &def_blk_aops;
+			inode->i_data.gfp_mask = GFP_USER;
 			spin_lock(&bdev_lock);
 			bdev = bdfind(dev, head);
 			if (!bdev) {
@@ -700,34 +549,23 @@
 	return res;
 }
 
-int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, int kind)
+static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
 {
-	int ret = -ENODEV;
-	kdev_t rdev = to_kdev_t(bdev->bd_dev); /* this should become bdev */
-	down(&bdev->bd_sem);
+	int ret = -ENXIO;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
 
+	down(&bdev->bd_sem);
 	lock_kernel();
 	if (!bdev->bd_op)
-		bdev->bd_op = get_blkfops(MAJOR(rdev));
+		bdev->bd_op = get_blkfops(MAJOR(dev));
 	if (bdev->bd_op) {
-		/*
-		 * This crockload is due to bad choice of ->open() type.
-		 * It will go away.
-		 * For now, block device ->open() routine must _not_
-		 * examine anything in 'inode' argument except ->i_rdev.
-		 */
-		struct file fake_file = {};
-		struct dentry fake_dentry = {};
-		ret = -ENOMEM;
-		fake_file.f_mode = mode;
-		fake_file.f_flags = flags;
-		fake_file.f_dentry = &fake_dentry;
-		fake_dentry.d_inode = bdev->bd_inode;
 		ret = 0;
 		if (bdev->bd_op->open)
-			ret = bdev->bd_op->open(bdev->bd_inode, &fake_file);
+			ret = bdev->bd_op->open(inode, file);
 		if (!ret) {
 			bdev->bd_openers++;
+			bdev->bd_inode->i_size = blkdev_size(dev);
+			bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
 		} else if (!bdev->bd_openers)
 			bdev->bd_op = NULL;
 	}
@@ -738,9 +576,26 @@
 	return ret;
 }
 
+int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, int kind)
+{
+	/*
+	 * This crockload is due to bad choice of ->open() type.
+	 * It will go away.
+	 * For now, block device ->open() routine must _not_
+	 * examine anything in 'inode' argument except ->i_rdev.
+	 */
+	struct file fake_file = {};
+	struct dentry fake_dentry = {};
+	fake_file.f_mode = mode;
+	fake_file.f_flags = flags;
+	fake_file.f_dentry = &fake_dentry;
+	fake_dentry.d_inode = bdev->bd_inode;
+
+	return do_open(bdev, bdev->bd_inode, &fake_file);
+}
+
 int blkdev_open(struct inode * inode, struct file * filp)
 {
-	int ret;
 	struct block_device *bdev;
 
 	/*
@@ -753,26 +608,8 @@
 
 	bd_acquire(inode);
 	bdev = inode->i_bdev;
-	down(&bdev->bd_sem);
 
-	ret = -ENXIO;
-	lock_kernel();
-	if (!bdev->bd_op)
-		bdev->bd_op = get_blkfops(MAJOR(inode->i_rdev));
-	if (bdev->bd_op) {
-		ret = 0;
-		if (bdev->bd_op->open)
-			ret = bdev->bd_op->open(inode,filp);
-		if (!ret)
-			bdev->bd_openers++;
-		else if (!bdev->bd_openers)
-			bdev->bd_op = NULL;
-	}	
-	unlock_kernel();
-	up(&bdev->bd_sem);
-	if (ret)
-		bdput(bdev);
-	return ret;
+	return do_open(bdev, inode, filp);
 }	
 
 int blkdev_put(struct block_device *bdev, int kind)
@@ -783,31 +620,12 @@
 
 	down(&bdev->bd_sem);
 	lock_kernel();
-	if (kind == BDEV_FILE) {
-		struct super_block * sb;
-
+	if (kind == BDEV_FILE)
 		__block_fsync(bd_inode);
-
-		/* Janitorianism: this shit must go away */
-		sb = get_super(bd_inode->i_rdev);
-		if (sb) {
-			if (sb->s_flags & MS_RDONLY) {
-				shrink_dcache_sb(sb);
-				invalidate_inodes(sb);
-				invalidate_buffers(bd_inode->i_rdev);
-			}
-			lock_super(sb);
-			if (sb->s_flags & MS_RDONLY)
-				update_buffers(bd_inode->i_rdev);
-			unlock_super(sb);
-			drop_super(sb);
-		}
-	} else if (kind == BDEV_FS)
+	else if (kind == BDEV_FS)
 		fsync_no_super(rdev);
-	if (!--bdev->bd_openers) {
-		truncate_inode_pages(bd_inode->i_mapping, 0);
-		invalidate_buffers(rdev);
-	}
+	if (!--bdev->bd_openers)
+		kill_bdev(bdev);
 	if (bdev->bd_op->release)
 		ret = bdev->bd_op->release(bd_inode, NULL);
 	if (!bdev->bd_openers)
@@ -837,7 +655,6 @@
 	sync_page: block_sync_page,
 	prepare_write: blkdev_prepare_write,
 	commit_write: blkdev_commit_write,
-	direct_IO: blkdev_direct_IO,
 };
 
 struct file_operations def_blk_fops = {
diff -u --recursive --new-file v2.4.10/linux/fs/buffer.c linux/fs/buffer.c
--- v2.4.10/linux/fs/buffer.c	Wed Sep 26 11:53:42 2001
+++ linux/fs/buffer.c	Sun Sep 30 12:05:19 2001
@@ -52,22 +52,13 @@
 #include <asm/bitops.h>
 #include <asm/mmu_context.h>
 
-#define NR_SIZES 7
-static char buffersize_index[65] =
-{-1,  0,  1, -1,  2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
-  4, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1,
-  5, -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,
-  6};
-
-#define BUFSIZE_INDEX(X) ((int) buffersize_index[(X)>>9])
 #define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
 #define NR_RESERVED (10*MAX_BUF_PER_PAGE)
 #define MAX_UNUSED_BUFFERS NR_RESERVED+20 /* don't ever have more than this 
 					     number of unused buffer heads */
 
 /* Anti-deadlock ordering:
- *	lru_list_lock > hash_table_lock > free_list_lock > unused_list_lock
+ *	lru_list_lock > hash_table_lock > unused_list_lock
  */
 
 #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_inode_buffers)
@@ -90,13 +81,7 @@
 static spinlock_t unused_list_lock = SPIN_LOCK_UNLOCKED;
 static DECLARE_WAIT_QUEUE_HEAD(buffer_wait);
 
-struct bh_free_head {
-	struct buffer_head *list;
-	spinlock_t lock;
-};
-static struct bh_free_head free_list[NR_SIZES];
-
-static int grow_buffers(int size);
+static int grow_buffers(kdev_t dev, unsigned long block, int size);
 static void __refile_buffer(struct buffer_head *);
 
 /* This is used by some architectures to estimate available memory. */
@@ -481,12 +466,16 @@
 	  ((block) << (bh_hash_shift - 12))))
 #define hash(dev,block) hash_table[(_hashfn(HASHDEV(dev),block) & bh_hash_mask)]
 
-static __inline__ void __hash_link(struct buffer_head *bh, struct buffer_head **head)
+static inline void __insert_into_hash_list(struct buffer_head *bh)
 {
-	if ((bh->b_next = *head) != NULL)
-		bh->b_next->b_pprev = &bh->b_next;
+	struct buffer_head **head = &hash(bh->b_dev, bh->b_blocknr);
+	struct buffer_head *next = *head;
+
 	*head = bh;
 	bh->b_pprev = head;
+	bh->b_next = next;
+	if (next != NULL)
+		next->b_pprev = &bh->b_next;
 }
 
 static __inline__ void __hash_unlink(struct buffer_head *bh)
@@ -503,6 +492,8 @@
 {
 	struct buffer_head **bhp = &lru_list[blist];
 
+	if (bh->b_prev_free || bh->b_next_free) BUG();
+
 	if(!*bhp) {
 		*bhp = bh;
 		bh->b_prev_free = bh;
@@ -530,19 +521,6 @@
 	}
 }
 
-static void __remove_from_free_list(struct buffer_head * bh, int index)
-{
-	if(bh->b_next_free == bh)
-		 free_list[index].list = NULL;
-	else {
-		bh->b_prev_free->b_next_free = bh->b_next_free;
-		bh->b_next_free->b_prev_free = bh->b_prev_free;
-		if (free_list[index].list == bh)
-			 free_list[index].list = bh->b_next_free;
-	}
-	bh->b_next_free = bh->b_prev_free = NULL;
-}
-
 /* must be called with both the hash_table_lock and the lru_list_lock
    held */
 static void __remove_from_queues(struct buffer_head *bh)
@@ -551,67 +529,28 @@
 	__remove_from_lru_list(bh, bh->b_list);
 }
 
-static void __insert_into_queues(struct buffer_head *bh)
-{
-	struct buffer_head **head = &hash(bh->b_dev, bh->b_blocknr);
-
-	__hash_link(bh, head);
-	__insert_into_lru_list(bh, bh->b_list);
-}
-
-/* This function must only run if there are no other
- * references _anywhere_ to this buffer head.
- */
-static void put_last_free(struct buffer_head * bh)
+struct buffer_head * get_hash_table(kdev_t dev, int block, int size)
 {
-	struct bh_free_head *head = &free_list[BUFSIZE_INDEX(bh->b_size)];
-	struct buffer_head **bhp = &head->list;
-
-	bh->b_state = 0;
+	struct buffer_head *bh, **p = &hash(dev, block);
 
-	spin_lock(&head->lock);
-	bh->b_dev = B_FREE;
-	if(!*bhp) {
-		*bhp = bh;
-		bh->b_prev_free = bh;
-	}
-	bh->b_next_free = *bhp;
-	bh->b_prev_free = (*bhp)->b_prev_free;
-	(*bhp)->b_prev_free->b_next_free = bh;
-	(*bhp)->b_prev_free = bh;
-	spin_unlock(&head->lock);
-}
-
-/*
- * Why like this, I hear you say... The reason is race-conditions.
- * As we don't lock buffers (unless we are reading them, that is),
- * something might happen to it while we sleep (ie a read-error
- * will force it bad). This shouldn't really happen currently, but
- * the code is ready.
- */
-static inline struct buffer_head * __get_hash_table(kdev_t dev, int block, int size)
-{
-	struct buffer_head *bh = hash(dev, block);
+	read_lock(&hash_table_lock);
 
-	for (; bh; bh = bh->b_next)
-		if (bh->b_blocknr == block	&&
-		    bh->b_size    == size	&&
-		    bh->b_dev     == dev)
+	for (;;) {
+		bh = *p;
+		if (!bh)
 			break;
-	if (bh)
+		p = &bh->b_next;
+		if (bh->b_blocknr != block)
+			continue;
+		if (bh->b_size != size)
+			continue;
+		if (bh->b_dev != dev)
+			continue;
 		get_bh(bh);
+		break;
+	}
 
-	return bh;
-}
-
-struct buffer_head * get_hash_table(kdev_t dev, int block, int size)
-{
-	struct buffer_head *bh;
-
-	read_lock(&hash_table_lock);
-	bh = __get_hash_table(dev, block, size);
 	read_unlock(&hash_table_lock);
-
 	return bh;
 }
 
@@ -688,10 +627,11 @@
    we think the disk contains more recent information than the buffercache.
    The update == 1 pass marks the buffers we need to update, the update == 2
    pass does the actual I/O. */
-void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers, int update)
+void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers)
 {
 	int i, nlist, slept;
 	struct buffer_head * bh, * bh_next;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);	/* will become bdev */
 
  retry:
 	slept = 0;
@@ -722,33 +662,14 @@
 			/* All buffers in the lru lists are mapped */
 			if (!buffer_mapped(bh))
 				BUG();
+			if (buffer_dirty(bh))
+				printk("invalidate: dirty buffer\n");
 			if (!atomic_read(&bh->b_count)) {
 				if (destroy_dirty_buffers || !buffer_dirty(bh)) {
 					remove_inode_queue(bh);
-					__remove_from_queues(bh);
-					put_last_free(bh);
 				}
-			} else if (update) {
-				if ((update == 2) ^ buffer_uptodate(bh)  &&
-				    (update == 2) ^ buffer_req(bh)) {
-					write_unlock(&hash_table_lock);
-					atomic_inc(&bh->b_count);
-					spin_unlock(&lru_list_lock);
-
-					if (update == 2) {
-						ll_rw_block(READ, 1, &bh);
-						wait_on_buffer(bh);
-					} else {
-						lock_buffer(bh);
-						clear_bit(BH_Uptodate, &bh->b_state);
-						clear_bit(BH_Req, &bh->b_state);
-						unlock_buffer(bh);
-					}						
-
-					atomic_dec(&bh->b_count);
-					goto retry;
-				}
-			}
+			} else
+				printk("invalidate: busy buffer\n");
 
 			write_unlock(&hash_table_lock);
 			if (slept)
@@ -759,81 +680,18 @@
 	spin_unlock(&lru_list_lock);
 	if (slept)
 		goto retry;
+
+	/* Get rid of the page cache */
+	invalidate_inode_pages(bdev->bd_inode);
 }
 
-void set_blocksize(kdev_t dev, int size)
+void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers)
 {
-	extern int *blksize_size[];
-	int i, nlist, slept;
-	struct buffer_head * bh, * bh_next;
-
-	if (!blksize_size[MAJOR(dev)])
-		return;
-
-	/* Size must be a power of two, and between 512 and PAGE_SIZE */
-	if (size > PAGE_SIZE || size < 512 || (size & (size-1)))
-		panic("Invalid blocksize passed to set_blocksize");
-
-	if (blksize_size[MAJOR(dev)][MINOR(dev)] == 0 && size == BLOCK_SIZE) {
-		blksize_size[MAJOR(dev)][MINOR(dev)] = size;
-		return;
-	}
-	if (blksize_size[MAJOR(dev)][MINOR(dev)] == size)
-		return;
-	sync_buffers(dev, 2);
-	blksize_size[MAJOR(dev)][MINOR(dev)] = size;
-
- retry:
-	slept = 0;
-	spin_lock(&lru_list_lock);
-	for(nlist = 0; nlist < NR_LIST; nlist++) {
-		bh = lru_list[nlist];
-		if (!bh)
-			continue;
-		for (i = nr_buffers_type[nlist]; i > 0 ; bh = bh_next, i--) {
-			bh_next = bh->b_next_free;
-			if (bh->b_dev != dev || bh->b_size == size)
-				continue;
-			/* Unhashed? */
-			if (!bh->b_pprev)
-				continue;
-			if (buffer_locked(bh)) {
-				get_bh(bh);
-				spin_unlock(&lru_list_lock);
-				wait_on_buffer(bh);
-				slept = 1;
-				spin_lock(&lru_list_lock);
-				put_bh(bh);
-			}
-
-			write_lock(&hash_table_lock);
-			if (!atomic_read(&bh->b_count)) {
-				if (buffer_dirty(bh))
-					printk(KERN_WARNING
-					       "set_blocksize: dev %s buffer_dirty %lu size %hu\n",
-					       kdevname(dev), bh->b_blocknr, bh->b_size);
-				remove_inode_queue(bh);
-				__remove_from_queues(bh);
-				put_last_free(bh);
-			} else {
-				if (atomic_set_buffer_clean(bh))
-					__refile_buffer(bh);
-				clear_bit(BH_Uptodate, &bh->b_state);
-				printk(KERN_WARNING
-				       "set_blocksize: "
-				       "b_count %d, dev %s, block %lu, from %p\n",
-				       atomic_read(&bh->b_count), bdevname(bh->b_dev),
-				       bh->b_blocknr, __builtin_return_address(0));
-			}
-			write_unlock(&hash_table_lock);
-			if (slept)
-				goto out;
-		}
+	struct block_device *bdev = bdget(dev);
+	if (bdev) {
+		invalidate_bdev(bdev, destroy_dirty_buffers);
+		bdput(bdev);
 	}
- out:
-	spin_unlock(&lru_list_lock);
-	if (slept)
-		goto retry;
 }
 
 static void free_more_memory(void)
@@ -1137,57 +995,16 @@
  */
 struct buffer_head * getblk(kdev_t dev, int block, int size)
 {
-	struct buffer_head * bh;
-	int isize;
+	for (;;) {
+		struct buffer_head * bh;
 
-repeat:
-	spin_lock(&lru_list_lock);
-	write_lock(&hash_table_lock);
-	bh = __get_hash_table(dev, block, size);
-	if (bh)
-		goto out;
-
-	isize = BUFSIZE_INDEX(size);
-	spin_lock(&free_list[isize].lock);
-	bh = free_list[isize].list;
-	if (bh) {
-		__remove_from_free_list(bh, isize);
-		atomic_set(&bh->b_count, 1);
-	}
-	spin_unlock(&free_list[isize].lock);
-
-	/*
-	 * OK, FINALLY we know that this buffer is the only one of
-	 * its kind, we hold a reference (b_count>0), it is unlocked,
-	 * and it is clean.
-	 */
-	if (bh) {
-		init_buffer(bh, NULL, NULL);
-		bh->b_dev = dev;
-		bh->b_blocknr = block;
-		bh->b_state = 1 << BH_Mapped;
+		bh = get_hash_table(dev, block, size);
+		if (bh)
+			return bh;
 
-		/* Insert the buffer into the regular lists */
-		__insert_into_queues(bh);
-	out:
-		write_unlock(&hash_table_lock);
-		spin_unlock(&lru_list_lock);
-		touch_buffer(bh);
-		return bh;
+		if (!grow_buffers(dev, block, size))
+			free_more_memory();
 	}
-
-	/*
-	 * If we block while refilling the free list, somebody may
-	 * create the buffer first ... search the hashes again.
-	 */
-	write_unlock(&hash_table_lock);
-	spin_unlock(&lru_list_lock);
-
-	if (!grow_buffers(size))
-		free_more_memory();
-
-	/* FIXME: getblk should fail if there's no enough memory */
-	goto repeat;
 }
 
 /* -1 -> no need to flush
@@ -1313,22 +1130,7 @@
  */
 void __bforget(struct buffer_head * buf)
 {
-	/* grab the lru lock here to block bdflush. */
-	spin_lock(&lru_list_lock);
-	write_lock(&hash_table_lock);
-	if (!atomic_dec_and_test(&buf->b_count) || buffer_locked(buf))
-		goto in_use;
-	__hash_unlink(buf);
-	write_unlock(&hash_table_lock);
-	remove_inode_queue(buf);
-	__remove_from_lru_list(buf, buf->b_list);
-	spin_unlock(&lru_list_lock);
-	put_last_free(buf);
-	return;
-
- in_use:
-	write_unlock(&hash_table_lock);
-	spin_unlock(&lru_list_lock);
+	__brelse(buf);
 }
 
 /**
@@ -1364,6 +1166,7 @@
 	if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) {
 		kmem_cache_free(bh_cachep, bh);
 	} else {
+		bh->b_dev = B_FREE;
 		bh->b_blocknr = -1;
 		bh->b_this_page = NULL;
 
@@ -1416,20 +1219,6 @@
 		}
 		spin_unlock(&unused_list_lock);
 	}
-#if 0
-	/*
-	 * (Pending further analysis ...)
-	 * Ordinary (non-async) requests can use a different memory priority
-	 * to free up pages. Any swapping thus generated will use async
-	 * buffer heads.
-	 */
-	if(!async &&
-	   (bh = kmem_cache_alloc(bh_cachep, SLAB_KERNEL)) != NULL) {
-		memset(bh, 0, sizeof(*bh));
-		init_waitqueue_head(&bh->b_wait);
-		return bh;
-	}
-#endif
 
 	return NULL;
 }
@@ -1470,7 +1259,7 @@
 		if (!bh)
 			goto no_grow;
 
-		bh->b_dev = B_FREE;  /* Flag as unused */
+		bh->b_dev = NODEV;
 		bh->b_this_page = head;
 		head = bh;
 
@@ -1524,7 +1313,10 @@
 	goto try_again;
 }
 
-static void unmap_buffer(struct buffer_head * bh)
+/*
+ * Called when truncating a buffer on a page completely.
+ */
+static void discard_buffer(struct buffer_head * bh)
 {
 	if (buffer_mapped(bh)) {
 		mark_buffer_clean(bh);
@@ -1564,7 +1356,7 @@
 		 * is this block fully flushed?
 		 */
 		if (offset <= curr_off)
-			unmap_buffer(bh);
+			discard_buffer(bh);
 		curr_off = next_off;
 		bh = next;
 	} while (bh != head);
@@ -1580,11 +1372,8 @@
 	 * instead.
 	 */
 	if (!offset) {
-		if (!try_to_free_buffers(page, 0)) {
-			if (drop_pagecache)
-				atomic_inc(&buffermem_pages);
+		if (!try_to_free_buffers(page, 0))
 			return 0;
-		}
 	}
 
 	return 1;
@@ -1667,10 +1456,10 @@
 		BUG();
 
 	if (!page->buffers)
-		create_empty_buffers(page, inode->i_dev, inode->i_sb->s_blocksize);
+		create_empty_buffers(page, inode->i_dev, 1 << inode->i_blkbits);
 	head = page->buffers;
 
-	block = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+	block = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 
 	bh = head;
 	i = 0;
@@ -1732,12 +1521,12 @@
 	struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
 	char *kaddr = kmap(page);
 
-	blocksize = inode->i_sb->s_blocksize;
+	blocksize = 1 << inode->i_blkbits;
 	if (!page->buffers)
 		create_empty_buffers(page, inode->i_dev, blocksize);
 	head = page->buffers;
 
-	bbits = inode->i_sb->s_blocksize_bits;
+	bbits = inode->i_blkbits;
 	block = page->index << (PAGE_CACHE_SHIFT - bbits);
 
 	for(bh = head, block_start = 0; bh != head || !block_start;
@@ -1800,7 +1589,7 @@
 	unsigned blocksize;
 	struct buffer_head *bh, *head;
 
-	blocksize = inode->i_sb->s_blocksize;
+	blocksize = 1 << inode->i_blkbits;
 
 	for(bh = head = page->buffers, block_start = 0;
 	    bh != head || !block_start;
@@ -1849,14 +1638,14 @@
 
 	if (!PageLocked(page))
 		PAGE_BUG(page);
-	blocksize = inode->i_sb->s_blocksize;
+	blocksize = 1 << inode->i_blkbits;
 	if (!page->buffers)
 		create_empty_buffers(page, inode->i_dev, blocksize);
 	head = page->buffers;
 
-	blocks = PAGE_CACHE_SIZE >> inode->i_sb->s_blocksize_bits;
-	iblock = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
-	lblock = (inode->i_size+blocksize-1) >> inode->i_sb->s_blocksize_bits;
+	blocks = PAGE_CACHE_SIZE >> inode->i_blkbits;
+	iblock = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	lblock = (inode->i_size+blocksize-1) >> inode->i_blkbits;
 	bh = head;
 	nr = 0;
 	i = 0;
@@ -1923,7 +1712,7 @@
 	unsigned long pgpos;
 	long status;
 	unsigned zerofrom;
-	unsigned blocksize = inode->i_sb->s_blocksize;
+	unsigned blocksize = 1 << inode->i_blkbits;
 	char *kaddr;
 
 	while(page->index > (pgpos = *bytes>>PAGE_CACHE_SHIFT)) {
@@ -2008,6 +1797,14 @@
 	return err;
 }
 
+int block_commit_write(struct page *page, unsigned from, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	__block_commit_write(inode,page,from,to);
+	kunmap(page);
+	return 0;
+}
+
 int generic_commit_write(struct file *file, struct page *page,
 		unsigned from, unsigned to)
 {
@@ -2032,7 +1829,7 @@
 	struct buffer_head *bh;
 	int err;
 
-	blocksize = inode->i_sb->s_blocksize;
+	blocksize = 1 << inode->i_blkbits;
 	length = offset & (blocksize - 1);
 
 	/* Block boundary? Nothing to do */
@@ -2040,7 +1837,7 @@
 		return 0;
 
 	length = blocksize - length;
-	iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+	iblock = index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 	
 	page = grab_cache_page(mapping, index);
 	err = -ENOMEM;
@@ -2141,47 +1938,6 @@
 	return tmp.b_blocknr;
 }
 
-int generic_direct_IO(int rw, struct inode * inode, struct kiobuf * iobuf, unsigned long blocknr, int blocksize, get_block_t * get_block)
-{
-	int i, nr_blocks, retval;
-	unsigned long * blocks = iobuf->blocks;
-
-	nr_blocks = iobuf->length / blocksize;
-	/* build the blocklist */
-	for (i = 0; i < nr_blocks; i++, blocknr++) {
-		struct buffer_head bh;
-
-		bh.b_state = 0;
-		bh.b_dev = inode->i_dev;
-		bh.b_size = blocksize;
-
-		retval = get_block(inode, blocknr, &bh, rw == READ ? 0 : 1);
-		if (retval)
-			goto out;
-
-		if (rw == READ) {
-			if (buffer_new(&bh))
-				BUG();
-			if (!buffer_mapped(&bh)) {
-				/* there was an hole in the filesystem */
-				blocks[i] = -1UL;
-				continue;
-			}
-		} else {
-			if (buffer_new(&bh))
-				unmap_underlying_metadata(&bh);
-			if (!buffer_mapped(&bh))
-				BUG();
-		}
-		blocks[i] = bh.b_blocknr;
-	}
-
-	retval = brw_kiovec(rw, 1, &iobuf, inode->i_dev, iobuf->blocks, blocksize);
-
- out:
-	return retval;
-}
-
 /*
  * IO completion routine for a buffer_head being used for kiobuf IO: we
  * can't dispatch the kiobuf callback until io_count reaches 0.  
@@ -2311,7 +2067,6 @@
 				}
 				tmp = bhs[bhind++];
 
-				tmp->b_dev = B_FREE;
 				tmp->b_size = size;
 				set_bh_page(tmp, map, offset);
 				tmp->b_this_page = tmp;
@@ -2447,67 +2202,129 @@
 	return err;
 }
 
+static inline void link_dev_buffers(struct page * page, struct buffer_head *head)
+{
+	struct buffer_head *bh, *tail;
+
+	bh = head;
+	do {
+		tail = bh;
+		bh = bh->b_this_page;
+	} while (bh);
+	tail->b_this_page = head;
+	page->buffers = head;
+	page_cache_get(page);
+}
+
+/*
+ * Create the page-cache page that contains the requested block
+ */
+static struct page * grow_dev_page(struct block_device *bdev, unsigned long index, int size)
+{
+	struct page * page;
+	struct buffer_head *bh;
+
+	page = find_or_create_page(bdev->bd_inode->i_mapping, index, GFP_NOFS);
+	if (IS_ERR(page))
+		return NULL;
+
+	if (!PageLocked(page))
+		BUG();
+
+	bh = page->buffers;
+	if (bh) {
+		if (bh->b_size == size)
+			return page;
+		if (!try_to_free_buffers(page, GFP_NOFS))
+			goto failed;
+	}
+
+	bh = create_buffers(page, size, 0);
+	if (!bh)
+		goto failed;
+	link_dev_buffers(page, bh);
+	return page;
+
+failed:
+	UnlockPage(page);
+	page_cache_release(page);
+	return NULL;
+}
+
+static void hash_page_buffers(struct page *page, kdev_t dev, int block, int size)
+{
+	struct buffer_head *head = page->buffers;
+	struct buffer_head *bh = head;
+	unsigned int uptodate;
+
+	uptodate = 1 << BH_Mapped;
+	if (Page_Uptodate(page))
+		uptodate |= 1 << BH_Uptodate;
+
+	write_lock(&hash_table_lock);
+	do {
+		if (!(bh->b_state & (1 << BH_Mapped))) {
+			init_buffer(bh, NULL, NULL);
+			bh->b_dev = dev;
+			bh->b_blocknr = block;
+			bh->b_state = uptodate;
+		}
+
+		/* Insert the buffer into the hash lists if necessary */
+		if (!bh->b_pprev)
+			__insert_into_hash_list(bh);
+
+		block++;
+		bh = bh->b_this_page;
+	} while (bh != head);
+	write_unlock(&hash_table_lock);
+}
+
 /*
  * Try to increase the number of buffers available: the size argument
  * is used to determine what kind of buffers we want.
  */
-static int grow_buffers(int size)
+static int grow_buffers(kdev_t dev, unsigned long block, int size)
 {
 	struct page * page;
-	struct buffer_head *bh, *tmp;
-	struct buffer_head * insert_point;
-	int isize;
+	struct block_device *bdev;
+	unsigned long index;
+	int sizebits;
 
 	if ((size & 511) || (size > PAGE_SIZE)) {
 		printk(KERN_ERR "VFS: grow_buffers: size = %d\n",size);
 		return 0;
 	}
+	sizebits = -1;
+	do {
+		sizebits++;
+	} while ((size << sizebits) < PAGE_SIZE);
 
-	page = alloc_page(GFP_NOFS);
-	if (!page)
-		goto out;
-	LockPage(page);
-	bh = create_buffers(page, size, 0);
-	if (!bh)
-		goto no_buffer_head;
-
-	isize = BUFSIZE_INDEX(size);
+	index = block >> sizebits;
+	block = index << sizebits;
 
-	spin_lock(&free_list[isize].lock);
-	insert_point = free_list[isize].list;
-	tmp = bh;
-	while (1) {
-		if (insert_point) {
-			tmp->b_next_free = insert_point->b_next_free;
-			tmp->b_prev_free = insert_point;
-			insert_point->b_next_free->b_prev_free = tmp;
-			insert_point->b_next_free = tmp;
-		} else {
-			tmp->b_prev_free = tmp;
-			tmp->b_next_free = tmp;
-		}
-		insert_point = tmp;
-		if (tmp->b_this_page)
-			tmp = tmp->b_this_page;
-		else
-			break;
+	bdev = bdget(kdev_t_to_nr(dev));
+	if (!bdev) {
+		printk("No block device for %s\n", kdevname(dev));
+		BUG();
 	}
-	tmp->b_this_page = bh;
-	free_list[isize].list = bh;
-	spin_unlock(&free_list[isize].lock);
-
-	page->buffers = bh;
-	page->flags &= ~(1 << PG_referenced);
-	lru_cache_add(page);
-	UnlockPage(page);
-	atomic_inc(&buffermem_pages);
-	return 1;
 
-no_buffer_head:
+	/* Create a page with the proper size buffers.. */
+	page = grow_dev_page(bdev, index, size);
+
+	/* This is "wrong" - talk to Al Viro */
+	atomic_dec(&bdev->bd_count);
+	if (!page)
+		return 0;
+
+	/* Hash in the buffers on the hash list */
+	hash_page_buffers(page, dev, block, size);
 	UnlockPage(page);
 	page_cache_release(page);
-out:
-	return 0;
+
+	/* We hashed up this page, so increment buffermem */
+	atomic_inc(&buffermem_pages);
+	return 1;
 }
 
 static int sync_page_buffers(struct buffer_head *bh, unsigned int gfp_mask)
@@ -2522,7 +2339,7 @@
 					ll_rw_block(WRITE, 1, &p);
 					tryagain = 0;
 				} else if (buffer_locked(p)) {
-					if (gfp_mask & __GFP_WAIT) {
+					if (gfp_mask & __GFP_WAITBUF) {
 						wait_on_buffer(p);
 						tryagain = 1;
 					} else
@@ -2557,12 +2374,10 @@
 int try_to_free_buffers(struct page * page, unsigned int gfp_mask)
 {
 	struct buffer_head * tmp, * bh = page->buffers;
-	int index = BUFSIZE_INDEX(bh->b_size);
 
 cleaned_buffers_try_again:
 	spin_lock(&lru_list_lock);
 	write_lock(&hash_table_lock);
-	spin_lock(&free_list[index].lock);
 	tmp = bh;
 	do {
 		if (buffer_busy(tmp))
@@ -2572,18 +2387,18 @@
 
 	spin_lock(&unused_list_lock);
 	tmp = bh;
+
+	/* if this buffer was hashed, this page counts as buffermem */
+	if (bh->b_pprev)
+		atomic_dec(&buffermem_pages);
 	do {
 		struct buffer_head * p = tmp;
 		tmp = tmp->b_this_page;
 
-		/* The buffer can be either on the regular
-		 * queues or on the free list..
-		 */
-		if (p->b_dev != B_FREE) {
-			remove_inode_queue(p);
-			__remove_from_queues(p);
-		} else
-			__remove_from_free_list(p, index);
+		if (p->b_dev == B_FREE) BUG();
+
+		remove_inode_queue(p);
+		__remove_from_queues(p);
 		__put_unused_buffer_head(p);
 	} while (tmp != bh);
 	spin_unlock(&unused_list_lock);
@@ -2594,14 +2409,12 @@
 	/* And free the page */
 	page->buffers = NULL;
 	page_cache_release(page);
-	spin_unlock(&free_list[index].lock);
 	write_unlock(&hash_table_lock);
 	spin_unlock(&lru_list_lock);
 	return 1;
 
 busy_buffer_page:
 	/* Uhhuh, start writeback so that we don't end up with all dirty pages */
-	spin_unlock(&free_list[index].lock);
 	write_unlock(&hash_table_lock);
 	spin_unlock(&lru_list_lock);
 	if (gfp_mask & __GFP_IO) {
@@ -2713,12 +2526,6 @@
 	/* Setup hash chains. */
 	for(i = 0; i < nr_hash; i++)
 		hash_table[i] = NULL;
-
-	/* Setup free lists. */
-	for(i = 0; i < NR_SIZES; i++) {
-		free_list[i].list = NULL;
-		free_list[i].lock = SPIN_LOCK_UNLOCKED;
-	}
 
 	/* Setup lru lists. */
 	for(i = 0; i < NR_LIST; i++)
diff -u --recursive --new-file v2.4.10/linux/fs/devfs/base.c linux/fs/devfs/base.c
--- v2.4.10/linux/fs/devfs/base.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/devfs/base.c	Mon Oct  8 11:38:51 2001
@@ -545,6 +545,9 @@
     20010919   Richard Gooch <rgooch@atnf.csiro.au>
 	       Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>.
   v0.116
+    20010927   Richard Gooch <rgooch@atnf.csiro.au>
+	       Went back to global rwsem for symlinks (refcount scheme no good)
+  v0.117
 */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -577,7 +580,7 @@
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
-#define DEVFS_VERSION            "0.116 (20010919)"
+#define DEVFS_VERSION            "0.117 (20010927)"
 
 #define DEVFS_NAME "devfs"
 
@@ -659,8 +662,6 @@
 
 struct symlink_type
 {
-    atomic_t refcount;           /*  When this drops to zero, it's unused    */
-    rwlock_t lock;               /*  Lock around the registered flag         */
     unsigned int length;         /*  Not including the NULL-termimator       */
     char *linkname;              /*  This is NULL-terminated                 */
 };
@@ -750,6 +751,8 @@
 static unsigned int boot_options = OPTION_NONE;
 #endif
 
+static DECLARE_RWSEM (symlink_rwsem);
+
 /*  Forward function declarations  */
 static struct devfs_entry *search_for_entry (struct devfs_entry *dir,
 					     const char *name,
@@ -807,19 +810,12 @@
     if (curr == NULL) return NULL;
     if (!S_ISLNK (curr->mode) || !traverse_symlink) return curr;
     /*  Need to follow the link: this is a stack chomper  */
-    read_lock (&curr->u.symlink.lock);
-    if (!curr->registered)
-    {
-	read_unlock (&curr->u.symlink.lock);
-	return NULL;
-    }
-    atomic_inc (&curr->u.symlink.refcount);
-    read_unlock (&curr->u.symlink.lock);
-    retval = search_for_entry (parent, curr->u.symlink.linkname,
-			       curr->u.symlink.length, FALSE, FALSE, NULL,
-			       TRUE);
-    if ( atomic_dec_and_test (&curr->u.symlink.refcount) )
-	kfree (curr->u.symlink.linkname);
+    down_read (&symlink_rwsem);
+    retval = curr->registered ?
+	search_for_entry (parent, curr->u.symlink.linkname,
+			  curr->u.symlink.length, FALSE, FALSE, NULL,
+			  TRUE) : NULL;
+    up_read (&symlink_rwsem);
     return retval;
 }   /*  End Function search_for_entry_in_dir  */
 
@@ -1436,11 +1432,11 @@
     }
     if (S_ISLNK (de->mode) && de->registered)
     {
-	write_lock (&de->u.symlink.lock);
 	de->registered = FALSE;
-	write_unlock (&de->u.symlink.lock);
-	if ( atomic_dec_and_test (&de->u.symlink.refcount) )
-	    kfree (de->u.symlink.linkname);
+	down_write (&symlink_rwsem);
+	if (de->u.symlink.linkname) kfree (de->u.symlink.linkname);
+	de->u.symlink.linkname = NULL;
+	up_write (&symlink_rwsem);
 	return;
     }
     if ( S_ISFIFO (de->mode) )
@@ -1520,8 +1516,10 @@
 	kfree (newlink);
 	return -ENOMEM;
     }
+    down_write (&symlink_rwsem);
     if (de->registered)
     {
+	up_write (&symlink_rwsem);
 	kfree (newlink);
 	printk ("%s: devfs_do_symlink(%s): entry already exists\n",
 		DEVFS_NAME, name);
@@ -1532,9 +1530,8 @@
     de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
     de->u.symlink.linkname = newlink;
     de->u.symlink.length = linklength;
-    atomic_set (&de->u.symlink.refcount, 1);
-    rwlock_init (&de->u.symlink.lock);
     de->registered = TRUE;
+    up_write (&symlink_rwsem);
     if (handle != NULL) *handle = de;
     return 0;
 }   /*  End Function devfs_do_symlink  */
@@ -2818,16 +2815,15 @@
     if (de == NULL) return -ENOENT;
     devfsd_notify_one (de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
 		       inode->i_uid, inode->i_gid, dir->i_sb->u.generic_sbp);
+    de->registered = FALSE;
+    de->hide = TRUE;
     if ( S_ISLNK (de->mode) )
     {
-	write_lock (&de->u.symlink.lock);
-	de->registered = FALSE;
-	write_unlock (&de->u.symlink.lock);
-	if ( atomic_dec_and_test (&de->u.symlink.refcount) )
-	    kfree (de->u.symlink.linkname);
+	down_write (&symlink_rwsem);
+	if (de->u.symlink.linkname) kfree (de->u.symlink.linkname);
+	de->u.symlink.linkname = NULL;
+	up_write (&symlink_rwsem);
     }
-    else de->registered = FALSE;
-    de->hide = TRUE;
     free_dentries (de);
     return 0;
 }   /*  End Function devfs_unlink  */
@@ -3029,17 +3025,10 @@
 
     de = get_devfs_entry_from_vfs_inode (dentry->d_inode, TRUE);
     if (!de) return -ENODEV;
-    read_lock (&de->u.symlink.lock);
-    if (!de->registered)
-    {
-	read_unlock (&de->u.symlink.lock);
-	return -ENODEV;
-    }
-    atomic_inc (&de->u.symlink.refcount);
-    read_unlock (&de->u.symlink.lock);
-    err = vfs_readlink (dentry, buffer, buflen, de->u.symlink.linkname);
-    if ( atomic_dec_and_test (&de->u.symlink.refcount) )
-	kfree (de->u.symlink.linkname);
+    down_read (&symlink_rwsem);
+    err = de->registered ? vfs_readlink (dentry, buffer, buflen,
+					 de->u.symlink.linkname) : -ENODEV;
+    up_read (&symlink_rwsem);
     return err;
 }   /*  End Function devfs_readlink  */
 
@@ -3050,17 +3039,10 @@
 
     de = get_devfs_entry_from_vfs_inode (dentry->d_inode, TRUE);
     if (!de) return -ENODEV;
-    read_lock (&de->u.symlink.lock);
-    if (!de->registered)
-    {
-	read_unlock (&de->u.symlink.lock);
-	return -ENODEV;
-    }
-    atomic_inc (&de->u.symlink.refcount);
-    read_unlock (&de->u.symlink.lock);
-    err = vfs_follow_link (nd, de->u.symlink.linkname);
-    if ( atomic_dec_and_test (&de->u.symlink.refcount) )
-	kfree (de->u.symlink.linkname);
+    down_read (&symlink_rwsem);
+    err = de->registered ? vfs_follow_link (nd,
+					    de->u.symlink.linkname) : -ENODEV;
+    up_read (&symlink_rwsem);
     return err;
 }   /*  End Function devfs_follow_link  */
 
diff -u --recursive --new-file v2.4.10/linux/fs/devpts/inode.c linux/fs/devpts/inode.c
--- v2.4.10/linux/fs/devpts/inode.c	Tue Apr 17 15:04:36 2001
+++ linux/fs/devpts/inode.c	Sun Sep 30 12:26:08 2001
@@ -250,3 +250,5 @@
 
 module_init(init_devpts_fs)
 module_exit(exit_devpts_fs)
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/fs/dquot.c linux/fs/dquot.c
--- v2.4.10/linux/fs/dquot.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/dquot.c	Fri Oct  5 12:23:53 2001
@@ -26,7 +26,7 @@
  *		dquot_incr_...() to calling functions.
  *		invalidate_dquots() now writes modified dquots.
  *		Serialized quota_off() and quota_on() for mount point.
- *		Fixed a few bugs in grow_dquots.
+ *		Fixed a few bugs in grow_dquots().
  *		Fixed deadlock in write_dquot() - we no longer account quotas on
  *		quota files
  *		remove_dquot_ref() moved to inode.c - it now traverses through inodes
@@ -34,13 +34,24 @@
  *		Added check for bogus uid and fixed check for group in quotactl.
  *		Jan Kara, <jack@suse.cz>, sponsored by SuSE CR, 10-11/99
  *
+ *		Used struct list_head instead of own list struct
+ *		Invalidation of dquots with dq_count > 0 no longer possible
+ *		Improved free_dquots list management
+ *		Quota and i_blocks are now updated in one place to avoid races
+ *		Warnings are now delayed so we won't block in critical section
+ *		Write updated not to require dquot lock
+ *		Jan Kara, <jack@suse.cz>, 9/2000
+ *
+ *		Added dynamic quota structure allocation
+ *		Jan Kara <jack@suse.cz> 12/2000
+ *
  * (C) Copyright 1994 - 1997 Marco van Wieringen 
  */
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/fs.h>
 #include <linux/sched.h>
-
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
@@ -48,8 +59,6 @@
 #include <linux/tty.h>
 #include <linux/file.h>
 #include <linux/slab.h>
-#include <linux/mount.h>
-#include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 
@@ -58,9 +67,7 @@
 #define __DQUOT_VERSION__	"dquot_6.4.0"
 
 int nr_dquots, nr_free_dquots;
-int max_dquots = NR_DQUOTS;
 
-static char quotamessage[MAX_QUOTA_MESSAGE];
 static char *quotatypes[] = INITQFNAMES;
 
 static inline struct quota_mount_options *sb_dqopt(struct super_block *sb)
@@ -74,28 +81,41 @@
  * free_dquots, and dquot_hash[] array. A single dquot structure may be
  * on all three lists, depending on its current state.
  *
- * All dquots are placed on the inuse_list when first created, and this
+ * All dquots are placed to the end of inuse_list when first created, and this
  * list is used for the sync and invalidate operations, which must look
  * at every dquot.
  *
  * Unused dquots (dq_count == 0) are added to the free_dquots list when
  * freed, and this list is searched whenever we need an available dquot.
  * Dquots are removed from the list as soon as they are used again, and
- * nr_free_dquots gives the number of dquots on the list.
+ * nr_free_dquots gives the number of dquots on the list. When dquot is
+ * invalidated it's completely released from memory.
  *
  * Dquots with a specific identity (device, type and id) are placed on
  * one of the dquot_hash[] hash chains. The provides an efficient search
- * mechanism to lcoate a specific dquot.
+ * mechanism to locate a specific dquot.
+ */
+
+/*
+ * Note that any operation which operates on dquot data (ie. dq_dqb) mustn't
+ * block while it's updating/reading it. Otherwise races would occur.
+ *
+ * Locked dquots might not be referenced in inodes - operations like
+ * add_dquot_space() does dqduplicate() and would complain. Currently
+ * dquot it locked only once in its existence - when it's being read
+ * to memory on first dqget() and at that time it can't be referenced
+ * from inode. Write operations on dquots don't hold dquot lock as they
+ * copy data to internal buffers before writing anyway and copying as well
+ * as any data update should be atomic. Also nobody can change used
+ * entries in dquot structure as this is done only when quota is destroyed
+ * and invalidate_dquots() waits for dquot to have dq_count == 0.
  */
 
-static struct dquot *inuse_list;
+static LIST_HEAD(inuse_list);
 static LIST_HEAD(free_dquots);
-static struct dquot *dquot_hash[NR_DQHASH];
-static int dquot_updating[NR_DQHASH];
+static struct list_head dquot_hash[NR_DQHASH];
 
 static struct dqstats dqstats;
-static DECLARE_WAIT_QUEUE_HEAD(dquot_wait);
-static DECLARE_WAIT_QUEUE_HEAD(update_wait);
 
 static void dqput(struct dquot *);
 static struct dquot *dqduplicate(struct dquot *);
@@ -123,38 +143,27 @@
 
 static inline void insert_dquot_hash(struct dquot *dquot)
 {
-	struct dquot **htable;
-
-	htable = &dquot_hash[hashfn(dquot->dq_dev, dquot->dq_id, dquot->dq_type)];
-	if ((dquot->dq_hash_next = *htable) != NULL)
-		(*htable)->dq_hash_pprev = &dquot->dq_hash_next;
-	*htable = dquot;
-	dquot->dq_hash_pprev = htable;
+	struct list_head *head = dquot_hash + hashfn(dquot->dq_dev, dquot->dq_id, dquot->dq_type);
+	list_add(&dquot->dq_hash, head);
 }
 
-static inline void hash_dquot(struct dquot *dquot)
+static inline void remove_dquot_hash(struct dquot *dquot)
 {
-	insert_dquot_hash(dquot);
-}
-
-static inline void unhash_dquot(struct dquot *dquot)
-{
-	if (dquot->dq_hash_pprev) {
-		if (dquot->dq_hash_next)
-			dquot->dq_hash_next->dq_hash_pprev = dquot->dq_hash_pprev;
-		*(dquot->dq_hash_pprev) = dquot->dq_hash_next;
-		dquot->dq_hash_pprev = NULL;
-	}
+	list_del(&dquot->dq_hash);
+	INIT_LIST_HEAD(&dquot->dq_hash);
 }
 
 static inline struct dquot *find_dquot(unsigned int hashent, kdev_t dev, unsigned int id, short type)
 {
+	struct list_head *head;
 	struct dquot *dquot;
 
-	for (dquot = dquot_hash[hashent]; dquot; dquot = dquot->dq_hash_next)
+	for (head = dquot_hash[hashent].next; head != dquot_hash+hashent; head = head->next) {
+		dquot = list_entry(head, struct dquot, dq_hash);
 		if (dquot->dq_dev == dev && dquot->dq_id == id && dquot->dq_type == type)
-			break;
-	return dquot;
+			return dquot;
+	}
+	return NODQUOT;
 }
 
 /* Add a dquot to the head of the free list */
@@ -171,6 +180,13 @@
 	nr_free_dquots++;
 }
 
+/* Move dquot to the head of free list (it must be already on it) */
+static inline void move_dquot_head(struct dquot *dquot)
+{
+	list_del(&dquot->dq_free);
+	list_add(&dquot->dq_free, &free_dquots);
+}
+
 static inline void remove_free_dquot(struct dquot *dquot)
 {
 	/* sanity check */
@@ -185,36 +201,30 @@
 
 static inline void put_inuse(struct dquot *dquot)
 {
-	if ((dquot->dq_next = inuse_list) != NULL)
-		inuse_list->dq_pprev = &dquot->dq_next;
-	inuse_list = dquot;
-	dquot->dq_pprev = &inuse_list;
+	/* We add to the back of inuse list so we don't have to restart
+	 * when traversing this list and we block */
+	list_add(&dquot->dq_inuse, inuse_list.prev);
+	nr_dquots++;
 }
 
-#if 0	/* currently not needed */
 static inline void remove_inuse(struct dquot *dquot)
 {
-	if (dquot->dq_pprev) {
-		if (dquot->dq_next)
-			dquot->dq_next->dq_pprev = dquot->dq_pprev;
-		*dquot->dq_pprev = dquot->dq_next;
-		dquot->dq_pprev = NULL;
-	}
+	nr_dquots--;
+	list_del(&dquot->dq_inuse);
 }
-#endif
 
 static void __wait_on_dquot(struct dquot *dquot)
 {
 	DECLARE_WAITQUEUE(wait, current);
 
-	add_wait_queue(&dquot->dq_wait, &wait);
+	add_wait_queue(&dquot->dq_wait_lock, &wait);
 repeat:
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	if (dquot->dq_flags & DQ_LOCKED) {
 		schedule();
 		goto repeat;
 	}
-	remove_wait_queue(&dquot->dq_wait, &wait);
+	remove_wait_queue(&dquot->dq_wait_lock, &wait);
 	current->state = TASK_RUNNING;
 }
 
@@ -233,7 +243,22 @@
 static inline void unlock_dquot(struct dquot *dquot)
 {
 	dquot->dq_flags &= ~DQ_LOCKED;
-	wake_up(&dquot->dq_wait);
+	wake_up(&dquot->dq_wait_lock);
+}
+
+static void __wait_dquot_unused(struct dquot *dquot)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	add_wait_queue(&dquot->dq_wait_free, &wait);
+repeat:
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	if (dquot->dq_count) {
+		schedule();
+		goto repeat;
+	}
+	remove_wait_queue(&dquot->dq_wait_free, &wait);
+	current->state = TASK_RUNNING;
 }
 
 /*
@@ -247,12 +272,8 @@
 	loff_t offset;
 	ssize_t ret;
 	struct semaphore *sem = &dquot->dq_sb->s_dquot.dqio_sem;
+	struct dqblk dqbuf;
 
-	lock_dquot(dquot);
-	if (!dquot->dq_sb) {	/* Invalidated quota? */
-		unlock_dquot(dquot);
-		return;
-	}
 	down(sem);
 	filp = dquot->dq_sb->s_dquot.files[type];
 	offset = dqoff(dquot->dq_id);
@@ -263,10 +284,11 @@
 	 * Note: clear the DQ_MOD flag unconditionally,
 	 * so we don't loop forever on failure.
 	 */
+	memcpy(&dqbuf, &dquot->dq_dqb, sizeof(struct dqblk));
 	dquot->dq_flags &= ~DQ_MOD;
 	ret = 0;
 	if (filp)
-		ret = filp->f_op->write(filp, (char *)&dquot->dq_dqb, 
+		ret = filp->f_op->write(filp, (char *)&dqbuf, 
 					sizeof(struct dqblk), &offset);
 	if (ret != sizeof(struct dqblk))
 		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
@@ -274,8 +296,6 @@
 
 	set_fs(fs);
 	up(sem);
-	unlock_dquot(dquot);
-
 	dqstats.writes++;
 }
 
@@ -318,96 +338,99 @@
 void clear_dquot(struct dquot *dquot)
 {
 	/* unhash it first */
-        unhash_dquot(dquot);
-        dquot->dq_sb = NULL;
-        dquot->dq_flags = 0;
-        dquot->dq_referenced = 0;
-        memset(&dquot->dq_dqb, 0, sizeof(struct dqblk));
+	remove_dquot_hash(dquot);
+	dquot->dq_sb = NULL;
+	dquot->dq_id = 0;
+	dquot->dq_dev = NODEV;
+	dquot->dq_type = -1;
+	dquot->dq_flags = 0;
+	dquot->dq_referenced = 0;
+	memset(&dquot->dq_dqb, 0, sizeof(struct dqblk));
 }
 
+/* Invalidate all dquots on the list, wait for all users. Note that this function is called
+ * after quota is disabled so no new quota might be created. As we only insert to the end of
+ * inuse list, we don't have to restart searching... */
 static void invalidate_dquots(struct super_block *sb, short type)
 {
-	struct dquot *dquot, *next;
-	int need_restart;
+	struct dquot *dquot;
+	struct list_head *head;
 
 restart:
-	next = inuse_list;	/* Here it is better. Otherwise the restart doesn't have any sense ;-) */
-	need_restart = 0;
-	while ((dquot = next) != NULL) {
-		next = dquot->dq_next;
+	for (head = inuse_list.next; head != &inuse_list; head = head->next) {
+		dquot = list_entry(head, struct dquot, dq_inuse);
 		if (dquot->dq_sb != sb)
 			continue;
 		if (dquot->dq_type != type)
 			continue;
-		if (dquot->dq_flags & DQ_LOCKED) {
-			__wait_on_dquot(dquot);
-
-			/* Set the flag for another pass. */
-			need_restart = 1;
+		if (dquot->dq_count)
 			/*
-			 * Make sure it's still the same dquot.
+			 *  Wait for any users of quota. As we have already cleared the flags in
+			 *  superblock and cleared all pointers from inodes we are assured
+			 *  that there will be no new users of this quota.
 			 */
-			if (dquot->dq_sb != sb)
-				continue;
-			if (dquot->dq_type != type)
-				continue;
-		}
-		/*
-		 *  Because inodes needn't to be the only holders of dquot
-		 *  the quota needn't to be written to disk. So we write it
-		 *  ourselves before discarding the data just for sure...
-		 */
-		if (dquot->dq_flags & DQ_MOD && dquot->dq_sb)
-		{
-			write_dquot(dquot);
-			need_restart = 1;	/* We slept on IO */
-		}
-		clear_dquot(dquot);
-	}
-	/*
-	 * If anything blocked, restart the operation
-	 * to ensure we don't miss any dquots.
-	 */ 
-	if (need_restart)
+			__wait_dquot_unused(dquot);
+		/* Quota now have no users and it has been written on last dqput() */
+		remove_dquot_hash(dquot);
+		remove_free_dquot(dquot);
+		remove_inuse(dquot);
+		kmem_cache_free(dquot_cachep, dquot);
 		goto restart;
+	}
 }
 
 int sync_dquots(kdev_t dev, short type)
 {
-	struct dquot *dquot, *next, *ddquot;
-	int need_restart;
+	struct list_head *head;
+	struct dquot *dquot;
 
 restart:
-	next = inuse_list;
-	need_restart = 0;
-	while ((dquot = next) != NULL) {
-		next = dquot->dq_next;
+	for (head = inuse_list.next; head != &inuse_list; head = head->next) {
+		dquot = list_entry(head, struct dquot, dq_inuse);
 		if (dev && dquot->dq_dev != dev)
 			continue;
                 if (type != -1 && dquot->dq_type != type)
 			continue;
 		if (!dquot->dq_sb)	/* Invalidated? */
 			continue;
-		if (!(dquot->dq_flags & (DQ_LOCKED | DQ_MOD)))
+		if (!(dquot->dq_flags & (DQ_MOD | DQ_LOCKED)))
 			continue;
+		/* Raise use count so quota won't be invalidated. We can't use dqduplicate() as it does too many tests */
+		dquot->dq_count++;
+		if (dquot->dq_flags & DQ_LOCKED)
+			wait_on_dquot(dquot);
+		if (dquot->dq_flags & DQ_MOD)
+			write_dquot(dquot);
+		dqput(dquot);
+		goto restart;
+	}
+	dqstats.syncs++;
+	return 0;
+}
 
-		if ((ddquot = dqduplicate(dquot)) == NODQUOT)
-			continue;
-		if (ddquot->dq_flags & DQ_MOD)
-			write_dquot(ddquot);
-		dqput(ddquot);
-		/* Set the flag for another pass. */
-		need_restart = 1;
+/* Free unused dquots from cache */
+static void prune_dqcache(int count)
+{
+	struct list_head *head;
+	struct dquot *dquot;
+
+	head = free_dquots.prev;
+	while (head != &free_dquots && count) {
+		dquot = list_entry(head, struct dquot, dq_free);
+		remove_dquot_hash(dquot);
+		remove_free_dquot(dquot);
+		remove_inuse(dquot);
+		kmem_cache_free(dquot_cachep, dquot);
+		count--;
+		head = free_dquots.prev;
 	}
-	/*
-	 * If anything blocked, restart the operation
-	 * to ensure we don't miss any dquots.
-	 */ 
-	if (need_restart)
-		goto restart;
+}
 
-	dqstats.syncs++;
-	return(0);
+int shrink_dqcache_memory(int priority, unsigned int gfp_mask)
+{
+	prune_dqcache(nr_free_dquots / (priority + 1));
+	kmem_cache_shrink(dquot_cachep);
+	return 0;
 }
 
 /* NOTE: If you change this function please check whether dqput_blocks() works right... */
@@ -423,24 +446,14 @@
 		return;
 	}
 
-	/*
-	 * If the dq_sb pointer isn't initialized this entry needs no
-	 * checking and doesn't need to be written. It's just an empty
-	 * dquot that is put back on to the freelist.
-	 */
-	if (dquot->dq_sb)
-		dqstats.drops++;
+	dqstats.drops++;
 we_slept:
 	if (dquot->dq_count > 1) {
 		/* We have more than one user... We can simply decrement use count */
 		dquot->dq_count--;
 		return;
 	}
-	if (dquot->dq_flags & DQ_LOCKED) {
-		printk(KERN_ERR "VFS: Locked quota to be put on the free list.\n");
-		dquot->dq_flags &= ~DQ_LOCKED;
-	}
-	if (dquot->dq_sb && dquot->dq_flags & DQ_MOD) {
+	if (dquot->dq_flags & DQ_MOD) {
 		write_dquot(dquot);
 		goto we_slept;
 	}
@@ -452,130 +465,49 @@
 		return;
 	}
 	dquot->dq_count--;
-	dquot->dq_flags &= ~DQ_MOD;	/* Modified flag has no sense on free list */
 	/* Place at end of LRU free queue */
 	put_dquot_last(dquot);
-	wake_up(&dquot_wait);
-}
-
-static int grow_dquots(void)
-{
-	struct dquot *dquot;
-	int cnt = 0;
-
-	while (cnt < 32) {
-		dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
-		if(!dquot)
-			return cnt;
-
-		nr_dquots++;
-		memset((caddr_t)dquot, 0, sizeof(struct dquot));
-		init_waitqueue_head(&dquot->dq_wait);
-		/* all dquots go on the inuse_list */
-		put_inuse(dquot);
-		put_dquot_head(dquot);
-		cnt++;
-	}
-	return cnt;
-}
-
-static struct dquot *find_best_candidate_weighted(void)
-{
-	struct list_head *tmp = &free_dquots;
-	struct dquot *dquot, *best = NULL;
-	unsigned long myscore, bestscore = ~0U;
-	int limit = (nr_free_dquots > 128) ? nr_free_dquots >> 2 : 32;
-
-	while ((tmp = tmp->next) != &free_dquots && --limit) {
-		dquot = list_entry(tmp, struct dquot, dq_free);
-		/* This should never happen... */
-		if (dquot->dq_flags & (DQ_LOCKED | DQ_MOD))
-			continue;
-		myscore = dquot->dq_referenced;
-		if (myscore < bestscore) {
-			bestscore = myscore;
-			best = dquot;
-		}
-	}
-	return best;
-}
-
-static inline struct dquot *find_best_free(void)
-{
-	struct list_head *tmp = &free_dquots;
-	struct dquot *dquot;
-	int limit = (nr_free_dquots > 1024) ? nr_free_dquots >> 5 : 32;
-
-	while ((tmp = tmp->next) != &free_dquots && --limit) {
-		dquot = list_entry(tmp, struct dquot, dq_free);
-		if (dquot->dq_referenced == 0)
-			return dquot;
-	}
-	return NULL;
+	wake_up(&dquot->dq_wait_free);
 }
 
 struct dquot *get_empty_dquot(void)
 {
 	struct dquot *dquot;
-	int shrink = 8;	/* Number of times we should try to shrink dcache and icache */
 
-repeat:
-	dquot = find_best_free();
-	if (!dquot)
-		goto pressure;
-got_it:
-	/* Sanity checks */
-	if (dquot->dq_flags & DQ_LOCKED)
-		printk(KERN_ERR "VFS: Locked dquot on the free list\n");
-	if (dquot->dq_count != 0)
-		printk(KERN_ERR "VFS: free dquot count=%d\n", dquot->dq_count);
+	dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
+	if(!dquot)
+		return NODQUOT;
 
-	remove_free_dquot(dquot);
+	memset((caddr_t)dquot, 0, sizeof(struct dquot));
+	init_waitqueue_head(&dquot->dq_wait_free);
+	init_waitqueue_head(&dquot->dq_wait_lock);
+	INIT_LIST_HEAD(&dquot->dq_free);
+	INIT_LIST_HEAD(&dquot->dq_inuse);
+	INIT_LIST_HEAD(&dquot->dq_hash);
 	dquot->dq_count = 1;
-	/* unhash and selectively clear the structure */
-	clear_dquot(dquot);
-	return dquot;
+	/* all dquots go on the inuse_list */
+	put_inuse(dquot);
 
-pressure:
-	if (nr_dquots < max_dquots)
-		if (grow_dquots())
-			goto repeat;
-
-	dquot = find_best_candidate_weighted();
-	if (dquot)
-		goto got_it;
-	/*
-	 * Try pruning the dcache to free up some dquots ...
-	 */
-	if (shrink) {
-		printk(KERN_DEBUG "get_empty_dquot: pruning dcache and icache\n");
-		prune_dcache(128);
-		prune_icache(128);
-		shrink--;
-		goto repeat;
-	}
-
-	printk("VFS: No free dquots, contact mvw@planets.elm.net\n");
-	sleep_on(&dquot_wait);
-	goto repeat;
+	return dquot;
 }
 
 static struct dquot *dqget(struct super_block *sb, unsigned int id, short type)
 {
 	unsigned int hashent = hashfn(sb->s_dev, id, type);
-	struct dquot *dquot, *empty = NULL;
+	struct dquot *dquot, *empty = NODQUOT;
 	struct quota_mount_options *dqopt = sb_dqopt(sb);
 
-        if (!is_enabled(dqopt, type))
-                return(NODQUOT);
-
 we_slept:
-	if ((dquot = find_dquot(hashent, sb->s_dev, id, type)) == NULL) {
-		if (empty == NULL) {
-			dquot_updating[hashent]++;
-			empty = get_empty_dquot();
-			if (!--dquot_updating[hashent])
-				wake_up(&update_wait);
+        if (!is_enabled(dqopt, type)) {
+		if (empty)
+			dqput(empty);
+                return NODQUOT;
+	}
+
+	if ((dquot = find_dquot(hashent, sb->s_dev, id, type)) == NODQUOT) {
+		if (empty == NODQUOT) {
+			if ((empty = get_empty_dquot()) == NODQUOT)
+				schedule();	/* Try to wait for a moment... */
 			goto we_slept;
 		}
 		dquot = empty;
@@ -584,25 +516,19 @@
         	dquot->dq_dev = sb->s_dev;
         	dquot->dq_sb = sb;
 		/* hash it first so it can be found */
-		hash_dquot(dquot);
+		insert_dquot_hash(dquot);
         	read_dquot(dquot);
 	} else {
-		if (!dquot->dq_count++) {
+		if (!dquot->dq_count++)
 			remove_free_dquot(dquot);
-		} else
-			dqstats.cache_hits++;
+		dqstats.cache_hits++;
 		wait_on_dquot(dquot);
 		if (empty)
 			dqput(empty);
 	}
 
-	while (dquot_updating[hashent])
-		sleep_on(&update_wait);
-
 	if (!dquot->dq_sb) {	/* Has somebody invalidated entry under us? */
-		/*
-		 *  Do it as if the quota was invalidated before we started
-		 */
+		printk(KERN_ERR "VFS: dqget(): Quota invalidated in dqget()!\n");
 		dqput(dquot);
 		return NODQUOT;
 	}
@@ -614,14 +540,16 @@
 
 static struct dquot *dqduplicate(struct dquot *dquot)
 {
-	if (dquot == NODQUOT || !dquot->dq_sb)
+	if (dquot == NODQUOT)
 		return NODQUOT;
 	dquot->dq_count++;
-	wait_on_dquot(dquot);
 	if (!dquot->dq_sb) {
+		printk(KERN_ERR "VFS: dqduplicate(): Invalidated quota to be duplicated!\n");
 		dquot->dq_count--;
 		return NODQUOT;
 	}
+	if (dquot->dq_flags & DQ_LOCKED)
+		printk(KERN_ERR "VFS: dqduplicate(): Locked quota to be duplicated!\n");
 	dquot->dq_referenced++;
 	dqstats.lookups++;
 	return dquot;
@@ -695,9 +623,9 @@
 				printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", dquot->dq_count);
 			list_add(&dquot->dq_free, tofree_head);	/* As dquot must have currently users it can't be on the free list... */
 			return 1;
-		} else {
-			dqput(dquot);   /* We have guaranteed we won't block */
 		}
+		else
+			dqput(dquot);   /* We have guaranteed we won't block */
 	}
 	return 0;
 }
@@ -765,14 +693,61 @@
 	return 0;
 }
 
-static void print_warning(struct dquot *dquot, int flag, const char *fmtstr)
-{
+/* Values of warnings */
+#define NOWARN 0
+#define IHARDWARN 1
+#define ISOFTLONGWARN 2
+#define ISOFTWARN 3
+#define BHARDWARN 4
+#define BSOFTLONGWARN 5
+#define BSOFTWARN 6
+
+/* Print warning to user which exceeded quota */
+static void print_warning(struct dquot *dquot, const char warntype)
+{
+	char *msg = NULL;
+	int flag = (warntype == BHARDWARN || warntype == BSOFTLONGWARN) ? DQ_BLKS :
+	  ((warntype == IHARDWARN || warntype == ISOFTLONGWARN) ? DQ_INODES : 0);
+
 	if (!need_print_warning(dquot, flag))
 		return;
-	sprintf(quotamessage, fmtstr,
-		bdevname(dquot->dq_sb->s_dev), quotatypes[dquot->dq_type]);
-	tty_write_message(current->tty, quotamessage);
 	dquot->dq_flags |= flag;
+	tty_write_message(current->tty, (char *)bdevname(dquot->dq_sb->s_dev));
+	if (warntype == ISOFTWARN || warntype == BSOFTWARN)
+		tty_write_message(current->tty, ": warning, ");
+	else
+		tty_write_message(current->tty, ": write failed, ");
+	tty_write_message(current->tty, quotatypes[dquot->dq_type]);
+	switch (warntype) {
+		case IHARDWARN:
+			msg = " file limit reached.\n";
+			break;
+		case ISOFTLONGWARN:
+			msg = " file quota exceeded too long.\n";
+			break;
+		case ISOFTWARN:
+			msg = " file quota exceeded.\n";
+			break;
+		case BHARDWARN:
+			msg = " block limit reached.\n";
+			break;
+		case BSOFTLONGWARN:
+			msg = " block quota exceeded too long.\n";
+			break;
+		case BSOFTWARN:
+			msg = " block quota exceeded.\n";
+			break;
+	}
+	tty_write_message(current->tty, msg);
+}
+
+static inline void flush_warnings(struct dquot **dquots, char *warntype)
+{
+	int i;
+
+	for (i = 0; i < MAXQUOTAS; i++)
+		if (dquots[i] != NODQUOT && warntype[i] != NOWARN)
+			print_warning(dquots[i], warntype[i]);
 }
 
 static inline char ignore_hardlimit(struct dquot *dquot)
@@ -780,15 +755,16 @@
 	return capable(CAP_SYS_RESOURCE) && !dquot->dq_sb->s_dquot.rsquash[dquot->dq_type];
 }
 
-static int check_idq(struct dquot *dquot, u_long inodes)
+static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
 {
+	*warntype = NOWARN;
 	if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
 		return QUOTA_OK;
 
 	if (dquot->dq_ihardlimit &&
 	   (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit &&
             !ignore_hardlimit(dquot)) {
-		print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n");
+		*warntype = IHARDWARN;
 		return NO_QUOTA;
 	}
 
@@ -796,22 +772,23 @@
 	   (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
 	    dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime &&
             !ignore_hardlimit(dquot)) {
-		print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n");
+		*warntype = ISOFTLONGWARN;
 		return NO_QUOTA;
 	}
 
 	if (dquot->dq_isoftlimit &&
 	   (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
 	    dquot->dq_itime == 0) {
-		print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n");
+		*warntype = ISOFTWARN;
 		dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[dquot->dq_type];
 	}
 
 	return QUOTA_OK;
 }
 
-static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
+static int check_bdq(struct dquot *dquot, ulong blocks, char prealloc, char *warntype)
 {
+	*warntype = 0;
 	if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
 		return QUOTA_OK;
 
@@ -819,7 +796,7 @@
 	   (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit &&
             !ignore_hardlimit(dquot)) {
 		if (!prealloc)
-			print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n");
+			*warntype = BHARDWARN;
 		return NO_QUOTA;
 	}
 
@@ -828,7 +805,7 @@
 	    dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime &&
             !ignore_hardlimit(dquot)) {
 		if (!prealloc)
-			print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n");
+			*warntype = BSOFTLONGWARN;
 		return NO_QUOTA;
 	}
 
@@ -836,7 +813,7 @@
 	   (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
 	    dquot->dq_btime == 0) {
 		if (!prealloc) {
-			print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n");
+			*warntype = BSOFTWARN;
 			dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[dquot->dq_type];
 		}
 		else
@@ -860,18 +837,11 @@
 	int error = -EFAULT;
 	struct dqblk dq_dqblk;
 
-	if (dqblk == (struct dqblk *)NULL)
+	if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk)))
 		return error;
 
-	if (flags & QUOTA_SYSCALL) {
-		if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk)))
-			return(error);
-	} else
-		memcpy((caddr_t)&dq_dqblk, (caddr_t)dqblk, sizeof(struct dqblk));
-
 	if (sb && (dquot = dqget(sb, id, type)) != NODQUOT) {
-		lock_dquot(dquot);
-
+		/* We can't block while changing quota structure... */
 		if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) {
 			dquot->dq_bhardlimit = dq_dqblk.dqb_bhardlimit;
 			dquot->dq_bsoftlimit = dq_dqblk.dqb_bsoftlimit;
@@ -908,15 +878,15 @@
 			dquot->dq_flags &= ~DQ_FAKE;
 
 		dquot->dq_flags |= DQ_MOD;
-		unlock_dquot(dquot);
 		dqput(dquot);
 	}
-	return(0);
+	return 0;
 }
 
 static int get_quota(struct super_block *sb, int id, short type, struct dqblk *dqblk)
 {
 	struct dquot *dquot;
+	struct dqblk data;
 	int error = -ESRCH;
 
 	if (!sb || !sb_has_quota_enabled(sb, type))
@@ -925,12 +895,11 @@
 	if (dquot == NODQUOT)
 		goto out;
 
-	lock_dquot(dquot);	/* We must protect against invalidating the quota */
+	memcpy(&data, &dquot->dq_dqb, sizeof(struct dqblk));        /* We copy data to preserve them from changing */
+	dqput(dquot);
 	error = -EFAULT;
-	if (dqblk && !copy_to_user(dqblk, &dquot->dq_dqb, sizeof(struct dqblk)))
+	if (dqblk && !copy_to_user(dqblk, &data, sizeof(struct dqblk)))
 		error = 0;
-	unlock_dquot(dquot);
-	dqput(dquot);
 out:
 	return error;
 }
@@ -965,6 +934,7 @@
 	return error;
 }
 
+#if 0	/* We are not going to support filesystems without i_blocks... */
 /*
  * This is a simple algorithm that calculates the size of a file in blocks.
  * This is only used on filesystems that do not have an i_blocks count.
@@ -988,6 +958,7 @@
 	}
 	return blocks;
 }
+#endif
 
 /*
  * Externally referenced functions through dquot_operations in inode.
@@ -996,22 +967,19 @@
  */
 void dquot_initialize(struct inode *inode, short type)
 {
-	struct dquot *dquot;
+	struct dquot *dquot[MAXQUOTAS];
 	unsigned int id = 0;
 	short cnt;
 
-	lock_kernel();
-	if (IS_NOQUOTA(inode)) {
-		unlock_kernel();
+	if (IS_NOQUOTA(inode))
 		return;
-	}
+	/* Build list of quotas to initialize... We can block here */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		dquot[cnt] = NODQUOT;
 		if (type != -1 && cnt != type)
 			continue;
-
 		if (!sb_has_quota_enabled(inode->i_sb, cnt))
 			continue;
-
 		if (inode->i_dquot[cnt] == NODQUOT) {
 			switch (cnt) {
 				case USRQUOTA:
@@ -1021,18 +989,22 @@
 					id = inode->i_gid;
 					break;
 			}
-			dquot = dqget(inode->i_sb, id, cnt);
-			if (dquot == NODQUOT)
-				continue;
-			if (inode->i_dquot[cnt] != NODQUOT) {
-				dqput(dquot);
-				continue;
-			} 
-			inode->i_dquot[cnt] = dquot;
-			inode->i_flags |= S_QUOTA;
+			dquot[cnt] = dqget(inode->i_sb, id, cnt);
 		}
 	}
-	unlock_kernel();
+	/* NOBLOCK START: Here we shouldn't block */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		if (dquot[cnt] == NODQUOT || !sb_has_quota_enabled(inode->i_sb, cnt) || inode->i_dquot[cnt] != NODQUOT)
+			continue;
+		inode->i_dquot[cnt] = dquot[cnt];
+		dquot[cnt] = NODQUOT;
+		inode->i_flags |= S_QUOTA;
+	}
+	/* NOBLOCK END */
+	/* Put quotas which we didn't use */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (dquot[cnt] != NODQUOT)
+			dqput(dquot[cnt]);
 }
 
 /*
@@ -1045,7 +1017,6 @@
 	struct dquot *dquot;
 	short cnt;
 
-	lock_kernel();
 	inode->i_flags &= ~S_QUOTA;
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
@@ -1054,229 +1025,180 @@
 		inode->i_dquot[cnt] = NODQUOT;
 		dqput(dquot);
 	}
-	unlock_kernel();
 }
 
 /*
- * Note: this is a blocking operation.
+ * This operation can block, but only after everything is updated
  */
-int dquot_alloc_block(const struct inode *inode, unsigned long number, char warn)
+int dquot_alloc_block(struct inode *inode, unsigned long number, char warn)
 {
-	int cnt;
+	int cnt, ret = NO_QUOTA;
 	struct dquot *dquot[MAXQUOTAS];
+	char warntype[MAXQUOTAS];
 
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		dquot[cnt] = NODQUOT;
+		warntype[cnt] = NOWARN;
+	}
+	/* NOBLOCK Start */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
 		if (dquot[cnt] == NODQUOT)
 			continue;
-		lock_dquot(dquot[cnt]);
-		if (check_bdq(dquot[cnt], number, warn))
-			goto put_all;
+		if (check_bdq(dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA)
+			goto warn_put_all;
 	}
-
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (dquot[cnt] == NODQUOT)
 			continue;
 		dquot_incr_blocks(dquot[cnt], number);
-		unlock_dquot(dquot[cnt]);
-		dqput(dquot[cnt]);
 	}
-
-	return QUOTA_OK;
-put_all:
-	for (; cnt >= 0; cnt--) {
-		if (dquot[cnt] == NODQUOT)
-			continue;
-		unlock_dquot(dquot[cnt]);
-		dqput(dquot[cnt]);
-	}
-	return NO_QUOTA;
+	inode->i_blocks += number << (BLOCK_SIZE_BITS - 9);
+	/* NOBLOCK End */
+	ret = QUOTA_OK;
+warn_put_all:
+	flush_warnings(dquot, warntype);
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (dquot[cnt] != NODQUOT)
+			dqput(dquot[cnt]);
+	return ret;
 }
 
 /*
- * Note: this is a blocking operation.
+ * This operation can block, but only after everything is updated
  */
 int dquot_alloc_inode(const struct inode *inode, unsigned long number)
 {
-	int cnt;
+	int cnt, ret = NO_QUOTA;
 	struct dquot *dquot[MAXQUOTAS];
+	char warntype[MAXQUOTAS];
 
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		dquot[cnt] = NODQUOT;
+		warntype[cnt] = NOWARN;
+	}
+	/* NOBLOCK Start */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
 		if (dquot[cnt] == NODQUOT)
 			continue;
-		lock_dquot(dquot[cnt]);
-		if (check_idq(dquot[cnt], number))
-			goto put_all;
+		if (check_idq(dquot[cnt], number, warntype+cnt) == NO_QUOTA)
+			goto warn_put_all;
 	}
 
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (dquot[cnt] == NODQUOT)
 			continue;
 		dquot_incr_inodes(dquot[cnt], number);
-		unlock_dquot(dquot[cnt]);
-		dqput(dquot[cnt]);
 	}
-
-	return QUOTA_OK;
-put_all:
-	for (; cnt >= 0; cnt--) {
-		if (dquot[cnt] == NODQUOT)
-			continue;
-		unlock_dquot(dquot[cnt]);
-		dqput(dquot[cnt]);
-	}
-	return NO_QUOTA;
+	/* NOBLOCK End */
+	ret = QUOTA_OK;
+warn_put_all:
+	flush_warnings(dquot, warntype);
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (dquot[cnt] != NODQUOT)
+			dqput(dquot[cnt]);
+	return ret;
 }
 
 /*
- * Note: this is a blocking operation.
+ * This is a non-blocking operation.
  */
-void dquot_free_block(const struct inode *inode, unsigned long number)
+void dquot_free_block(struct inode *inode, unsigned long number)
 {
 	unsigned short cnt;
 	struct dquot *dquot;
 
+	/* NOBLOCK Start */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		dquot = inode->i_dquot[cnt];
+		dquot = dqduplicate(inode->i_dquot[cnt]);
 		if (dquot == NODQUOT)
 			continue;
-		wait_on_dquot(dquot);
 		dquot_decr_blocks(dquot, number);
+		dqput(dquot);
 	}
+	inode->i_blocks -= number << (BLOCK_SIZE_BITS - 9);
+	/* NOBLOCK End */
 }
 
 /*
- * Note: this is a blocking operation.
+ * This is a non-blocking operation.
  */
 void dquot_free_inode(const struct inode *inode, unsigned long number)
 {
 	unsigned short cnt;
 	struct dquot *dquot;
 
+	/* NOBLOCK Start */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		dquot = inode->i_dquot[cnt];
+		dquot = dqduplicate(inode->i_dquot[cnt]);
 		if (dquot == NODQUOT)
 			continue;
-		wait_on_dquot(dquot);
 		dquot_decr_inodes(dquot, number);
+		dqput(dquot);
 	}
+	/* NOBLOCK End */
 }
 
 /*
  * Transfer the number of inode and blocks from one diskquota to an other.
  *
- * Note: this is a blocking operation.
+ * This operation can block, but only after everything is updated
  */
-int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
+int dquot_transfer(struct inode *inode, struct iattr *iattr)
 {
-	struct inode *inode = dentry -> d_inode;
 	unsigned long blocks;
 	struct dquot *transfer_from[MAXQUOTAS];
 	struct dquot *transfer_to[MAXQUOTAS];
-	short cnt, disc;
-	int error = -EDQUOT;
-
-	if (!inode)
-		return -ENOENT;
-	/* Arguably we could consider that as error, but... no fs - no quota */
-	if (!inode->i_sb)
-		return 0;
+	int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
+	    chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
+	char warntype[MAXQUOTAS];
 
-	lock_kernel();
-	/*
-	 * Build the transfer_from and transfer_to lists and check quotas to see
-	 * if operation is permitted.
-	 */
+	/* Clear the arrays */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
+		warntype[cnt] = NOWARN;
+	}
+	/* First build the transfer_to list - here we can block on reading of dquots... */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		transfer_from[cnt] = NODQUOT;
-		transfer_to[cnt] = NODQUOT;
-
 		if (!sb_has_quota_enabled(inode->i_sb, cnt))
 			continue;
-
 		switch (cnt) {
 			case USRQUOTA:
-				if (inode->i_uid == iattr->ia_uid)
+				if (!chuid)
 					continue;
-				/* We can get transfer_from from inode, can't we? */
-				transfer_from[cnt] = dqget(inode->i_sb, inode->i_uid, cnt);
 				transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
 				break;
 			case GRPQUOTA:
-				if (inode->i_gid == iattr->ia_gid)
+				if (!chgid)
 					continue;
-				transfer_from[cnt] = dqget(inode->i_sb, inode->i_gid, cnt);
 				transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
 				break;
 		}
-
-		/* Something bad (eg. quotaoff) happened while we were sleeping? */
-		if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
-		{
-			if (transfer_from[cnt] != NODQUOT) {
-				dqput(transfer_from[cnt]);
-				transfer_from[cnt] = NODQUOT;
-			}
-			if (transfer_to[cnt] != NODQUOT) {
-				dqput(transfer_to[cnt]);
-				transfer_to[cnt] = NODQUOT;
-			}
-			continue;
-		}
-		/*
-		 *  We have to lock the quotas to prevent races...
-		 */
-		if (transfer_from[cnt] < transfer_to[cnt])
-		{
-                	lock_dquot(transfer_from[cnt]);
-			lock_dquot(transfer_to[cnt]);
-		}
-		else
-		{
-			lock_dquot(transfer_to[cnt]);
-			lock_dquot(transfer_from[cnt]);
-		}
-
-		/*
-		 * The entries might got invalidated while locking. The second
-		 * dqget() could block and so the first structure might got
-		 * invalidated or locked...
-		 */
-		if (!transfer_to[cnt]->dq_sb || !transfer_from[cnt]->dq_sb) {
-			cnt++;
-			goto put_all;
-		}
 	}
-
-	/*
-	 * Find out if this filesystem uses i_blocks.
-	 */
-	if (!inode->i_sb->s_blocksize)
-		blocks = isize_to_blocks(inode->i_size, BLOCK_SIZE_BITS);
-	else
-		blocks = (inode->i_blocks >> 1);
+	/* NOBLOCK START: From now on we shouldn't block */
+	blocks = (inode->i_blocks >> 1);
+	/* Build the transfer_from list and check the limits */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (!transfer_to[cnt])
+		/* The second test can fail when quotaoff is in progress... */
+		if (transfer_to[cnt] == NODQUOT || !sb_has_quota_enabled(inode->i_sb, cnt))
 			continue;
-		if (check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
-		    check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
-			cnt = MAXQUOTAS;
-			goto put_all;
-		}
+		transfer_from[cnt] = dqduplicate(inode->i_dquot[cnt]);
+		if (transfer_from[cnt] == NODQUOT)	/* Can happen on quotafiles (quota isn't initialized on them)... */
+			continue;
+		if (check_idq(transfer_to[cnt], 1, warntype+cnt) == NO_QUOTA ||
+		    check_bdq(transfer_to[cnt], blocks, 0, warntype+cnt) == NO_QUOTA)
+			goto warn_put_all;
 	}
 
-	if ((error = notify_change(dentry, iattr)))
-		goto put_all; 
 	/*
-	 * Finally perform the needed transfer from transfer_from to transfer_to,
-	 * and release any pointers to dquots not needed anymore.
+	 * Finally perform the needed transfer from transfer_from to transfer_to
 	 */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		/*
 		 * Skip changes for same uid or gid or for non-existing quota-type.
 		 */
-		if (transfer_from[cnt] == NODQUOT && transfer_to[cnt] == NODQUOT)
+		if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
 			continue;
 
 		dquot_decr_inodes(transfer_from[cnt], 1);
@@ -1285,40 +1207,34 @@
 		dquot_incr_inodes(transfer_to[cnt], 1);
 		dquot_incr_blocks(transfer_to[cnt], blocks);
 
-		unlock_dquot(transfer_from[cnt]);
-		dqput(transfer_from[cnt]);
-		if (inode->i_dquot[cnt] != NODQUOT) {
-			struct dquot *temp = inode->i_dquot[cnt];
-			inode->i_dquot[cnt] = transfer_to[cnt];
-			unlock_dquot(transfer_to[cnt]);
-			dqput(temp);
-		} else {
-			unlock_dquot(transfer_to[cnt]);
-			dqput(transfer_to[cnt]);
-		}
+		if (inode->i_dquot[cnt] == NODQUOT)
+			BUG();
+		inode->i_dquot[cnt] = transfer_to[cnt];
+		/*
+		 * We've got to release transfer_from[] twice - once for dquot_transfer() and
+		 * once for inode. We don't want to release transfer_to[] as it's now placed in inode
+		 */
+		transfer_to[cnt] = transfer_from[cnt];
 	}
-
-	unlock_kernel();
-	return 0;
-put_all:
-	for (disc = 0; disc < cnt; disc++) {
-		/* There should be none or both pointers set but... */
-		if (transfer_to[disc] != NODQUOT) {
-			unlock_dquot(transfer_to[disc]);
-			dqput(transfer_to[disc]);
-		}
-		if (transfer_from[disc] != NODQUOT) {
-			unlock_dquot(transfer_from[disc]);
-			dqput(transfer_from[disc]);
-		}
+	/* NOBLOCK END. From now on we can block as we wish */
+	ret = QUOTA_OK;
+warn_put_all:
+	flush_warnings(transfer_to, warntype);
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		if (transfer_to[cnt] != NODQUOT)
+			dqput(transfer_to[cnt]);
+		if (transfer_from[cnt] != NODQUOT)
+			dqput(transfer_from[cnt]);
 	}
-	unlock_kernel();
-	return error;
+	return ret;
 }
 
-
 static int __init dquot_init(void)
 {
+	int i;
+
+	for (i = 0; i < NR_DQHASH; i++)
+		INIT_LIST_HEAD(dquot_hash + i);
 	printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
 	return 0;
 }
@@ -1371,7 +1287,6 @@
 {
 	struct file *filp;
 	short cnt;
-	int enabled = 0;
 	struct quota_mount_options *dqopt = sb_dqopt(sb);
 
 	if (!sb)
@@ -1390,27 +1305,15 @@
 		remove_dquot_ref(sb, cnt);
 		invalidate_dquots(sb, cnt);
 
-		/* Wait for any pending IO - remove me as soon as invalidate is more polite */
-		down(&dqopt->dqio_sem);
 		filp = dqopt->files[cnt];
 		dqopt->files[cnt] = (struct file *)NULL;
 		dqopt->inode_expire[cnt] = 0;
 		dqopt->block_expire[cnt] = 0;
-		up(&dqopt->dqio_sem);
 		fput(filp);
 	}	
-
-	/*
-	 * Check whether any quota is still enabled,
-	 * and if not clear the dq_op pointer.
-	 */
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-		enabled |= is_enabled(dqopt, cnt);
-	if (!enabled)
-		sb->dq_op = NULL;
 	up(&dqopt->dqoff_sem);
 out:
-	return(0);
+	return 0;
 }
 
 static inline int check_quotafile_size(loff_t size)
@@ -1459,8 +1362,8 @@
 	dquot_drop(inode);
 	inode->i_flags |= S_NOQUOTA;
 
-	set_enable_flags(dqopt, type);
 	dqopt->files[type] = f;
+	set_enable_flags(dqopt, type);
 
 	dquot = dqget(sb, 0, type);
 	dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
@@ -1511,11 +1414,11 @@
 		case Q_GETQUOTA:
 			if (((type == USRQUOTA && current->euid != id) ||
 			     (type == GRPQUOTA && !in_egroup_p(id))) &&
-			    !capable(CAP_SYS_RESOURCE))
+			    !capable(CAP_SYS_ADMIN))
 				goto out;
 			break;
 		default:
-			if (!capable(CAP_SYS_RESOURCE))
+			if (!capable(CAP_SYS_ADMIN))
 				goto out;
 	}
 
@@ -1536,13 +1439,16 @@
 		ret = -ENOTBLK;
 		if (!S_ISBLK(mode))
 			goto out;
+		ret = -ENODEV;
 		sb = get_super(dev);
+		if (!sb)
+			goto out;
 	}
 
 	ret = -EINVAL;
 	switch (cmds) {
 		case Q_QUOTAON:
-			ret = sb ? quota_on(sb, type, (char *) addr) : -ENODEV;
+			ret = quota_on(sb, type, (char *) addr);
 			goto out;
 		case Q_QUOTAOFF:
 			ret = quota_off(sb, type);
@@ -1572,9 +1478,7 @@
 			goto out;
 	}
 
-	flags |= QUOTA_SYSCALL;
-
-	ret = -ESRCH;
+	ret = -NODEV;
 	if (sb && sb_has_quota_enabled(sb, type))
 		ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr);
 out:
diff -u --recursive --new-file v2.4.10/linux/fs/efs/inode.c linux/fs/efs/inode.c
--- v2.4.10/linux/fs/efs/inode.c	Mon May  8 11:11:29 2000
+++ linux/fs/efs/inode.c	Sun Sep 30 12:26:08 2001
@@ -9,6 +9,8 @@
 
 #include <linux/efs_fs.h>
 #include <linux/efs_fs_sb.h>
+#include <linux/module.h>
+
 
 extern int efs_get_block(struct inode *, long, struct buffer_head *, int);
 static int efs_readpage(struct file *file, struct page *page)
@@ -302,3 +304,4 @@
 	return 0;
 }  
 
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
--- v2.4.10/linux/fs/ext2/balloc.c	Wed Jul 25 17:10:24 2001
+++ linux/fs/ext2/balloc.c	Fri Oct  5 12:23:53 2001
@@ -247,7 +247,8 @@
 	return slot;
 }
 
-void ext2_free_blocks (const struct inode * inode, unsigned long block,
+/* Free given blocks, update quota and i_blocks field */
+void ext2_free_blocks (struct inode * inode, unsigned long block,
 		       unsigned long count)
 {
 	struct buffer_head * bh;
@@ -318,7 +319,7 @@
 				      "bit already cleared for block %lu",
 				      block + i);
 		else {
-			DQUOT_FREE_BLOCK(sb, inode, 1);
+			DQUOT_FREE_BLOCK(inode, 1);
 			gdp->bg_free_blocks_count =
 				cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)+1);
 			es->s_free_blocks_count =
@@ -351,8 +352,9 @@
  * is allocated.  Otherwise a forward search is made for a free block; within 
  * each block group the search first looks for an entire free byte in the block
  * bitmap, and then for any free bit if that fails.
+ * This function also updates quota and i_blocks field.
  */
-int ext2_new_block (const struct inode * inode, unsigned long goal,
+int ext2_new_block (struct inode * inode, unsigned long goal,
     u32 * prealloc_count, u32 * prealloc_block, int * err)
 {
 	struct buffer_head * bh;
@@ -508,7 +510,7 @@
 	/*
 	 * Check quota for allocation of this block.
 	 */
-	if(DQUOT_ALLOC_BLOCK(sb, inode, 1)) {
+	if(DQUOT_ALLOC_BLOCK(inode, 1)) {
 		*err = -EDQUOT;
 		goto out;
 	}
@@ -526,7 +528,7 @@
 	if (ext2_set_bit (j, bh->b_data)) {
 		ext2_warning (sb, "ext2_new_block",
 			      "bit already set for block %d", j);
-		DQUOT_FREE_BLOCK(sb, inode, 1);
+		DQUOT_FREE_BLOCK(inode, 1);
 		goto repeat;
 	}
 
@@ -549,13 +551,13 @@
 		for (k = 1;
 		     k < prealloc_goal && (j + k) < EXT2_BLOCKS_PER_GROUP(sb);
 		     k++, next_block++) {
-			if (DQUOT_PREALLOC_BLOCK(sb, inode, 1))
+			if (DQUOT_PREALLOC_BLOCK(inode, 1))
 				break;
 			/* Writer: ->i_prealloc* */
 			if (*prealloc_block + *prealloc_count != next_block ||
 			    ext2_set_bit (j + k, bh->b_data)) {
 				/* Writer: end */
-				DQUOT_FREE_BLOCK(sb, inode, 1);
+				DQUOT_FREE_BLOCK(inode, 1);
  				break;
 			}
 			(*prealloc_count)++;
diff -u --recursive --new-file v2.4.10/linux/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c
--- v2.4.10/linux/fs/ext2/ialloc.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/ext2/ialloc.c	Fri Oct  5 12:23:53 2001
@@ -196,7 +196,7 @@
 	 */
 	if (!is_bad_inode(inode)) {
 		/* Quota is already initialized in iput() */
-	    	DQUOT_FREE_INODE(sb, inode);
+	    	DQUOT_FREE_INODE(inode);
 		DQUOT_DROP(inode);
 	}
 
@@ -454,7 +454,7 @@
 	mark_inode_dirty(inode);
 
 	unlock_super (sb);
-	if(DQUOT_ALLOC_INODE(sb, inode)) {
+	if(DQUOT_ALLOC_INODE(inode)) {
 		DQUOT_DROP(inode);
 		inode->i_flags |= S_NOQUOTA;
 		inode->i_nlink = 0;
diff -u --recursive --new-file v2.4.10/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.4.10/linux/fs/ext2/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/ext2/inode.c	Fri Oct  5 12:23:53 2001
@@ -28,6 +28,7 @@
 #include <linux/smp_lock.h>
 #include <linux/sched.h>
 #include <linux/highuid.h>
+#include <linux/quotaops.h>
 
 static int ext2_update_inode(struct inode * inode, int do_sync);
 
@@ -445,7 +446,7 @@
 
 	/* Verify that place we are splicing to is still there and vacant */
 
-	/* Writer: pointers, ->i_next_alloc*, ->i_blocks */
+	/* Writer: pointers, ->i_next_alloc* */
 	if (!verify_chain(chain, where-1) || *where->p)
 		/* Writer: end */
 		goto changed;
@@ -455,7 +456,6 @@
 	*where->p = where->key;
 	inode->u.ext2_i.i_next_alloc_block = block;
 	inode->u.ext2_i.i_next_alloc_goal = le32_to_cpu(where[num-1].key);
-	inode->i_blocks += num * inode->i_sb->s_blocksize/512;
 
 	/* Writer: end */
 
@@ -586,10 +586,6 @@
 {
 	return generic_block_bmap(mapping,block,ext2_get_block);
 }
-static int ext2_direct_IO(int rw, struct inode * inode, struct kiobuf * iobuf, unsigned long blocknr, int blocksize)
-{
-	return generic_direct_IO(rw, inode, iobuf, blocknr, blocksize, ext2_get_block);
-}
 struct address_space_operations ext2_aops = {
 	readpage: ext2_readpage,
 	writepage: ext2_writepage,
@@ -597,7 +593,6 @@
 	prepare_write: ext2_prepare_write,
 	commit_write: generic_commit_write,
 	bmap: ext2_bmap,
-	direct_IO: ext2_direct_IO,
 };
 
 /*
@@ -707,7 +702,6 @@
  */
 static inline void ext2_free_data(struct inode *inode, u32 *p, u32 *q)
 {
-	int blocks = inode->i_sb->s_blocksize / 512;
 	unsigned long block_to_free = 0, count = 0;
 	unsigned long nr;
 
@@ -721,9 +715,6 @@
 			else if (block_to_free == nr - count)
 				count++;
 			else {
-				/* Writer: ->i_blocks */
-				inode->i_blocks -= blocks * count;
-				/* Writer: end */
 				mark_inode_dirty(inode);
 				ext2_free_blocks (inode, block_to_free, count);
 			free_this:
@@ -733,9 +724,6 @@
 		}
 	}
 	if (count > 0) {
-		/* Writer: ->i_blocks */
-		inode->i_blocks -= blocks * count;
-		/* Writer: end */
 		mark_inode_dirty(inode);
 		ext2_free_blocks (inode, block_to_free, count);
 	}
@@ -780,9 +768,6 @@
 					   (u32*)bh->b_data + addr_per_block,
 					   depth);
 			bforget(bh);
-			/* Writer: ->i_blocks */
-			inode->i_blocks -= inode->i_sb->s_blocksize / 512;
-			/* Writer: end */
 			ext2_free_blocks(inode, nr, 1);
 			mark_inode_dirty(inode);
 		}
@@ -1182,7 +1167,9 @@
 		goto out;
 
 	retval = inode_change_ok(inode, iattr);
-	if (retval != 0)
+	if (retval != 0 || (((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
+	    (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) &&
+	    DQUOT_TRANSFER(inode, iattr)))
 		goto out;
 
 	inode_setattr(inode, iattr);
diff -u --recursive --new-file v2.4.10/linux/fs/ext2/super.c linux/fs/ext2/super.c
--- v2.4.10/linux/fs/ext2/super.c	Wed Jul 25 17:10:24 2001
+++ linux/fs/ext2/super.c	Wed Oct  3 22:57:36 2001
@@ -408,7 +408,6 @@
 	unsigned long offset = 0;
 	kdev_t dev = sb->s_dev;
 	int blocksize = BLOCK_SIZE;
-	int hblock;
 	int db_count;
 	int i, j;
 
@@ -429,7 +428,10 @@
 		return NULL;
 	}
 
-	set_blocksize (dev, blocksize);
+	if (set_blocksize(dev, blocksize) < 0) {
+		printk ("EXT2-fs: unable to set blocksize %d\n", blocksize);
+		return NULL;
+	}
 
 	/*
 	 * If the superblock doesn't start on a sector boundary,
@@ -488,24 +490,19 @@
 
 	sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);
 
-	if (sb->s_blocksize != BLOCK_SIZE &&
-	    (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||
-	     sb->s_blocksize == 4096)) {
-		/*
-		 * Make sure the blocksize for the filesystem is larger
-		 * than the hardware sectorsize for the machine.
-		 */
-		hblock = get_hardsect_size(dev);
-		if (sb->s_blocksize < hblock) {
+	/* If the blocksize doesn't match, re-read the thing.. */
+	if (sb->s_blocksize != blocksize) {
+		blocksize = sb->s_blocksize;
+		brelse(bh);
+
+		if (set_blocksize(dev, blocksize) < 0) {
 			printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n");
-			goto failed_mount;
+			return NULL;
 		}
 
-		brelse (bh);
-		set_blocksize (dev, sb->s_blocksize);
-		logic_sb_block = (sb_block*BLOCK_SIZE) / sb->s_blocksize;
-		offset = (sb_block*BLOCK_SIZE) % sb->s_blocksize;
-		bh = bread (dev, logic_sb_block, sb->s_blocksize);
+		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
+		offset = (sb_block*BLOCK_SIZE) % blocksize;
+		bh = bread (dev, logic_sb_block, blocksize);
 		if(!bh) {
 			printk("EXT2-fs: Couldn't read superblock on "
 			       "2nd try.\n");
@@ -518,6 +515,7 @@
 			goto failed_mount;
 		}
 	}
+
 	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {
 		sb->u.ext2_sb.s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
 		sb->u.ext2_sb.s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
diff -u --recursive --new-file v2.4.10/linux/fs/inode.c linux/fs/inode.c
--- v2.4.10/linux/fs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/inode.c	Fri Sep 28 18:03:48 2001
@@ -816,6 +816,7 @@
 		list_add(&inode->i_list, &inode_in_use);
 		inode->i_sb = NULL;
 		inode->i_dev = 0;
+		inode->i_blkbits = 0;
 		inode->i_ino = ++last_ino;
 		inode->i_flags = 0;
 		atomic_set(&inode->i_count, 1);
@@ -849,6 +850,7 @@
 			list_add(&inode->i_hash, head);
 			inode->i_sb = sb;
 			inode->i_dev = sb->s_dev;
+			inode->i_blkbits = sb->s_blocksize_bits;
 			inode->i_ino = ino;
 			inode->i_flags = 0;
 			atomic_set(&inode->i_count, 1);
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/Makefile linux/fs/jffs/Makefile
--- v2.4.10/linux/fs/jffs/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/fs/jffs/Makefile	Thu Oct  4 15:13:18 2001
@@ -1,7 +1,7 @@
 #
 # Makefile for the linux Journalling Flash FileSystem (JFFS) routines.
 #
-# $Id: Makefile,v 1.7 2000/08/04 12:46:34 dwmw2 Exp $
+# $Id: Makefile,v 1.11 2001/09/25 20:59:41 dwmw2 Exp $
 #
 # Note! Dependencies are done automagically by 'make dep', which also
 # removes any old dependencies. DON'T put your own dependencies here
@@ -9,28 +9,24 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_JFFS_FS
+list-multi := jffs.o
 
-# We're being invoked outside a normal kernel build. Fake it
-EXTRA_CFLAGS= -I$(shell pwd)/../../include
-
-# You need to change this to build for 2.2, dunno how to check for it.
-
-#INODE_O := inode-v22.o
-INODE_O := inode-v23.o
-
-else
+jffs-objs := jffs_fm.o intrep.o
 
 ifeq ($(PATCHLEVEL),2)
-	INODE_O := inode-v22.o
+	jffs-objs += inode-v22.o
 else
-	INODE_O := inode-v23.o
+	jffs-objs += inode-v23.o
 endif
 
+ifeq ($(CONFIG_JFFS_PROC_FS),y)
+	jffs-objs += jffs_proc.o
 endif
 
 O_TARGET := jffs.o
-obj-m    := $(O_TARGET)
-obj-y    := jffs_fm.o intrep.o $(INODE_O)
+
+obj-y := $(jffs-objs)
+obj-m := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/inode-v23.c linux/fs/jffs/inode-v23.c
--- v2.4.10/linux/fs/jffs/inode-v23.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs/inode-v23.c	Thu Oct  4 15:14:35 2001
@@ -10,8 +10,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: inode-v23.c,v 1.43.2.6 2001/01/09 00:32:48 dwmw2 Exp $
- * + sb_maxbytes / generic_file_open() fixes for 2.4.0-ac4
+ * $Id: inode-v23.c,v 1.70 2001/10/02 09:16:02 dwmw2 Exp $
  *
  * Ported to Linux 2.3.x and MTD:
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -52,8 +51,12 @@
 #include <asm/semaphore.h>
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
+
 #include "jffs_fm.h"
 #include "intrep.h"
+#if CONFIG_JFFS_PROC_FS
+#include "jffs_proc.h"
+#endif
 
 static int jffs_remove(struct inode *dir, struct dentry *dentry, int type);
 
@@ -64,6 +67,8 @@
 static struct inode_operations jffs_dir_inode_operations;
 static struct address_space_operations jffs_address_operations;
 
+kmem_cache_t     *node_cache = NULL;
+kmem_cache_t     *fm_cache = NULL;
 
 /* Called by the VFS at mount time to initialize the whole file system.  */
 static struct super_block *
@@ -109,6 +114,15 @@
 
 	c = (struct jffs_control *) sb->u.generic_sbp;
 
+#ifdef CONFIG_JFFS_PROC_FS
+	/* Set up the jffs proc file system.  */
+	if (jffs_register_jffs_proc_dir(dev, c) < 0) {
+		printk(KERN_WARNING "JFFS: Failed to initialize the JFFS "
+			"proc file system for device %s.\n",
+			kdevname(dev));
+	}
+#endif
+
 	/* Set the Garbage Collection thresholds */
 
 	/* GC if free space goes below 5% of the total size */
@@ -153,6 +167,10 @@
 
 	D2(printk("jffs_put_super()\n"));
 
+#ifdef CONFIG_JFFS_PROC_FS
+	jffs_unregister_jffs_proc_dir(c);
+#endif
+
 	if (c->gc_task) {
 		D1(printk (KERN_NOTICE "jffs_put_super(): Telling gc thread to die.\n"));
 		send_sig(SIGKILL, c->gc_task, 1);
@@ -215,15 +233,13 @@
 		recoverable = 1;
         }
 
-	if (!(new_node = (struct jffs_node *)
-			 kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
+	if (!(new_node = jffs_alloc_node())) {
 		D(printk("jffs_setattr(): Allocation failed!\n"));
 		D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
 		up(&fmc->biglock);
 		return -ENOMEM;
 	}
 
-	DJM(no_jffs_node++);
 	new_node->data_offset = 0;
 	new_node->removed_size = 0;
 	raw_inode.magic = JFFS_MAGIC_BITMASK;
@@ -304,8 +320,7 @@
 	/* Write this node to the flash.  */
 	if ((res = jffs_write_node(c, new_node, &raw_inode, f->name, 0, recoverable, f)) < 0) {
 		D(printk("jffs_notify_change(): The write failed!\n"));
-		kfree(new_node);
-		DJM(no_jffs_node--);
+		jffs_free_node(new_node);
 		D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
 		up(&c->fmc->biglock);
 		return res;
@@ -373,9 +388,9 @@
 	buf->f_bsize = PAGE_CACHE_SIZE;
 	buf->f_blocks = (fmc->flash_size / PAGE_CACHE_SIZE)
 		       - (fmc->min_free_size / PAGE_CACHE_SIZE);
-	buf->f_bfree = (jffs_free_size1(fmc) / PAGE_CACHE_SIZE
-		       + jffs_free_size2(fmc) / PAGE_CACHE_SIZE)
-		      - (fmc->min_free_size / PAGE_CACHE_SIZE);
+	buf->f_bfree = (jffs_free_size1(fmc) + jffs_free_size2(fmc) +
+		       fmc->dirty_size - fmc->min_free_size)
+			       >> PAGE_CACHE_SHIFT;
 	buf->f_bavail = buf->f_bfree;
 
 	/* Find out how many files there are in the filesystem.  */
@@ -404,7 +419,7 @@
 	__u32 rename_data = 0;
 
 	D2(printk("***jffs_rename()\n"));
-	
+
 	D(printk("jffs_rename(): old_dir: 0x%p, old name: 0x%p, "
 		 "new_dir: 0x%p, new name: 0x%p\n",
 		 old_dir, old_dentry->d_name.name,
@@ -440,12 +455,10 @@
 	down(&c->fmc->biglock);
 	/* Create a node and initialize as much as needed.  */
 	result = -ENOMEM;
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_rename(): Allocation failed: node == 0\n"));
 		goto jffs_rename_end;
 	}
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -487,8 +500,7 @@
 				      new_dentry->d_name.name,
 				      (unsigned char*)&rename_data, 0, f)) < 0) {
 		D(printk("jffs_rename(): Failed to write node to flash.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_rename_end;
 	}
 	raw_inode.dsize = 0;
@@ -557,7 +569,7 @@
 	if (filp->f_pos == 0) {
 		D3(printk("jffs_readdir(): \".\" %lu\n", inode->i_ino));
 		if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
-		  D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
+			D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
 			up(&c->fmc->biglock);
 			return 0;
 		}
@@ -573,7 +585,7 @@
 		}
 		D3(printk("jffs_readdir(): \"..\" %u\n", ddino));
 		if (filldir(dirent, "..", 2, filp->f_pos, ddino, DT_DIR) < 0) {
-		  D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
+			D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
 			up(&c->fmc->biglock);
 			return 0;
 		}
@@ -581,7 +593,7 @@
 	}
 	f = ((struct jffs_file *)inode->u.generic_ip)->children;
 
-	j=2;
+	j = 2;
 	while(f && (f->deleted || j++ < filp->f_pos )) {
 		f = f->sibling_next;
 	}
@@ -649,11 +661,11 @@
 
 	/* iget calls jffs_read_inode, so we need to drop the biglock
            before calling iget.  Unfortunately, the GC has a tendency
-           to sneak in here, because iget sometimes calls schedule (). 
-         */
+           to sneak in here, because iget sometimes calls schedule ().
+	*/
 
 	if ((len == 1) && (name[0] == '.')) {
-                D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
+		D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
 		up(&c->fmc->biglock);
 		if (!(inode = iget(dir->i_sb, d->ino))) {
 			D(printk("jffs_lookup(): . iget() ==> NULL\n"));
@@ -702,12 +714,12 @@
 
 /* Try to read a page of data from a file.  */
 static int
-jffs_readpage(struct file *file, struct page *page)
+jffs_do_readpage_nolock(struct file *file, struct page *page)
 {
 	void *buf;
 	unsigned long read_len;
-	int result = -EIO;
-	struct inode *inode = page->mapping->host;
+	int result;
+	struct inode *inode = (struct inode*)page->mapping->host;
 	struct jffs_file *f = (struct jffs_file *)inode->u.generic_ip;
 	struct jffs_control *c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
 	int r;
@@ -725,43 +737,51 @@
 	D3(printk (KERN_NOTICE "readpage(): down biglock\n"));
 	down(&c->fmc->biglock);
 
+	read_len = 0;
+	result = 0;
+
 	offset = page->index << PAGE_CACHE_SHIFT;
 	if (offset < inode->i_size) {
 		read_len = min_t(long, inode->i_size - offset, PAGE_SIZE);
 		r = jffs_read_data(f, buf, offset, read_len);
-		if (r == read_len) {
-			if (read_len < PAGE_SIZE) {
-				memset(buf + read_len, 0,
-				       PAGE_SIZE - read_len);
-			}
-			SetPageUptodate(page);
-			result = 0;
+		if (r != read_len) {
+			result = -EIO;
+			D(
+			        printk("***jffs_readpage(): Read error! "
+				       "Wanted to read %lu bytes but only "
+				       "read %d bytes.\n", read_len, r);
+			  );
 		}
-		D(else {
-			printk("***jffs_readpage(): Read error! "
-			       "Wanted to read %lu bytes but only "
-			       "read %d bytes.\n", read_len, r);
-		});
+
 	}
 
+	/* This handles the case of partial or no read in above */
+	if(read_len < PAGE_SIZE)
+	        memset(buf + read_len, 0, PAGE_SIZE - read_len);
+
 	D3(printk (KERN_NOTICE "readpage(): up biglock\n"));
 	up(&c->fmc->biglock);
-	
+
 	if (result) {
-		memset(buf, 0, PAGE_SIZE);
 	        SetPageError(page);
+	}else {
+	        SetPageUptodate(page);	        
 	}
 	flush_dcache_page(page);
 
-	UnlockPage(page);
-
 	put_page(page);
 
 	D3(printk("jffs_readpage(): Leaving...\n"));
 
 	return result;
-} /* jffs_readpage()  */
+} /* jffs_do_readpage_nolock()  */
 
+static int jffs_readpage(struct file *file, struct page *page)
+{
+	int ret = jffs_do_readpage_nolock(file, page);
+	UnlockPage(page);
+	return ret;
+}
 
 /* Create a new directory.  */
 static int
@@ -805,13 +825,11 @@
 	}
 
 	/* Create a node and initialize it as much as needed.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_mkdir(): Allocation failed: node == 0\n"));
 		result = -ENOMEM;
 		goto jffs_mkdir_end;
 	}
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -840,8 +858,7 @@
 	if ((result = jffs_write_node(c, node, &raw_inode,
 				      dentry->d_name.name, 0, 0, NULL)) < 0) {
 		D(printk("jffs_mkdir(): jffs_write_node() failed.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_mkdir_end;
 	}
 
@@ -918,8 +935,8 @@
 	int result = 0;
 
 	D1({
-	        int len = dentry->d_name.len;
-	        const char *name = dentry->d_name.name;
+		int len = dentry->d_name.len;
+		const char *name = dentry->d_name.name;
 		char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
 		memcpy(_name, name, len);
 		_name[len] = '\0';
@@ -968,12 +985,10 @@
 
 	/* Create a node for the deletion.  */
 	result = -ENOMEM;
-	if (!(del_node = (struct jffs_node *)
-			 kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
+	if (!(del_node = jffs_alloc_node())) {
 		D(printk("jffs_remove(): Allocation failed!\n"));
 		goto jffs_remove_end;
 	}
-	DJM(no_jffs_node++);
 	del_node->data_offset = 0;
 	del_node->removed_size = 0;
 
@@ -999,8 +1014,7 @@
 
 	/* Write the new node to the flash memory.  */
 	if (jffs_write_node(c, del_node, &raw_inode, 0, 0, 1, del_f) < 0) {
-		kfree(del_node);
-		DJM(no_jffs_node--);
+		jffs_free_node(del_node);
 		result = -EIO;
 		goto jffs_remove_end;
 	}
@@ -1045,13 +1059,11 @@
 	down(&c->fmc->biglock);
 
 	/* Create and initialize a new node.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_mknod(): Allocation failed!\n"));
 		result = -ENOMEM;
 		goto jffs_mknod_err;
 	}
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -1078,7 +1090,7 @@
 
 	/* Write the new node to the flash.  */
 	if ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,
-				  (unsigned char *)&dev, 0, NULL)) < 0) {
+				   (unsigned char *)&dev, 0, NULL)) < 0) {
 		D(printk("jffs_mknod(): jffs_write_node() failed.\n"));
 		result = err;
 		goto jffs_mknod_err;
@@ -1105,8 +1117,7 @@
 
 jffs_mknod_err:
 	if (node) {
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 	}
 
 jffs_mknod_end:
@@ -1129,7 +1140,7 @@
 	int err;
 
 	D1({
-	        int len = dentry->d_name.len;
+		int len = dentry->d_name.len; 
 		char *_name = (char *)kmalloc(len + 1, GFP_KERNEL);
 		char *_symname = (char *)kmalloc(symname_len + 1, GFP_KERNEL);
 		memcpy(_name, dentry->d_name.name, len);
@@ -1153,15 +1164,13 @@
 	c = dir_f->c;
 
 	/* Create a node and initialize it as much as needed.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_symlink(): Allocation failed: node = NULL\n"));
 		return -ENOMEM;
 	}
 	D3(printk (KERN_NOTICE "symlink(): down biglock\n"));
 	down(&c->fmc->biglock);
 
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -1189,8 +1198,7 @@
 	if ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,
 				   (const unsigned char *)symname, 0, NULL)) < 0) {
 		D(printk("jffs_symlink(): jffs_write_node() failed.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_symlink_end;
 	}
 
@@ -1236,7 +1244,7 @@
 	int err;
 
 	D1({
-	        int len = dentry->d_name.len;
+		int len = dentry->d_name.len;
 		char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
 		memcpy(s, dentry->d_name.name, len);
 		s[len] = '\0';
@@ -1254,15 +1262,13 @@
 	c = dir_f->c;
 
 	/* Create a node and initialize as much as needed.  */
-	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-						  GFP_KERNEL))) {
+	if (!(node = jffs_alloc_node())) {
 		D(printk("jffs_create(): Allocation failed: node == 0\n"));
 		return -ENOMEM;
 	}
 	D3(printk (KERN_NOTICE "create(): down biglock\n"));
 	down(&c->fmc->biglock);
 
-	DJM(no_jffs_node++);
 	node->data_offset = 0;
 	node->removed_size = 0;
 
@@ -1290,8 +1296,7 @@
 	if ((err = jffs_write_node(c, node, &raw_inode,
 				   dentry->d_name.name, 0, 0, NULL)) < 0) {
 		D(printk("jffs_create(): jffs_write_node() failed.\n"));
-		kfree(node);
-		DJM(no_jffs_node--);
+		jffs_free_node(node);
 		goto jffs_create_end;
 	}
 
@@ -1349,32 +1354,32 @@
 		err = -EROFS;
 		goto out_isem;
 	}
-#endif
+#endif	
 	err = -EINVAL;
 
 	if (!S_ISREG(inode->i_mode)) {
 		D(printk("jffs_file_write(): inode->i_mode == 0x%08x\n",
-			 inode->i_mode));
+				inode->i_mode));
 		goto out_isem;
 	}
 
 	if (!(f = (struct jffs_file *)inode->u.generic_ip)) {
 		D(printk("jffs_file_write(): inode->u.generic_ip = 0x%p\n",
-			 inode->u.generic_ip));
+				inode->u.generic_ip));
 		goto out_isem;
 	}
 
 	c = f->c;
 
 	/*
-	 * This will never trigger with sane page sizes.  leave it in anyway,
-	 * since I'm thinking about how to merge larger writes (the current idea
-	 * is to poke a thread that does the actual I/O and starts by doing a
-	 * down(&inode->i_sem).  then we would need to get the page cache pages
-	 * and have a list of I/O requests and do write-merging here.
+	 * This will never trigger with sane page sizes.  leave it in
+	 * anyway, since I'm thinking about how to merge larger writes
+	 * (the current idea is to poke a thread that does the actual
+	 * I/O and starts by doing a down(&inode->i_sem).  then we
+	 * would need to get the page cache pages and have a list of
+	 * I/O requests and do write-merging here.
 	 * -- prumpf
 	 */
-	
 	thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
 
 	D3(printk (KERN_NOTICE "file_write(): down biglock\n"));
@@ -1389,24 +1394,22 @@
 	while (count) {
 		/* Things are going to be written so we could allocate and
 		   initialize the necessary data structures now.  */
-		if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
-							  GFP_KERNEL))) {
+		if (!(node = jffs_alloc_node())) {
 			D(printk("jffs_file_write(): node == 0\n"));
 			err = -ENOMEM;
 			goto out;
 		}
-		DJM(no_jffs_node++);
-		
+
 		node->data_offset = pos;
 		node->removed_size = 0;
-		
+
 		/* Initialize the raw inode.  */
 		raw_inode.magic = JFFS_MAGIC_BITMASK;
 		raw_inode.ino = f->ino;
 		raw_inode.pino = f->pino;
 
 		raw_inode.mode = f->mode;
-		
+
 		raw_inode.uid = f->uid;
 		raw_inode.gid = f->gid;
 		raw_inode.atime = CURRENT_TIME;
@@ -1420,14 +1423,13 @@
 		raw_inode.spare = 0;
 		raw_inode.rename = 0;
 		raw_inode.deleted = 0;
-		
+
 		if (pos < f->size) {
-			node->removed_size = raw_inode.rsize =
-				min_t(unsigned int, thiscount, f->size - pos);
-			
-			/* If this node is going entirely over the top of old data, 
-			   we can allow it to go into the reserved space, because 
-			   we can that GC can reclaim the space later.
+			node->removed_size = raw_inode.rsize = min(thiscount, (__u32)(f->size - pos));
+
+			/* If this node is going entirely over the top of old data,
+			   we can allow it to go into the reserved space, because
+			   we know that GC can reclaim the space later.
 			*/
 			if (pos + thiscount < f->size) {
 				/* If all the data we're overwriting are _real_,
@@ -1436,21 +1438,20 @@
 				*/
 			}
 		}
-		
+
 		/* Write the new node to the flash.  */
-		/* NOTE: We would be quite happy if jffs_write_node() wrote a 
-		   smaller node than we were expecting. There's no need for it 
-		   to waste the space at the end of the flash just because it's 
+		/* NOTE: We would be quite happy if jffs_write_node() wrote a
+		   smaller node than we were expecting. There's no need for it
+		   to waste the space at the end of the flash just because it's
 		   a little smaller than what we asked for. But that's a whole
-		   new can of worms which I'm not going to open this week.
+		   new can of worms which I'm not going to open this week. 
 		   -- dwmw2.
 		*/
 		if ((err = jffs_write_node(c, node, &raw_inode, f->name,
 					   (const unsigned char *)buf,
 					   recoverable, f)) < 0) {
 			D(printk("jffs_file_write(): jffs_write_node() failed.\n"));
-			kfree(node);
-			DJM(no_jffs_node--);
+			jffs_free_node(node);
 			goto out;
 		}
 
@@ -1466,7 +1467,7 @@
 
 		D3(printk("jffs_file_write(): new f_pos %ld.\n", (long)pos));
 
-		thiscount = min_t(unsigned int, c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
+		thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
 	}
  out:
 	D3(printk (KERN_NOTICE "file_write(): up biglock\n"));
@@ -1487,22 +1488,26 @@
 
 static ssize_t
 jffs_prepare_write(struct file *filp, struct page *page,
-		   unsigned from, unsigned to)
+                  unsigned from, unsigned to)
 {
 	/* FIXME: we should detect some error conditions here */
-	
+
+	/* Bugger that. We should make sure the page is uptodate */
+	if (!Page_Uptodate(page) && (from || to < PAGE_CACHE_SIZE))
+		return jffs_do_readpage_nolock(filp, page);
+
 	return 0;
 } /* jffs_prepare_write() */
 
 static ssize_t
 jffs_commit_write(struct file *filp, struct page *page,
-		  unsigned from, unsigned to)
+                 unsigned from, unsigned to)
 {
-	void *addr = page_address(page) + from;
-	/* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */
-	loff_t pos = (page->index<<PAGE_CACHE_SHIFT) + from;
-	
-	return jffs_file_write(filp, addr, to-from, &pos);
+       void *addr = page_address(page) + from;
+       /* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */
+       loff_t pos = (page->index<<PAGE_CACHE_SHIFT) + from;
+
+       return jffs_file_write(filp, addr, to-from, &pos);
 } /* jffs_commit_write() */
 
 /* This is our ioctl() routine.  */
@@ -1556,7 +1561,7 @@
 			if (copy_to_user((struct jffs_flash_status *)arg,
 					 &fst,
 					 sizeof(struct jffs_flash_status))) {
-			  ret = -EFAULT;
+				ret = -EFAULT;
 			}
 		}
 		break;
@@ -1577,22 +1582,25 @@
 
 static int jffs_fsync(struct file *f, struct dentry *d, int datasync)
 {
-	/* We currently have O_SYNC operations at all times. 
-	   Do nothing
+	/* We currently have O_SYNC operations at all times.
+	   Do nothing.
 	*/
 	return 0;
 }
 
 
+extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
+extern loff_t generic_file_llseek(struct file *, loff_t, int) __attribute__((weak));
+
 static struct file_operations jffs_file_operations =
 {
-	llseek:	generic_file_llseek,  /* llseek */
-	read:  generic_file_read,    /* read */
-	write: generic_file_write,   /* write */
-	ioctl: jffs_ioctl,           /* ioctl */
-	mmap:  generic_file_mmap,    /* mmap */
-	open:  generic_file_open,
-	fsync: jffs_fsync,
+	open:	generic_file_open,
+	llseek:	generic_file_llseek,
+	read:	generic_file_read,
+	write:	generic_file_write,
+	ioctl:	jffs_ioctl,
+	mmap:	generic_file_mmap,
+	fsync:	jffs_fsync,
 };
 
 
@@ -1690,11 +1698,10 @@
 {
 	struct jffs_file *f;
 	struct jffs_control *c;
-	D1(printk("jffs_delete_inode(): inode->i_ino == %lu\n",
+	D3(printk("jffs_delete_inode(): inode->i_ino == %lu\n",
 		  inode->i_ino));
 
 	lock_kernel();
-
 	inode->i_size = 0;
 	inode->i_blocks = 0;
 	inode->u.generic_ip = 0;
@@ -1717,7 +1724,6 @@
 	jffs_garbage_collect_trigger(c);
 }
 
-
 static struct super_operations jffs_ops =
 {
 	read_inode:   jffs_read_inode,
@@ -1733,9 +1739,16 @@
 static int __init
 init_jffs_fs(void)
 {
-	printk("JFFS version "
-	       JFFS_VERSION_STRING
-	       ", (C) 1999, 2000  Axis Communications AB\n");
+	printk(KERN_INFO "JFFS version " JFFS_VERSION_STRING
+		", (C) 1999, 2000  Axis Communications AB\n");
+	
+#ifdef CONFIG_JFFS_PROC_FS
+	jffs_proc_root = proc_mkdir("jffs", proc_root_fs);
+#endif
+	fm_cache = kmem_cache_create("jffs_fm", sizeof(struct jffs_fm),
+				     0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+	node_cache = kmem_cache_create("jffs_node",sizeof(struct jffs_node),
+				       0, SLAB_HWCACHE_ALIGN, NULL, NULL);
 	return register_filesystem(&jffs_fs_type);
 }
 
@@ -1743,9 +1756,15 @@
 exit_jffs_fs(void)
 {
 	unregister_filesystem(&jffs_fs_type);
+	kmem_cache_destroy(fm_cache);
+	kmem_cache_destroy(node_cache);
 }
 
 EXPORT_NO_SYMBOLS;
 
 module_init(init_jffs_fs)
 module_exit(exit_jffs_fs)
+
+MODULE_DESCRIPTION("The Journalling Flash File System");
+MODULE_AUTHOR("Axis Communications AB.");
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/intrep.c linux/fs/jffs/intrep.c
--- v2.4.10/linux/fs/jffs/intrep.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs/intrep.c	Thu Oct  4 15:13:18 2001
@@ -10,7 +10,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: intrep.c,v 1.71.2.4 2001/01/08 23:27:02 dwmw2 Exp $
+ * $Id: intrep.c,v 1.102 2001/09/23 23:28:36 dwmw2 Exp $
  *
  * Ported to Linux 2.3.x and MTD:
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -56,6 +56,7 @@
  */
 
 #define __NO_VERSION__
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/jffs.h>
@@ -73,9 +74,9 @@
 #include "intrep.h"
 #include "jffs_fm.h"
 
-#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
-long no_jffs_file = 0;
 long no_jffs_node = 0;
+long no_jffs_file = 0;
+#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
 long no_jffs_control = 0;
 long no_jffs_raw_inode = 0;
 long no_jffs_node_ref = 0;
@@ -87,9 +88,24 @@
 
 static int jffs_scan_flash(struct jffs_control *c);
 static int jffs_update_file(struct jffs_file *f, struct jffs_node *node);
-static __u8 flash_read_u8(struct mtd_info *mtd, loff_t from);
 
-#if 1
+#if CONFIG_JFFS_FS_VERBOSE > 0
+static __u8
+flash_read_u8(struct mtd_info *mtd, loff_t from)
+{
+	size_t retlen;
+	__u8 ret;
+	int res;
+
+	res = MTD_READ(mtd, from, 1, &retlen, &ret);
+	if (retlen != 1) {
+		printk("Didn't read a byte in flash_read_u8(). Returned %d\n", res);
+		return 0;
+	}
+
+	return ret;
+}
+
 static void
 jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size)
 {
@@ -135,6 +151,7 @@
 		size -= 16;
 	}
 }
+
 #endif
 
 #define flash_safe_acquire(arg)
@@ -149,7 +166,7 @@
 	int res;
 
 	D3(printk(KERN_NOTICE "flash_safe_read(%p, %08x, %p, %08x)\n",
-		  mtd, from, buf, count));
+		  mtd, (unsigned int) from, buf, count));
 
 	res = MTD_READ(mtd, from, count, &retlen, buf);
 	if (retlen != count) {
@@ -176,33 +193,58 @@
 }
 
 
-static __u8
-flash_read_u8(struct mtd_info *mtd, loff_t from)
+static int
+flash_safe_write(struct mtd_info *mtd, loff_t to,
+		 const u_char *buf, size_t count)
 {
 	size_t retlen;
-	__u8 ret;
 	int res;
 
-	res = MTD_READ(mtd, from, 1, &retlen, &ret);
-	if (retlen != 1) {
-		printk("Didn't read a byte in flash_read_u8(). Returned %d\n", res);
-		return 0;
-	}
+	D3(printk(KERN_NOTICE "flash_safe_write(%p, %08x, %p, %08x)\n",
+		  mtd, (unsigned int) to, buf, count));
 
-	return ret;
+	res = MTD_WRITE(mtd, to, count, &retlen, buf);
+	if (retlen != count) {
+		printk("Didn't write all bytes in flash_safe_write(). Returned %d\n", res);
+	}
+	return res?res:retlen;
 }
 
 
 static int
-flash_safe_write(struct mtd_info *mtd, loff_t to,
-		 const u_char *buf, size_t count)
+flash_safe_writev(struct mtd_info *mtd, const struct iovec *vecs,
+			unsigned long iovec_cnt, loff_t to)
 {
-	size_t retlen;
+	size_t retlen, retlen_a;
+	int i;
 	int res;
 
-	res = MTD_WRITE(mtd, to, count, &retlen, buf);
-	if (retlen != count) {
-		printk("Didn't write all bytes in flash_safe_write(). Returned %d\n", res);
+	D3(printk(KERN_NOTICE "flash_safe_writev(%p, %08x, %p)\n",
+		  mtd, (unsigned int) to, vecs));
+	
+	if (mtd->writev) {
+		res = MTD_WRITEV(mtd, vecs, iovec_cnt, to, &retlen);
+		return res ? res : retlen;
+	}
+	/* Not implemented writev. Repeatedly use write - on the not so
+	   unreasonable assumption that the mtd driver doesn't care how
+	   many write cycles we use. */
+	res=0;
+	retlen=0;
+
+	for (i=0; !res && i<iovec_cnt; i++) {
+		res = MTD_WRITE(mtd, to, vecs[i].iov_len, &retlen_a, vecs[i].iov_base);
+		if (retlen_a != vecs[i].iov_len) {
+			printk("Didn't write all bytes in flash_safe_writev(). Returned %d\n", res);
+			if (i != iovec_cnt-1)
+				return -EIO;
+		}
+		/* If res is non-zero, retlen_a is undefined, but we don't
+		   care because in that case it's not going to be 
+		   returned anyway.
+		*/
+		to += retlen_a;
+		retlen += retlen_a;
 	}
 	return res?res:retlen;
 }
@@ -212,20 +254,20 @@
 flash_memset(struct mtd_info *mtd, loff_t to,
 	     const u_char c, size_t size)
 {
-	static unsigned char pattern[16];
+	static unsigned char pattern[64];
 	int i;
 
 	/* fill up pattern */
 
-	for(i = 0; i < 16; i++)
+	for(i = 0; i < 64; i++)
 		pattern[i] = c;
 
-	/* write as many 16-byte chunks as we can */
+	/* write as many 64-byte chunks as we can */
 
-	while (size >= 16) {
-		flash_safe_write(mtd, to, pattern, 16);
-		size -= 16;
-		to += 16;
+	while (size >= 64) {
+		flash_safe_write(mtd, to, pattern, 64);
+		size -= 64;
+		to += 64;
 	}
 
 	/* and the rest */
@@ -305,8 +347,8 @@
 }
 
 
-__u32
-jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size)
+int
+jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
 {
 	__u32 sum = 0;
 	loff_t ptr = start;
@@ -315,7 +357,10 @@
 
 	/* Allocate read buffer */
 	read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
-
+	if (!read_buf) {
+		printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n");
+		return -ENOMEM;
+	}
 	/* Loop until checksum done */
 	while (size) {
 		/* Get amount of data to read */
@@ -342,8 +387,10 @@
 
 	/* Return result */
 	D3(printk("checksum result: 0x%08x\n", sum));
-	return sum;
+	*result = sum;
+	return 0;
 }
+
 static __inline__ void jffs_fm_write_lock(struct jffs_fmcontrol *fmc)
 {
   //	down(&fmc->wlock);
@@ -367,7 +414,7 @@
 		D(printk("jffs_create_file(): Failed!\n"));
 		return 0;
 	}
-	DJM(no_jffs_file++);
+	no_jffs_file++;
 	memset(f, 0, sizeof(struct jffs_file));
 	f->ino = raw_inode->ino;
 	f->pino = raw_inode->pino;
@@ -471,11 +518,10 @@
 						 GFP_KERNEL))) {
 		return -ENOMEM;
 	}
-	DJM(no_jffs_file++);
-	if (!(node = (struct jffs_node *)kmalloc(sizeof(struct jffs_node),
-						 GFP_KERNEL))) {
+	no_jffs_file++;
+	if (!(node = jffs_alloc_node())) {
 		kfree(root);
-		DJM(no_jffs_file--);
+		no_jffs_file--;
 		return -ENOMEM;
 	}
 	DJM(no_jffs_node++);
@@ -509,7 +555,26 @@
 	c->building_fs = 1;
 	c->sb = sb;
 	if ((err = jffs_scan_flash(c)) < 0) {
-		goto jffs_build_fs_fail;
+		if(err == -EAGAIN){
+			/* scan_flash() wants us to try once more. A flipping 
+			   bits sector was detect in the middle of the scan flash.
+			   Clean up old allocated memory before going in.
+			*/
+			D1(printk("jffs_build_fs: Cleaning up all control structures,"
+				  " reallocating them and trying mount again.\n"));
+			jffs_cleanup_control(c);
+			if (!(c = jffs_create_control(sb->s_dev))) {
+				return -ENOMEM;
+			}
+			c->building_fs = 1;
+			c->sb = sb;
+
+			if ((err = jffs_scan_flash(c)) < 0) {
+				goto jffs_build_fs_fail;
+			}			
+		}else{
+			goto jffs_build_fs_fail;
+		}
 	}
 
 	/* Add a virtual root node if no one exists.  */
@@ -564,6 +629,125 @@
 } /* jffs_build_fs()  */
 
 
+/*
+  This checks for sectors that were being erased in their previous 
+  lifetimes and for some reason or the other (power fail etc.), 
+  the erase cycles never completed.
+  As the flash array would have reverted back to read status, 
+  these sectors are detected by the symptom of the "flipping bits",
+  i.e. bits being read back differently from the same location in
+  flash if read multiple times.
+  The only solution to this is to re-erase the entire
+  sector.
+  Unfortunately detecting "flipping bits" is not a simple exercise
+  as a bit may be read back at 1 or 0 depending on the alignment 
+  of the stars in the universe.
+  The level of confidence is in direct proportion to the number of 
+  scans done. By power fail testing I (Vipin) have been able to 
+  proove that reading twice is not enough.
+  Maybe 4 times? Change NUM_REREADS to a higher number if you want
+  a (even) higher degree of confidence in your mount process. 
+  A higher number would of course slow down your mount.
+*/
+int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){
+
+#define NUM_REREADS             4 /* see note above */
+#define READ_AHEAD_BYTES        4096 /* must be a multiple of 4, 
+					usually set to kernel page size */
+
+	__u8 *read_buf1;
+	__u8 *read_buf2;
+
+	int err = 0;
+	int retlen;
+	int i;
+	int cnt;
+	__u32 offset;
+	loff_t pos = 0;
+	loff_t end = fmc->flash_size;
+
+
+	/* Allocate read buffers */
+	read_buf1 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+	if (!read_buf1)
+		return -ENOMEM;
+
+	read_buf2 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+	if (!read_buf2) {
+		kfree(read_buf1);
+		return -ENOMEM;
+	}
+
+ CHECK_NEXT:
+	while(pos < end){
+		
+		D1(printk("check_partly_erased_sector():checking sector which contains"
+			  " offset 0x%x for flipping bits..\n", (__u32)pos));
+		
+		retlen = flash_safe_read(fmc->mtd, pos,
+					 &read_buf1[0], READ_AHEAD_BYTES);
+		retlen &= ~3;
+		
+		for(cnt = 0; cnt < NUM_REREADS; cnt++){
+			(void)flash_safe_read(fmc->mtd, pos,
+					      &read_buf2[0], READ_AHEAD_BYTES);
+			
+			for (i=0 ; i < retlen ; i+=4) {
+				/* buffers MUST match, double word for word! */
+				if(*((__u32 *) &read_buf1[i]) !=
+				   *((__u32 *) &read_buf2[i])
+				   ){
+				        /* flipping bits detected, time to erase sector */
+					/* This will help us log some statistics etc. */
+					D1(printk("Flipping bits detected in re-read round:%i of %i\n",
+					       cnt, NUM_REREADS));
+					D1(printk("check_partly_erased_sectors:flipping bits detected"
+						  " @offset:0x%x(0x%x!=0x%x)\n",
+						  (__u32)pos+i, *((__u32 *) &read_buf1[i]), 
+						  *((__u32 *) &read_buf2[i])));
+					
+				        /* calculate start of present sector */
+					offset = (((__u32)pos+i)/(__u32)fmc->sector_size) * (__u32)fmc->sector_size;
+					
+					D1(printk("check_partly_erased_sector():erasing sector starting 0x%x.\n",
+						  offset));
+					
+					if (flash_erase_region(fmc->mtd,
+							       offset, fmc->sector_size) < 0) {
+						printk(KERN_ERR "JFFS: Erase of flash failed. "
+						       "offset = %u, erase_size = %d\n",
+						       offset , fmc->sector_size);
+						
+						err = -EIO;
+						goto returnBack;
+
+					}else{
+						D1(printk("JFFS: Erase of flash sector @0x%x successful.\n",
+						       offset));
+						/* skip ahead to the next sector */
+						pos = (((__u32)pos+i)/(__u32)fmc->sector_size) * (__u32)fmc->sector_size;
+						pos += fmc->sector_size;
+						goto CHECK_NEXT;
+					}
+				}
+			}
+		}
+		pos += READ_AHEAD_BYTES;
+	}
+
+ returnBack:
+	kfree(read_buf1);
+	kfree(read_buf2);
+
+	D2(printk("check_partly_erased_sector():Done checking all sectors till offset 0x%x for flipping bits.\n",
+		  (__u32)pos));
+
+	return err;
+
+}/* end check_partly_erased_sectors() */
+
+
+
 /* Scan the whole flash memory in order to find all nodes in the
    file systems.  */
 static int
@@ -577,20 +761,51 @@
 	__u8 tmp_accurate;
 	__u16 tmp_chksum;
 	__u32 deleted_file;
-	loff_t pos = fmc->flash_start;
+	loff_t pos = 0;
 	loff_t start;
-	loff_t end = fmc->flash_start + fmc->flash_size;
+	loff_t test_start;
+	loff_t end = fmc->flash_size;
 	__u8 *read_buf;
 	int i, len, retlen;
+	__u32 offset;
+
+	__u32 free_chunk_size1;
+	__u32 free_chunk_size2;
+
+	
+#define NUMFREEALLOWED     2        /* 2 chunks of at least erase size space allowed */
+	int num_free_space = 0;       /* Flag err if more than TWO
+				       free blocks found. This is NOT allowed
+				       by the current jffs design.
+				    */
+	int num_free_spc_not_accp = 0; /* For debugging purposed keep count 
+					of how much free space was rejected and
+					marked dirty
+				     */
 
 	D1(printk("jffs_scan_flash(): start pos = 0x%lx, end = 0x%lx\n",
 		  (long)pos, (long)end));
 
 	flash_safe_acquire(fmc->mtd);
 
+	/*
+	  check and make sure that any sector does not suffer
+	  from the "partly erased, bit flipping syndrome" (TM Vipin :)
+	  If so, offending sectors will be erased.
+	*/
+	if(check_partly_erased_sectors(fmc) < 0){
+
+		flash_safe_release(fmc->mtd);
+		return -EIO; /* bad, bad, bad error. Cannot continue.*/
+	}
+
 	/* Allocate read buffer */
 	read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
-
+	if (!read_buf) {
+		flash_safe_release(fmc->mtd);
+		return -ENOMEM;
+	}
+			      
 	/* Start the scan.  */
 	while (pos < end) {
 		deleted_file = 0;
@@ -600,32 +815,40 @@
 
 		switch (flash_read_u32(fmc->mtd, pos)) {
 		case JFFS_EMPTY_BITMASK:
-			/* We have found 0xff at this position.  We have to
+			/* We have found 0xffffffff at this position.  We have to
 			   scan the rest of the flash till the end or till
-			   something else than 0xff is found.  */
-			D1(printk("jffs_scan_flash(): 0xff at pos 0x%lx.\n",
+			   something else than 0xffffffff is found.
+		           Keep going till we do not find JFFS_EMPTY_BITMASK 
+			   anymore */
+
+			D1(printk("jffs_scan_flash(): 0xffffffff at pos 0x%lx.\n",
 				  (long)pos));
 
-			len = end - pos < 4096 ? end - pos : 4096;
+		        while(pos < end){
 
-			retlen = flash_safe_read(fmc->mtd, pos,
+			      len = end - pos < 4096 ? end - pos : 4096;
+			      
+			      retlen = flash_safe_read(fmc->mtd, pos,
 						 &read_buf[0], len);
 
-			retlen &= ~3;
-
-			for (i=0 ; i < retlen ; i+=4, pos += 4) {
-				if(*((__u32 *) &read_buf[i]) !=
-						JFFS_EMPTY_BITMASK)
+			      retlen &= ~3;
+			      
+			      for (i=0 ; i < retlen ; i+=4, pos += 4) {
+				      if(*((__u32 *) &read_buf[i]) !=
+					 JFFS_EMPTY_BITMASK)
 					break;
+			      }
+			      if (i == retlen)
+				    continue;
+			      else
+				    break;
 			}
-			if (i == retlen)
-				continue;
-
-			D1(printk("jffs_scan_flash(): 0xff ended at "
-				  "pos 0x%lx.\n", (long)pos));
 
+			D1(printk("jffs_scan_flash():0xffffffff ended at pos 0x%lx.\n",
+				  (long)pos));
+			
 			/* If some free space ends in the middle of a sector,
-				treat it as dirty rather than clean.
+			   treat it as dirty rather than clean.
 			   This is to handle the case where one thread 
 			   allocated space for a node, but didn't get to
 			   actually _write_ it before power was lost, leaving
@@ -638,20 +861,127 @@
 				   only from the beginning of this sector
 				   (or from start) 
 				*/
-				if (start < (pos & ~(fmc->sector_size-1))) {
-					D1(printk("Reducing start to 0x%lx from 0x%lx\n", (unsigned long)pos & ~(fmc->sector_size-1), (unsigned long)start));
-					start = pos & ~(fmc->sector_size-1);
+
+			        test_start = pos & ~(fmc->sector_size-1); /* end of last sector */
+
+				if (start < test_start) {
+
+				        /* free space started in the previous sector! */
+
+					if((num_free_space < NUMFREEALLOWED) && 
+					   ((unsigned int)(test_start - start) >= fmc->sector_size)){
+
+				                /*
+						  Count it in if we are still under NUMFREEALLOWED *and* it is 
+						  at least 1 erase sector in length. This will keep us from 
+						  picking any little ole' space as "free".
+						*/
+					  
+					        D1(printk("Reducing end of free space to 0x%x from 0x%x\n",
+							  (unsigned int)test_start, (unsigned int)pos));
+
+						D1(printk("Free space accepted: Starting 0x%x for 0x%x bytes\n",
+							  (unsigned int) start,
+							  (unsigned int)(test_start - start)));
+
+						/* below, space from "start" to "pos" will be marked dirty. */
+						start = test_start; 
+						
+						/* Being in here means that we have found at least an entire 
+						   erase sector size of free space ending on a sector boundary.
+						   Keep track of free spaces accepted.
+						*/
+						num_free_space++;
+					}else{
+					        num_free_spc_not_accp++;
+					        D1(printk("Free space (#%i) found but *Not* accepted: Starting"
+							  " 0x%x for 0x%x bytes\n",
+							  num_free_spc_not_accp, (unsigned int)start, 
+							  (unsigned int)((unsigned int)(pos & ~(fmc->sector_size-1)) - (unsigned int)start)));
+					        
+					}
+					
 				}
-				D1(printk("Dirty space: 0x%lx for 0x%lx bytes\n", (unsigned long)start, (unsigned long)(pos - start)));
-				jffs_fmalloced(fmc, (__u32) start,
-					       (__u32) (pos - start), 0);
+				if((((__u32)(pos - start)) != 0)){
+
+				        D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
+						  (unsigned int) start, (unsigned int) (pos - start)));
+					jffs_fmalloced(fmc, (__u32) start,
+						       (__u32) (pos - start), 0);
+				}else{
+					/* "Flipping bits" detected. This means that our scan for them
+					   did not catch this offset. See check_partly_erased_sectors() for
+					   more info.
+					*/
+				        
+					D1(printk("jffs_scan_flash():wants to allocate dirty flash "
+						  "space for 0 bytes.\n"));
+					D1(printk("jffs_scan_flash(): Flipping bits! We will free "
+						  "all allocated memory, erase this sector and remount\n"));
+
+					/* calculate start of present sector */
+					offset = (((__u32)pos)/(__u32)fmc->sector_size) * (__u32)fmc->sector_size;
+					
+					D1(printk("jffs_scan_flash():erasing sector starting 0x%x.\n",
+						  offset));
+					
+					if (flash_erase_region(fmc->mtd,
+							       offset, fmc->sector_size) < 0) {
+						printk(KERN_ERR "JFFS: Erase of flash failed. "
+						       "offset = %u, erase_size = %d\n",
+						       offset , fmc->sector_size);
+
+						flash_safe_release(fmc->mtd);
+						kfree (read_buf);
+						return -1; /* bad, bad, bad! */
+
+					}
+					flash_safe_release(fmc->mtd);
+					kfree (read_buf);
+
+					return -EAGAIN; /* erased offending sector. Try mount one more time please. */
+				}
+			}else{
+			        /* Being in here means that we have found free space that ends on an erase sector
+				   boundary.
+				   Count it in if we are still under NUMFREEALLOWED *and* it is at least 1 erase 
+				   sector in length. This will keep us from picking any little ole' space as "free".
+				 */
+			         if((num_free_space < NUMFREEALLOWED) && 
+				    ((unsigned int)(pos - start) >= fmc->sector_size)){
+				           /* We really don't do anything to mark space as free, except *not* 
+					      mark it dirty and just advance the "pos" location pointer. 
+					      It will automatically be picked up as free space.
+					    */ 
+				           num_free_space++;
+				           D1(printk("Free space accepted: Starting 0x%x for 0x%x bytes\n",
+						     (unsigned int) start, (unsigned int) (pos - start)));
+				 }else{
+				         num_free_spc_not_accp++;
+					 D1(printk("Free space (#%i) found but *Not* accepted: Starting "
+						   "0x%x for 0x%x bytes\n", num_free_spc_not_accp, 
+						   (unsigned int) start, 
+						   (unsigned int) (pos - start)));
+					 
+					 /* Mark this space as dirty. We already have our free space. */
+					 D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
+						   (unsigned int) start, (unsigned int) (pos - start)));
+					 jffs_fmalloced(fmc, (__u32) start,
+							(__u32) (pos - start), 0);				           
+				 }
+				 
+			}
+			if(num_free_space > NUMFREEALLOWED){
+			         printk(KERN_WARNING "jffs_scan_flash(): Found free space "
+					"number %i. Only %i free space is allowed.\n",
+					num_free_space, NUMFREEALLOWED);			      
 			}
 			continue;
 
 		case JFFS_DIRTY_BITMASK:
-			/* We have found 0x00 at this position.  Scan as far
+			/* We have found 0x00000000 at this position.  Scan as far
 			   as possible to find out how much is dirty.  */
-			D1(printk("jffs_scan_flash(): 0x00 at pos 0x%lx.\n",
+			D1(printk("jffs_scan_flash(): 0x00000000 at pos 0x%lx.\n",
 				  (long)pos));
 			for (; pos < end
 			       && JFFS_DIRTY_BITMASK == flash_read_u32(fmc->mtd, pos);
@@ -675,68 +1005,33 @@
 				  "hexdump(pos = 0x%lx, len = 128):\n",
 				  (long)pos));
 			D1(jffs_hexdump(fmc->mtd, pos, 128));
-		cont_dirty:
+
 			for (pos += 4; pos < end; pos += 4) {
 				switch (flash_read_u32(fmc->mtd, pos)) {
 				case JFFS_MAGIC_BITMASK:
-					jffs_fmalloced(fmc, (__u32) start,
-						       (__u32) (pos - start),
-						       0);
-					goto cont_scan;
 				case JFFS_EMPTY_BITMASK:
-					/* First, mark as dirty the region
-					   which really does contain crap. */
-					jffs_fmalloced(fmc, (__u32) start,
-						       (__u32) (pos - start),
-						       0);
+					/* handle these in the main switch() loop */
+					goto cont_scan;
 
-					/* Then, scan the region which looks free.
-					   Depending on how large it is, we may
-					   mark it dirty too.
-					*/
-					start = pos;
-					for (; pos < end ; pos += 4) {
-						switch (flash_read_u32(fmc->mtd, pos)) {
-						case JFFS_MAGIC_BITMASK:
-							if (pos - start < fmc->max_chunk_size) {
-								/* Not much free space. Mark it dirty. */
-								jffs_fmalloced(fmc, (__u32)start,
-									       (__u32)pos-start, 0);
-							}
-							goto cont_scan;
-
-						case JFFS_EMPTY_BITMASK:
-							/* More empty space */
-							continue;
-				
-						default: 
-							/* i.e. more dirt */
-							if (pos - start < fmc->max_chunk_size) {
-								/* There wasn't much before the dirt
-								   started again. Just mark it all dirty
-								*/
-								goto cont_dirty;
-							}
-							/* There was quite a lot of free space. Leave it
-							   free.
-							*/
-							goto cont_scan;
-						}
-					}
 				default:
 					break;
 				}
 			}
+
 			cont_scan:
+			/* First, mark as dirty the region
+			   which really does contain crap. */
+			jffs_fmalloced(fmc, (__u32) start,
+				       (__u32) (pos - start),
+				       0);
+			
 			continue;
-		}
+		}/* switch */
 
 		/* We have found the beginning of an inode.  Create a
 		   node for it unless there already is one available.  */
 		if (!node) {
-			if (!(node = (struct jffs_node *)
-				     kmalloc(sizeof(struct jffs_node),
-					     GFP_KERNEL))) {
+			if (!(node = jffs_alloc_node())) {
 				/* Free read buffer */
 				kfree (read_buf);
 
@@ -844,7 +1139,13 @@
 			if (raw_inode.rename) {
 				deleted_file = flash_read_u32(fmc->mtd, pos);
 			}
-			checksum = jffs_checksum_flash(fmc->mtd, pos, raw_inode.dsize);
+			if (jffs_checksum_flash(fmc->mtd, pos, raw_inode.dsize, &checksum)) {
+				printk("jffs_checksum_flash() failed to calculate a checksum\n");
+				jffs_fmalloced(fmc, (__u32) start,
+					       (__u32) (pos - start), 0);
+				/* Reuse this unused struct jffs_node.  */
+				continue;
+			}				
 			pos += raw_inode.dsize
 			       + JFFS_GET_PAD_BYTES(raw_inode.dsize);
 
@@ -885,7 +1186,7 @@
 						  node);
 			if (!node->fm) {
 				D(printk("jffs_scan_flash(): !node->fm\n"));
-				kfree(node);
+				jffs_free_node(node);
 				DJM(no_jffs_node--);
 
 				/* Free read buffer */
@@ -909,7 +1210,7 @@
 					  GFP_KERNEL);
 				if (!dl) {
 					D(printk("jffs_scan_flash: !dl\n"));
-					kfree(node);
+					jffs_free_node(node);
 					DJM(no_jffs_node--);
 
 					/* Release the flash device */
@@ -938,7 +1239,7 @@
 	}
 
 	if (node) {
-		kfree(node);
+		jffs_free_node(node);
 		DJM(no_jffs_node--);
 	}
 	jffs_build_end(fmc);
@@ -946,10 +1247,32 @@
 	/* Free read buffer */
 	kfree (read_buf);
 
+	if(!num_free_space){
+	        printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "
+		       "chunk of free space. This is BAD!\n");
+	}
+
 	/* Return happy */
 	D3(printk("jffs_scan_flash(): Leaving...\n"));
 	flash_safe_release(fmc->mtd);
-	return 0;
+
+	/* This is to trap the "free size accounting screwed error. */
+	free_chunk_size1 = jffs_free_size1(fmc);
+	free_chunk_size2 = jffs_free_size2(fmc);
+
+	if (free_chunk_size1 + free_chunk_size2 != fmc->free_size) {
+
+		printk(KERN_WARNING "jffs_scan_falsh():Free size accounting screwed\n");
+		printk(KERN_WARNING "jfffs_scan_flash():free_chunk_size1 == 0x%x, "
+		       "free_chunk_size2 == 0x%x, fmc->free_size == 0x%x\n", 
+		       free_chunk_size1, free_chunk_size2, fmc->free_size);
+
+		return -1; /* Do NOT mount f/s so that we can inspect what happened.
+			      Mounting this  screwed up f/s will screw us up anyway.
+			    */
+	}	
+
+	return 0; /* as far as we are concerned, we are happy! */
 } /* jffs_scan_flash()  */
 
 
@@ -1199,7 +1522,7 @@
 				  mod_type));
 			jffs_unlink_node_from_version_list(f, cur);
 			jffs_fmfree(f->c->fmc, cur->fm, cur);
-			kfree(cur);
+			jffs_free_node(cur);
 			DJM(no_jffs_node--);
 		}
 		else {
@@ -1419,7 +1742,10 @@
 		struct jffs_file *f)
 {
 	struct jffs_fmcontrol *fmc = c->fmc;
-	struct jffs_fm *fm = NULL;
+	struct jffs_fm *fm;
+	struct iovec node_iovec[4];
+	unsigned long iovec_cnt;
+
 	__u32 pos;
 	int err;
 	__u32 slack = 0;
@@ -1458,6 +1784,9 @@
 
 	jffs_fm_write_lock(fmc);
 
+retry:
+	fm = NULL;
+	err = 0;
 	while (!fm) {
 
 		/* Deadlocks suck. */
@@ -1527,6 +1856,10 @@
 	if (f) {
 		raw_inode->version = f->highest_version + 1;
 		D1(printk (KERN_NOTICE "jffs_write_node(): setting version of %s to %d\n", f->name, raw_inode->version));
+
+		/* if the file was deleted, set the deleted bit in the raw inode */
+		if (f->deleted)
+			raw_inode->deleted = 1;
 	}
 
 	/* Compute the checksum for the data and name chunks.  */
@@ -1545,46 +1878,48 @@
 		  "flash at pos 0x%lx:\n", (long)pos));
 	D3(jffs_print_raw_inode(raw_inode));
 
-	/* Step 1: Write the raw jffs inode to the flash.  */
-	if ((err = flash_safe_write(fmc->mtd, pos,
-				    (u_char *)raw_inode,
-				    sizeof(struct jffs_raw_inode))) < 0) {
-		jffs_fmfree_partly(fmc, fm,
-				   total_name_size + total_data_size);
-		jffs_fm_write_unlock(fmc);
-		printk(KERN_ERR "JFFS: jffs_write_node: Failed to write "
-		       "raw_inode.\n");
-		return err;
-	}
-	pos += sizeof(struct jffs_raw_inode);
+	/* The actual raw JFFS node */
+	node_iovec[0].iov_base = (void *) raw_inode;
+	node_iovec[0].iov_len = (size_t) sizeof(struct jffs_raw_inode);
+	iovec_cnt = 1;
 
-	/* Step 2: Write the name, if there is any.  */
+	/* Get name and size if there is one */
 	if (raw_inode->nsize) {
-		if ((err = flash_safe_write(fmc->mtd, pos,
-					    (u_char *)name,
-					    raw_inode->nsize)) < 0) {
-			jffs_fmfree_partly(fmc, fm, total_data_size);
-			jffs_fm_write_unlock(fmc);
-			printk(KERN_ERR "JFFS: jffs_write_node: Failed to "
-                              "write the name.\n");
-			return err;
+		node_iovec[iovec_cnt].iov_base = (void *) name;
+		node_iovec[iovec_cnt].iov_len = (size_t) raw_inode->nsize;
+		iovec_cnt++;
+
+		if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) {
+			static char allff[3]={255,255,255};
+			/* Add some extra padding if necessary */
+			node_iovec[iovec_cnt].iov_base = allff;
+			node_iovec[iovec_cnt].iov_len =
+				JFFS_GET_PAD_BYTES(raw_inode->nsize);
+			iovec_cnt++;
 		}
-		pos += total_name_size;
 	}
-	if (raw_inode->deleted)
-		f->deleted = 1;
 
-	/* Step 3: Append the actual data, if any.  */
+	/* Get data and size if there is any */
 	if (raw_inode->dsize) {
-		if ((err = flash_safe_write(fmc->mtd, pos, data,
-					    raw_inode->dsize)) < 0) {
-			jffs_fmfree_partly(fmc, fm, 0);
-			jffs_fm_write_unlock(fmc);
-			printk(KERN_ERR "JFFS: jffs_write_node: Failed to "
-			       "write the data.\n");
-			return err;
-		}
+		node_iovec[iovec_cnt].iov_base = (void *) data;
+		node_iovec[iovec_cnt].iov_len = (size_t) raw_inode->dsize;
+		iovec_cnt++;
+		/* No need to pad this because we're not actually putting
+		   anything after it.
+		*/
 	}
+
+	if ((err = flash_safe_writev(fmc->mtd, node_iovec, iovec_cnt,
+				    pos) < 0)) {
+		jffs_fmfree_partly(fmc, fm, 0);
+		jffs_fm_write_unlock(fmc);
+		printk(KERN_ERR "JFFS: jffs_write_node: Failed to write, "
+		       "requested %i, wrote %i\n", total_size, err);
+		goto retry;
+	}
+	if (raw_inode->deleted)
+		f->deleted = 1;
+
 	jffs_fm_write_unlock(fmc);
 	D3(printk("jffs_write_node(): Leaving...\n"));
 	return raw_inode->dsize;
@@ -1609,7 +1944,7 @@
 		  "version: %u, node_offset: %u\n",
 		  f->name, node->ino, node->version, node_offset));
 
-	r = min_t(u32, avail, max_size);
+	r = min(avail, max_size);
 	D3(printk(KERN_NOTICE "jffs_get_node_data\n"));
 	flash_safe_read(fmc->mtd, pos, buf, r);
 
@@ -1662,8 +1997,8 @@
 		int r;
 		if (!node->fm) {
 			/* This node does not refer to real data.  */
-			r = min_t(u32, size - read_data,
-				node->data_size - node_offset);
+			r = min(size - read_data,
+				     node->data_size - node_offset);
 			memset(&buf[read_data], 0, r);
 		}
 		else if ((r = jffs_get_node_data(f, node, &buf[read_data],
@@ -1720,7 +2055,7 @@
 	while (node) {
 		p = node;
 		node = node->version_next;
-		kfree(p);
+		jffs_free_node(p);
 		DJM(no_jffs_node--);
 	}
 	return 0;
@@ -1739,10 +2074,15 @@
 		DJM(no_name--);
 	}
 	kfree(f);
-	DJM(no_jffs_file--);
+	no_jffs_file--;
 	return 0;
 }
 
+long
+jffs_get_file_count(void)
+{
+	return no_jffs_file;
+}
 
 /* See if a file is deleted. If so, mark that file's nodes as obsolete.  */
 int
@@ -1856,9 +2196,7 @@
 			D3(printk("jffs_delete_data(): Split node with "
 				  "version number %u.\n", n->version));
 
-			if (!(new_node = (struct jffs_node *)
-					 kmalloc(sizeof(struct jffs_node),
-						 GFP_KERNEL))) {
+			if (!(new_node = jffs_alloc_node())) {
 				D(printk("jffs_delete_data(): -ENOMEM\n"));
 				return -ENOMEM;
 			}
@@ -1904,8 +2242,8 @@
 		else {
 			/* No.  No need to split the node.  Just remove
 			   the end of the node.  */
-			int r = min_t(u32, n->data_offset + n->data_size
-				    - offset, remove_size);
+			int r = min(n->data_offset + n->data_size
+					 - offset, remove_size);
 			n->data_size -= r;
 			remove_size -= r;
 			n = n->range_next;
@@ -1927,7 +2265,7 @@
 			}
 			jffs_unlink_node_from_range_list(f, p);
 			jffs_unlink_node_from_version_list(f, p);
-			kfree(p);
+			jffs_free_node(p);
 			DJM(no_jffs_node--);
 		}
 		else {
@@ -2043,9 +2381,7 @@
 		   front of this insertion.  This "virtual node" will not
 		   be associated with any space on the flash device.  */
 		struct jffs_node *virtual_node;
-		if (!(virtual_node = (struct jffs_node *)
-				     kmalloc(sizeof(struct jffs_node),
-					     GFP_KERNEL))) {
+		if (!(virtual_node = jffs_alloc_node())) {
 			return -ENOMEM;
 		}
 
@@ -2325,7 +2661,7 @@
 
 /* Rewrite `size' bytes, and begin at `node'.  */
 int
-jffs_rewrite_data(struct jffs_file *f, struct jffs_node *node, int size)
+jffs_rewrite_data(struct jffs_file *f, struct jffs_node *node, __u32 size)
 {
 	struct jffs_control *c = f->c;
 	struct jffs_fmcontrol *fmc = c->fmc;
@@ -2343,8 +2679,7 @@
 		  f->ino, (f->name ? f->name : "(null)"), size));
 
 	/* Create and initialize the new node.  */
-	if (!(new_node = (struct jffs_node *)
-			 kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
+	if (!(new_node = jffs_alloc_node())) {
 		D(printk("jffs_rewrite_data(): "
 			 "Failed to allocate node.\n"));
 		return -ENOMEM;
@@ -2359,13 +2694,15 @@
 	new_node->fm_offset = sizeof(struct jffs_raw_inode)
 			      + total_name_size;
 
+retry:
 	jffs_fm_write_lock(fmc);
+	err = 0;
 
 	if ((err = jffs_fmalloc(fmc, total_size, new_node, &fm)) < 0) {
 		DJM(no_jffs_node--);
 		jffs_fm_write_unlock(fmc);
 		D(printk("jffs_rewrite_data(): Failed to allocate fm.\n"));
-		kfree(new_node);
+		jffs_free_node(new_node);
 		return err;
 	}
 	else if (!fm->nodes) {
@@ -2405,7 +2742,7 @@
 	raw_inode.nlink = f->nlink;
 	raw_inode.spare = 0;
 	raw_inode.rename = 0;
-	raw_inode.deleted = 0;
+	raw_inode.deleted = f->deleted;
 	raw_inode.accurate = 0xff;
 	raw_inode.dchksum = 0;
 	raw_inode.nchksum = 0;
@@ -2426,23 +2763,27 @@
 				   total_name_size + total_data_size);
 		jffs_fm_write_unlock(fmc);
 		printk(KERN_ERR "JFFS: jffs_rewrite_data: Write error during "
-		       "rewrite. (raw inode)\n");
-		return err;
+			"rewrite. (raw inode)\n");
+		printk(KERN_ERR "JFFS: jffs_rewrite_data: Now retrying "
+			"rewrite. (raw inode)\n");
+		goto retry;
 	}
 	pos += sizeof(struct jffs_raw_inode);
 
 	/* Write the name to the flash memory.  */
 	if (f->nsize) {
 		D3(printk("jffs_rewrite_data(): Writing name \"%s\" to "
-			  "pos 0x%ul.\n", f->name, (long)pos));
+			  "pos 0x%ul.\n", f->name, (unsigned int) pos));
 		if ((err = flash_safe_write(fmc->mtd, pos,
 					    (u_char *)f->name,
 					    f->nsize)) < 0) {
 			jffs_fmfree_partly(fmc, fm, total_data_size);
 			jffs_fm_write_unlock(fmc);
 			printk(KERN_ERR "JFFS: jffs_rewrite_data: Write "
-			       "error during rewrite. (name)\n");
-			return err;
+				"error during rewrite. (name)\n");
+			printk(KERN_ERR "JFFS: jffs_rewrite_data: Now retrying "
+				"rewrite. (name)\n");
+			goto retry;
 		}
 		pos += total_name_size;
 		raw_inode.nchksum = jffs_checksum(f->name, f->nsize);
@@ -2460,7 +2801,7 @@
 		}
 
 		while (size) {
-			__u32 s = min_t(int, size, PAGE_SIZE);
+			__u32 s = min(size, (__u32)PAGE_SIZE);
 			if ((r = jffs_read_data(f, (char *)page,
 						offset, s)) < s) {
 				free_page((unsigned long)page);
@@ -2479,7 +2820,7 @@
 				printk(KERN_ERR "JFFS: jffs_rewrite_data: "
 				       "Write error during rewrite. "
 				       "(data)\n");
-				return err;
+				goto retry;
 			}
 			pos += r;
 			size -= r;
@@ -2506,7 +2847,7 @@
 		jffs_fm_write_unlock(fmc);
 		printk(KERN_ERR "JFFS: jffs_rewrite_data: Write error during "
 		       "rewrite. (checksum)\n");
-		return err;
+		goto retry;
 	}
 
 	/* Now make the file system aware of the newly written node.  */
@@ -2528,9 +2869,10 @@
 	struct jffs_fmcontrol *fmc = c->fmc;
 	struct jffs_node *node;
 	struct jffs_file *f;
-	int size, err = 0;
-	int data_size;
-	int total_name_size;
+	int err = 0;
+	__u32 size;
+	__u32 data_size;
+	__u32 total_name_size;
 	__u32 extra_available;
 	__u32 space_needed;
 	__u32 free_chunk_size1 = jffs_free_size1(fmc);
@@ -2654,10 +2996,10 @@
 	   what's available */
 	if (size > JFFS_PAD(node->data_size) + total_name_size + 
 	    sizeof(struct jffs_raw_inode) + extra_available) {
-		D1(printk("Reducing size of new node from %d to %d to avoid "
-			  "catching our tail\n", size,
-			  JFFS_PAD(node->data_size) + JFFS_PAD(node->name_size) + 
-			  sizeof(struct jffs_raw_inode) + extra_available));
+		D1(printk("Reducing size of new node from %d to %ld to avoid "
+		       "catching our tail\n", size, 
+			  (long) (JFFS_PAD(node->data_size) + JFFS_PAD(node->name_size) + 
+			  sizeof(struct jffs_raw_inode) + extra_available)));
 		D1(printk("space_needed = %d, extra_available = %d\n", 
 			  space_needed, extra_available));
 
@@ -2789,7 +3131,7 @@
 		return err;
 	}
 
-	offset = fmc->head->offset - fmc->flash_start;
+	offset = fmc->head->offset;
 
 	/* Now, let's try to do the erase.  */
 	if ((err = flash_erase_region(fmc->mtd,
@@ -2821,7 +3163,7 @@
 				printk("JFFS: Erase failed! pos = 0x%lx\n",
 				       (long)pos);
 				jffs_hexdump(fmc->mtd, pos,
-					     min_t(u32, 256, end - pos));
+					     jffs_min(256, end - pos));
 				err = -1;
 				break;
 			}
@@ -2947,17 +3289,31 @@
 		   c->fmc->free_size, c->fmc->dirty_size, c->fmc->sector_size));
 
 	/* If there's not enough dirty space to free a block, there's no point. */
-	if (c->fmc->dirty_size < c->fmc->sector_size)
+	if (c->fmc->dirty_size < c->fmc->sector_size) {
+		D2(printk(KERN_NOTICE "thread_should_wake(): Not waking. Insufficient dirty space\n"));
 		return 0;
-
+	}
+#if 1
+	/* If there is too much RAM used by the various structures, GC */
+	if (jffs_get_node_inuse() > (c->fmc->used_size/c->fmc->max_chunk_size * 5 + jffs_get_file_count() * 2 + 50)) {
+		/* FIXME: Provide proof that this test can be satisfied. We
+		   don't want a filesystem doing endless GC just because this
+		   condition cannot ever be false.
+		*/
+		D2(printk(KERN_NOTICE "thread_should_wake(): Waking due to number of nodes\n"));
+		return 1;
+	}
+#endif
 	/* If there are fewer free bytes than the threshold, GC */
-	if (c->fmc->dirty_size < c->gc_minfree_threshold)
+	if (c->fmc->free_size < c->gc_minfree_threshold) {
+		D2(printk(KERN_NOTICE "thread_should_wake(): Waking due to insufficent free space\n"));
 		return 1;
-
+	}
 	/* If there are more dirty bytes than the threshold, GC */
-	if (c->fmc->dirty_size > c->gc_maxdirty_threshold)
+	if (c->fmc->dirty_size > c->gc_maxdirty_threshold) {
+		D2(printk(KERN_NOTICE "thread_should_wake(): Waking due to excessive dirty space\n"));
 		return 1;
-	
+	}	
 	/* FIXME: What about the "There are many versions of a node" condition? */
 
 	return 0;
@@ -3039,18 +3395,12 @@
 			case SIGKILL:
 				D1(printk("jffs_garbage_collect_thread(): SIGKILL received.\n"));
 				c->gc_task = NULL;
-				unlock_kernel();
 				complete_and_exit(&c->gc_thread_comp, 0);
 			}
 		}
 
 
 		D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): collecting.\n"));
-
-		if (fmc->dirty_size < fmc->sector_size) {
-			D1(printk(KERN_WARNING "jffs_garbage_collect_thread with insufficient dirty space (0x%x)\n", fmc->dirty_size));
-			continue;
-		}
 
 		D3(printk (KERN_NOTICE "g_c_thread(): down biglock\n"));
 		down(&fmc->biglock);
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/intrep.h linux/fs/jffs/intrep.h
--- v2.4.10/linux/fs/jffs/intrep.h	Mon Aug 27 12:41:46 2001
+++ linux/fs/jffs/intrep.h	Thu Oct  4 15:13:18 2001
@@ -10,13 +10,18 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: intrep.h,v 1.11 2000/08/17 22:46:46 bmatthews Exp $
+ * $Id: intrep.h,v 1.14 2001/09/23 23:28:37 dwmw2 Exp $
  *
  */
 
 #ifndef __LINUX_JFFS_INTREP_H__
 #define __LINUX_JFFS_INTREP_H__
 #include "jffs_fm.h"
+struct jffs_node *jffs_alloc_node(void);
+void jffs_free_node(struct jffs_node *n);
+int jffs_get_node_inuse(void);
+long jffs_get_file_count(void);
+
 __u32 jffs_checksum(const void *data, int size);
 
 void jffs_cleanup_control(struct jffs_control *c);
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/jffs_fm.c linux/fs/jffs/jffs_fm.c
--- v2.4.10/linux/fs/jffs/jffs_fm.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs/jffs_fm.c	Thu Oct  4 15:13:18 2001
@@ -10,7 +10,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: jffs_fm.c,v 1.18 2000/08/21 10:41:45 dwmw2 Exp $
+ * $Id: jffs_fm.c,v 1.27 2001/09/20 12:29:47 dwmw2 Exp $
  *
  * Ported to Linux 2.3.x and MTD:
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -26,6 +26,8 @@
 static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset);
 #endif
 
+extern kmem_cache_t     *fm_cache;
+extern kmem_cache_t     *node_cache;
 
 /* This function creates a new shiny flash memory control structure.  */
 struct jffs_fmcontrol *
@@ -46,16 +48,14 @@
 
 	mtd = get_mtd_device(NULL, MINOR(dev));
 
-	if (!mtd)
-	{
+	if (!mtd) {
 		kfree(fmc);
+		DJM(no_jffs_fmcontrol--);
 		return NULL;
 	}
 	
 	/* Retrieve the size of the flash memory.  */
-	fmc->flash_start = 0;
 	fmc->flash_size = mtd->size;
-	D3(printk("  fmc->flash_start = 0x%08x\n", fmc->flash_start));
 	D3(printk("  fmc->flash_size = %d bytes\n", fmc->flash_size));
 
 	fmc->used_size = 0;
@@ -71,8 +71,11 @@
 		   to write out larger nodes than the ones it's obsoleting.
 		   We should fix it so it doesn't have to write the name
 		   _every_ time. Later.
+	   + another 2 sectors because people keep getting GC stuck and
+	           we don't know why. This scares me - I want formal proof
+		   of correctness of whatever number we put here. dwmw2.
 	*/
-	fmc->min_free_size = fmc->sector_size << 1;
+	fmc->min_free_size = fmc->sector_size << 2;
 	fmc->mtd = mtd;
 	fmc->c = c;
 	fmc->head = 0;
@@ -117,8 +120,7 @@
 
 		while ((cur = next)) {
 			next = next->next;
-			kfree(cur);
-			DJM(no_jffs_fm--);
+			jffs_free_fm(cur);
 		}
 		put_mtd_device(fmc->mtd);
 		kfree(fmc);
@@ -135,7 +137,7 @@
 {
 	__u32 head;
 	__u32 tail;
-	__u32 end = fmc->flash_start + fmc->flash_size;
+	__u32 end = fmc->flash_size;
 
 	if (!fmc->head) {
 		/* There is nothing on the flash.  */
@@ -146,11 +148,11 @@
 	head = fmc->head->offset;
 	tail = fmc->tail->offset + fmc->tail->size;
 	if (tail == end) {
-		tail = fmc->flash_start;
+		tail = 0;
 	}
 	ASSERT(else if (tail > end) {
 		printk(KERN_WARNING "jffs_free_size1(): tail > end\n");
-		tail = fmc->flash_start;
+		tail = 0;
 	});
 
 	if (head <= tail) {
@@ -178,12 +180,12 @@
 	if (fmc->head) {
 		__u32 head = fmc->head->offset;
 		__u32 tail = fmc->tail->offset + fmc->tail->size;
-		if (tail == fmc->flash_start + fmc->flash_size) {
-			tail = fmc->flash_start;
+		if (tail == fmc->flash_size) {
+			tail = 0;
 		}
 
 		if (tail >= head) {
-			return head - fmc->flash_start;
+			return head;
 		}
 	}
 	return 0;
@@ -206,12 +208,10 @@
 
 	*result = 0;
 
-	if (!(fm = (struct jffs_fm*)kmalloc(sizeof(struct jffs_fm),
-					    GFP_KERNEL))) {
+	if (!(fm = jffs_alloc_fm())) {
 		D(printk("jffs_fmalloc(): kmalloc() failed! (fm)\n"));
 		return -ENOMEM;
 	}
-	DJM(no_jffs_fm++);
 
 	free_chunk_size1 = jffs_free_size1(fmc);
 	free_chunk_size2 = jffs_free_size2(fmc);
@@ -230,8 +230,7 @@
 					  GFP_KERNEL))) {
 			D(printk("jffs_fmalloc(): kmalloc() failed! "
 				 "(node_ref)\n"));
-			kfree(fm);
-			DJM(no_jffs_fm--);
+			jffs_free_fm(fm);
 			return -ENOMEM;
 		}
 		DJM(no_jffs_node_ref++);
@@ -239,22 +238,19 @@
 		fm->nodes->next = 0;
 		if (fmc->tail) {
 			fm->offset = fmc->tail->offset + fmc->tail->size;
-			if (fm->offset
-			    == fmc->flash_start + fmc->flash_size) {
-				fm->offset = fmc->flash_start;
+			if (fm->offset == fmc->flash_size) {
+				fm->offset = 0;
 			}
-			ASSERT(else if (fm->offset
-					> fmc->flash_start
-					  + fmc->flash_size) {
+			ASSERT(else if (fm->offset > fmc->flash_size) {
 				printk(KERN_WARNING "jffs_fmalloc(): "
 				       "offset > flash_end\n");
-				fm->offset = fmc->flash_start;
+				fm->offset = 0;
 			});
 		}
 		else {
 			/* There don't have to be files in the file
 			   system yet.  */
-			fm->offset = fmc->flash_start;
+			fm->offset = 0;
 		}
 		fm->size = size;
 		fmc->free_size -= size;
@@ -263,8 +259,7 @@
 	else if (size > free_chunk_size2) {
 		printk(KERN_WARNING "JFFS: Tried to allocate a too "
 		       "large flash memory chunk. (size = %u)\n", size);
-		kfree(fm);
-		DJM(no_jffs_fm--);
+		jffs_free_fm(fm);
 		return -ENOSPC;
 	}
 	else {
@@ -350,7 +345,6 @@
 			return -1;
 		}
 #endif
-		fmc->c->sb->s_dirt = 1;
 	}
 
 	ASSERT(if (!del) {
@@ -372,13 +366,11 @@
 
 	D3(printk("jffs_fmalloced()\n"));
 
-	if (!(fm = (struct jffs_fm *)kmalloc(sizeof(struct jffs_fm),
-					     GFP_KERNEL))) {
+	if (!(fm = jffs_alloc_fm())) {
 		D(printk("jffs_fmalloced(0x%p, %u, %u, 0x%p): failed!\n",
 			 fmc, offset, size, node));
 		return 0;
 	}
-	DJM(no_jffs_fm++);
 	fm->offset = offset;
 	fm->size = size;
 	fm->prev = 0;
@@ -391,8 +383,7 @@
 				  kmalloc(sizeof(struct jffs_node_ref),
 					  GFP_KERNEL))) {
 			D(printk("jffs_fmalloced(): !fm->nodes\n"));
-			kfree(fm);
-			DJM(no_jffs_fm--);
+			jffs_free_fm(fm);
 			return 0;
 		}
 		DJM(no_jffs_node_ref++);
@@ -469,6 +460,7 @@
 	fmc->used_size -= fm->size;
 	if (fm == fmc->tail) {
 		fm->size -= size;
+		fmc->free_size += size;
 	}
 	fmc->dirty_size += fm->size;
 }
@@ -535,8 +527,7 @@
 			fm = fm->next;
 			fm->prev = 0;
 			fmc->head = fm;
-			kfree(del);
-			DJM(no_jffs_fm--);
+			jffs_free_fm(del);
 		}
 		else {
 			fm->size -= erased_size;
@@ -664,7 +655,7 @@
 
 	/* Calculate how much space that is dirty.  */
 	for (fm = fmc->head; fm && !fm->nodes; fm = fm->next) {
-		if (size && fm->offset == fmc->flash_start) {
+		if (size && fm->offset == 0) {
 			/* We have reached the beginning of the flash.  */
 			break;
 		}
@@ -674,14 +665,13 @@
 	/* Someone's signature contained this:
 	   There's a fine line between fishing and just standing on
 	   the shore like an idiot...  */
-	ret = jffs_flash_erasable_size(fmc->mtd,
-				       fmc->head->offset - fmc->flash_start, size);
+	ret = jffs_flash_erasable_size(fmc->mtd, fmc->head->offset, size);
 
 	ASSERT(if (ret < 0) {
 		printk("jffs_erasable_size: flash_erasable_size() "
 		       "returned something less than zero (%ld).\n", ret);
 		printk("jffs_erasable_size: offset = 0x%08x\n",
-		       fmc->head->offset - fmc->flash_start);
+		       fmc->head->offset);
 	});
 
 	/* If there is dirt on the flash (which is the reason to why
@@ -705,21 +695,58 @@
 			if (del->next) {
 				del->next->prev = head;
 			}
-			kfree(del);
-			DJM(no_jffs_fm--);
+			jffs_free_fm(del);
 		}
 	}
 
 	return (ret >= 0 ? ret : 0);
 }
 
+struct jffs_fm *jffs_alloc_fm(void)
+{
+	struct jffs_fm *fm;
+
+	fm = kmem_cache_alloc(fm_cache,GFP_KERNEL);
+	DJM(if (fm) no_jffs_fm++;);
+	
+	return fm;
+}
+
+void jffs_free_fm(struct jffs_fm *n)
+{
+	kmem_cache_free(fm_cache,n);
+	DJM(no_jffs_fm--);
+}
+
+
+
+struct jffs_node *jffs_alloc_node(void)
+{
+	struct jffs_node *n;
+
+	n = (struct jffs_node *)kmem_cache_alloc(node_cache,GFP_KERNEL);
+	if(n != NULL)
+		no_jffs_node++;
+	return n;
+}
+
+void jffs_free_node(struct jffs_node *n)
+{
+	kmem_cache_free(node_cache,n);
+	no_jffs_node--;
+}
+
+
+int jffs_get_node_inuse(void)
+{
+	return no_jffs_node;
+}
 
 void
 jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
 {
 	D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
 	D(printk("{\n"));
-	D(printk("        0x%08x, /* flash_start  */\n", fmc->flash_start));
 	D(printk("        %u, /* flash_size  */\n", fmc->flash_size));
 	D(printk("        %u, /* used_size  */\n", fmc->used_size));
 	D(printk("        %u, /* dirty_size  */\n", fmc->dirty_size));
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/jffs_fm.h linux/fs/jffs/jffs_fm.h
--- v2.4.10/linux/fs/jffs/jffs_fm.h	Mon Dec 11 13:26:54 2000
+++ linux/fs/jffs/jffs_fm.h	Thu Oct  4 15:13:18 2001
@@ -10,7 +10,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: jffs_fm.h,v 1.10 2000/08/17 15:42:44 dwmw2 Exp $
+ * $Id: jffs_fm.h,v 1.13 2001/01/11 12:03:25 dwmw2 Exp $
  *
  * Ported to Linux 2.3.x and MTD:
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -59,10 +59,15 @@
 
 /* How many padding bytes should be inserted between two chunks of data
    on the flash?  */
-#define JFFS_GET_PAD_BYTES(size) ((JFFS_ALIGN_SIZE                     \
-				  - ((__u32)(size) % JFFS_ALIGN_SIZE)) \
-				  % JFFS_ALIGN_SIZE)
+#define JFFS_GET_PAD_BYTES(size) ( (JFFS_ALIGN_SIZE-1) & -(__u32)(size) )
 #define JFFS_PAD(size) ( (size + (JFFS_ALIGN_SIZE-1)) & ~(JFFS_ALIGN_SIZE-1) )
+
+
+
+void jffs_free_fm(struct jffs_fm *n);
+struct jffs_fm *jffs_alloc_fm(void);
+
+
 struct jffs_node_ref
 {
 	struct jffs_node *node;
@@ -82,7 +87,6 @@
 
 struct jffs_fmcontrol
 {
-	__u32 flash_start;
 	__u32 flash_size;
 	__u32 used_size;
 	__u32 dirty_size;
@@ -115,6 +119,7 @@
    the scan is completed, the two lists are merged together. The jffs_fm
    struct that head_extra references is the logical beginning of the
    flash memory so it will be referenced by the head member.  */
+
 
 
 struct jffs_fmcontrol *jffs_build_begin(struct jffs_control *c, kdev_t dev);
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/jffs_proc.c linux/fs/jffs/jffs_proc.c
--- v2.4.10/linux/fs/jffs/jffs_proc.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/jffs/jffs_proc.c	Thu Oct  4 15:13:18 2001
@@ -0,0 +1,269 @@
+/*
+ * JFFS -- Journaling Flash File System, Linux implementation.
+ *
+ * Copyright (C) 2000  Axis Communications AB.
+ *
+ * Created by Simon Kagstrom <simonk@axis.com>.
+ *
+ * $Id: jffs_proc.c,v 1.5 2001/06/02 14:34:55 dwmw2 Exp $
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *  Overview:
+ *   This file defines JFFS partition entries in the proc file system.
+ *
+ *  TODO:
+ *   Create some more proc files for different kinds of info, i.e. statistics
+ *   about written and read bytes, number of calls to different routines,
+ *   reports about failures.
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/jffs.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include "jffs_fm.h"
+#include "jffs_proc.h"
+
+/*
+ * Structure for a JFFS partition in the system
+ */
+struct jffs_partition_dir {
+	struct jffs_control *c;
+	struct proc_dir_entry *part_root;
+	struct proc_dir_entry *part_info;
+	struct proc_dir_entry *part_layout;
+	struct jffs_partition_dir *next;
+};
+
+/*
+ * Structure for top-level entry in '/proc/fs' directory
+ */
+struct proc_dir_entry *jffs_proc_root;
+
+/*
+ * Linked list of 'jffs_partition_dirs' to help us track
+ * the mounted JFFS partitions in the system
+ */
+static struct jffs_partition_dir *jffs_part_dirs = 0;
+
+/*
+ * Read functions for entries
+ */
+static int jffs_proc_info_read(char *page, char **start, off_t off,
+		int count, int *eof, void *data);
+static int jffs_proc_layout_read (char *page, char **start, off_t off,
+		int count, int *eof, void *data);
+
+
+/*
+ * Register a JFFS partition directory (called upon mount)
+ */
+int jffs_register_jffs_proc_dir(kdev_t dev, struct jffs_control *c)
+{
+	struct jffs_partition_dir *part_dir;
+	struct proc_dir_entry *part_info = 0;
+	struct proc_dir_entry *part_layout = 0;
+	struct proc_dir_entry *part_root = 0;
+
+	/* Allocate structure for local JFFS partition table */
+	if (!(part_dir = (struct jffs_partition_dir *)
+		kmalloc (sizeof (struct jffs_partition_dir), GFP_KERNEL))) {
+		return -ENOMEM;
+	}
+
+	/* Create entry for this partition */
+	if ((part_root = create_proc_entry (kdevname(dev),
+		S_IFDIR | S_IRUGO | S_IXUGO, jffs_proc_root))) {
+		part_root->read_proc = jffs_proc_info_read;
+		part_root->data = (void *) c;
+	}
+	else {
+		kfree (part_dir);
+		return -ENOMEM;
+	}
+
+	/* Create entry for 'info' file */
+	if ((part_info = create_proc_entry ("info", 0, part_root))) {
+		part_info->read_proc = jffs_proc_info_read;
+		part_info->data = (void *) c;
+	}
+	else {
+		remove_proc_entry (part_root->name, jffs_proc_root);
+		kfree (part_dir);
+		return -ENOMEM;
+	}
+
+	/* Create entry for 'layout' file */
+	if ((part_layout = create_proc_entry ("layout", 0, part_root))) {
+		part_layout->read_proc = jffs_proc_layout_read;
+		part_layout->data = (void *) c;
+	}
+	else {
+		remove_proc_entry (part_info->name, part_root);
+		remove_proc_entry (part_root->name, jffs_proc_root);
+		kfree (part_dir);
+		return -ENOMEM;
+	}
+
+	/* Fill in structure for table and insert in the list */
+	part_dir->c = c;
+	part_dir->part_root = part_root;
+	part_dir->part_info = part_info;
+	part_dir->part_layout = part_layout;
+	part_dir->next = jffs_part_dirs;
+	jffs_part_dirs = part_dir;
+
+	/* Return happy */
+	return 0;
+}
+
+
+/*
+ * Unregister a JFFS partition directory (called at umount)
+ */
+int jffs_unregister_jffs_proc_dir(struct jffs_control *c)
+{
+	struct jffs_partition_dir *part_dir = jffs_part_dirs;
+	struct jffs_partition_dir *prev_part_dir = 0;
+
+	while (part_dir) {
+		if (part_dir->c == c) {
+			/* Remove entries for partition */
+			remove_proc_entry (part_dir->part_info->name,
+				part_dir->part_root);
+			remove_proc_entry (part_dir->part_layout->name,
+				part_dir->part_root);
+			remove_proc_entry (part_dir->part_root->name,
+				jffs_proc_root);
+
+			/* Remove entry from list */
+			if (prev_part_dir)
+				prev_part_dir->next = part_dir->next;
+			else
+				jffs_part_dirs = part_dir->next;
+
+			/*
+			 * Check to see if this is the last one
+			 * and remove the entry from '/proc/fs'
+			 * if it is.
+			 */
+			if (jffs_part_dirs == part_dir->next)
+#if LINUX_VERSION_CODE < 0x020300
+				remove_proc_entry ("jffs", &proc_root_fs);
+#else
+				remove_proc_entry ("jffs", proc_root_fs);
+#endif
+
+			/* Free memory for entry */
+			kfree(part_dir);
+
+			/* Return happy */
+			return 0;
+		}
+
+		/* Move to next entry */
+		prev_part_dir = part_dir;
+		part_dir = part_dir->next;
+	}
+
+	/* Return unhappy */
+	return -1;
+}
+
+
+/*
+ * Read a JFFS partition's `info' file
+ */
+static int jffs_proc_info_read (char *page, char **start, off_t off,
+		int count, int *eof, void *data)
+{
+	struct jffs_control *c = (struct jffs_control *) data;
+	int len = 0;
+
+	/* Get information on the parition */
+	len += sprintf (page,
+		"partition size:     %08lX (%u)\n"
+		"sector size:        %08lX (%u)\n"
+		"used size:          %08lX (%u)\n"
+		"dirty size:         %08lX (%u)\n"
+		"free size:          %08lX (%u)\n\n",
+		(unsigned long) c->fmc->flash_size, c->fmc->flash_size,
+		(unsigned long) c->fmc->sector_size, c->fmc->sector_size,
+		(unsigned long) c->fmc->used_size, c->fmc->used_size,
+		(unsigned long) c->fmc->dirty_size, c->fmc->dirty_size,
+		(unsigned long) (c->fmc->flash_size -
+			(c->fmc->used_size + c->fmc->dirty_size)),
+		c->fmc->flash_size - (c->fmc->used_size + c->fmc->dirty_size));
+
+	/* We're done */
+	*eof = 1;
+
+	/* Return length */
+	return len;
+}
+
+
+/*
+ * Read a JFFS partition's `layout' file
+ */
+static int jffs_proc_layout_read (char *page, char **start, off_t off,
+		int count, int *eof, void *data)
+{
+	struct jffs_control *c = (struct jffs_control *) data;
+	struct jffs_fm *fm = 0;
+	struct jffs_fm *last_fm = 0;
+	int len = 0;
+
+	/* Get the first item in the list */
+ 	fm = c->fmc->head;
+
+	/* Print free space */
+	if (fm && fm->offset) {
+		len += sprintf (page, "00000000 %08lX free\n",
+			(unsigned long) fm->offset);
+	}
+
+	/* Loop through all of the flash control structures */
+	while (fm && (len < (off + count))) {
+		if (fm->nodes) {
+			len += sprintf (page + len,
+				"%08lX %08lX ino=%08lX, ver=%08lX\n",
+				(unsigned long) fm->offset,
+				(unsigned long) fm->size,
+				(unsigned long) fm->nodes->node->ino,
+				(unsigned long) fm->nodes->node->version);
+		}
+		else {
+			len += sprintf (page + len,
+				"%08lX %08lX dirty\n",
+				(unsigned long) fm->offset,
+				(unsigned long) fm->size);
+		}
+		last_fm = fm;
+		fm = fm->next;
+	}
+
+	/* Print free space */
+	if ((len < (off + count)) && last_fm
+	    && (last_fm->offset < c->fmc->flash_size)) {
+		len += sprintf (page + len,
+			       "%08lX %08lX free\n",
+			       (unsigned long) last_fm->offset + 
+				last_fm->size,
+			       (unsigned long) (c->fmc->flash_size -
+						    (last_fm->offset + last_fm->size)));
+	}
+
+	/* We're done */
+	*eof = 1;
+
+	/* Return length */
+	return len;
+}
diff -u --recursive --new-file v2.4.10/linux/fs/jffs/jffs_proc.h linux/fs/jffs/jffs_proc.h
--- v2.4.10/linux/fs/jffs/jffs_proc.h	Wed Dec 31 16:00:00 1969
+++ linux/fs/jffs/jffs_proc.h	Thu Oct  4 15:13:18 2001
@@ -0,0 +1,28 @@
+/*
+ * JFFS -- Journaling Flash File System, Linux implementation.
+ *
+ * Copyright (C) 2000  Axis Communications AB.
+ *
+ * Created by Simon Kagstrom <simonk@axis.com>.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * $Id: jffs_proc.h,v 1.2 2000/11/15 22:04:12 sjhill Exp $
+ */
+
+/* jffs_proc.h defines a structure for inclusion in the proc-file system.  */
+#ifndef __LINUX_JFFS_PROC_H__
+#define __LINUX_JFFS_PROC_H__
+
+#include <linux/proc_fs.h>
+
+/* The proc_dir_entry for jffs (defined in jffs_proc.c).  */
+extern struct proc_dir_entry *jffs_proc_root;
+
+int jffs_register_jffs_proc_dir(kdev_t dev, struct jffs_control *c);
+int jffs_unregister_jffs_proc_dir(struct jffs_control *c);
+
+#endif /* __LINUX_JFFS_PROC_H__ */
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/Makefile linux/fs/jffs2/Makefile
--- v2.4.10/linux/fs/jffs2/Makefile	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/Makefile	Thu Oct  4 15:13:18 2001
@@ -1,7 +1,7 @@
 #
 # Makefile for the linux Journalling Flash FileSystem (JFFS) routines.
 #
-# $Id: Makefile,v 1.21 2001/03/25 22:36:12 dwmw2 Exp $
+# $Id: Makefile,v 1.25 2001/09/25 20:59:41 dwmw2 Exp $
 #
 # Note! Dependencies are done automagically by 'make dep', which also
 # removes any old dependencies. DON'T put your own dependencies here
@@ -9,16 +9,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_JFFS2_FS
-
-CC += -I$(shell pwd)/../../include
-
-obj-m := jffs2.o comprmod.o
-# We're being invoked outside a normal kernel build. Fake it
-EXTRA_CFLAGS= -DCONFIG_JFFS2_FS_DEBUG=1 -g
-endif
-
-obj-$(CONFIG_JFFS2_FS)	+= jffs2.o
 
 COMPR_OBJS	:= compr.o compr_rubin.o compr_rtime.o pushpull.o \
 			compr_zlib.o zlib.o
@@ -26,13 +16,10 @@
 	read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \
 	symlink.o build.o erase.o background.o
 
-jffs2-objs	:= $(COMPR_OBJS) $(JFFS2_OBJS)
-comprmod-objs	:= $(COMPR_OBJS) comprtest.o
+O_TARGET := jffs2.o
 
-jffs2.o: $(jffs2-objs)
-	$(LD) -r -o $@ $(jffs2-objs)
-
-comprmod.o: $(comprmod-objs)
-	$(LD) -r -o $@ $(comprmod-objs)
+obj-y := $(COMPR_OBJS) $(JFFS2_OBJS)
+obj-m := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/background.c linux/fs/jffs2/background.c
--- v2.4.10/linux/fs/jffs2/background.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/background.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: background.c,v 1.10 2001/03/15 15:38:23 dwmw2 Exp $
+ * $Id: background.c,v 1.15 2001/09/20 08:05:04 dwmw2 Exp $
  *
  */
 
@@ -43,7 +43,7 @@
 #include <linux/jffs2.h>
 #include <linux/mtd/mtd.h>
 #include <linux/interrupt.h>
-#include <linux/smp_lock.h>
+#include <linux/completion.h>
 #include "nodelist.h"
 
 
@@ -58,23 +58,28 @@
 	spin_unlock_bh(&c->erase_completion_lock);
 }
 
+/* This must only ever be called when no GC thread is currently running */
 int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
 {
 	pid_t pid;
 	int ret = 0;
-	init_MUTEX_LOCKED(&c->gc_thread_sem);
+
+	if (c->gc_task)
+		BUG();
+
+	init_MUTEX_LOCKED(&c->gc_thread_start);
 	init_completion(&c->gc_thread_exit);
-	
+
 	pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES);
 	if (pid < 0) {
 		printk(KERN_WARNING "fork failed for JFFS2 garbage collect thread: %d\n", -pid);
+		complete(&c->gc_thread_exit);
 		ret = pid;
 	} else {
 		/* Wait for it... */
 		D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
-		down(&c->gc_thread_sem);
+		down(&c->gc_thread_start);
 	}
-	up(&c->gc_thread_sem);
  
 	return ret;
 }
@@ -87,7 +92,6 @@
 		send_sig(SIGKILL, c->gc_task, 1);
 	}
 	spin_unlock_bh(&c->erase_completion_lock);
-	down(&c->gc_thread_sem);
 	wait_for_completion(&c->gc_thread_exit);
 }
 
@@ -98,7 +102,7 @@
 	daemonize();
 	current->tty = NULL;
 	c->gc_task = current;
-	up(&c->gc_thread_sem);
+	up(&c->gc_thread_start);
 
         sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index);
 
@@ -116,9 +120,8 @@
 			D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
 		}
                 
-                schedule(); /* Yes, we do this even if we want to go
-			       on immediately - we're a low priority 
-			       background task. */
+		if (current->need_resched)
+			schedule();
 
                 /* Put_super will send a SIGKILL and then wait on the sem. 
                  */
@@ -142,8 +145,7 @@
 				spin_lock_bh(&c->erase_completion_lock);
                                 c->gc_task = NULL;
 				spin_unlock_bh(&c->erase_completion_lock);
-				up(&c->gc_thread_sem);
-				complete_and_exit(&c->gc_thread_exit,0 );
+				complete_and_exit(&c->gc_thread_exit, 0);
 
 			case SIGHUP:
 				D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): SIGHUP received.\n"));
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/compr.c linux/fs/jffs2/compr.c
--- v2.4.10/linux/fs/jffs2/compr.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/compr.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: compr.c,v 1.16 2001/03/15 15:38:23 dwmw2 Exp $
+ * $Id: compr.c,v 1.17 2001/09/23 09:56:46 dwmw2 Exp $
  *
  */
 
@@ -77,18 +77,19 @@
 	if (!ret) {
 		return JFFS2_COMPR_ZLIB;
 	}
-
+#if 0 /* Disabled 23/9/1. With zlib it hardly ever gets a look in */
 	ret = dynrubin_compress(data_in, cpage_out, datalen, cdatalen);
 	if (!ret) {
 		return JFFS2_COMPR_DYNRUBIN;
 	}
-
-#if 0 /* Phase this one out */
+#endif
+#if 0 /* Disabled 26/2/1. Obsoleted by dynrubin */
 	ret = rubinmips_compress(data_in, cpage_out, datalen, cdatalen);
 	if (!ret) {
 		return JFFS2_COMPR_RUBINMIPS;
 	}
 #endif
+	/* rtime does manage to recompress already-compressed data */
 	ret = rtime_compress(data_in, cpage_out, datalen, cdatalen);
 	if (!ret) {
 		return JFFS2_COMPR_RTIME;
@@ -126,13 +127,20 @@
 	case JFFS2_COMPR_RTIME:
 		rtime_decompress(cdata_in, data_out, cdatalen, datalen);
 		break;
-#if 1 /* Phase this one out */
+
 	case JFFS2_COMPR_RUBINMIPS:
+#if 0 /* Disabled 23/9/1 */
 		rubinmips_decompress(cdata_in, data_out, cdatalen, datalen);
-		break;
+#else
+		printk(KERN_WARNING "JFFS2: Rubinmips compression encountered but support not compiled in!\n");
 #endif
+		break;
 	case JFFS2_COMPR_DYNRUBIN:
+#if 1 /* Phase this one out */
 		dynrubin_decompress(cdata_in, data_out, cdatalen, datalen);
+#else
+		printk(KERN_WARNING "JFFS2: Dynrubin compression encountered but support not compiled in!\n");
+#endif
 		break;
 
 	default:
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/compr_rubin.c linux/fs/jffs2/compr_rubin.c
--- v2.4.10/linux/fs/jffs2/compr_rubin.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/compr_rubin.c	Thu Oct  4 15:13:18 2001
@@ -31,12 +31,13 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: compr_rubin.c,v 1.11 2001/03/21 16:20:48 dwmw2 Exp $
+ * $Id: compr_rubin.c,v 1.13 2001/09/23 10:06:05 rmk Exp $
  *
  */
 
  
 #include <linux/string.h>
+#include <linux/types.h>
 #include "compr_rubin.h"
 #include "histo_mips.h"
 
@@ -114,26 +115,51 @@
 		;
 }
 
-
+static void __do_decode(struct rubin_state *rs, unsigned long p, unsigned long q)
+{
+	register unsigned long lower_bits_rubin = LOWER_BITS_RUBIN;
+	unsigned long rec_q;
+	int c, bits = 0;
+
+	/*
+	 * First, work out how many bits we need from the input stream.
+	 * Note that we have already done the initial check on this
+	 * loop prior to calling this function.
+	 */
+	do {
+		bits++;
+		q &= lower_bits_rubin;
+		q <<= 1;
+		p <<= 1;
+	} while ((q >= UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN));
+
+	rs->p = p;
+	rs->q = q;
+
+	rs->bit_number += bits;
+
+	/*
+	 * Now get the bits.  We really want this to be "get n bits".
+	 */
+	rec_q = rs->rec_q;
+	do {
+		c = pullbit(&rs->pp);
+		rec_q &= lower_bits_rubin;
+		rec_q <<= 1;
+		rec_q += c;
+	} while (--bits);
+	rs->rec_q = rec_q;
+}
 
 int decode(struct rubin_state *rs, long A, long B)
 {
-
-	char c;
-	long i0, i1, threshold;
+	unsigned long p = rs->p, q = rs->q;
+	long i0, threshold;
 	int symbol;
-	
 
-	while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) {
-		c = pullbit(&rs->pp);
-		rs->bit_number++;
-		rs->q &= LOWER_BITS_RUBIN;
-		rs->q <<= 1;
-		rs->p <<= 1;
-		rs->rec_q &= LOWER_BITS_RUBIN;
-		rs->rec_q <<= 1;
-		rs->rec_q += c;
-	};
+	if (q >= UPPER_BIT_RUBIN || ((p + q) <= UPPER_BIT_RUBIN))
+		__do_decode(rs, p, q);
+
 	i0 = A * rs->p / (A + B);
 	if (i0 <= 0) {
 		i0 = 1;
@@ -141,19 +167,16 @@
 	if (i0 >= rs->p) {
 		i0 = rs->p - 1;
 	}
-	i1 = rs->p - i0;
-
 
 	threshold = rs->q + i0;
-	if (rs->rec_q < threshold) {
-		symbol = 0;
-		rs->p = i0;
-	} else {
-		symbol = 1;
-		rs->p = i1;
+	symbol = rs->rec_q >= threshold;
+	if (rs->rec_q >= threshold) {
 		rs->q += i0;
+		i0 = rs->p - i0;
 	}
-	
+
+	rs->p = i0;
+
 	return symbol;
 }
 
@@ -179,11 +202,11 @@
 
 static int in_byte(struct rubin_state *rs)
 {
-	int i;
-	int result=0;
-	for (i=0;i<8;i++) {
-		result |=  decode(rs, rs->bit_divider-rs->bits[i],rs->bits[i])<<i;
-	}
+	int i, result = 0, bit_divider = rs->bit_divider;
+
+	for (i = 0; i < 8; i++)
+		result |= decode(rs, bit_divider - rs->bits[i], rs->bits[i]) << i;
+
 	return result;
 }
 
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/compr_zlib.c linux/fs/jffs2/compr_zlib.c
--- v2.4.10/linux/fs/jffs2/compr_zlib.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/compr_zlib.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: compr_zlib.c,v 1.6 2001/04/18 15:04:00 dwmw2 Exp $
+ * $Id: compr_zlib.c,v 1.8 2001/09/20 15:28:31 dwmw2 Exp $
  *
  */
 
@@ -39,6 +39,7 @@
 
 #ifdef __KERNEL__
 #include <linux/kernel.h>
+#include <linux/mtd/compatmac.h> /* for min() */
 #include <linux/slab.h>
 #include <linux/jffs2.h>
 #include "nodelist.h"
@@ -104,7 +105,7 @@
 
 	while (strm.total_out < *dstlen - STREAM_END_SPACE && strm.total_in < *sourcelen) {
 		strm.avail_out = *dstlen - (strm.total_out + STREAM_END_SPACE);
-		strm.avail_in = min(*sourcelen-strm.total_in, strm.avail_out);
+		strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out);
 		D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
 			  strm.avail_in, strm.avail_out));
 		ret = deflate(&strm, Z_PARTIAL_FLUSH);
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/erase.c linux/fs/jffs2/erase.c
--- v2.4.10/linux/fs/jffs2/erase.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/erase.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: erase.c,v 1.19 2001/03/25 22:36:12 dwmw2 Exp $
+ * $Id: erase.c,v 1.23 2001/09/19 21:51:11 dwmw2 Exp $
  *
  */
 #include <linux/kernel.h>
@@ -93,7 +93,10 @@
 		return;
 	}
 
-	printk(KERN_WARNING "Erase at 0x%08x failed immediately: %d\n", jeb->offset, ret);
+	if (ret == -EROFS) 
+		printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset);
+	else
+		printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret);
 	spin_lock_bh(&c->erase_completion_lock);
 	list_del(&jeb->list);
 	list_add(&jeb->list, &c->bad_list);
@@ -152,7 +155,7 @@
 		spin_unlock(&priv->c->erase_completion_lock);
 		wake_up(&priv->c->erase_wait);
 	} else {
-		D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08lx\n", instr->addr));
+		D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", instr->addr));
 		spin_lock(&priv->c->erase_completion_lock);
 		list_del(&priv->jeb->list);
 		list_add_tail(&priv->jeb->list, &priv->c->erase_complete_list);
@@ -165,48 +168,72 @@
 
 /* Hmmm. Maybe we should accept the extra space it takes and make
    this a standard doubly-linked list? */
-static inline void jffs2_remove_node_ref_from_ino_list(struct jffs2_sb_info *sbinfo, struct jffs2_raw_node_ref *ref)
+static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
+			struct jffs2_raw_node_ref *ref, struct jffs2_eraseblock *jeb)
 {
-	struct jffs2_inode_cache *ic;
-	struct jffs2_raw_node_ref **prev, *this;
-	D2(int c=0);
+	struct jffs2_inode_cache *ic = NULL;
+	struct jffs2_raw_node_ref **prev;
 
-	this = ref;
-	while(this->next_in_ino)
-		 this = this->next_in_ino;
+	prev = &ref->next_in_ino;
 
-	ic = (struct jffs2_inode_cache *)this;
+	/* Walk the inode's list once, removing any nodes from this eraseblock */
+	while (1) {
+		if (!(*prev)->next_in_ino) {
+			/* We're looking at the jffs2_inode_cache, which is 
+			   at the end of the linked list. Stash it and continue
+			   from the beginning of the list */
+			ic = (struct jffs2_inode_cache *)(*prev);
+			prev = &ic->nodes;
+			continue;
+		} 
+
+		if (((*prev)->flash_offset & ~(c->sector_size -1)) == jeb->offset) {
+			/* It's in the block we're erasing */
+			struct jffs2_raw_node_ref *this;
+
+			this = *prev;
+			*prev = this->next_in_ino;
+			this->next_in_ino = NULL;
 
-	D1(printk(KERN_DEBUG "Removing node at phys 0x%08x from ino #%u\n", ref->flash_offset &~3, ic->ino));
+			if (this == ref)
+				break;
 
-	prev = &ic->nodes;
-	if (!*prev) {
-		printk(KERN_WARNING "Eep. ic->nodes == NULL.\n");
-		return;
-	}
-	while (*prev != ref) {
-		if (!(*prev)->next_in_ino) {
-		        printk(KERN_WARNING "Eep. node at phys 0x%08x, mem %p. next_in_ino is NULL.\n", (*prev)->flash_offset &~3, 
-			       *prev);
-			return;
+			continue;
 		}
-		prev = &(*prev)->next_in_ino;
+		/* Not to be deleted. Skip */
+		prev = &((*prev)->next_in_ino);
 	}
-	*prev = ref->next_in_ino;
-	this = ic->nodes;
-	D2(printk(KERN_DEBUG "After remove_node_ref_from_ino_list: \n" KERN_DEBUG);
-	while(this) {
-		printk( "0x%08x(%d)->", this->flash_offset & ~3, this->flash_offset &3);
-		if (++c == 5) {
-			printk("\n" KERN_DEBUG);
-			c=0;
-		}
-		this = this->next_in_ino;
+
+	/* PARANOIA */
+	if (!ic) {
+		printk(KERN_WARNING "inode_cache not found in remove_node_refs()!!\n");
+		return;
 	}
-	printk("\n"););
+
+	D1(printk(KERN_DEBUG "Removed nodes in range 0x%08x-0x%08x from ino #%u\n",
+		  jeb->offset, jeb->offset + c->sector_size, ic->ino));
+
+	D2({
+		int i=0;
+        struct jffs2_raw_node_ref *this;		
+        printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG);
+
+		this = ic->nodes;
+	   
+		while(this) {
+			printk( "0x%08x(%d)->", this->flash_offset & ~3, this->flash_offset &3);
+			if (++i == 5) {
+				printk("\n" KERN_DEBUG);
+				i=0;
+			}
+			this = this->next_in_ino;
+		}
+		printk("\n");
+	});
+
 	if (ic->nodes == (void *)ic) {
 		D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
-		jffs2_del_ino_cache(sbinfo, ic);
+		jffs2_del_ino_cache(c, ic);
 		jffs2_free_inode_cache(ic);
 	}
 }
@@ -221,8 +248,8 @@
 		
 		/* Remove from the inode-list */
 		if (ref->next_in_ino)
-			jffs2_remove_node_ref_from_ino_list(c, ref);
-		/* else it was a non-inode node so don't bother */
+			jffs2_remove_node_refs_from_ino_list(c, ref, jeb);
+		/* else it was a non-inode node or already removed, so don't bother */
 
 		jffs2_free_raw_node_ref(ref);
 	}
@@ -267,7 +294,7 @@
 
 			D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));
 			while(ofs < jeb->offset + c->sector_size) {
-				__u32 readlen = min(PAGE_SIZE, jeb->offset + c->sector_size - ofs);
+				__u32 readlen = min((__u32)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
 				int i;
 
 				ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/file.c linux/fs/jffs2/file.c
--- v2.4.10/linux/fs/jffs2/file.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/file.c	Thu Oct  4 15:13:18 2001
@@ -31,11 +31,12 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: file.c,v 1.55 2001/05/29 09:19:24 dwmw2 Exp $
+ * $Id: file.c,v 1.58 2001/09/20 15:28:31 dwmw2 Exp $
  *
  */
 
 #include <linux/kernel.h>
+#include <linux/mtd/compatmac.h> /* for min() */
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
@@ -44,6 +45,7 @@
 #include "crc32.h"
 
 extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
+extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) __attribute__((weak));
 
 
 int jffs2_null_fsync(struct file *filp, struct dentry *dentry, int datasync)
@@ -360,7 +362,7 @@
 		ri.mode = inode->i_mode;
 		ri.uid = inode->i_uid;
 		ri.gid = inode->i_gid;
-		ri.isize = max(inode->i_size, pageofs);
+		ri.isize = max((__u32)inode->i_size, pageofs);
 		ri.atime = ri.ctime = ri.mtime = CURRENT_TIME;
 		ri.offset = inode->i_size;
 		ri.dsize = pageofs - inode->i_size;
@@ -409,9 +411,9 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-	ssize_t newsize = max(filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end);
+	__u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end);
 	__u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT);
-	unsigned writelen = min(PAGE_CACHE_SIZE, newsize - file_ofs);
+	__u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs);
 	struct jffs2_raw_inode *ri;
 	int ret = 0;
 	ssize_t writtenlen = 0;
@@ -467,7 +469,7 @@
 		ri->mode = inode->i_mode;
 		ri->uid = inode->i_uid;
 		ri->gid = inode->i_gid;
-		ri->isize = max(inode->i_size, file_ofs + datalen);
+		ri->isize = max((__u32)inode->i_size, file_ofs + datalen);
 		ri->atime = ri->ctime = ri->mtime = CURRENT_TIME;
 		ri->offset = file_ofs;
 		ri->csize = cdatalen;
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/gc.c linux/fs/jffs2/gc.c
--- v2.4.10/linux/fs/jffs2/gc.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/gc.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: gc.c,v 1.51 2001/05/24 22:24:39 dwmw2 Exp $
+ * $Id: gc.c,v 1.52 2001/09/19 21:53:47 dwmw2 Exp $
  *
  */
 
@@ -562,7 +562,7 @@
 		/* Shitloads of space */
 		/* FIXME: Integrate this properly with GC calculations */
 		start &= ~(PAGE_CACHE_SIZE-1);
-		end = min(start + PAGE_CACHE_SIZE, inode->i_size);
+		end = min_t(__u32, start + PAGE_CACHE_SIZE, inode->i_size);
 		D1(printk(KERN_DEBUG "Plenty of free space, so expanding to write from offset 0x%x to 0x%x\n",
 			  start, end));
 		if (end < orig_end) {
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/nodelist.c linux/fs/jffs2/nodelist.c
--- v2.4.10/linux/fs/jffs2/nodelist.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/nodelist.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: nodelist.c,v 1.28 2001/03/27 06:20:04 dwmw2 Exp $
+ * $Id: nodelist.c,v 1.29 2001/09/19 00:06:35 dwmw2 Exp $
  *
  */
 
@@ -177,7 +177,7 @@
 				   dirent we've already read from the flash
 				*/
 			if (retlen > sizeof(struct jffs2_raw_dirent))
-				memcpy(&fd->name[0], &node.d.name[0], min(node.d.nsize, retlen-sizeof(struct jffs2_raw_dirent)));
+				memcpy(&fd->name[0], &node.d.name[0], min((__u32)node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
 				
 				/* Do we need to copy any more of the name directly
 				   from the flash?
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/nodelist.h linux/fs/jffs2/nodelist.h
--- v2.4.10/linux/fs/jffs2/nodelist.h	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/nodelist.h	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: nodelist.h,v 1.45 2001/03/20 17:43:57 dwmw2 Exp $
+ * $Id: nodelist.h,v 1.46 2001/09/18 23:43:05 dwmw2 Exp $
  *
  */
 
@@ -232,10 +232,6 @@
 
 
 #define PAD(x) (((x)+3)&~3)
-
-/* These probably ought to be somewhere central. */
-//#define min(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_y:_x; })
-//#define max(x,y) ({ typeof((x)) _x = (x); typeof((y)) _y = (y); (_x>_y)?_x:_y; })
 
 static inline int jffs2_raw_ref_to_inum(struct jffs2_raw_node_ref *raw)
 {
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/nodemgmt.c linux/fs/jffs2/nodemgmt.c
--- v2.4.10/linux/fs/jffs2/nodemgmt.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/nodemgmt.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: nodemgmt.c,v 1.39 2001/04/11 22:20:26 dwmw2 Exp $
+ * $Id: nodemgmt.c,v 1.45 2001/09/20 08:05:05 dwmw2 Exp $
  *
  */
 
@@ -100,12 +100,13 @@
 			ret = jffs2_garbage_collect_pass(c);
 			if (ret)
 				return ret;
-			if (signal_pending(current)) {
-				return -EINTR;
-			}
-			if(current->need_resched) {
+
+			if (current->need_resched)
 				schedule();
-			}
+
+			if (signal_pending(current))
+				return -EINTR;
+
 			down(&c->alloc_sem);
 			spin_lock_bh(&c->erase_completion_lock);
 		}
@@ -347,6 +348,8 @@
 	spin_unlock_bh(&c->erase_completion_lock);
 
 	if (c->mtd->type != MTD_NORFLASH && c->mtd->type != MTD_RAM)
+		return;
+	if (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
 		return;
 
 	D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref->flash_offset &~3));
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/pushpull.c linux/fs/jffs2/pushpull.c
--- v2.4.10/linux/fs/jffs2/pushpull.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/pushpull.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: pushpull.c,v 1.6 2001/03/15 15:38:24 dwmw2 Exp $
+ * $Id: pushpull.c,v 1.7 2001/09/23 10:04:15 rmk Exp $
  *
  */
 
@@ -69,20 +69,3 @@
 {
 	return pp->ofs;
 }
-	
-
-int pullbit(struct pushpull *pp)
-{
-	int bit;
-
-	bit = (pp->buf[pp->ofs >> 3] >> (7-(pp->ofs & 7))) & 1;
-
-	pp->ofs++;
-	return bit;
-}
-
-int pulledbits (struct pushpull *pp)
-{
-	return pp->ofs;
-}
-     
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/pushpull.h linux/fs/jffs2/pushpull.h
--- v2.4.10/linux/fs/jffs2/pushpull.h	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/pushpull.h	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: pushpull.h,v 1.4 2001/03/15 15:38:24 dwmw2 Exp $
+ * $Id: pushpull.h,v 1.5 2001/09/23 10:04:15 rmk Exp $
  *
  */
 
@@ -47,7 +47,20 @@
 void init_pushpull(struct pushpull *, char *, unsigned, unsigned, unsigned);
 int pushbit(struct pushpull *pp, int bit, int use_reserved);
 int pushedbits(struct pushpull *pp);
-int pullbit(struct pushpull *pp);
-int pulledbits(struct pushpull *);
+
+static inline int pullbit(struct pushpull *pp)
+{
+	int bit;
+
+	bit = (pp->buf[pp->ofs >> 3] >> (7-(pp->ofs & 7))) & 1;
+
+	pp->ofs++;
+	return bit;
+}
+
+static inline int pulledbits(struct pushpull *pp)
+{
+	return pp->ofs;
+}
 
 #endif /* __PUSHPULL_H__ */
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/scan.c linux/fs/jffs2/scan.c
--- v2.4.10/linux/fs/jffs2/scan.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/scan.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: scan.c,v 1.44 2001/04/13 00:46:41 nico Exp $
+ * $Id: scan.c,v 1.51 2001/09/19 00:06:35 dwmw2 Exp $
  *
  */
 #include <linux/kernel.h>
@@ -76,6 +76,8 @@
 int jffs2_scan_medium(struct jffs2_sb_info *c)
 {
 	int i, ret;
+	__u32 empty_blocks = 0;
+
 	if (!c->blocks) {
 		printk(KERN_WARNING "EEEK! c->blocks is NULL!\n");
 		return -EINVAL;
@@ -84,13 +86,24 @@
 		struct jffs2_eraseblock *jeb = &c->blocks[i];
 
 		ret = jffs2_scan_eraseblock(c, jeb);
-		if (ret)
+		if (ret < 0)
 			return ret;
 
 		ACCT_PARANOIA_CHECK(jeb);
 
-		   /* Now decide which list to put it on */
-		if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
+		/* Now decide which list to put it on */
+		if (ret == 1) {
+			/* 
+			 * Empty block.   Since we can't be sure it 
+			 * was entirely erased, we just queue it for erase
+			 * again.  It will be marked as such when the erase
+			 * is complete.  Meanwhile we still count it as empty
+			 * for later checks.
+			 */
+			list_add(&jeb->list, &c->erase_pending_list);
+			empty_blocks++;
+			c->nr_erasing_blocks++;
+		} else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
 			/* Only a CLEANMARKER node is valid */
 			if (!jeb->dirty_size) {
 				/* It's actually free */
@@ -127,11 +140,15 @@
 			printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset);
                         list_add(&jeb->list, &c->erase_pending_list);
 			c->nr_erasing_blocks++;
-                }
-        }
-	if (c->nr_erasing_blocks)
+		}
+	}
+	if (c->nr_erasing_blocks) {
+		if (!c->used_size && empty_blocks != c->nr_blocks) {
+			printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
+			return -EIO;
+		}
 		jffs2_erase_pending_trigger(c);
-
+	}
 	return 0;
 }
 
@@ -140,13 +157,22 @@
 	__u32 ofs, prevofs;
 	__u32 hdr_crc, nodetype;
 	int err;
-	int noise = 10;
+	int noise = 0;
 
 	ofs = jeb->offset;
 	prevofs = jeb->offset - 1;
 
 	D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
 
+	err = jffs2_scan_empty(c, jeb, &ofs, &noise);
+	if (err) return err;
+	if (ofs == jeb->offset + c->sector_size) {
+		D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
+		return 1;	/* special return code */
+	}
+	
+	noise = 10;
+
 	while(ofs < jeb->offset + c->sector_size) {
 		ssize_t retlen;
 		ACCT_PARANOIA_CHECK(jeb);
@@ -272,6 +298,8 @@
 			case JFFS2_FEATURE_ROCOMPAT:
 				printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
 			        c->flags |= JFFS2_SB_FLAG_RO;
+				if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY))
+					return -EROFS;
 				DIRTY_SPACE(PAD(node.totlen));
 				ofs += PAD(node.totlen);
 				continue;
@@ -306,7 +334,7 @@
 	__u32 scanlen = (jeb->offset + c->sector_size) - *startofs;
 	__u32 curofs = *startofs;
 	
-	buf = kmalloc(min(PAGE_SIZE, scanlen), GFP_KERNEL);
+	buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL);
 	if (!buf) {
 		printk(KERN_WARNING "Scan buffer allocation failed\n");
 		return -ENOMEM;
@@ -315,9 +343,9 @@
 		ssize_t retlen;
 		int ret, i;
 		
-		ret = c->mtd->read(c->mtd, curofs, min(PAGE_SIZE, scanlen), &retlen, (char *)buf);
+		ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf);
 		if(ret) {
-			D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%lx bytes at 0x%08x returned %d\n", min(PAGE_SIZE, scanlen), curofs, ret));
+			D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret));
 			kfree(buf);
 			return ret;
 		}
@@ -606,6 +634,8 @@
 	if (crc != rd.name_crc) {
 		printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
 		       *ofs, rd.name_crc, crc);	
+		fd->name[rd.nsize]=0;
+		D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));
 		jffs2_free_full_dirent(fd);
 		/* FIXME: Why do we believe totlen? */
 		DIRTY_SPACE(PAD(rd.totlen));
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/super.c linux/fs/jffs2/super.c
--- v2.4.10/linux/fs/jffs2/super.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/super.c	Thu Oct  4 15:14:35 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: super.c,v 1.43 2001/05/29 08:59:47 dwmw2 Exp $
+ * $Id: super.c,v 1.48 2001/10/02 09:16:23 dwmw2 Exp $
  *
  */
 
@@ -47,7 +47,6 @@
 #include <linux/pagemap.h>
 #include <linux/mtd/mtd.h>
 #include <linux/interrupt.h>
-
 #include "nodelist.h"
 
 #ifndef MTD_BLOCK_MAJOR
@@ -68,7 +67,7 @@
 	put_super:	jffs2_put_super,
 	write_super:	jffs2_write_super,
 	statfs:		jffs2_statfs,
-//	remount_fs:	jffs2_remount_fs,
+	remount_fs:	jffs2_remount_fs,
 	clear_inode:	jffs2_clear_inode
 };
 
@@ -270,7 +269,8 @@
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = JFFS2_SUPER_MAGIC;
-	jffs2_start_garbage_collect_thread(c);
+	if (!(sb->s_flags & MS_RDONLY))
+		jffs2_start_garbage_collect_thread(c);
 	return sb;
 
  out_root_i:
@@ -290,19 +290,47 @@
 
 	D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
 
-	jffs2_stop_garbage_collect_thread(c);
+	if (!(sb->s_flags & MS_RDONLY))
+		jffs2_stop_garbage_collect_thread(c);
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
 	kfree(c->blocks);
+	if (c->mtd->sync)
+		c->mtd->sync(c->mtd);
 	put_mtd_device(c->mtd);
 	
 	D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
 }
 
+int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
+{
+	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+
+	if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
+		return -EROFS;
+
+	/* We stop if it was running, then restart if it needs to.
+	   This also catches the case where it was stopped and this
+	   is just a remount to restart it */
+	if (!(sb->s_flags & MS_RDONLY))
+		jffs2_stop_garbage_collect_thread(c);
+
+	if (!(*flags & MS_RDONLY))
+		jffs2_start_garbage_collect_thread(c);
+	
+	sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY);
+
+	return 0;
+}
+
 void jffs2_write_super (struct super_block *sb)
 {
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
 	sb->s_dirt = 0;
+
+	if (sb->s_flags & MS_RDONLY)
+		return;
+
 	jffs2_garbage_collect_trigger(c);
 	jffs2_erase_pending_blocks(c);
 	jffs2_mark_erased_blocks(c);
@@ -353,3 +381,8 @@
 
 module_init(init_jffs2_fs);
 module_exit(exit_jffs2_fs);
+
+MODULE_DESCRIPTION("The Journalling Flash File System, v2");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for 
+		       // the sake of this tag. It's Free Software.
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/write.c linux/fs/jffs2/write.c
--- v2.4.10/linux/fs/jffs2/write.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/jffs2/write.c	Thu Oct  4 15:13:18 2001
@@ -31,7 +31,7 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: write.c,v 1.27 2001/04/11 15:29:34 dwmw2 Exp $
+ * $Id: write.c,v 1.28 2001/05/01 16:25:25 dwmw2 Exp $
  *
  */
 
@@ -255,7 +255,7 @@
 	struct iovec vecs[2];
 	int ret;
 
-	D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name \"%s\"->ino #%u\n", rd->pino, name, rd->ino));
+	D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", rd->pino, name, name, rd->ino, rd->name_crc));
 	writecheck(c->mtd, flash_ofs);
 
 	D1(if(rd->hdr_crc != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/clntlock.c linux/fs/lockd/clntlock.c
--- v2.4.10/linux/fs/lockd/clntlock.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/lockd/clntlock.c	Mon Oct  1 13:45:47 2001
@@ -8,6 +8,7 @@
 
 #define __KERNEL_SYSCALLS__
 
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/nfs_fs.h>
@@ -17,7 +18,7 @@
 #include <linux/lockd/lockd.h>
 #include <linux/smp_lock.h>
 
-#define NLMDBG_FACILITY		NLMDBG_CIENT
+#define NLMDBG_FACILITY		NLMDBG_CLIENT
 
 /*
  * Local function prototypes
@@ -131,29 +132,63 @@
  */
 
 /*
+ * Mark the locks for reclaiming.
+ * FIXME: In 2.5 we don't want to iterate through any global file_lock_list.
+ *        Maintain NLM lock reclaiming lists in the nlm_host instead.
+ */
+static
+void nlmclnt_mark_reclaim(struct nlm_host *host)
+{
+	struct file_lock *fl;
+	struct inode *inode;
+	struct list_head *tmp;
+
+	list_for_each(tmp, &file_lock_list) {
+		fl = list_entry(tmp, struct file_lock, fl_link);
+
+		inode = fl->fl_file->f_dentry->d_inode;
+		if (inode->i_sb->s_magic != NFS_SUPER_MAGIC)
+			continue;
+		if (fl->fl_u.nfs_fl.host != host)
+			continue;
+		if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED))
+			continue;
+		fl->fl_u.nfs_fl.flags |= NFS_LCK_RECLAIM;
+	}
+}
+
+/*
+ * Someone has sent us an SM_NOTIFY. Ensure we bind to the new port number,
+ * that we mark locks for reclaiming, and that we bump the pseudo NSM state.
+ */
+static inline
+void nlmclnt_prepare_reclaim(struct nlm_host *host, u32 newstate)
+{
+	host->h_monitored = 0;
+	host->h_nsmstate = newstate;
+	host->h_state++;
+	host->h_nextrebind = 0;
+	nlm_rebind_host(host);
+	nlmclnt_mark_reclaim(host);
+	dprintk("NLM: reclaiming locks for host %s", host->h_name);
+}
+
+/*
  * Reclaim all locks on server host. We do this by spawning a separate
  * reclaimer thread.
- * FIXME: should bump MOD_USE_COUNT while reclaiming
  */
 void
 nlmclnt_recovery(struct nlm_host *host, u32 newstate)
 {
-	if (!host->h_reclaiming++) {
+	if (host->h_reclaiming++) {
 		if (host->h_nsmstate == newstate)
 			return;
-		printk(KERN_WARNING
-			"lockd: Uh-oh! Interfering reclaims for host %s",
-			host->h_name);
-		host->h_monitored = 0;
-		host->h_nsmstate = newstate;
-		host->h_state++;
-		nlm_release_host(host);
+		nlmclnt_prepare_reclaim(host, newstate);
 	} else {
-		host->h_monitored = 0;
-		host->h_nsmstate = newstate;
-		host->h_state++;
+		nlmclnt_prepare_reclaim(host, newstate);
 		nlm_get_host(host);
-		kernel_thread(reclaimer, host, 0);
+		MOD_INC_USE_COUNT;
+		kernel_thread(reclaimer, host, CLONE_SIGNAL);
 	}
 }
 
@@ -163,32 +198,38 @@
 	struct nlm_host	  *host = (struct nlm_host *) ptr;
 	struct nlm_wait	  *block;
 	struct list_head *tmp;
+	struct file_lock *fl;
+	struct inode *inode;
 
+	daemonize();
 	reparent_to_init();
 	snprintf(current->comm, sizeof(current->comm),
 		 "%s-reclaim",
 		 host->h_name);
-	
+
 	/* This one ensures that our parent doesn't terminate while the
 	 * reclaim is in progress */
 	lock_kernel();
 	lockd_up();
 
-	/* First, reclaim all locks that have been granted previously. */
+	/* First, reclaim all locks that have been marked. */
 restart:
-	tmp = file_lock_list.next;
-	while (tmp != &file_lock_list) {
-		struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
-		struct inode *inode = fl->fl_file->f_dentry->d_inode;
-		if (inode->i_sb->s_magic == NFS_SUPER_MAGIC &&
-				nlm_cmp_addr(NFS_ADDR(inode), &host->h_addr) &&
-				fl->fl_u.nfs_fl.state != host->h_state &&
-				(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED)) {
-			fl->fl_u.nfs_fl.flags &= ~ NFS_LCK_GRANTED;
-			nlmclnt_reclaim(host, fl);	/* This sleeps */
-			goto restart;
-		}
-		tmp = tmp->next;
+	list_for_each(tmp, &file_lock_list) {
+		fl = list_entry(tmp, struct file_lock, fl_link);
+
+		inode = fl->fl_file->f_dentry->d_inode;
+		if (inode->i_sb->s_magic != NFS_SUPER_MAGIC)
+			continue;
+		if (fl->fl_u.nfs_fl.host != host)
+			continue;
+		if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_RECLAIM))
+			continue;
+
+		fl->fl_u.nfs_fl.flags &= ~NFS_LCK_RECLAIM;
+		nlmclnt_reclaim(host, fl);
+		if (signalled())
+			break;
+		goto restart;
 	}
 
 	host->h_reclaiming = 0;
@@ -206,6 +247,7 @@
 	nlm_release_host(host);
 	lockd_down();
 	unlock_kernel();
+	MOD_DEC_USE_COUNT;
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/clntproc.c linux/fs/lockd/clntproc.c
--- v2.4.10/linux/fs/lockd/clntproc.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/lockd/clntproc.c	Mon Oct  8 12:36:07 2001
@@ -18,6 +18,7 @@
 #include <linux/lockd/sm_inter.h>
 
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
+#define NLMCLNT_GRACE_WAIT	(5*HZ)
 
 static int	nlmclnt_test(struct nlm_rqst *, struct file_lock *);
 static int	nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
@@ -557,19 +558,22 @@
 
 	if (task->tk_status < 0) {
 		dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status);
-		goto retry_unlock;
+		goto retry_rebind;
 	}
-	if (status != NLM_LCK_GRANTED
-	 && status != NLM_LCK_DENIED_GRACE_PERIOD) {
-		printk("lockd: unexpected unlock status: %d\n", status);
+	if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
+		rpc_delay(task, NLMCLNT_GRACE_WAIT);
+		goto retry_unlock;
 	}
+	if (status != NLM_LCK_GRANTED)
+		printk(KERN_WARNING "lockd: unexpected unlock status: %d\n", status);
 
 die:
 	nlm_release_host(req->a_host);
 	kfree(req);
 	return;
- retry_unlock:
+ retry_rebind:
 	nlm_rebind_host(req->a_host);
+ retry_unlock:
 	rpc_restart_call(task);
 }
 
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/host.c linux/fs/lockd/host.c
--- v2.4.10/linux/fs/lockd/host.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/lockd/host.c	Mon Oct  1 13:45:47 2001
@@ -51,7 +51,8 @@
 struct nlm_host *
 nlmsvc_lookup_host(struct svc_rqst *rqstp)
 {
-	return nlm_lookup_host(rqstp->rq_client, &rqstp->rq_addr, 0, 0);
+	return nlm_lookup_host(rqstp->rq_client, &rqstp->rq_addr,
+			       rqstp->rq_prot, rqstp->rq_vers);
 }
 
 /*
@@ -97,7 +98,9 @@
 		nlm_gc_hosts();
 
 	for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) {
-		if (host->h_version != version || host->h_proto != proto)
+		if (proto && host->h_proto != proto)
+			continue;
+		if (version && host->h_version != version)
 			continue;
 
 		if (nlm_match_host(host, clnt, sin)) {
@@ -325,7 +328,8 @@
 			}
 			dprintk("lockd: delete host %s\n", host->h_name);
 			*q = host->h_next;
-			if (host->h_monitored)
+			/* Don't unmonitor hosts that have been invalidated */
+			if (host->h_monitored && !host->h_killed)
 				nsm_unmonitor(host);
 			if ((clnt = host->h_rpcclnt) != NULL) {
 				if (atomic_read(&clnt->cl_users)) {
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/lockd_syms.c linux/fs/lockd/lockd_syms.c
--- v2.4.10/linux/fs/lockd/lockd_syms.c	Thu Mar  9 06:57:08 2000
+++ linux/fs/lockd/lockd_syms.c	Mon Oct  1 13:45:47 2001
@@ -35,8 +35,4 @@
 EXPORT_SYMBOL(nlmsvc_invalidate_client);
 EXPORT_SYMBOL(nlmsvc_ops);
 
-/* Configuration at insmod time */
-EXPORT_SYMBOL(nlmsvc_grace_period);
-EXPORT_SYMBOL(nlmsvc_timeout);
-
 #endif /* CONFIG_MODULES */
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/mon.c linux/fs/lockd/mon.c
--- v2.4.10/linux/fs/lockd/mon.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/lockd/mon.c	Mon Oct  1 13:45:47 2001
@@ -43,7 +43,7 @@
 
 	args.addr = host->h_addr.sin_addr.s_addr;
 	args.prog = NLM_PROGRAM;
-	args.vers = 1;
+	args.vers = host->h_version;
 	args.proc = NLMPROC_NSM_NOTIFY;
 	memset(res, 0, sizeof(*res));
 
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/svc.c linux/fs/lockd/svc.c
--- v2.4.10/linux/fs/lockd/svc.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/lockd/svc.c	Wed Oct  3 22:27:48 2001
@@ -15,6 +15,7 @@
 #define __KERNEL_SYSCALLS__
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/init.h>
 
 #include <linux/sched.h>
 #include <linux/errno.h>
@@ -43,7 +44,7 @@
 static DECLARE_MUTEX(nlmsvc_sema);
 static unsigned int		nlmsvc_users;
 static pid_t			nlmsvc_pid;
-unsigned long			nlmsvc_grace_period;
+int				nlmsvc_grace_period;
 unsigned long			nlmsvc_timeout;
 
 static DECLARE_MUTEX_LOCKED(lockd_start);
@@ -55,6 +56,26 @@
  */
 unsigned long			nlm_grace_period;
 unsigned long			nlm_timeout = LOCKD_DFLT_TIMEO;
+unsigned long			nlm_udpport, nlm_tcpport;
+
+static unsigned long set_grace_period(void)
+{
+	unsigned long grace_period;
+
+	/* Note: nlm_timeout should always be nonzero */
+	if (nlm_grace_period)
+		grace_period = ((nlm_grace_period + nlm_timeout - 1)
+				/ nlm_timeout) * nlm_timeout * HZ;
+	else
+		grace_period = nlm_timeout * 5 * HZ;
+	nlmsvc_grace_period = 1;
+	return grace_period + jiffies;
+}
+
+static inline void clear_grace_period(void)
+{
+	nlmsvc_grace_period = 0;
+}
 
 /*
  * This is the lockd kernel thread
@@ -84,7 +105,7 @@
 	spin_lock_irq(&current->sigmask_lock);
 	siginitsetinv(&current->blocked, sigmask(SIGKILL));
 	recalc_sigpending(current);
-	spin_unlock_irq(&current->sigmask_lock);		
+	spin_unlock_irq(&current->sigmask_lock);
 
 	/* kick rpciod */
 	rpciod_up();
@@ -93,21 +114,10 @@
 
 	if (!nlm_timeout)
 		nlm_timeout = LOCKD_DFLT_TIMEO;
-
-#ifdef RPC_DEBUG
-	nlmsvc_grace_period = 10 * HZ;
-#else
-	if (nlm_grace_period) {
-		nlmsvc_grace_period += (1 + nlm_grace_period / nlm_timeout)
-						* nlm_timeout * HZ;
-	} else {
-		nlmsvc_grace_period += 5 * nlm_timeout * HZ;
-	}
-#endif
-
-	grace_period_expire = nlmsvc_grace_period + jiffies;
 	nlmsvc_timeout = nlm_timeout * HZ;
 
+	grace_period_expire = set_grace_period();
+
 	/*
 	 * The main request loop. We don't terminate until the last
 	 * NFS mount or NFS daemon has gone away, and we've been sent a
@@ -122,13 +132,7 @@
 			spin_unlock_irq(&current->sigmask_lock);
 			if (nlmsvc_ops) {
 				nlmsvc_ops->detach();
-#ifdef RPC_DEBUG
-				nlmsvc_grace_period = 10 * HZ;
-#else
-				nlmsvc_grace_period += 5 * nlm_timeout * HZ;
-
-#endif
-				grace_period_expire = nlmsvc_grace_period + jiffies;
+				grace_period_expire = set_grace_period();
 			}
 		}
 
@@ -140,16 +144,15 @@
 		 */
 		if (!nlmsvc_grace_period) {
 			timeout = nlmsvc_retry_blocked();
-		} else if (time_before(nlmsvc_grace_period, jiffies))
-			nlmsvc_grace_period = 0;
+		} else if (time_before(grace_period_expire, jiffies))
+			clear_grace_period();
 
 		/*
 		 * Find a socket with data available and call its
 		 * recvfrom routine.
 		 */
-		if ((err = svc_recv(serv, rqstp, timeout)) == -EAGAIN
-			|| err == -EINTR
-			)
+		err = svc_recv(serv, rqstp, timeout);
+		if (err == -EAGAIN || err == -EINTR)
 			continue;
 		if (err < 0) {
 			printk(KERN_WARNING
@@ -240,9 +243,9 @@
 		goto out;
 	}
 
-	if ((error = svc_makesock(serv, IPPROTO_UDP, 0)) < 0 
+	if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0 
 #ifdef CONFIG_NFSD_TCP
-	 || (error = svc_makesock(serv, IPPROTO_TCP, 0)) < 0
+	 || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0
 #endif
 		) {
 		if (warned++ == 0) 
@@ -322,6 +325,8 @@
 MODULE_DESCRIPTION("NFS file locking service version " LOCKD_VERSION ".");
 MODULE_PARM(nlm_grace_period, "10-240l");
 MODULE_PARM(nlm_timeout, "3-20l");
+MODULE_PARM(nlm_udpport, "0-65535l");
+MODULE_PARM(nlm_tcpport, "0-65535l");
 
 int
 init_module(void)
@@ -339,13 +344,31 @@
 	/* FIXME: delete all NLM clients */
 	nlm_shutdown_hosts();
 }
+#else
+/* not a module, so process bootargs
+ * lockd.udpport and lockd.tcpport
+ */
+
+static int __init udpport_set(char *str)
+{
+	nlm_udpport = simple_strtoul(str, NULL, 0);
+	return 1;
+}
+static int __init tcpport_set(char *str)
+{
+	nlm_tcpport = simple_strtoul(str, NULL, 0);
+	return 1;
+}
+__setup("lockd.udpport=", udpport_set);
+__setup("lockd.tcpport=", tcpport_set);
+
 #endif
 
 /*
  * Define NLM program and procedures
  */
 static struct svc_version	nlmsvc_version1 = {
-	1, 16, nlmsvc_procedures, NULL
+	1, 17, nlmsvc_procedures, NULL
 };
 static struct svc_version	nlmsvc_version3 = {
 	3, 24, nlmsvc_procedures, NULL
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/svc4proc.c linux/fs/lockd/svc4proc.c
--- v2.4.10/linux/fs/lockd/svc4proc.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/lockd/svc4proc.c	Mon Oct  1 13:45:47 2001
@@ -420,6 +420,8 @@
 					      void	        *resp)
 {
 	struct sockaddr_in	saddr = rqstp->rq_addr;
+	int			vers = rqstp->rq_vers;
+	int			prot = rqstp->rq_prot;
 	struct nlm_host		*host;
 
 	dprintk("lockd: SM_NOTIFY     called\n");
@@ -435,8 +437,8 @@
 	/* Obtain the host pointer for this NFS server and try to
 	 * reclaim all locks we hold on this server.
 	 */
-	saddr.sin_addr.s_addr = argp->addr;	
-	if ((host = nlm_lookup_host(NULL, &saddr, IPPROTO_UDP, 1)) != NULL) {
+	saddr.sin_addr.s_addr = argp->addr;
+	if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
 		nlmclnt_recovery(host, argp->state);
 		nlm_release_host(host);
 	}
@@ -444,7 +446,7 @@
 	/* If we run on an NFS server, delete all locks held by the client */
 	if (nlmsvc_ops != NULL) {
 		struct svc_client	*clnt;
-		saddr.sin_addr.s_addr = argp->addr;	
+		saddr.sin_addr.s_addr = argp->addr;
 		if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL 
 		 && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) {
 			nlmsvc_free_host_resources(host);
@@ -549,7 +551,8 @@
   PROC(cancel_res,	cancelres,	norep,		res,	void),
   PROC(unlock_res,	unlockres,	norep,		res,	void),
   PROC(granted_res,	grantedres,	norep,		res,	void),
-  PROC(none,		void,		void,		void,	void),
+  /* statd callback */
+  PROC(sm_notify,	reboot,		void,		reboot,	void),
   PROC(none,		void,		void,		void,	void),
   PROC(none,		void,		void,		void,	void),
   PROC(none,		void,		void,		void,	void),
@@ -558,6 +561,4 @@
   PROC(nm_lock,		lockargs,	res,		args,	res),
   PROC(free_all,	notify,		void,		args,	void),
 
-  /* statd callback */
-  PROC(sm_notify,	reboot,		void,		reboot,	void),
 };
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/svcproc.c linux/fs/lockd/svcproc.c
--- v2.4.10/linux/fs/lockd/svcproc.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/lockd/svcproc.c	Mon Oct  1 13:45:47 2001
@@ -445,6 +445,8 @@
 					      void	        *resp)
 {
 	struct sockaddr_in	saddr = rqstp->rq_addr;
+	int			vers = rqstp->rq_vers;
+	int			prot = rqstp->rq_prot;
 	struct nlm_host		*host;
 
 	dprintk("lockd: SM_NOTIFY     called\n");
@@ -460,8 +462,8 @@
 	/* Obtain the host pointer for this NFS server and try to
 	 * reclaim all locks we hold on this server.
 	 */
-	saddr.sin_addr.s_addr = argp->addr;	
-	if ((host = nlm_lookup_host(NULL, &saddr, IPPROTO_UDP, 1)) != NULL) {
+	saddr.sin_addr.s_addr = argp->addr;
+	if ((host = nlmclnt_lookup_host(&saddr, prot, vers)) != NULL) {
 		nlmclnt_recovery(host, argp->state);
 		nlm_release_host(host);
 	}
@@ -574,7 +576,8 @@
   PROC(cancel_res,	cancelres,	norep,		res,	void),
   PROC(unlock_res,	unlockres,	norep,		res,	void),
   PROC(granted_res,	grantedres,	norep,		res,	void),
-  PROC(none,		void,		void,		void,	void),
+  /* statd callback */
+  PROC(sm_notify,	reboot,		void,		reboot,	void),
   PROC(none,		void,		void,		void,	void),
   PROC(none,		void,		void,		void,	void),
   PROC(none,		void,		void,		void,	void),
@@ -583,6 +586,4 @@
   PROC(nm_lock,		lockargs,	res,		args,	res),
   PROC(free_all,	notify,		void,		args,	void),
 
-  /* statd callback */
-  PROC(sm_notify,	reboot,		void,		reboot,	void),
 };
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/svcsubs.c linux/fs/lockd/svcsubs.c
--- v2.4.10/linux/fs/lockd/svcsubs.c	Fri Jun 23 21:12:53 2000
+++ linux/fs/lockd/svcsubs.c	Mon Oct  1 13:45:47 2001
@@ -305,6 +305,7 @@
 		dprintk("lockd: invalidating client for %s\n", host->h_name);
 		nlmsvc_free_host_resources(host);
 		host->h_expires = 0;
+		host->h_killed = 1;
 		nlm_release_host(host);
 	}
 }
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/xdr.c linux/fs/lockd/xdr.c
--- v2.4.10/linux/fs/lockd/xdr.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/lockd/xdr.c	Mon Oct  1 13:45:47 2001
@@ -367,7 +367,8 @@
 	if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
 		return 0;
 	argp->state = ntohl(*p++);
-	argp->addr = ntohl(*p++);
+	/* Preserve the address in network byte order */
+	argp->addr = *p++;
 	return xdr_argsize_check(rqstp, p);
 }
 
diff -u --recursive --new-file v2.4.10/linux/fs/lockd/xdr4.c linux/fs/lockd/xdr4.c
--- v2.4.10/linux/fs/lockd/xdr4.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/lockd/xdr4.c	Mon Oct  1 13:45:47 2001
@@ -373,7 +373,8 @@
 	if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
 		return 0;
 	argp->state = ntohl(*p++);
-	argp->addr = ntohl(*p++);
+	/* Preserve the address in network byte order */
+	argp->addr = *p++;
 	return xdr_argsize_check(rqstp, p);
 }
 
diff -u --recursive --new-file v2.4.10/linux/fs/minix/inode.c linux/fs/minix/inode.c
--- v2.4.10/linux/fs/minix/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/minix/inode.c	Sun Sep 30 12:26:08 2001
@@ -529,3 +529,5 @@
 
 module_init(init_minix_fs)
 module_exit(exit_minix_fs)
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/fs/namei.c linux/fs/namei.c
--- v2.4.10/linux/fs/namei.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/namei.c	Tue Oct  9 09:56:10 2001
@@ -324,19 +324,28 @@
 	return result;
 }
 
+/*
+ * Yes, this really increments the link_count by 5, and
+ * decrements it by 4. Together with checking against 40,
+ * this limits recursive symlink follows to 8, while
+ * limiting consecutive symlinks to 40.
+ *
+ * Without that kind of total limit, nasty chains of consecutive
+ * symlinks can cause almost arbitrarily long lookups. 
+ */
 static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	int err;
-	if (current->link_count >= 8)
+	if (current->link_count >= 40)
 		goto loop;
 	if (current->need_resched) {
 		current->state = TASK_RUNNING;
 		schedule();
 	}
-	current->link_count++;
+	current->link_count += 5;
 	UPDATE_ATIME(dentry->d_inode);
 	err = dentry->d_inode->i_op->follow_link(dentry, nd);
-	current->link_count--;
+	current->link_count -= 4;
 	return err;
 loop:
 	path_release(nd);
@@ -425,6 +434,7 @@
 		nd->mnt = parent;
 	}
 }
+
 /*
  * Name resolution.
  *
@@ -433,7 +443,7 @@
  *
  * We expect 'base' to be positive and a directory.
  */
-int path_walk(const char * name, struct nameidata *nd)
+int link_path_walk(const char * name, struct nameidata *nd)
 {
 	struct dentry *dentry;
 	struct inode *inode;
@@ -624,6 +634,12 @@
 	return err;
 }
 
+int path_walk(const char * name, struct nameidata *nd)
+{
+	current->link_count = 0;
+	return link_path_walk(name, nd);
+}
+
 /* SMP-safe */
 /* returns 1 if everything is done */
 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
@@ -1935,7 +1951,7 @@
 			/* weird __emul_prefix() stuff did it */
 			goto out;
 	}
-	res = path_walk(link, nd);
+	res = link_path_walk(link, nd);
 out:
 	if (current->link_count || res || nd->last_type!=LAST_NORM)
 		return res;
diff -u --recursive --new-file v2.4.10/linux/fs/namespace.c linux/fs/namespace.c
--- v2.4.10/linux/fs/namespace.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/namespace.c	Fri Oct  5 13:08:47 2001
@@ -0,0 +1,1124 @@
+/*
+ *  linux/fs/namespace.c
+ *
+ * (C) Copyright Al Viro 2000, 2001
+ *	Released under GPL v2.
+ *
+ * Based on code from fs/super.c, copyright Linus Torvalds and others.
+ * Heavily rewritten.
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/quotaops.h>
+#include <linux/acct.h>
+#include <linux/module.h>
+#include <linux/devfs_fs_kernel.h>
+
+#include <asm/uaccess.h>
+
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/nfs_mount.h>
+
+struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data);
+int do_remount_sb(struct super_block *sb, int flags, void * data);
+void kill_super(struct super_block *sb);
+
+static struct list_head *mount_hashtable;
+static int hash_mask, hash_bits;
+static kmem_cache_t *mnt_cache; 
+
+static LIST_HEAD(vfsmntlist);
+static DECLARE_MUTEX(mount_sem);
+
+/* Will be static */
+struct vfsmount *root_vfsmnt;
+
+static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
+{
+	unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
+	tmp += ((unsigned long) dentry / L1_CACHE_BYTES);
+	tmp = tmp + (tmp >> hash_bits);
+	return tmp & hash_mask;
+}
+
+struct vfsmount *alloc_vfsmnt(void)
+{
+	struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL); 
+	if (mnt) {
+		memset(mnt, 0, sizeof(struct vfsmount));
+		atomic_set(&mnt->mnt_count,1);
+		INIT_LIST_HEAD(&mnt->mnt_hash);
+		INIT_LIST_HEAD(&mnt->mnt_child);
+		INIT_LIST_HEAD(&mnt->mnt_mounts);
+		INIT_LIST_HEAD(&mnt->mnt_list);
+	}
+	return mnt;
+}
+
+void free_vfsmnt(struct vfsmount *mnt)
+{
+	if (mnt->mnt_devname)
+		kfree(mnt->mnt_devname);
+	kmem_cache_free(mnt_cache, mnt);
+}
+
+void set_devname(struct vfsmount *mnt, const char *name)
+{
+	if (name) {
+		int size = strlen(name)+1;
+		char * newname = kmalloc(size, GFP_KERNEL);
+		if (newname) {
+			memcpy(newname, name, size);
+			mnt->mnt_devname = newname;
+		}
+	}
+}
+
+struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
+{
+	struct list_head * head = mount_hashtable + hash(mnt, dentry);
+	struct list_head * tmp = head;
+	struct vfsmount *p;
+
+	for (;;) {
+		tmp = tmp->next;
+		p = NULL;
+		if (tmp == head)
+			break;
+		p = list_entry(tmp, struct vfsmount, mnt_hash);
+		if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry)
+			break;
+	}
+	return p;
+}
+
+static int check_mnt(struct vfsmount *mnt)
+{
+	spin_lock(&dcache_lock);
+	while (mnt->mnt_parent != mnt)
+		mnt = mnt->mnt_parent;
+	spin_unlock(&dcache_lock);
+	return mnt == root_vfsmnt;
+}
+
+static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
+{
+	old_nd->dentry = mnt->mnt_mountpoint;
+	old_nd->mnt = mnt->mnt_parent;
+	mnt->mnt_parent = mnt;
+	mnt->mnt_mountpoint = mnt->mnt_root;
+	list_del_init(&mnt->mnt_child);
+	list_del_init(&mnt->mnt_hash);
+	old_nd->dentry->d_mounted--;
+}
+
+static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
+{
+	mnt->mnt_parent = mntget(nd->mnt);
+	mnt->mnt_mountpoint = dget(nd->dentry);
+	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
+	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+	nd->dentry->d_mounted++;
+}
+
+static struct vfsmount *next_mnt(struct vfsmount *p, struct vfsmount *root)
+{
+	struct list_head *next = p->mnt_mounts.next;
+	if (next == &p->mnt_mounts) {
+		while (1) {
+			if (p == root)
+				return NULL;
+			next = p->mnt_child.next;
+			if (next != &p->mnt_parent->mnt_mounts)
+				break;
+			p = p->mnt_parent;
+		}
+	}
+	return list_entry(next, struct vfsmount, mnt_child);
+}
+
+static struct vfsmount *
+clone_mnt(struct vfsmount *old, struct dentry *root)
+{
+	struct super_block *sb = old->mnt_sb;
+	struct vfsmount *mnt = alloc_vfsmnt();
+
+	if (mnt) {
+		mnt->mnt_flags = old->mnt_flags;
+		set_devname(mnt, old->mnt_devname);
+		atomic_inc(&sb->s_active);
+		mnt->mnt_sb = sb;
+		mnt->mnt_root = dget(root);
+	}
+	return mnt;
+}
+
+void __mntput(struct vfsmount *mnt)
+{
+	struct super_block *sb = mnt->mnt_sb;
+	dput(mnt->mnt_root);
+	free_vfsmnt(mnt);
+	kill_super(sb);
+}
+
+/* Use octal escapes, like mount does, for embedded spaces etc. */
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static int
+mangle(const unsigned char *s, char *buf, int len) {
+        char *sp;
+        int n;
+
+        sp = buf;
+        while(*s && sp-buf < len-3) {
+                for (n = 0; n < sizeof(need_escaping); n++) {
+                        if (*s == need_escaping[n]) {
+                                *sp++ = '\\';
+                                *sp++ = '0' + ((*s & 0300) >> 6);
+                                *sp++ = '0' + ((*s & 070) >> 3);
+                                *sp++ = '0' + (*s & 07);
+                                goto next;
+                        }
+                }
+                *sp++ = *s;
+        next:
+                s++;
+        }
+        return sp - buf;	/* no trailing NUL */
+}
+
+static struct proc_fs_info {
+	int flag;
+	char *str;
+} fs_info[] = {
+	{ MS_SYNCHRONOUS, ",sync" },
+	{ MS_MANDLOCK, ",mand" },
+	{ MS_NOATIME, ",noatime" },
+	{ MS_NODIRATIME, ",nodiratime" },
+	{ 0, NULL }
+};
+
+static struct proc_fs_info mnt_info[] = {
+	{ MNT_NOSUID, ",nosuid" },
+	{ MNT_NODEV, ",nodev" },
+	{ MNT_NOEXEC, ",noexec" },
+	{ 0, NULL }
+};
+
+static struct proc_nfs_info {
+	int flag;
+	char *str;
+	char *nostr;
+} nfs_info[] = {
+	{ NFS_MOUNT_SOFT, ",soft", ",hard" },
+	{ NFS_MOUNT_INTR, ",intr", "" },
+	{ NFS_MOUNT_POSIX, ",posix", "" },
+	{ NFS_MOUNT_TCP, ",tcp", ",udp" },
+	{ NFS_MOUNT_NOCTO, ",nocto", "" },
+	{ NFS_MOUNT_NOAC, ",noac", "" },
+	{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
+	{ NFS_MOUNT_BROKEN_SUID, ",broken_suid", "" },
+	{ 0, NULL, NULL }
+};
+
+int get_filesystem_info( char *buf )
+{
+	struct list_head *p;
+	struct proc_fs_info *fs_infop;
+	struct proc_nfs_info *nfs_infop;
+	struct nfs_server *nfss;
+	int len, prevlen;
+	char *path, *buffer = (char *) __get_free_page(GFP_KERNEL);
+
+	if (!buffer) return 0;
+	len = prevlen = 0;
+
+#define FREEROOM	((int)PAGE_SIZE-200-len)
+#define MANGLE(s)	len += mangle((s), buf+len, FREEROOM);
+
+	for (p = vfsmntlist.next; p != &vfsmntlist; p = p->next) {
+		struct vfsmount *tmp = list_entry(p, struct vfsmount, mnt_list);
+		path = d_path(tmp->mnt_root, tmp, buffer, PAGE_SIZE);
+		if (!path)
+			continue;
+		MANGLE(tmp->mnt_devname ? tmp->mnt_devname : "none");
+		buf[len++] = ' ';
+		MANGLE(path);
+		buf[len++] = ' ';
+		MANGLE(tmp->mnt_sb->s_type->name);
+		len += sprintf(buf+len, " %s",
+			       tmp->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
+		for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
+			if (tmp->mnt_sb->s_flags & fs_infop->flag)
+				MANGLE(fs_infop->str);
+		}
+		for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
+			if (tmp->mnt_flags & fs_infop->flag)
+				MANGLE(fs_infop->str);
+		}
+		if (!strcmp("nfs", tmp->mnt_sb->s_type->name)) {
+			nfss = &tmp->mnt_sb->u.nfs_sb.s_server;
+			len += sprintf(buf+len, ",v%d", nfss->rpc_ops->version);
+
+			len += sprintf(buf+len, ",rsize=%d", nfss->rsize);
+
+			len += sprintf(buf+len, ",wsize=%d", nfss->wsize);
+#if 0
+			if (nfss->timeo != 7*HZ/10) {
+				len += sprintf(buf+len, ",timeo=%d",
+					       nfss->timeo*10/HZ);
+			}
+			if (nfss->retrans != 3) {
+				len += sprintf(buf+len, ",retrans=%d",
+					       nfss->retrans);
+			}
+#endif
+			if (nfss->acregmin != 3*HZ) {
+				len += sprintf(buf+len, ",acregmin=%d",
+					       nfss->acregmin/HZ);
+			}
+			if (nfss->acregmax != 60*HZ) {
+				len += sprintf(buf+len, ",acregmax=%d",
+					       nfss->acregmax/HZ);
+			}
+			if (nfss->acdirmin != 30*HZ) {
+				len += sprintf(buf+len, ",acdirmin=%d",
+					       nfss->acdirmin/HZ);
+			}
+			if (nfss->acdirmax != 60*HZ) {
+				len += sprintf(buf+len, ",acdirmax=%d",
+					       nfss->acdirmax/HZ);
+			}
+			for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
+				char *str;
+				if (nfss->flags & nfs_infop->flag)
+					str = nfs_infop->str;
+				else
+					str = nfs_infop->nostr;
+				MANGLE(str);
+			}
+			len += sprintf(buf+len, ",addr=");
+			MANGLE(nfss->hostname);
+		}
+		len += sprintf(buf + len, " 0 0\n");
+		if (FREEROOM <= 3) {
+			len = prevlen;
+			len += sprintf(buf+len, "# truncated\n");
+			break;
+		}
+		prevlen = len;
+	}
+
+	free_page((unsigned long) buffer);
+	return len;
+#undef MANGLE
+#undef FREEROOM
+}
+
+/*
+ * Doesn't take quota and stuff into account. IOW, in some cases it will
+ * give false negatives. The main reason why it's here is that we need
+ * a non-destructive way to look for easily umountable filesystems.
+ */
+int may_umount(struct vfsmount *mnt)
+{
+	if (atomic_read(&mnt->mnt_count) > 2)
+		return -EBUSY;
+	return 0;
+}
+
+void umount_tree(struct vfsmount *mnt)
+{
+	struct vfsmount *p;
+	LIST_HEAD(kill);
+
+	if (list_empty(&mnt->mnt_list))
+		return;
+
+	for (p = mnt; p; p = next_mnt(p, mnt)) {
+		list_del(&p->mnt_list);
+		list_add(&p->mnt_list, &kill);
+	}
+
+	while (!list_empty(&kill)) {
+		mnt = list_entry(kill.next, struct vfsmount, mnt_list);
+		list_del_init(&mnt->mnt_list);
+		if (mnt->mnt_parent == mnt) {
+			spin_unlock(&dcache_lock);
+		} else {
+			struct nameidata old_nd;
+			detach_mnt(mnt, &old_nd);
+			spin_unlock(&dcache_lock);
+			path_release(&old_nd);
+		}
+		mntput(mnt);
+		spin_lock(&dcache_lock);
+	}
+}
+
+static int do_umount(struct vfsmount *mnt, int flags)
+{
+	struct super_block * sb = mnt->mnt_sb;
+	int retval = 0;
+
+	/*
+	 * If we may have to abort operations to get out of this
+	 * mount, and they will themselves hold resources we must
+	 * allow the fs to do things. In the Unix tradition of
+	 * 'Gee thats tricky lets do it in userspace' the umount_begin
+	 * might fail to complete on the first run through as other tasks
+	 * must return, and the like. Thats for the mount program to worry
+	 * about for the moment.
+	 */
+
+	lock_kernel();
+	if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
+		sb->s_op->umount_begin(sb);
+	unlock_kernel();
+
+	/*
+	 * No sense to grab the lock for this test, but test itself looks
+	 * somewhat bogus. Suggestions for better replacement?
+	 * Ho-hum... In principle, we might treat that as umount + switch
+	 * to rootfs. GC would eventually take care of the old vfsmount.
+	 * Actually it makes sense, especially if rootfs would contain a
+	 * /reboot - static binary that would close all descriptors and
+	 * call reboot(9). Then init(8) could umount root and exec /reboot.
+	 */
+	if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
+		/*
+		 * Special case for "unmounting" root ...
+		 * we just try to remount it readonly.
+		 */
+		down_write(&sb->s_umount);
+		if (!(sb->s_flags & MS_RDONLY)) {
+			lock_kernel();
+			retval = do_remount_sb(sb, MS_RDONLY, 0);
+			unlock_kernel();
+		}
+		up_write(&sb->s_umount);
+		return retval;
+	}
+
+	down(&mount_sem);
+	spin_lock(&dcache_lock);
+
+	if (atomic_read(&sb->s_active) == 1) {
+		/* last instance - try to be smart */
+		spin_unlock(&dcache_lock);
+		lock_kernel();
+		DQUOT_OFF(sb);
+		acct_auto_close(sb->s_dev);
+		unlock_kernel();
+		spin_lock(&dcache_lock);
+	}
+	retval = -EBUSY;
+	if (atomic_read(&mnt->mnt_count) == 2 || flags & MNT_DETACH) {
+		umount_tree(mnt);
+		retval = 0;
+	}
+	spin_unlock(&dcache_lock);
+	up(&mount_sem);
+	return retval;
+}
+
+/*
+ * Now umount can handle mount points as well as block devices.
+ * This is important for filesystems which use unnamed block devices.
+ *
+ * We now support a flag for forced unmount like the other 'big iron'
+ * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD
+ */
+
+asmlinkage long sys_umount(char * name, int flags)
+{
+	struct nameidata nd;
+	char *kname;
+	int retval;
+
+	kname = getname(name);
+	retval = PTR_ERR(kname);
+	if (IS_ERR(kname))
+		goto out;
+	retval = 0;
+	if (path_init(kname, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd))
+		retval = path_walk(kname, &nd);
+	putname(kname);
+	if (retval)
+		goto out;
+	retval = -EINVAL;
+	if (nd.dentry != nd.mnt->mnt_root)
+		goto dput_and_out;
+	if (!check_mnt(nd.mnt))
+		goto dput_and_out;
+
+	retval = -EPERM;
+	if (!capable(CAP_SYS_ADMIN))
+		goto dput_and_out;
+
+	retval = do_umount(nd.mnt, flags);
+dput_and_out:
+	path_release(&nd);
+out:
+	return retval;
+}
+
+/*
+ *	The 2.0 compatible umount. No flags. 
+ */
+ 
+asmlinkage long sys_oldumount(char * name)
+{
+	return sys_umount(name,0);
+}
+
+static int mount_is_safe(struct nameidata *nd)
+{
+	if (capable(CAP_SYS_ADMIN))
+		return 0;
+	return -EPERM;
+#ifdef notyet
+	if (S_ISLNK(nd->dentry->d_inode->i_mode))
+		return -EPERM;
+	if (nd->dentry->d_inode->i_mode & S_ISVTX) {
+		if (current->uid != nd->dentry->d_inode->i_uid)
+			return -EPERM;
+	}
+	if (permission(nd->dentry->d_inode, MAY_WRITE))
+		return -EPERM;
+	return 0;
+#endif
+}
+
+static struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry)
+{
+	struct vfsmount *p, *next, *q, *res;
+	struct nameidata nd;
+
+	p = mnt;
+	res = nd.mnt = q = clone_mnt(p, dentry);
+	if (!q)
+		goto Enomem;
+	q->mnt_parent = q;
+	q->mnt_mountpoint = p->mnt_mountpoint;
+
+	while ( (next = next_mnt(p, mnt)) != NULL) {
+		while (p != next->mnt_parent) {
+			p = p->mnt_parent;
+			q = q->mnt_parent;
+		}
+		p = next;
+		nd.mnt = q;
+		nd.dentry = p->mnt_mountpoint;
+		q = clone_mnt(p, p->mnt_root);
+		if (!q)
+			goto Enomem;
+		spin_lock(&dcache_lock);
+		list_add_tail(&q->mnt_list, &res->mnt_list);
+		attach_mnt(q, &nd);
+		spin_unlock(&dcache_lock);
+	}
+	return res;
+Enomem:
+	if (res) {
+		spin_lock(&dcache_lock);
+		umount_tree(res);
+		spin_unlock(&dcache_lock);
+	}
+	return NULL;
+}
+
+/* Will become static */
+int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
+{
+	int err;
+	if (mnt->mnt_sb->s_flags & MS_NOUSER)
+		return -EINVAL;
+
+	if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
+	      S_ISDIR(mnt->mnt_root->d_inode->i_mode))
+		return -ENOTDIR;
+
+	err = -ENOENT;
+	down(&nd->dentry->d_inode->i_zombie);
+	if (IS_DEADDIR(nd->dentry->d_inode))
+		goto out_unlock;
+
+	spin_lock(&dcache_lock);
+	if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) {
+		struct list_head head;
+		attach_mnt(mnt, nd);
+		list_add_tail(&head, &mnt->mnt_list);
+		list_splice(&head, vfsmntlist.prev);
+		mntget(mnt);
+		err = 0;
+	}
+	spin_unlock(&dcache_lock);
+out_unlock:
+	up(&nd->dentry->d_inode->i_zombie);
+	return err;
+}
+
+/*
+ * do loopback mount.
+ */
+static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
+{
+	struct nameidata old_nd;
+	struct vfsmount *mnt = NULL;
+	int err = mount_is_safe(nd);
+	if (err)
+		return err;
+	if (!old_name || !*old_name)
+		return -EINVAL;
+	if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
+		err = path_walk(old_name, &old_nd);
+	if (err)
+		return err;
+
+	down(&mount_sem);
+	err = -EINVAL;
+	if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
+		err = -ENOMEM;
+		if (recurse)
+			mnt = copy_tree(old_nd.mnt, old_nd.dentry);
+		else
+			mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
+	}
+
+	if (mnt) {
+		err = graft_tree(mnt, nd);
+		if (err && recurse)
+			umount_tree(mnt);
+		mntput(mnt);
+	}
+
+	up(&mount_sem);
+	path_release(&old_nd);
+	return err;
+}
+
+/*
+ * change filesystem flags. dir should be a physical root of filesystem.
+ * If you've mounted a non-root directory somewhere and want to do remount
+ * on it - tough luck.
+ */
+
+static int do_remount(struct nameidata *nd,int flags,int mnt_flags,void *data)
+{
+	int err;
+	struct super_block * sb = nd->mnt->mnt_sb;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (!check_mnt(nd->mnt))
+		return -EINVAL;
+
+	if (nd->dentry != nd->mnt->mnt_root)
+		return -EINVAL;
+
+	down_write(&sb->s_umount);
+	err = do_remount_sb(sb, flags, data);
+	if (!err)
+		nd->mnt->mnt_flags=mnt_flags;
+	up_write(&sb->s_umount);
+	return err;
+}
+
+static int do_add_mount(struct nameidata *nd, char *type, int flags,
+			int mnt_flags, char *name, void *data)
+{
+	struct vfsmount *mnt = do_kern_mount(type, flags, name, data);
+	int err = PTR_ERR(mnt);
+
+	if (IS_ERR(mnt))
+		goto out;
+
+	down(&mount_sem);
+	/* Something was mounted here while we slept */
+	while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+		;
+	err = -EINVAL;
+	if (!check_mnt(nd->mnt))
+		goto unlock;
+
+	/* Refuse the same filesystem on the same mount point */
+	err = -EBUSY;
+	if (nd->mnt->mnt_sb == mnt->mnt_sb && nd->mnt->mnt_root == nd->dentry)
+		goto unlock;
+
+	mnt->mnt_flags = mnt_flags;
+	err = graft_tree(mnt, nd);
+unlock:
+	up(&mount_sem);
+	mntput(mnt);
+out:
+	return err;
+}
+
+static int copy_mount_options (const void *data, unsigned long *where)
+{
+	int i;
+	unsigned long page;
+	unsigned long size;
+	
+	*where = 0;
+	if (!data)
+		return 0;
+
+	if (!(page = __get_free_page(GFP_KERNEL)))
+		return -ENOMEM;
+
+	/* We only care that *some* data at the address the user
+	 * gave us is valid.  Just in case, we'll zero
+	 * the remainder of the page.
+	 */
+	/* copy_from_user cannot cross TASK_SIZE ! */
+	size = TASK_SIZE - (unsigned long)data;
+	if (size > PAGE_SIZE)
+		size = PAGE_SIZE;
+
+	i = size - copy_from_user((void *)page, data, size);
+	if (!i) {
+		free_page(page); 
+		return -EFAULT;
+	}
+	if (i != PAGE_SIZE)
+		memset((char *)page + i, 0, PAGE_SIZE - i);
+	*where = page;
+	return 0;
+}
+
+/*
+ * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
+ * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
+ *
+ * data is a (void *) that can point to any structure up to
+ * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
+ * information (or be NULL).
+ *
+ * Pre-0.97 versions of mount() didn't have a flags word.
+ * When the flags word was introduced its top half was required
+ * to have the magic value 0xC0ED, and this remained so until 2.4.0-test9.
+ * Therefore, if this magic number is present, it carries no information
+ * and must be discarded.
+ */
+long do_mount(char * dev_name, char * dir_name, char *type_page,
+		  unsigned long flags, void *data_page)
+{
+	struct nameidata nd;
+	int retval = 0;
+	int mnt_flags = 0;
+
+	/* Discard magic */
+	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
+		flags &= ~MS_MGC_MSK;
+
+	/* Basic sanity checks */
+
+	if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE))
+		return -EINVAL;
+	if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))
+		return -EINVAL;
+
+	/* Separate the per-mountpoint flags */
+	if (flags & MS_NOSUID)
+		mnt_flags |= MNT_NOSUID;
+	if (flags & MS_NODEV)
+		mnt_flags |= MNT_NODEV;
+	if (flags & MS_NOEXEC)
+		mnt_flags |= MNT_NOEXEC;
+	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
+
+	/* ... and get the mountpoint */
+	if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+		retval = path_walk(dir_name, &nd);
+	if (retval)
+		return retval;
+
+	if (flags & MS_REMOUNT)
+		retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
+				    data_page);
+	else if (flags & MS_BIND)
+		retval = do_loopback(&nd, dev_name, flags & MS_REC);
+	else
+		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
+				      dev_name, data_page);
+	path_release(&nd);
+	return retval;
+}
+
+asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
+			  unsigned long flags, void * data)
+{
+	int retval;
+	unsigned long data_page;
+	unsigned long type_page;
+	unsigned long dev_page;
+	char *dir_page;
+
+	retval = copy_mount_options (type, &type_page);
+	if (retval < 0)
+		return retval;
+
+	dir_page = getname(dir_name);
+	retval = PTR_ERR(dir_page);
+	if (IS_ERR(dir_page))
+		goto out1;
+
+	retval = copy_mount_options (dev_name, &dev_page);
+	if (retval < 0)
+		goto out2;
+
+	retval = copy_mount_options (data, &data_page);
+	if (retval < 0)
+		goto out3;
+
+	lock_kernel();
+	retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
+			  flags, (void*)data_page);
+	unlock_kernel();
+	free_page(data_page);
+
+out3:
+	free_page(dev_page);
+out2:
+	putname(dir_page);
+out1:
+	free_page(type_page);
+	return retval;
+}
+
+static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
+{
+	struct task_struct *p;
+	struct fs_struct *fs;
+
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		task_lock(p);
+		fs = p->fs;
+		if (fs) {
+			atomic_inc(&fs->count);
+			task_unlock(p);
+			if (fs->root==old_nd->dentry&&fs->rootmnt==old_nd->mnt)
+				set_fs_root(fs, new_nd->mnt, new_nd->dentry);
+			if (fs->pwd==old_nd->dentry&&fs->pwdmnt==old_nd->mnt)
+				set_fs_pwd(fs, new_nd->mnt, new_nd->dentry);
+			put_fs_struct(fs);
+		} else
+			task_unlock(p);
+	}
+	read_unlock(&tasklist_lock);
+}
+
+/*
+ * Moves the current root to put_root, and sets root/cwd of all processes
+ * which had them on the old root to new_root.
+ *
+ * Note:
+ *  - we don't move root/cwd if they are not at the root (reason: if something
+ *    cared enough to change them, it's probably wrong to force them elsewhere)
+ *  - it's okay to pick a root that isn't the root of a file system, e.g.
+ *    /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
+ *    though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
+ *    first.
+ */
+
+asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
+{
+	struct vfsmount *tmp;
+	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
+	char *name;
+	int error;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	lock_kernel();
+
+	name = getname(new_root);
+	error = PTR_ERR(name);
+	if (IS_ERR(name))
+		goto out0;
+	error = 0;
+	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
+		error = path_walk(name, &new_nd);
+	putname(name);
+	if (error)
+		goto out0;
+	error = -EINVAL;
+	if (!check_mnt(new_nd.mnt))
+		goto out1;
+
+	name = getname(put_old);
+	error = PTR_ERR(name);
+	if (IS_ERR(name))
+		goto out1;
+	error = 0;
+	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
+		error = path_walk(name, &old_nd);
+	putname(name);
+	if (error)
+		goto out1;
+
+	read_lock(&current->fs->lock);
+	user_nd.mnt = mntget(current->fs->rootmnt);
+	user_nd.dentry = dget(current->fs->root);
+	read_unlock(&current->fs->lock);
+	down(&mount_sem);
+	down(&old_nd.dentry->d_inode->i_zombie);
+	error = -EINVAL;
+	if (!check_mnt(user_nd.mnt))
+		goto out2;
+	error = -ENOENT;
+	if (IS_DEADDIR(new_nd.dentry->d_inode))
+		goto out2;
+	if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry))
+		goto out2;
+	if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry))
+		goto out2;
+	error = -EBUSY;
+	if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt)
+		goto out2; /* loop */
+	error = -EINVAL;
+	if (user_nd.mnt->mnt_root != user_nd.dentry)
+		goto out2;
+	if (new_nd.mnt->mnt_root != new_nd.dentry)
+		goto out2; /* not a mountpoint */
+	tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
+	spin_lock(&dcache_lock);
+	if (tmp != new_nd.mnt) {
+		for (;;) {
+			if (tmp->mnt_parent == tmp)
+				goto out3;
+			if (tmp->mnt_parent == new_nd.mnt)
+				break;
+			tmp = tmp->mnt_parent;
+		}
+		if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry))
+			goto out3;
+	} else if (!is_subdir(old_nd.dentry, new_nd.dentry))
+		goto out3;
+	detach_mnt(new_nd.mnt, &parent_nd);
+	detach_mnt(user_nd.mnt, &root_parent);
+	attach_mnt(user_nd.mnt, &old_nd);
+	attach_mnt(new_nd.mnt, &root_parent);
+	spin_unlock(&dcache_lock);
+	chroot_fs_refs(&user_nd, &new_nd);
+	error = 0;
+	path_release(&root_parent);
+	path_release(&parent_nd);
+out2:
+	up(&old_nd.dentry->d_inode->i_zombie);
+	up(&mount_sem);
+	path_release(&user_nd);
+	path_release(&old_nd);
+out1:
+	path_release(&new_nd);
+out0:
+	unlock_kernel();
+	return error;
+out3:
+	spin_unlock(&dcache_lock);
+	goto out2;
+}
+
+/*
+ * Absolutely minimal fake fs - only empty root directory and nothing else.
+ * In 2.5 we'll use ramfs or tmpfs, but for now it's all we need - just
+ * something to go with root vfsmount.
+ */
+static struct dentry *rootfs_lookup(struct inode *dir, struct dentry *dentry)
+{
+	d_add(dentry, NULL);
+	return NULL;
+}
+static struct file_operations rootfs_dir_operations = {
+	read:		generic_read_dir,
+	readdir:	dcache_readdir,
+};
+static struct inode_operations rootfs_dir_inode_operations = {
+	lookup:		rootfs_lookup,
+};
+static struct super_block *rootfs_read_super(struct super_block * sb, void * data, int silent)
+{
+	struct inode * inode;
+	struct dentry * root;
+	static struct super_operations s_ops = {};
+	sb->s_op = &s_ops;
+	inode = new_inode(sb);
+	if (!inode)
+		return NULL;
+	inode->i_mode = S_IFDIR|0555;
+	inode->i_uid = inode->i_gid = 0;
+	inode->i_op = &rootfs_dir_inode_operations;
+	inode->i_fop = &rootfs_dir_operations;
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return NULL;
+	}
+	sb->s_root = root;
+	return sb;
+}
+static DECLARE_FSTYPE(root_fs_type, "rootfs", rootfs_read_super, FS_NOMOUNT);
+
+static void __init init_mount_tree(void)
+{
+	register_filesystem(&root_fs_type);
+	root_vfsmnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
+	if (IS_ERR(root_vfsmnt))
+		panic("can't allocate root vfsmount");
+}
+
+void __init mnt_init(unsigned long mempages)
+{
+	struct list_head *d;
+	unsigned long order;
+	unsigned int nr_hash;
+	int i;
+
+	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
+					0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+	if (!mnt_cache)
+		panic("Cannot create vfsmount cache");
+
+	mempages >>= (16 - PAGE_SHIFT);
+	mempages *= sizeof(struct list_head);
+	for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
+		;
+
+	do {
+		mount_hashtable = (struct list_head *)
+			__get_free_pages(GFP_ATOMIC, order);
+	} while (mount_hashtable == NULL && --order >= 0);
+
+	if (!mount_hashtable)
+		panic("Failed to allocate mount hash table\n");
+
+	/*
+	 * Find the power-of-two list-heads that can fit into the allocation..
+	 * We don't guarantee that "sizeof(struct list_head)" is necessarily
+	 * a power-of-two.
+	 */
+	nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct list_head);
+	hash_bits = 0;
+	do {
+		hash_bits++;
+	} while ((nr_hash >> hash_bits) != 0);
+	hash_bits--;
+
+	/*
+	 * Re-calculate the actual number of entries and the mask
+	 * from the number of bits we can fit.
+	 */
+	nr_hash = 1UL << hash_bits;
+	hash_mask = nr_hash-1;
+
+	printk("Mount-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+			nr_hash, order, (PAGE_SIZE << order));
+
+	/* And initialize the newly allocated array */
+	d = mount_hashtable;
+	i = nr_hash;
+	do {
+		INIT_LIST_HEAD(d);
+		d++;
+		i--;
+	} while (i);
+	init_mount_tree();
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+int __init change_root(kdev_t new_root_dev,const char *put_old)
+{
+	struct vfsmount *old_rootmnt;
+	struct nameidata devfs_nd, nd;
+	struct nameidata parent_nd;
+	char *new_devname = kmalloc(strlen("/dev/root.old")+1, GFP_KERNEL);
+	int error = 0;
+
+	if (new_devname)
+		strcpy(new_devname, "/dev/root.old");
+
+	read_lock(&current->fs->lock);
+	old_rootmnt = mntget(current->fs->rootmnt);
+	read_unlock(&current->fs->lock);
+	/*  First unmount devfs if mounted  */
+	if (path_init("/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
+		error = path_walk("/dev", &devfs_nd);
+	if (!error) {
+		if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
+		    devfs_nd.dentry == devfs_nd.mnt->mnt_root) {
+			do_umount(devfs_nd.mnt, 0);
+		}
+		path_release(&devfs_nd);
+	}
+	spin_lock(&dcache_lock);
+	detach_mnt(old_rootmnt, &parent_nd);
+	spin_unlock(&dcache_lock);
+	ROOT_DEV = new_root_dev;
+	mount_root();
+#if 1
+	shrink_dcache();
+	printk("change_root: old root has d_count=%d\n", 
+	       atomic_read(&old_rootmnt->mnt_root->d_count));
+#endif
+	mount_devfs_fs ();
+	/*
+	 * Get the new mount directory
+	 */
+	error = 0;
+	if (path_init(put_old, LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
+		error = path_walk(put_old, &nd);
+	if (error) {
+		int blivet;
+		struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
+
+		atomic_inc(&ramdisk->bd_count);
+		blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
+		printk(KERN_NOTICE "Trying to unmount old root ... ");
+		if (!blivet) {
+			spin_lock(&dcache_lock);
+			list_del(&old_rootmnt->mnt_list);
+ 			spin_unlock(&dcache_lock);
+ 			mntput(old_rootmnt);
+			mntput(old_rootmnt);
+			blivet = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
+			path_release(&parent_nd);
+			blkdev_put(ramdisk, BDEV_FS);
+		}
+		if (blivet) {
+			printk(KERN_ERR "error %d\n", blivet);
+		} else {
+			printk("okay\n");
+			error = 0;
+		}			
+		kfree(new_devname);
+		return error;
+	}
+
+	spin_lock(&dcache_lock);
+	attach_mnt(old_rootmnt, &nd);
+	if (new_devname) {
+		if (old_rootmnt->mnt_devname)
+			kfree(old_rootmnt->mnt_devname);
+		old_rootmnt->mnt_devname = new_devname;
+	}
+	spin_unlock(&dcache_lock);
+
+	/* put the old stuff */
+	path_release(&parent_nd);
+	mntput(old_rootmnt);
+	path_release(&nd);
+	return 0;
+}
+
+#endif
diff -u --recursive --new-file v2.4.10/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- v2.4.10/linux/fs/ncpfs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/ncpfs/inode.c	Sun Sep 30 12:26:08 2001
@@ -730,3 +730,4 @@
 
 module_init(init_ncp_fs)
 module_exit(exit_ncp_fs)
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.4.10/linux/fs/nfs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/nfs/inode.c	Mon Oct  1 13:45:47 2001
@@ -312,6 +312,7 @@
 	if (data->flags & NFS_MOUNT_NOAC) {
 		data->acregmin = data->acregmax = 0;
 		data->acdirmin = data->acdirmax = 0;
+		sb->s_flags |= MS_SYNCHRONOUS;
 	}
 	server->acregmin = data->acregmin*HZ;
 	server->acregmax = data->acregmax*HZ;
diff -u --recursive --new-file v2.4.10/linux/fs/nfs/nfs3proc.c linux/fs/nfs/nfs3proc.c
--- v2.4.10/linux/fs/nfs/nfs3proc.c	Sun Dec  3 18:01:01 2000
+++ linux/fs/nfs/nfs3proc.c	Mon Oct  1 13:45:37 2001
@@ -362,8 +362,8 @@
 		struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
 	struct nfs_fattr	dir_attr;
-	struct nfs3_createargs	arg = { NFS_FH(dir), name->name, name->len,
-					sattr, 0, { 0, 0 } };
+	struct nfs3_mkdirargs	arg = { NFS_FH(dir), name->name, name->len,
+					sattr };
 	struct nfs3_diropres	res = { &dir_attr, fhandle, fattr };
 	int			status;
 
diff -u --recursive --new-file v2.4.10/linux/fs/nfs/write.c linux/fs/nfs/write.c
--- v2.4.10/linux/fs/nfs/write.c	Mon Aug 27 12:41:46 2001
+++ linux/fs/nfs/write.c	Mon Oct  1 13:45:47 2001
@@ -288,7 +288,7 @@
 		goto out;
 do_it:
 	lock_kernel();
-	if (NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) {
+	if (NFS_SERVER(inode)->wsize >= PAGE_CACHE_SIZE && !IS_SYNC(inode)) {
 		err = nfs_writepage_async(NULL, inode, page, 0, offset);
 		if (err >= 0)
 			err = 0;
@@ -1031,7 +1031,7 @@
 	 * If wsize is smaller than page size, update and write
 	 * page synchronously.
 	 */
-	if (NFS_SERVER(inode)->wsize < PAGE_SIZE)
+	if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE || IS_SYNC(inode))
 		return nfs_writepage_sync(file, inode, page, offset, count);
 
 	/*
diff -u --recursive --new-file v2.4.10/linux/fs/nfsd/export.c linux/fs/nfsd/export.c
--- v2.4.10/linux/fs/nfsd/export.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/nfsd/export.c	Wed Oct  3 22:57:36 2001
@@ -550,15 +550,15 @@
 	{ NFSEXP_INSECURE_PORT, {"insecure", ""}},
 	{ NFSEXP_ROOTSQUASH, {"root_squash", "no_root_squash"}},
 	{ NFSEXP_ALLSQUASH, {"all_squash", ""}},
-	{ NFSEXP_ASYNC, {"async", ""}},
-	{ NFSEXP_GATHERED_WRITES, {"wdelay", ""}},
+	{ NFSEXP_ASYNC, {"async", "sync"}},
+	{ NFSEXP_GATHERED_WRITES, {"wdelay", "no_wdelay"}},
 	{ NFSEXP_UIDMAP, {"uidmap", ""}},
 	{ NFSEXP_KERBEROS, { "kerberos", ""}},
 	{ NFSEXP_SUNSECURE, { "sunsecure", ""}},
 	{ NFSEXP_CROSSMNT, {"nohide", ""}},
 	{ NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
 	{ NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
-#ifdef NSMFS
+#ifdef MSNFS
 	{ NFSEXP_MSNFS, {"msnfs", ""}},
 #endif
 	{ 0, {"", ""}}
diff -u --recursive --new-file v2.4.10/linux/fs/nfsd/nfs3xdr.c linux/fs/nfsd/nfs3xdr.c
--- v2.4.10/linux/fs/nfsd/nfs3xdr.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/nfsd/nfs3xdr.c	Wed Oct  3 22:27:48 2001
@@ -99,7 +99,7 @@
 	char		*name;
 	int		i;
 
-	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXPATHLEN)) != NULL) {
+	if ((p = xdr_decode_string(p, namp, lenp, NFS3_MAXPATHLEN)) != NULL) {
 		for (i = 0, name = *namp; i < *lenp; i++, name++) {
 			if (*name == '\0')
 				return NULL;
diff -u --recursive --new-file v2.4.10/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.4.10/linux/fs/nfsd/nfsfh.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/nfsd/nfsfh.c	Wed Oct  3 22:59:22 2001
@@ -731,8 +731,10 @@
 {
 	struct super_block *sb = dentry->d_inode->i_sb;
 	
-	if (dentry == exp->ex_dentry)
+	if (dentry == exp->ex_dentry) {
+		*maxsize = 0;
 		return 0;
+	}
 
 	if (sb->s_op->dentry_to_fh) {
 		int need_parent = !S_ISDIR(dentry->d_inode->i_mode) &&
diff -u --recursive --new-file v2.4.10/linux/fs/nfsd/nfsxdr.c linux/fs/nfsd/nfsxdr.c
--- v2.4.10/linux/fs/nfsd/nfsxdr.c	Mon Aug 27 12:41:46 2001
+++ linux/fs/nfsd/nfsxdr.c	Wed Oct  3 22:27:48 2001
@@ -65,7 +65,7 @@
 	char		*name;
 	int		i;
 
-	if ((p = xdr_decode_string(p, namp, lenp, NFS_MAXNAMLEN)) != NULL) {
+	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXNAMLEN)) != NULL) {
 		for (i = 0, name = *namp; i < *lenp; i++, name++) {
 			if (*name == '\0' || *name == '/')
 				return NULL;
diff -u --recursive --new-file v2.4.10/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- v2.4.10/linux/fs/nfsd/vfs.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/nfsd/vfs.c	Fri Oct  5 12:23:53 2001
@@ -227,7 +227,7 @@
 #define	MAX_TOUCH_TIME_ERROR (30*60)
 	if (err
 	    && (iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
-	    && iap->ia_mtime == iap->ia_ctime
+	    && iap->ia_mtime == iap->ia_atime
 	    ) {
 	    /* looks good.  now just make sure time is in the right ballpark.
 	     * solaris, at least, doesn't seem to care what the time request is
@@ -296,16 +296,6 @@
 
 
 	iap->ia_valid |= ATTR_CTIME;
-#ifdef CONFIG_QUOTA
-	/* DQUOT_TRANSFER needs both ia_uid and ia_gid defined */
-	if (iap->ia_valid & (ATTR_UID|ATTR_GID)) {
-		if (! (iap->ia_valid & ATTR_UID))
-			iap->ia_uid = inode->i_uid;
-		if (! (iap->ia_valid & ATTR_GID))
-			iap->ia_gid = inode->i_gid;
-		iap->ia_valid |= ATTR_UID|ATTR_GID;
-	}
-#endif /* CONFIG_QUOTA */
 
 	if (iap->ia_valid & ATTR_SIZE) {
 		fh_lock(fhp);
@@ -313,12 +303,7 @@
 	}
 	err = nfserr_notsync;
 	if (!check_guard || guardtime == inode->i_ctime) {
-#ifdef CONFIG_QUOTA
-		if (iap->ia_valid & (ATTR_UID|ATTR_GID)) 
-			err = DQUOT_TRANSFER(dentry, iap);
-		else
-#endif
-			err = notify_change(dentry, iap);
+		err = notify_change(dentry, iap);
 		err = nfserrno(err);
 	}
 	if (size_change) {
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp1251.c linux/fs/nls/nls_cp1251.c
--- v2.4.10/linux/fs/nls/nls_cp1251.c	Fri Apr  6 10:51:19 2001
+++ linux/fs/nls/nls_cp1251.c	Sun Sep 30 12:26:08 2001
@@ -315,3 +315,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp1255.c linux/fs/nls/nls_cp1255.c
--- v2.4.10/linux/fs/nls/nls_cp1255.c	Sat May 19 17:47:55 2001
+++ linux/fs/nls/nls_cp1255.c	Sun Sep 30 12:26:08 2001
@@ -396,3 +396,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp437.c linux/fs/nls/nls_cp437.c
--- v2.4.10/linux/fs/nls/nls_cp437.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp437.c	Sun Sep 30 12:26:08 2001
@@ -401,3 +401,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp737.c linux/fs/nls/nls_cp737.c
--- v2.4.10/linux/fs/nls/nls_cp737.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp737.c	Sun Sep 30 12:26:08 2001
@@ -364,3 +364,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp775.c linux/fs/nls/nls_cp775.c
--- v2.4.10/linux/fs/nls/nls_cp775.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp775.c	Sun Sep 30 12:26:08 2001
@@ -333,3 +333,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp850.c linux/fs/nls/nls_cp850.c
--- v2.4.10/linux/fs/nls/nls_cp850.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp850.c	Sun Sep 30 12:26:08 2001
@@ -329,3 +329,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp852.c linux/fs/nls/nls_cp852.c
--- v2.4.10/linux/fs/nls/nls_cp852.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp852.c	Sun Sep 30 12:26:08 2001
@@ -351,3 +351,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp855.c linux/fs/nls/nls_cp855.c
--- v2.4.10/linux/fs/nls/nls_cp855.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp855.c	Sun Sep 30 12:26:08 2001
@@ -313,3 +313,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp857.c linux/fs/nls/nls_cp857.c
--- v2.4.10/linux/fs/nls/nls_cp857.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp857.c	Sun Sep 30 12:26:08 2001
@@ -315,3 +315,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp860.c linux/fs/nls/nls_cp860.c
--- v2.4.10/linux/fs/nls/nls_cp860.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp860.c	Sun Sep 30 12:26:08 2001
@@ -378,3 +378,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp861.c linux/fs/nls/nls_cp861.c
--- v2.4.10/linux/fs/nls/nls_cp861.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp861.c	Sun Sep 30 12:26:08 2001
@@ -401,3 +401,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp862.c linux/fs/nls/nls_cp862.c
--- v2.4.10/linux/fs/nls/nls_cp862.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp862.c	Sun Sep 30 12:26:08 2001
@@ -435,3 +435,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp863.c linux/fs/nls/nls_cp863.c
--- v2.4.10/linux/fs/nls/nls_cp863.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp863.c	Sun Sep 30 12:26:08 2001
@@ -395,3 +395,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp864.c linux/fs/nls/nls_cp864.c
--- v2.4.10/linux/fs/nls/nls_cp864.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp864.c	Sun Sep 30 12:26:08 2001
@@ -421,3 +421,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp865.c linux/fs/nls/nls_cp865.c
--- v2.4.10/linux/fs/nls/nls_cp865.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp865.c	Sun Sep 30 12:26:08 2001
@@ -401,3 +401,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp866.c linux/fs/nls/nls_cp866.c
--- v2.4.10/linux/fs/nls/nls_cp866.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp866.c	Sun Sep 30 12:26:08 2001
@@ -319,3 +319,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp869.c linux/fs/nls/nls_cp869.c
--- v2.4.10/linux/fs/nls/nls_cp869.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp869.c	Sun Sep 30 12:26:08 2001
@@ -329,3 +329,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/nls/nls_cp874.c linux/fs/nls/nls_cp874.c
--- v2.4.10/linux/fs/nls/nls_cp874.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp874.c	Sun Sep 30 12:26:08 2001
@@ -287,3 +287,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -u --recursive --new-file v2.4.10/linux/fs/ntfs/Makefile linux/fs/ntfs/Makefile
--- v2.4.10/linux/fs/ntfs/Makefile	Sun Sep 23 11:41:00 2001
+++ linux/fs/ntfs/Makefile	Sun Sep 30 11:42:44 2001
@@ -5,7 +5,7 @@
 obj-y   := fs.o sysctl.o support.o util.o inode.o dir.o super.o attr.o unistr.o
 obj-m   := $(O_TARGET)
 # New version format started 3 February 2001.
-EXTRA_CFLAGS = -DNTFS_VERSION=\"1.1.19\" #-DDEBUG
+EXTRA_CFLAGS = -DNTFS_VERSION=\"1.1.20\" #-DDEBUG
 
 include $(TOPDIR)/Rules.make
 
diff -u --recursive --new-file v2.4.10/linux/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- v2.4.10/linux/fs/ntfs/fs.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/ntfs/fs.c	Sun Sep 30 11:42:44 2001
@@ -27,6 +27,7 @@
 #include <linux/locks.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <linux/blkdev.h>
 #include <asm/page.h>
 #include <linux/nls.h>
 #include <linux/ntfs_fs.h>
@@ -1012,22 +1013,27 @@
 {
 	ntfs_volume *vol;
 	struct buffer_head *bh;
-	int i, to_read;
+	int i, to_read, blocksize;
 
 	ntfs_debug(DEBUG_OTHER, "ntfs_read_super\n");
 	vol = NTFS_SB2VOL(sb);
 	init_ntfs_super_block(vol);
 	if (!parse_options(vol, (char*)options))
 		goto ntfs_read_super_vol;
-	/* Assume a 512 bytes block device for now. */
-	set_blocksize(sb->s_dev, 512);
+	blocksize = get_hardsect_size(sb->s_dev);
+	if (blocksize < 512)
+		blocksize = 512;
+	if (set_blocksize(sb->s_dev, blocksize) < 0) {
+		ntfs_error("Unable to set blocksize %d.\n", blocksize);
+		goto ntfs_read_super_vol;
+	}
 	/* Read the super block (boot block). */
-	if (!(bh = bread(sb->s_dev, 0, 512))) {
+	if (!(bh = bread(sb->s_dev, 0, blocksize))) {
 		ntfs_error("Reading super block failed\n");
 		goto ntfs_read_super_unl;
 	}
 	ntfs_debug(DEBUG_OTHER, "Done reading boot block\n");
-	/* Check for 'NTFS' magic number */
+	/* Check for valid 'NTFS' boot sector. */
 	if (!is_boot_sector_ntfs(bh->b_data)) {
 		ntfs_debug(DEBUG_OTHER, "Not a NTFS volume\n");
 		bforget(bh);
@@ -1040,7 +1046,7 @@
 		goto ntfs_read_super_unl;
 	}
 	ntfs_debug(DEBUG_OTHER, "$Mft at cluster 0x%lx\n", vol->mft_lcn);
-	bforget(bh);
+	brelse(bh);
 	NTFS_SB(vol) = sb;
 	if (vol->cluster_size > PAGE_SIZE) {
 		ntfs_error("Partition cluster size is not supported yet (it "
@@ -1050,9 +1056,12 @@
 	ntfs_debug(DEBUG_OTHER, "Done to init volume\n");
 	/* Inform the kernel that a device block is a NTFS cluster. */
 	sb->s_blocksize = vol->cluster_size;
-	for (i = sb->s_blocksize, sb->s_blocksize_bits = 0; i != 1; i >>= 1)
-		sb->s_blocksize_bits++;
-	set_blocksize(sb->s_dev, sb->s_blocksize);
+	sb->s_blocksize_bits = vol->cluster_size_bits;
+	if (blocksize != vol->cluster_size &&
+			set_blocksize(sb->s_dev, sb->s_blocksize) < 0) {
+		ntfs_error("Cluster size too small for device.\n");
+		goto ntfs_read_super_unl;
+	}
 	ntfs_debug(DEBUG_OTHER, "set_blocksize\n");
 	/* Allocate an MFT record (MFT record can be smaller than a cluster). */
 	i = vol->cluster_size;
diff -u --recursive --new-file v2.4.10/linux/fs/ntfs/inode.c linux/fs/ntfs/inode.c
--- v2.4.10/linux/fs/ntfs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/ntfs/inode.c	Sun Sep 30 11:42:44 2001
@@ -592,18 +592,23 @@
 		 * If write extends beyond _allocated_ size, extend attribute,
 		 * updating attr->allocated and attr->size in the process. (AIA)
 		 */
-		if (offset + l > attr->allocated) {
+		if ((!attr->resident && offset + l > attr->allocated) ||
+				(attr->resident && offset + l > attr->size)) {
 			error = ntfs_resize_attr(ino, attr, offset + l);
 			if (error)
 				return error;
-		} else if (offset + l > attr->size)
-			/* If amount of data has increased: update. */
-			attr->size = offset + l;
-		/* If amount of initialised data has increased: update. */
-		if (offset + l > attr->initialized) {
-			/* FIXME: Zero-out the section between the old
-			 * initialised length and the write start. (AIA) */
-			attr->initialized = offset + l;
+		}
+		if (!attr->resident) {
+			/* Has amount of data increased? */
+			if (offset + l > attr->size)
+				attr->size = offset + l;
+			/* Has amount of initialised data increased? */
+			if (offset + l > attr->initialized) {
+				/* FIXME: Clear the section between the old
+			 	 * initialised length and the write start.
+				 * (AIA) */
+				attr->initialized = offset + l;
+			}
 		}
 	}
 	if (attr->resident) {
@@ -619,10 +624,11 @@
 		if (offset >= attr->initialized)
 			return ntfs_read_zero(dest, l);
 		if (offset + l > attr->initialized) {
-			dest->size = chunk = offset + l - attr->initialized;
+			dest->size = chunk = attr->initialized - offset;
 			error = ntfs_readwrite_attr(ino, attr, offset, dest);
-			if (error)
+			if (error || (dest->size != chunk && (error = -EIO, 1)))
 				return error;
+			dest->size += l - chunk;
 			return ntfs_read_zero(dest, l - chunk);
 		}
 		if (attr->flags & ATTR_IS_COMPRESSED)
@@ -707,31 +713,25 @@
 	return ntfs_readwrite_attr(ino, attr, offset, buf);
 }
 
+/* -2 = error, -1 = hole, >= 0 means real disk cluster (lcn). */
 int ntfs_vcn_to_lcn(ntfs_inode *ino, int vcn)
 {
 	int rnum;
 	ntfs_attribute *data;
 	
 	data = ntfs_find_attr(ino, ino->vol->at_data, 0);
-	/* It's hard to give an error code. */
 	if (!data || data->resident || data->flags & (ATTR_IS_COMPRESSED |
 			ATTR_IS_ENCRYPTED))
-		return -1;
+		return -2;
 	if (data->size <= (__s64)vcn << ino->vol->cluster_size_bits)
-		return -1;
-	/*
-	 * For Linux, block number 0 represents a hole. - No problem as we do
-	 * not support bmap in any form whatsoever. The FIBMAP sys call is
-	 * deprecated anyway and NTFS is not a block based file system so
-	 * allowing bmapping is complete and utter garbage IMO. Use mmap once
-	 * we implement it... (AIA)
-	 */
+		return -2;
 	if (data->initialized <= (__s64)vcn << ino->vol->cluster_size_bits)
-		return 0;
+		return -1;
 	for (rnum = 0; rnum < data->d.r.len &&
-				vcn >= data->d.r.runlist[rnum].len; rnum++)
+			vcn >= data->d.r.runlist[rnum].len; rnum++)
 		vcn -= data->d.r.runlist[rnum].len;
-	/* We need to cope with sparse runs. (AIA) */
+	if (data->d.r.runlist[rnum].lcn >= 0)
+		return data->d.r.runlist[rnum].lcn + vcn;
 	return data->d.r.runlist[rnum].lcn + vcn;
 }
 
diff -u --recursive --new-file v2.4.10/linux/fs/open.c linux/fs/open.c
--- v2.4.10/linux/fs/open.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/open.c	Fri Oct  5 12:23:53 2001
@@ -554,7 +554,7 @@
 		newattrs.ia_mode &= ~S_ISGID;
 		newattrs.ia_valid |= ATTR_MODE;
 	}
-	error = DQUOT_TRANSFER(dentry, &newattrs);
+	error = notify_change(dentry, &newattrs);
 out:
 	return error;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/acorn.c linux/fs/partitions/acorn.c
--- v2.4.10/linux/fs/partitions/acorn.c	Mon Sep 18 15:15:26 2000
+++ linux/fs/partitions/acorn.c	Mon Oct  1 20:03:26 2001
@@ -22,15 +22,16 @@
 #include "acorn.h"
 
 static void
-adfspart_setgeometry(kdev_t dev, unsigned int secspertrack, unsigned int heads,
-		     unsigned long totalblocks)
+adfspart_setgeometry(kdev_t dev, unsigned int secspertrack, unsigned int heads)
 {
+#ifdef CONFIG_BLK_DEV_MFM
 	extern void xd_set_geometry(kdev_t dev, unsigned char, unsigned char,
 				    unsigned long, unsigned int);
 
-#ifdef CONFIG_BLK_DEV_MFM
-	if (MAJOR(dev) == MFM_ACORN_MAJOR)
+	if (MAJOR(dev) == MFM_ACORN_MAJOR) {
+		unsigned long totalblocks = hd->part[MINOR(dev)].nr_sects;
 		xd_set_geometry(dev, secspertrack, heads, totalblocks, 1);
+	}
 #endif
 }
 
@@ -60,32 +61,26 @@
 
 #ifdef CONFIG_ACORN_PARTITION_RISCIX
 static int
-riscix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sect,
-		 int minor, unsigned long nr_sects)
+riscix_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sect, int minor, unsigned long nr_sects)
 {
-	struct buffer_head *bh;
+	Sector sect;
 	struct riscix_record *rr;
-	unsigned int riscix_minor;
 	
-	if(get_ptable_blocksize(dev)!=1024)
-		return 0;
+	rr = (struct riscix_record *)read_dev_sector(bdev, first_sect, &sect);
+	if (!rr)
+		return -1;
 
 	printk(" [RISCiX]");
 
-	add_gd_partition(hd, riscix_minor = minor++, first_sect, nr_sects);
-	hd->sizes[riscix_minor] = hd->part[riscix_minor].nr_sects >>
-					(BLOCK_SIZE_BITS - 9);
-	dev = MKDEV(hd->major, riscix_minor);
-
-	if (!(bh = bread(dev, 0, 1024)))
-		return -1;
 
-	rr = (struct riscix_record *)bh->b_data;
 	if (rr->magic == RISCIX_MAGIC) {
+		unsigned long size = nr_sects > 2 ? 2 : nr_sects;
 		int part;
 
 		printk(" <");
 
+		add_gd_partition(hd, minor++, first_sect, size);
 		for (part = 0; part < 8; part++) {
 			if (rr->part[part].one &&
 			    memcmp(rr->part[part].name, "All\0", 4)) {
@@ -97,38 +92,32 @@
 		}
 
 		printk(" >\n");
-
-		if (hd->part[riscix_minor].nr_sects > 2)
-			hd->part[riscix_minor].nr_sects = 2;
+	} else {
+		add_gd_partition(hd, minor++, first_sect, nr_sects);
 	}
 
-	brelse(bh);
+	put_dev_sector(sect);
 	return minor;
 }
 #endif
 
 static int
-linux_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sect,
-		int minor, unsigned long nr_sects)
+linux_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sect, int minor, unsigned long nr_sects)
 {
-	struct buffer_head *bh;
+	Sector sect;
 	struct linux_part *linuxp;
-	unsigned int linux_minor, mask = (1 << hd->minor_shift) - 1;
+	unsigned int mask = (1 << hd->minor_shift) - 1;
+	unsigned long size = nr_sects > 2 ? 2 : nr_sects;
 
-	if(get_ptable_blocksize(dev)!=1024)
-		return 0;
-		
 	printk(" [Linux]");
 
-	add_gd_partition(hd, linux_minor = minor++, first_sect, nr_sects);
-	hd->sizes[linux_minor] = hd->part[linux_minor].nr_sects >>
-					(BLOCK_SIZE_BITS - 9);
-	dev = MKDEV(hd->major, linux_minor);
+	add_gd_partition(hd, minor++, first_sect, size);
 
-	if (!(bh = bread(dev, 0, 1024)))
+	linuxp = (struct linux_part *)read_dev_sector(bdev, first_sect, &sect);
+	if (!linuxp)
 		return -1;
 
-	linuxp = (struct linux_part *)bh->b_data;
 	printk(" <");
 	while (linuxp->magic == cpu_to_le32(LINUX_NATIVE_MAGIC) ||
 	       linuxp->magic == cpu_to_le32(LINUX_SWAP_MAGIC)) {
@@ -140,29 +129,22 @@
 		linuxp ++;
 	}
 	printk(" >");
-	/*
-	 * Prevent someone doing a mkswap or mkfs on this partition
-	 */
-	if(hd->part[linux_minor].nr_sects > 2)
-		hd->part[linux_minor].nr_sects = 2;
 
-	brelse(bh);
+	put_dev_sector(sect);
 	return minor;
 }
 
 #ifdef CONFIG_ACORN_PARTITION_CUMANA
 static int
-adfspart_check_CUMANA(struct gendisk *hd, kdev_t dev,
+adfspart_check_CUMANA(struct gendisk *hd, struct block_device *bdev,
 		      unsigned long first_sector, int minor)
 {
 	unsigned int start_blk = 0, mask = (1 << hd->minor_shift) - 1;
-	struct buffer_head *bh = NULL;
+	Sector sect;
+	unsigned char *data;
 	char *name = "CUMANA/ADFS";
 	int first = 1;
 
-	if(get_ptable_blocksize(dev)!=1024)
-		return 0;
-
 	/*
 	 * Try Cumana style partitions - sector 3 contains ADFS boot block
 	 * with pointer to next 'drive'.
@@ -183,16 +165,17 @@
 		if (!(minor & mask))
 			break;
 
-		if (!(bh = bread(dev, start_blk + 3, 1024)))
+		data = read_dev_sector(bdev, start_blk * 2 + 6, &sect);
+		if (!data)
 			return -1;
 
-		dr = adfs_partition(hd, name, bh->b_data,
-				    first_sector, minor++);
+		dr = adfs_partition(hd, name, data, first_sector, minor++);
 		if (!dr)
 			break;
+
 		name = NULL;
 
-		nr_sects = (bh->b_data[0x1fd] + (bh->b_data[0x1fe] << 8)) *
+		nr_sects = (data[0x1fd] + (data[0x1fe] << 8)) *
 			   (dr->heads + (dr->lowsector & 0x40 ? 1 : 0)) *
 			   dr->secspertrack;
 
@@ -204,30 +187,28 @@
 		start_blk += nr_sects >> (BLOCK_SIZE_BITS - 9);
 		nr_sects = 0; /* hmm - should be partition size */
 
-		switch (bh->b_data[0x1fc] & 15) {
+		switch (data[0x1fc] & 15) {
 		case 0: /* No partition / ADFS? */
 			break;
 
 #ifdef CONFIG_ACORN_PARTITION_RISCIX
 		case PARTITION_RISCIX_SCSI:
 			/* RISCiX - we don't know how to find the next one. */
-			minor = riscix_partition(hd, dev, first_sector,
+			minor = riscix_partition(hd, bdev, first_sector,
 						 minor, nr_sects);
 			break;
 #endif
 
 		case PARTITION_LINUX:
-			minor = linux_partition(hd, dev, first_sector,
+			minor = linux_partition(hd, bdev, first_sector,
 						minor, nr_sects);
 			break;
 		}
-		brelse(bh);
-		bh = NULL;
+		put_dev_sector(sect);
 		if (minor == -1)
 			return minor;
 	} while (1);
-	if (bh)
-		bforget(bh);
+	put_dev_sector(sect);
 	return first ? 0 : 1;
 }
 #endif
@@ -248,73 +229,73 @@
  *	    hda2 = non-ADFS partition.
  */
 static int
-adfspart_check_ADFS(struct gendisk *hd, kdev_t dev,
+adfspart_check_ADFS(struct gendisk *hd, struct block_device *bdev,
 		   unsigned long first_sector, int minor)
 {
 	unsigned long start_sect, nr_sects, sectscyl, heads;
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	struct adfs_discrecord *dr;
+	unsigned char id;
 
-	if(get_ptable_blocksize(dev)!=1024)
-		return 0;
-
-	if (!(bh = bread(dev, 3, 1024)))
+	data = read_dev_sector(bdev, 6, &sect);
+	if (!data)
 		return -1;
 
-	dr = adfs_partition(hd, "ADFS", bh->b_data, first_sector, minor++);
+	dr = adfs_partition(hd, "ADFS", data, first_sector, minor++);
 	if (!dr) {
-		bforget(bh);
+		put_dev_sector(sect);
     		return 0;
 	}
 
 	heads = dr->heads + ((dr->lowsector >> 6) & 1);
-	adfspart_setgeometry(dev, dr->secspertrack, heads,
-			     hd->part[MINOR(dev)].nr_sects);
 	sectscyl = dr->secspertrack * heads;
+	start_sect = ((data[0x1fe] << 8) + data[0x1fd]) * sectscyl;
+	id = data[0x1fc] & 15;
+	put_dev_sector(sect);
+
+	adfspart_setgeometry(to_kdev_t(bdev->bd_dev), dr->secspertrack, heads);
+	invalidate_bdev(bdev, 1);
+	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
 
 	/*
 	 * Work out start of non-adfs partition.
 	 */
-	start_sect = ((bh->b_data[0x1fe] << 8) + bh->b_data[0x1fd]) * sectscyl;
-	nr_sects = hd->part[MINOR(dev)].nr_sects - start_sect;
+	nr_sects = hd->part[MINOR(to_kdev_t(bdev->bd_dev))].nr_sects - start_sect;
 
 	if (start_sect) {
 		first_sector += start_sect;
 
-		switch (bh->b_data[0x1fc] & 15) {
+		switch (id) {
 #ifdef CONFIG_ACORN_PARTITION_RISCIX
 		case PARTITION_RISCIX_SCSI:
 		case PARTITION_RISCIX_MFM:
-			minor = riscix_partition(hd, dev, first_sector,
+			minor = riscix_partition(hd, bdev, first_sector,
 						 minor, nr_sects);
 			break;
 #endif
 
 		case PARTITION_LINUX:
-			minor = linux_partition(hd, dev, first_sector,
+			minor = linux_partition(hd, bdev, first_sector,
 						minor, nr_sects);
 			break;
 		}
 	}
-	brelse(bh);
 	return 1;
 }
 #endif
 
 #ifdef CONFIG_ACORN_PARTITION_ICS
-static int adfspart_check_ICSLinux(kdev_t dev, unsigned long block)
+static int adfspart_check_ICSLinux(struct block_device *bdev, unsigned long block)
 {
-	struct buffer_head *bh;
-	unsigned int offset = block & 1 ? 512 : 0;
+	Sector sect;
+	unsigned char *data = read_dev_sector(bdev, block, &sect);
 	int result = 0;
 
-	bh = bread(dev, block >> 1, 1024);
-
-	if (bh != NULL) {
-		if (memcmp(bh->b_data + offset, "LinuxPart", 9) == 0)
+	if (data) {
+		if (memcmp(data, "LinuxPart", 9) == 0)
 			result = 1;
-
-		brelse(bh);
+		put_dev_sector(sect);
 	}
 
 	return result;
@@ -333,38 +314,37 @@
  *		..etc..
  */
 static int
-adfspart_check_ICS(struct gendisk *hd, kdev_t dev,
+adfspart_check_ICS(struct gendisk *hd, struct block_device *bdev,
 		   unsigned long first_sector, int minor)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	unsigned long sum;
 	unsigned int i, mask = (1 << hd->minor_shift) - 1;
 	struct ics_part *p;
 
-	if(get_ptable_blocksize(dev)!=1024)
-		return 0;
-		
 	/*
 	 * Try ICS style partitions - sector 0 contains partition info.
 	 */
-	if (!(bh = bread(dev, 0, 1024)))
+	data = read_dev_sector(bdev, 0, &sect);
+	if (!data)
 	    	return -1;
 
 	/*
 	 * check for a valid checksum
 	 */
 	for (i = 0, sum = 0x50617274; i < 508; i++)
-		sum += bh->b_data[i];
+		sum += data[i];
 
-	sum -= le32_to_cpu(*(__u32 *)(&bh->b_data[508]));
+	sum -= le32_to_cpu(*(__u32 *)(&data[508]));
 	if (sum) {
-	    	bforget(bh);
+	    	put_dev_sector(sect);
 		return 0; /* not ICS partition table */
 	}
 
 	printk(" [ICS]");
 
-	for (p = (struct ics_part *)bh->b_data; p->size; p++) {
+	for (p = (struct ics_part *)data; p->size; p++) {
 		unsigned long start;
 		long size;
 
@@ -381,7 +361,7 @@
 			 * We use the first sector to identify what type
 			 * this partition is...
 			 */
-			if (size > 1 && adfspart_check_ICSLinux(dev, start)) {
+			if (size > 1 && adfspart_check_ICSLinux(bdev, start)) {
 				start += 1;
 				size -= 1;
 			}
@@ -393,12 +373,11 @@
 		}
 	}
 
-	brelse(bh);
+	put_dev_sector(sect);
 	return 1;
 }
 #endif
 
-#ifdef CONFIG_ACORN_PARTITION_POWERTEC
 /*
  * Purpose: allocate ICS partitions.
  * Params : hd		- pointer to gendisk structure to store partition info.
@@ -411,29 +390,32 @@
  *	    hda2 = ADFS partition 1 on first drive.
  *		..etc..
  */
+#ifdef CONFIG_ACORN_PARTITION_POWERTEC
 static int
-adfspart_check_POWERTEC(struct gendisk *hd, kdev_t dev,
+adfspart_check_POWERTEC(struct gendisk *hd, struct block_device *bdev,
 			unsigned long first_sector, int minor)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	struct ptec_partition *p;
 	unsigned char checksum;
 	int i;
 
-	if (!(bh = bread(dev, 0, 1024)))
+	data = read_dev_sector(bdev, 0, &sect);
+	if (!data)
 		return -1;
 
 	for (checksum = 0x2a, i = 0; i < 511; i++)
-		checksum += bh->b_data[i];
+		checksum += data[i];
 
-	if (checksum != bh->b_data[511]) {
-		bforget(bh);
+	if (checksum != data[511]) {
+		put_dev_sector(sect);
 		return 0;
 	}
 
 	printk(" [POWERTEC]");
 
-	for (i = 0, p = (struct ptec_partition *)bh->b_data; i < 12; i++, p++) {
+	for (i = 0, p = (struct ptec_partition *)data; i < 12; i++, p++) {
 		unsigned long start;
 		unsigned long size;
 
@@ -446,24 +428,24 @@
 		minor++;
 	}
 
-	brelse(bh);
+	put_dev_sector(sect);
 	return 1;
 }
 #endif
 
-static int (*partfn[])(struct gendisk *, kdev_t, unsigned long, int) = {
+static int (*partfn[])(struct gendisk *, struct block_device *, unsigned long, int) = {
 #ifdef CONFIG_ACORN_PARTITION_ICS
 	adfspart_check_ICS,
 #endif
+#ifdef CONFIG_ACORN_PARTITION_POWERTEC
+	adfspart_check_POWERTEC,
+#endif
 #ifdef CONFIG_ACORN_PARTITION_CUMANA
 	adfspart_check_CUMANA,
 #endif
 #ifdef CONFIG_ACORN_PARTITION_ADFS
 	adfspart_check_ADFS,
 #endif
-#ifdef CONFIG_ACORN_PARTITION_POWERTEC
-	adfspart_check_POWERTEC,
-#endif
 	NULL
 };
 /*
@@ -478,17 +460,18 @@
  *
  * Returns: -1 on error, 0 if not ADFS format, 1 if ok.
  */
-int acorn_partition(struct gendisk *hd, kdev_t dev,
+int acorn_partition(struct gendisk *hd, struct block_device *bdev,
 		    unsigned long first_sect, int first_minor)
 {
-	int r = 0, i;
-
-	for (i = 0; partfn[i] && r == 0; i++)
-		r = partfn[i](hd, dev, first_sect, first_minor);
+	int i;
 
-	if (r < 0 && warn_no_part)
-		printk(" unable to read boot sectors / partition sectors\n");
-	if (r > 0)
-		printk("\n");
-	return r;
+	for (i = 0; partfn[i]; i++) {
+		int r = partfn[i](hd, bdev, first_sect, first_minor);
+		if (r) {
+			if (r > 0)
+				printk("\n");
+			return r;
+		}
+	}
+	return 0;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/acorn.h linux/fs/partitions/acorn.h
--- v2.4.10/linux/fs/partitions/acorn.h	Tue Aug  7 12:51:06 2001
+++ linux/fs/partitions/acorn.h	Tue Oct  9 15:23:56 2001
@@ -50,6 +50,6 @@
 };
 	
 
-int acorn_partition(struct gendisk *hd, kdev_t dev,
+int acorn_partition(struct gendisk *hd, struct block_device *bdev,
 		   unsigned long first_sect, int first_minor);
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/amiga.c linux/fs/partitions/amiga.c
--- v2.4.10/linux/fs/partitions/amiga.c	Wed Feb 16 15:42:06 2000
+++ linux/fs/partitions/amiga.c	Mon Oct  1 20:03:26 2001
@@ -31,90 +31,82 @@
 }
 
 int
-amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor)
+amiga_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sector, int first_part_minor)
 {
-	struct buffer_head	*bh;
-	struct RigidDiskBlock	*rdb;
-	struct PartitionBlock	*pb;
-	int			 start_sect;
-	int			 nr_sects;
-	int			 blk;
-	int			 part, res;
-	int			 old_blocksize;
-	int			 blocksize;
-
-	old_blocksize = get_ptable_blocksize(dev);
-	blocksize = get_hardsect_size(dev);
-
-	if (blocksize < 512)
-		blocksize = 512;
-
-	set_blocksize(dev,blocksize);
-	res = 0;
-
-	for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
-		if(!(bh = bread(dev,blk,blocksize))) {
-			if (warn_no_part) printk("Dev %s: unable to read RDB block %d\n",
-			       kdevname(dev),blk);
+	Sector sect;
+	unsigned char *data;
+	struct RigidDiskBlock *rdb;
+	struct PartitionBlock *pb;
+	int start_sect, nr_sects, blk, part, res = 0;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
+
+	for (blk = 0; ; blk++, put_dev_sector(sect)) {
+		if (blk == RDB_ALLOCATION_LIMIT)
+			goto rdb_done;
+		data = read_dev_sector(bdev, blk, &sect);
+		if (!data) {
+			if (warn_no_part)
+				printk("Dev %s: unable to read RDB block %d\n",
+				       bdevname(dev), blk);
 			goto rdb_done;
 		}
-		if (*(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK)) {
-			rdb = (struct RigidDiskBlock *)bh->b_data;
-			if (checksum_block((u32 *)bh->b_data,be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
-				/* Try again with 0xdc..0xdf zeroed, Windows might have
-				 * trashed it.
-				 */
-				*(u32 *)(&bh->b_data[0xdc]) = 0;
-				if (checksum_block((u32 *)bh->b_data,
-						be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
-					brelse(bh);
-					printk("Dev %s: RDB in block %d has bad checksum\n",
-					       kdevname(dev),blk);
-					continue;
-				}
-				printk("Warning: Trashed word at 0xd0 in block %d "
-					"ignored in checksum calculation\n",blk);
-			}
-			printk(" RDSK");
-			blk = be32_to_cpu(rdb->rdb_PartitionList);
-			brelse(bh);
-			for (part = 1; blk > 0 && part <= 16; part++) {
-				if (!(bh = bread(dev,blk,blocksize))) {
-					if (warn_no_part) printk("Dev %s: unable to read partition block %d\n",
-						       kdevname(dev),blk);
-					goto rdb_done;
-				}
-				pb  = (struct PartitionBlock *)bh->b_data;
-				blk = be32_to_cpu(pb->pb_Next);
-				if (pb->pb_ID == cpu_to_be32(IDNAME_PARTITION) && checksum_block(
-				    (u32 *)pb,be32_to_cpu(pb->pb_SummedLongs) & 0x7F) == 0 ) {
-
-					/* Tell Kernel about it */
-
-					if (!(nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
-							  be32_to_cpu(pb->pb_Environment[9])) *
-							 be32_to_cpu(pb->pb_Environment[3]) *
-							 be32_to_cpu(pb->pb_Environment[5]))) {
-						brelse(bh);
-						continue;
- 					}
-					start_sect = be32_to_cpu(pb->pb_Environment[9]) *
-						     be32_to_cpu(pb->pb_Environment[3]) *
-						     be32_to_cpu(pb->pb_Environment[5]);
-					add_gd_partition(hd,first_part_minor,start_sect,nr_sects);
-					first_part_minor++;
-					res = 1;
-				}
-				brelse(bh);
-			}
-			printk("\n");
+		if (*(u32 *)data != cpu_to_be32(IDNAME_RIGIDDISK))
+			continue;
+
+		rdb = (struct RigidDiskBlock *)data;
+		if (checksum_block((u32 *)data, be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F) == 0)
 			break;
+		/* Try again with 0xdc..0xdf zeroed, Windows might have
+		 * trashed it.
+		 */
+		*(u32 *)(data+0xdc) = 0;
+		if (checksum_block((u32 *)data,
+				be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) {
+			printk("Warning: Trashed word at 0xd0 in block %d "
+				"ignored in checksum calculation\n",blk);
+			break;
+		}
+
+		printk("Dev %s: RDB in block %d has bad checksum\n",
+			       bdevname(dev),blk);
+	}
+
+	printk(" RDSK");
+	blk = be32_to_cpu(rdb->rdb_PartitionList);
+	put_dev_sector(sect);
+	for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) {
+		data = read_dev_sector(bdev, blk, &sect);
+		if (!data) {
+			if (warn_no_part)
+				printk("Dev %s: unable to read partition block %d\n",
+				       bdevname(dev),blk);
+			goto rdb_done;
 		}
-		else
-			brelse(bh);
+		pb  = (struct PartitionBlock *)data;
+		blk = be32_to_cpu(pb->pb_Next);
+		if (pb->pb_ID != cpu_to_be32(IDNAME_PARTITION))
+			continue;
+		if (checksum_block((u32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 )
+			continue;
+
+		/* Tell Kernel about it */
+
+		nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
+			    be32_to_cpu(pb->pb_Environment[9])) *
+			   be32_to_cpu(pb->pb_Environment[3]) *
+			   be32_to_cpu(pb->pb_Environment[5]);
+		if (!nr_sects)
+			continue;
+		start_sect = be32_to_cpu(pb->pb_Environment[9]) *
+			     be32_to_cpu(pb->pb_Environment[3]) *
+			     be32_to_cpu(pb->pb_Environment[5]);
+		add_gd_partition(hd,first_part_minor,start_sect,nr_sects);
+		first_part_minor++;
+		res = 1;
 	}
+	printk("\n");
 
 rdb_done:
-	set_blocksize(dev,old_blocksize);
 	return res;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/amiga.h linux/fs/partitions/amiga.h
--- v2.4.10/linux/fs/partitions/amiga.h	Thu Aug 12 12:26:06 1999
+++ linux/fs/partitions/amiga.h	Mon Oct  1 20:03:26 2001
@@ -3,6 +3,6 @@
  */
 
 int
-amiga_partition(struct gendisk *hd, kdev_t dev,
+amiga_partition(struct gendisk *hd, struct block_device *bdev,
 		unsigned long first_sector, int first_part_minor);
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/atari.c linux/fs/partitions/atari.c
--- v2.4.10/linux/fs/partitions/atari.c	Thu Oct 12 14:19:32 2000
+++ linux/fs/partitions/atari.c	Mon Oct  1 20:03:26 2001
@@ -33,146 +33,130 @@
      be32_to_cpu((pi)->st) <= (hdsiz) &&				     \
      be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
 
-int atari_partition (struct gendisk *hd, kdev_t dev,
+static inline int OK_id(char *s)
+{
+	return  memcmp (s, "GEM", 3) == 0 || memcmp (s, "BGM", 3) == 0 ||
+		memcmp (s, "LNX", 3) == 0 || memcmp (s, "SWP", 3) == 0 ||
+		memcmp (s, "RAW", 3) == 0 ;
+}
+
+int atari_partition (struct gendisk *hd, struct block_device *bdev,
 		     unsigned long first_sector, int minor)
 {
-  int m_lim = minor + hd->max_p;
-  struct buffer_head *bh;
-  struct rootsector *rs;
-  struct partition_info *pi;
-  u32 extensect;
-  u32 hd_size;
+	int m_lim = minor + hd->max_p;
+	Sector sect;
+	struct rootsector *rs;
+	struct partition_info *pi;
+	u32 extensect;
+	u32 hd_size;
 #ifdef ICD_PARTS
-  int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
+	int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
 #endif
 
-  bh = bread (dev, 0, get_ptable_blocksize(dev));
-  if (!bh) {
-      if (warn_no_part) printk (" unable to read block 0 (partition table)\n");
-      return -1;
-  }
-
-  /* Verify this is an Atari rootsector: */
-  rs = (struct rootsector *) bh->b_data;
-  hd_size = hd->part[minor - 1].nr_sects;
-  if (!VALID_PARTITION(&rs->part[0], hd_size) &&
-      !VALID_PARTITION(&rs->part[1], hd_size) &&
-      !VALID_PARTITION(&rs->part[2], hd_size) &&
-      !VALID_PARTITION(&rs->part[3], hd_size)) {
-      /* if there's no valid primary partition, assume that no Atari
-	 format partition table (there's no reliable magic or the like
-	 :-() */
-      brelse(bh);
-      return 0;
-  }
-
-  pi = &rs->part[0];
-  printk (" AHDI");
-  for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
-    {
-      if (pi->flg & 1)
-	/* active partition */
-	{
-	  if (memcmp (pi->id, "XGM", 3) == 0)
-	    /* extension partition */
-	    {
-	      struct rootsector *xrs;
-	      struct buffer_head *xbh;
-	      ulong partsect;
+	rs = (struct rootsector *) read_dev_sector(bdev, 0, &sect);
+	if (!rs)
+		return -1;
+
+	/* Verify this is an Atari rootsector: */
+	hd_size = hd->part[minor - 1].nr_sects;
+	if (!VALID_PARTITION(&rs->part[0], hd_size) &&
+	    !VALID_PARTITION(&rs->part[1], hd_size) &&
+	    !VALID_PARTITION(&rs->part[2], hd_size) &&
+	    !VALID_PARTITION(&rs->part[3], hd_size)) {
+		/*
+		 * if there's no valid primary partition, assume that no Atari
+		 * format partition table (there's no reliable magic or the like
+	         * :-()
+		 */
+		put_dev_sector(sect);
+		return 0;
+	}
 
+	pi = &rs->part[0];
+	printk (" AHDI");
+	for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++) {
+		struct rootsector *xrs;
+		Sector sect2;
+		ulong partsect;
+
+		if ( !(pi->flg & 1) )
+			continue;
+		/* active partition */
+		if (memcmp (pi->id, "XGM", 3) != 0) {
+			/* we don't care about other id's */
+			add_gd_partition (hd, minor, be32_to_cpu(pi->st),
+					be32_to_cpu(pi->siz));
+			continue;
+		}
+		/* extension partition */
 #ifdef ICD_PARTS
-	      part_fmt = 1;
+		part_fmt = 1;
 #endif
-	      printk(" XGM<");
-	      partsect = extensect = be32_to_cpu(pi->st);
-	      while (1)
-		{
-		  xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev));
-		  if (!xbh)
-		    {
-		      printk (" block %ld read failed\n", partsect);
-		      brelse(bh);
-		      return 0;
-		    }
-		  if (partsect & 1)
-		    xrs = (struct rootsector *) &xbh->b_data[512];
-		  else
-		    xrs = (struct rootsector *) &xbh->b_data[0];
-
-		  /* ++roman: sanity check: bit 0 of flg field must be set */
-		  if (!(xrs->part[0].flg & 1)) {
-		    printk( "\nFirst sub-partition in extended partition is not valid!\n" );
-		    break;
-		  }
+		printk(" XGM<");
+		partsect = extensect = be32_to_cpu(pi->st);
+		while (1) {
+			xrs = (struct rootsector *)read_dev_sector(bdev, partsect, &sect2);
+			if (!xrs) {
+				printk (" block %ld read failed\n", partsect);
+				put_dev_sector(sect);
+				return 0;
+			}
+
+			/* ++roman: sanity check: bit 0 of flg field must be set */
+			if (!(xrs->part[0].flg & 1)) {
+				printk( "\nFirst sub-partition in extended partition is not valid!\n" );
+				put_dev_sector(sect2);
+				break;
+			}
 
-		  add_gd_partition(hd, minor,
+			add_gd_partition(hd, minor,
 				   partsect + be32_to_cpu(xrs->part[0].st),
 				   be32_to_cpu(xrs->part[0].siz));
 
-		  if (!(xrs->part[1].flg & 1)) {
-		    /* end of linked partition list */
-		    brelse( xbh );
-		    break;
-		  }
-		  if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
-		    printk( "\nID of extended partition is not XGM!\n" );
-		    brelse( xbh );
-		    break;
-		  }
-
-		  partsect = be32_to_cpu(xrs->part[1].st) + extensect;
-		  brelse (xbh);
-		  minor++;
-		  if (minor >= m_lim) {
-		    printk( "\nMaximum number of partitions reached!\n" );
-		    break;
-		  }
+			if (!(xrs->part[1].flg & 1)) {
+				/* end of linked partition list */
+				put_dev_sector(sect2);
+				break;
+			}
+			if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
+				printk("\nID of extended partition is not XGM!\n");
+				put_dev_sector(sect2);
+				break;
+			}
+
+			partsect = be32_to_cpu(xrs->part[1].st) + extensect;
+			put_dev_sector(sect2);
+			minor++;
+			if (minor >= m_lim) {
+				printk( "\nMaximum number of partitions reached!\n" );
+				break;
+			}
 		}
-	      printk(" >");
-	    }
-	  else
-	    {
-	      /* we don't care about other id's */
-	      add_gd_partition (hd, minor, be32_to_cpu(pi->st),
-				be32_to_cpu(pi->siz));
-	    }
+		printk(" >");
 	}
-    }
 #ifdef ICD_PARTS
-  if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
-  {
-    pi = &rs->icdpart[0];
-    /* sanity check: no ICD format if first partition invalid */
-    if (memcmp (pi->id, "GEM", 3) == 0 ||
-        memcmp (pi->id, "BGM", 3) == 0 ||
-        memcmp (pi->id, "LNX", 3) == 0 ||
-        memcmp (pi->id, "SWP", 3) == 0 ||
-        memcmp (pi->id, "RAW", 3) == 0 )
-    {
-      printk(" ICD<");
-      for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
-      {
-        /* accept only GEM,BGM,RAW,LNX,SWP partitions */
-        if (pi->flg & 1 && 
-            (memcmp (pi->id, "GEM", 3) == 0 ||
-             memcmp (pi->id, "BGM", 3) == 0 ||
-             memcmp (pi->id, "LNX", 3) == 0 ||
-             memcmp (pi->id, "SWP", 3) == 0 ||
-             memcmp (pi->id, "RAW", 3) == 0) )
-        {
-          part_fmt = 2;
-	  add_gd_partition (hd, minor, be32_to_cpu(pi->st),
-			    be32_to_cpu(pi->siz));
-        }
-      }
-      printk(" >");
-    }
-  }
+	if ( part_fmt!=1 ) { /* no extended partitions -> test ICD-format */
+		pi = &rs->icdpart[0];
+		/* sanity check: no ICD format if first partition invalid */
+		if (OK_id(pi->id)) {
+			printk(" ICD<");
+			for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++) {
+				/* accept only GEM,BGM,RAW,LNX,SWP partitions */
+				if (!((pi->flg & 1) && OK_id(pi->id)))
+					continue;
+				part_fmt = 2;
+				add_gd_partition (hd, minor,
+						be32_to_cpu(pi->st),
+						be32_to_cpu(pi->siz));
+			}
+			printk(" >");
+		}
+	}
 #endif
-  brelse (bh);
+	put_dev_sector(sect);
 
-  printk ("\n");
+	printk ("\n");
 
-  return 1;
+	return 1;
 }
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/atari.h linux/fs/partitions/atari.h
--- v2.4.10/linux/fs/partitions/atari.h	Sat Sep  4 13:09:36 1999
+++ linux/fs/partitions/atari.h	Mon Oct  1 20:03:26 2001
@@ -31,6 +31,6 @@
   u16 checksum;			/* checksum for bootable disks */
 } __attribute__((__packed__));
 
-int atari_partition (struct gendisk *hd, kdev_t dev,
+int atari_partition (struct gendisk *hd, struct block_device *bdev,
 		     unsigned long first_sector, int first_part_minor);
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/check.c linux/fs/partitions/check.c
--- v2.4.10/linux/fs/partitions/check.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/partitions/check.c	Mon Oct  1 20:03:26 2001
@@ -38,7 +38,7 @@
 
 int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
 
-static int (*check_part[])(struct gendisk *hd, kdev_t dev, unsigned long first_sect, int first_minor) = {
+static int (*check_part[])(struct gendisk *hd, struct block_device *bdev, unsigned long first_sect, int first_minor) = {
 #ifdef CONFIG_ACORN_PARTITION
 	acorn_partition,
 #endif
@@ -177,6 +177,15 @@
  			sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
  		return buf;
  	}
+	if (hd->major == ATARAID_MAJOR) {
+		int disk = minor >> hd->minor_shift;
+		int part = minor & (( 1 << hd->minor_shift) - 1);
+		if (part == 0)
+			sprintf(buf, "%s/d%d", maj, disk);
+		else
+			sprintf(buf, "%s/d%dp%d", maj, disk, part);
+		return buf;
+	}
 	if (part)
 		sprintf(buf, "%s%c%d", maj, unit+'a', part);
 	else
@@ -206,54 +215,12 @@
 #endif
 }
 
-unsigned int get_ptable_blocksize(kdev_t dev)
-{
-	int ret = 1024;
-
-	/*
-	 * See whether the low-level driver has given us a minumum blocksize.
-	 * If so, check to see whether it is larger than the default of 1024.
-	 */
-	if (!blksize_size[MAJOR(dev)])
-		return ret;
-
-	/*
-	 * Check for certain special power of two sizes that we allow.
-	 * With anything larger than 1024, we must force the blocksize up to
-	 * the natural blocksize for the device so that we don't have to try
-	 * and read partial sectors.  Anything smaller should be just fine.
-	 */
-
-	switch (blksize_size[MAJOR(dev)][MINOR(dev)]) {
-		case 2048:
-			ret = 2048;
-			break;
-		case 4096:
-			ret = 4096;
-			break;
-		case 8192:
-			ret = 8192;
-			break;
-		case 1024:
-		case 512:
-		case 256:
-		case 0:
-			/*
-			 * These are all OK.
-			 */
-			break;
-		default:
-			panic("Strange blocksize for partition table\n");
-	}
-
-	return ret;
-}
-
 static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
 {
 	devfs_handle_t de = NULL;
 	static int first_time = 1;
 	unsigned long first_sector;
+	struct block_device *bdev;
 	char buf[64];
 	int i;
 
@@ -278,12 +245,23 @@
 		printk(KERN_INFO " /dev/%s:", buf + i);
 	else
 		printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf));
-	for (i = 0; check_part[i]; i++)
-		if (check_part[i](hd, dev, first_sector, first_part_minor))
+	bdev = bdget(kdev_t_to_nr(dev));
+	bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9;
+	for (i = 0; check_part[i]; i++) {
+		int res;
+		res = check_part[i](hd, bdev, first_sector, first_part_minor);
+		if (res) {
+			if (res < 0 &&  warn_no_part)
+				printk(" unable to read partition table\n");
 			goto setup_devfs;
+		}
+	}
 
 	printk(" unknown partition table\n");
 setup_devfs:
+	invalidate_bdev(bdev, 1);
+	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
+	bdput(bdev);
 	i = first_part_minor - 1;
 	devfs_register_partitions (hd, i, hd->sizes ? 0 : 1);
 }
@@ -418,4 +396,27 @@
 			dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
 		blk_size[dev->major] = dev->sizes;
 	}
+}
+
+unsigned char *read_dev_sector(struct block_device *bdev, unsigned long n, Sector *p)
+{
+	struct address_space *mapping = bdev->bd_inode->i_mapping;
+	int sect = PAGE_CACHE_SIZE / 512;
+	struct page *page;
+
+	page = read_cache_page(mapping, n/sect,
+			(filler_t *)mapping->a_ops->readpage, NULL);
+	if (!IS_ERR(page)) {
+		wait_on_page(page);
+		if (!Page_Uptodate(page))
+			goto fail;
+		if (PageError(page))
+			goto fail;
+		p->v = page;
+		return (unsigned char *)page_address(page) + 512 * (n % sect);
+fail:
+		page_cache_release(page);
+	}
+	p->v = NULL;
+	return NULL;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/check.h linux/fs/partitions/check.h
--- v2.4.10/linux/fs/partitions/check.h	Wed Feb 16 15:42:06 2000
+++ linux/fs/partitions/check.h	Mon Oct  1 20:03:26 2001
@@ -4,9 +4,13 @@
  */
 void add_gd_partition(struct gendisk *hd, int minor, int start, int size);
 
-/*
- * Get the default block size for this device
- */
-unsigned int get_ptable_blocksize(kdev_t dev);
+typedef struct {struct page *v;} Sector;
+
+unsigned char *read_dev_sector(struct block_device *, unsigned long, Sector *);
+
+static inline void put_dev_sector(Sector p)
+{
+	page_cache_release(p.v);
+}
 
 extern int warn_no_part;
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/ibm.c linux/fs/partitions/ibm.c
--- v2.4.10/linux/fs/partitions/ibm.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/partitions/ibm.c	Mon Oct  1 20:03:26 2001
@@ -42,30 +42,6 @@
 			     [ibm_partition_none] = "(nonl)"
 };
 
-static int
-get_drive_geometry(int kdev,struct hd_geometry *geo) 
-{
-	struct block_device *bdev = bdget(kdev_t_to_nr(kdev));
-	int rc = blkdev_get(bdev, 0, 1, BDEV_FILE);
-        if ( rc == 0 ) {
-		rc = ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo);
-		blkdev_put(bdev, BDEV_FILE);
-	}
-	return rc;
-}
-
-static int
-get_drive_info(int kdev,dasd_information_t *info) 
-{
-	struct block_device *bdev = bdget(kdev_t_to_nr(kdev));
-	int rc = blkdev_get(bdev, 0, 1, BDEV_FILE);
-        if ( rc == 0 ) {
-		rc = ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)(info));
-		blkdev_put(bdev, BDEV_FILE);
-	}
-	return rc;
-}
-
 static ibm_partition_t
 get_partition_type ( char * type )
 {
@@ -89,10 +65,8 @@
 	       int offset,
 	       int size) {
 
-        add_gd_partition( hd, minor, 0,size);
-	add_gd_partition( hd, minor + 1, 
-			   offset * (blocksize >> 9),
-			   size-offset*(blocksize>>9));
+        add_gd_partition( hd, minor, 0, size);
+	add_gd_partition( hd, minor+1, offset*blocksize, size-offset*blocksize);
 }
 
 
@@ -119,10 +93,11 @@
 }
 
 int 
-ibm_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int
-first_part_minor)
+ibm_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sector, int first_part_minor)
 {
-	struct buffer_head *bh, *buf;
+	Sector sect, sect2;
+	unsigned char *data;
 	ibm_partition_t partition_type;
 	char type[5] = {0,};
 	char name[7] = {0,};
@@ -133,40 +108,41 @@
 	format1_label_t f1;
 	volume_label_t vlabel;
 	dasd_information_t *info;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
 
-	if ( first_sector != 0 ) {
+	if ( first_sector != 0 )
 		BUG();
-	}
+
 	info = (struct dasd_information_t *)kmalloc(sizeof(dasd_information_t),
 						    GFP_KERNEL);
 	if ( info == NULL )
 		return 0;
-	if (get_drive_info (dev,info)) 
+	if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)(info)))
 		return 0;
 	geo = (struct hd_geometry *)kmalloc(sizeof(struct hd_geometry),
 					    GFP_KERNEL);
 	if ( geo == NULL )
 		return 0;
-	if (get_drive_geometry (dev,geo)) 
+	if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo);
 		return 0;
 	blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
 	if ( blocksize <= 0 ) {
 		return 0;
 	}
+	blocksize >>= 9;
 	
-	set_blocksize(dev, blocksize);  /* OUCH !! */
-	if ( ( bh = bread( dev, info->label_block, blocksize) ) != NULL ) {
-		strncpy ( type,bh -> b_data + 0, 4);
-		if ((!info->FBA_layout) && (!strcmp(info->type,"ECKD"))) {
-		        
-		        strncpy ( name,bh -> b_data + 8, 6);
-		} else {
-		        strncpy ( name,bh -> b_data + 4, 6);		  
-		}
-		memcpy (&vlabel, bh->b_data, sizeof(volume_label_t));
-        } else {
+	data = read_dev_sector(bdev, inode->label_block*blocksize, &sect);
+	if (!data)
 		return 0;
+
+	strncpy (type, data, 4);
+	if ((!info->FBA_layout) && (!strcmp(info->type,"ECKD"))) {
+		strncpy ( name, data + 8, 6);
+	} else {
+		strncpy ( name, data + 4, 6);
 	}
+	memcpy (&vlabel, data, sizeof(volume_label_t));
+
 	EBCASC(type,4);
 	EBCASC(name,6);
 	
@@ -174,12 +150,12 @@
 	printk ( "%4s/%8s:",part_names[partition_type],name);
 	switch ( partition_type ) {
 	case ibm_partition_cms1:
-		if (* (((long *)bh->b_data) + 13) != 0) {
+		if (* ((long *)data + 13) != 0) {
 			/* disk is reserved minidisk */
-			long *label=(long*)bh->b_data;
-			blocksize = label[3];
+			long *label=(long*)data;
+			blocksize = label[3]>>9;
 			offset = label[13];
-			size = (label[7]-1)*(blocksize>>9); 
+			size = (label[7]-1)*blocksize; 
 			printk ("(MDSK)");
 		} else {
 			offset = (info->label_block + 1);
@@ -199,9 +175,10 @@
 		
 		/* get block number and read then first format1 label */
 		blk = cchhb2blk(&vlabel.vtoc, geo) + 1;
-		if ((buf = bread( dev, blk, blocksize)) != NULL) {
-		        memcpy (&f1, buf->b_data, sizeof(format1_label_t));
-			bforget(buf);
+		data = read_dev_sector(bdev, blk * blocksize, &sect2);
+		if (data) {
+		        memcpy (&f1, data, sizeof(format1_label_t));
+			put_dev_sector(sect2);
 		}
 		
 		while (f1.DS1FMTID == _ascebc['1']) {
@@ -211,14 +188,14 @@
 			
 			counter++;
 			add_gd_partition(hd, MINOR(dev) + counter, 
-					 offset * (blocksize >> 9),
-					 psize * (blocksize >> 9));
+					 offset * blocksize,
+					 psize * blocksize);
 			
 			blk++;
-			if ((buf = bread( dev, blk, blocksize)) != NULL) {
-			        memcpy (&f1, buf->b_data, 
-					sizeof(format1_label_t));
-				bforget(buf);
+			data = read_dev_sector(bdev, blk * blocksize, &sect2);
+			if (data) {
+			        memcpy (&f1, data, sizeof(format1_label_t));
+				put_dev_sector(sect2);
 			}
 		}
 		break;
@@ -228,6 +205,6 @@
 	}
 	
 	printk ( "\n" );
-	bforget(bh);
+	put_dev_sector(sect);
 	return 1;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/ibm.h linux/fs/partitions/ibm.h
--- v2.4.10/linux/fs/partitions/ibm.h	Fri Feb 16 16:02:37 2001
+++ linux/fs/partitions/ibm.h	Mon Oct  1 20:03:26 2001
@@ -1 +1 @@
-int ibm_partition(struct gendisk *, kdev_t, unsigned long, int);
+int ibm_partition(struct gendisk *, struct block_device *, unsigned long, int);
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/ldm.c linux/fs/partitions/ldm.c
--- v2.4.10/linux/fs/partitions/ldm.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/partitions/ldm.c	Mon Oct  1 20:03:26 2001
@@ -178,10 +178,12 @@
  */
 static int create_data_partitions(struct gendisk *hd,
 		const unsigned long first_sector, int first_part_minor,
-		const kdev_t dev, const struct vmdb *vm,
-		const struct privhead *ph, const struct ldmdisk *dk)
+		struct block_device *bdev, const struct vmdb *vm,
+		const struct privhead *ph, const struct ldmdisk *dk,
+		unsigned long base)
 {
-	struct buffer_head *bh;
+	Sector  sect;
+	unsigned char *data;
 	struct vblk *vb;
 	int vblk;
 	int vsize;		/* VBLK size. */
@@ -192,14 +194,14 @@
 	if (!vb)
 		goto no_mem;
 	vsize   = vm->vblk_size;
-	if (vsize < 1 || vsize > LDM_BLOCKSIZE)
+	if (vsize < 1 || vsize > 512)
 		goto err_out;
-	perbuf  = LDM_BLOCKSIZE / vsize;
-	if (perbuf < 1 || LDM_BLOCKSIZE % vsize)
+	perbuf  = 512 / vsize;
+	if (perbuf < 1 || 512 % vsize)
 		goto err_out;
 					/* 512 == VMDB size */
-	lastbuf = (vm->last_vblk_seq - (512 / vsize)) / perbuf;
-	lastofs = (vm->last_vblk_seq - (512 / vsize)) % perbuf;
+	lastbuf = vm->last_vblk_seq / perbuf - 1;
+	lastofs = vm->last_vblk_seq % perbuf;
 	if (lastofs)
 		lastbuf++;
 	if (OFF_VBLK * LDM_BLOCKSIZE + vm->last_vblk_seq * vsize >
@@ -207,17 +209,18 @@
 		goto err_out;
 	printk(" <");
 	for (buffer = 0; buffer < lastbuf; buffer++) {
-		if (!(bh = bread(dev, buffer + OFF_VBLK, LDM_BLOCKSIZE)))
+		data = read_dev_sector(bdev, base + 2*OFF_VBLK + buffer, &sect);
+		if (!data)
 			goto read_err;
 		for (vblk = 0; vblk < perbuf; vblk++) {
 			u8 *block;
 			
 			if (lastofs && buffer == lastbuf - 1 && vblk >= lastofs)
 				break;
-			block = bh->b_data + vsize * vblk;
-			if (block + vsize > (u8*)bh->b_data + LDM_BLOCKSIZE)
+			block = data + vsize * vblk;
+			if (block + vsize > data + 512)
 				goto brelse_out;
-			if (parse_vblk(block, LDM_BLOCKSIZE, vb) != 1)
+			if (parse_vblk(block, vsize, vb) != 1)
 				continue;
 			if (vb->vblk_type != VBLK_PART)
 				continue;
@@ -229,7 +232,7 @@
 					vb->num_sectors) == 1)
 				first_part_minor++;
 		}
-		brelse(bh);
+		put_dev_sector(sect);
 	}
 	printk(" >\n");
 	err = 1;
@@ -237,7 +240,7 @@
 	kfree(vb);
 	return err;
 brelse_out:
-	brelse(bh);
+	put_dev_sector(sect);
 	goto err_out;
 no_mem:
 	printk(LDM_CRIT "Not enough memory to allocate required buffers.\n");
@@ -326,10 +329,12 @@
  *
  * Return 1 on success and -1 on error, in which case @dk is undefined.
  */
-static int get_disk_objid(const kdev_t dev, const struct vmdb *vm,
-		const struct privhead *ph, struct ldmdisk *dk)
+static int get_disk_objid(struct block_device *bdev, const struct vmdb *vm,
+		const struct privhead *ph, struct ldmdisk *dk,
+		unsigned long base)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	u8 *disk_id;
 	int vblk;
 	int vsize;		/* VBLK size. */
@@ -340,21 +345,22 @@
 	if (!disk_id)
 		goto no_mem;
 	vsize   = vm->vblk_size;
-	if (vsize < 1 || vsize > LDM_BLOCKSIZE)
+	if (vsize < 1 || vsize > 512)
 		goto err_out;
-	perbuf  = LDM_BLOCKSIZE / vsize;
-	if (perbuf < 1 || LDM_BLOCKSIZE % vsize)
+	perbuf  = 512 / vsize;
+	if (perbuf < 1 || 512 % vsize)
 		goto err_out;
 					/* 512 == VMDB size */
-	lastbuf = (vm->last_vblk_seq - (512 / vsize)) / perbuf;
-	lastofs = (vm->last_vblk_seq - (512 / vsize)) % perbuf;
+	lastbuf = vm->last_vblk_seq / perbuf - 1;
+	lastofs = vm->last_vblk_seq % perbuf;
 	if (lastofs)
 		lastbuf++;
 	if (OFF_VBLK * LDM_BLOCKSIZE + vm->last_vblk_seq * vsize >
 			ph->config_size * 512)
 		goto err_out;
 	for (buffer = 0; buffer < lastbuf; buffer++) {
-		if (!(bh = bread(dev, buffer + OFF_VBLK, LDM_BLOCKSIZE)))
+		data = read_dev_sector(bdev, base + 2*OFF_VBLK + buffer, &sect);
+		if (!data)
 			goto read_err;
 		for (vblk = 0; vblk < perbuf; vblk++) {
 			int rel_objid, rel_name, delta;
@@ -362,20 +368,19 @@
 
 			if (lastofs && buffer == lastbuf - 1 && vblk >= lastofs)
 				break;
-			block = bh->b_data + vblk * vsize;
+			block = data + vblk * vsize;
 			delta = vblk * vsize + 0x18;
-			if (delta >= LDM_BLOCKSIZE)
+			if (delta >= 512)
 				goto brelse_out;
 			if (block[0x13] != VBLK_DISK)
 				continue;
 			/* Calculate relative offsets. */
 			rel_objid = 1 + block[0x18];
-			if (delta + rel_objid >= LDM_BLOCKSIZE)
+			if (delta + rel_objid >= 512)
 				goto brelse_out;
 			rel_name  = 1 + block[0x18 + rel_objid] + rel_objid;
-			if (delta + rel_name >= LDM_BLOCKSIZE ||
-			    delta + rel_name + block[0x18 + rel_name] >=
-					LDM_BLOCKSIZE)
+			if (delta + rel_name >= 512 ||
+			    delta + rel_name + block[0x18 + rel_name] >= 512)
 				goto brelse_out;
 			err = get_vstr(block + 0x18 + rel_name, disk_id,
 					DISK_ID_SIZE);
@@ -383,7 +388,7 @@
 				goto brelse_out;
 			if (!strncmp(disk_id, ph->disk_id, DISK_ID_SIZE)) {
 				dk->obj_id = get_vnum(block + 0x18, &err);
-				brelse(bh);
+				put_dev_sector(sect);
 				if (err)
 					goto out;
 				strncpy(dk->disk_id, ph->disk_id,
@@ -393,14 +398,14 @@
 				goto out;
 			}
 		}
-		brelse(bh);
+		put_dev_sector(sect);
 	}
 	err = -1;
 out:
 	kfree(disk_id);
 	return err;
 brelse_out:
-	brelse(bh);
+	put_dev_sector(sect);
 	goto err_out;
 no_mem:
 	printk(LDM_CRIT "Not enough memory to allocate required buffers.\n");
@@ -457,17 +462,19 @@
  *
  * Return 1 on success and -1 on error, in which case @vm is undefined.
  */
-static int validate_vmdb(const kdev_t dev, struct vmdb *vm)
+static int validate_vmdb(struct block_device *bdev, struct vmdb *vm, unsigned long base)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	int ret;
 
-	if (!(bh = bread(dev, OFF_VMDB, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, base + OFF_VMDB * 2 + 1, &sect);
+	if (!data) {
 		printk(LDM_CRIT "Disk read failed in validate_vmdb.\n");
 		return -1;
 	}
-	ret = parse_vmdb(bh->b_data + 0x200, vm);
-	brelse(bh);
+	ret = parse_vmdb(data, vm);
+	put_dev_sector(sect);
 	return ret;
 }
 
@@ -553,9 +560,12 @@
  *
  * Return 1 on success and -1 on error, in which case @toc1 is undefined.
  */
-static int validate_tocblocks(const kdev_t devdb, struct tocblock *toc1)
+static int validate_tocblocks(struct block_device *bdev,
+			struct tocblock *toc1,
+			unsigned long base)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	struct tocblock *toc2 = NULL, *toc3 = NULL, *toc4 = NULL;
 	int err;
 
@@ -569,39 +579,43 @@
 	if (!toc4)
 		goto no_mem;
 	/* Read and parse first toc. */
-	if (!(bh = bread(devdb, OFF_TOCBLOCK1, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, base + OFF_TOCBLOCK1 * 2 + 1, &sect);
+	if (!data) {
 		printk(LDM_CRIT "Disk read 1 failed in validate_tocblocks.\n");
 		goto err_out;
 	}
-	err = parse_tocblock(bh->b_data + 0x0200, toc1);
-	brelse(bh);
+	err = parse_tocblock(data, toc1);
+	put_dev_sector(sect);
 	if (err != 1)
 		goto out;
 	/* Read and parse second toc. */
-	if (!(bh = bread(devdb, OFF_TOCBLOCK2, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, base + OFF_TOCBLOCK2 * 2, &sect);
+	if (!data) {
 		printk(LDM_CRIT "Disk read 2 failed in validate_tocblocks.\n");
 		goto err_out;
 	}
-	err = parse_tocblock(bh->b_data, toc2);
-	brelse(bh);
+	err = parse_tocblock(data, toc2);
+	put_dev_sector(sect);
 	if (err != 1)
 		goto out;
 	/* Read and parse third toc. */
-	if (!(bh = bread(devdb, OFF_TOCBLOCK3, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, base + OFF_TOCBLOCK3 * 2 + 1, &sect);
+	if (!data) {
 		printk(LDM_CRIT "Disk read 3 failed in validate_tocblocks.\n");
 		goto err_out;
 	}
-	err = parse_tocblock(bh->b_data + 0x0200, toc3);
-	brelse(bh);
+	err = parse_tocblock(data, toc3);
+	put_dev_sector(sect);
 	if (err != 1)
 		goto out;
 	/* Read and parse fourth toc. */
-	if (!(bh = bread(devdb, OFF_TOCBLOCK4, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, base + OFF_TOCBLOCK4 * 2, &sect);
+	if (!data) {
 		printk(LDM_CRIT "Disk read 4 failed in validate_tocblocks.\n");
 		goto err_out;
 	}
-	err = parse_tocblock(bh->b_data, toc4);
-	brelse(bh);
+	err = parse_tocblock(data, toc4);
+	put_dev_sector(sect);
 	if (err != 1)
 		goto out;
 	/* Compare all tocs. */
@@ -665,9 +679,12 @@
  *
  * Return 1 on succes and -1 on error.
  */
-static int validate_privheads(const kdev_t dev, const struct privhead *ph1)
+static int validate_privheads(struct block_device *bdev,
+			      const struct privhead *ph1,
+			      unsigned long base)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	struct privhead *ph2 = NULL, *ph3 = NULL;
 	int err;
 
@@ -677,20 +694,22 @@
 	ph3 = (struct privhead*)kmalloc(sizeof(*ph3), GFP_KERNEL);
 	if (!ph3)
 		goto no_mem;
-	if (!(bh = bread(dev, OFF_PRIVHEAD2, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, base + OFF_PRIVHEAD2 * 2, &sect);
+	if (!data) {
 		printk(LDM_CRIT "Disk read 1 failed in validate_privheads.\n");
 		goto err_out;
 	}
-	err = parse_privhead(bh->b_data, ph2);
-	brelse(bh);
+	err = parse_privhead(data, ph2);
+	put_dev_sector(sect);
 	if (err != 1)
 		goto out;
-	if (!(bh = bread(dev, OFF_PRIVHEAD3, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, base + OFF_PRIVHEAD3 * 2 + 1, &sect);
+	if (!data) {
 		printk(LDM_CRIT "Disk read 2 failed in validate_privheads.\n");
 		goto err_out;
 	}
-	err = parse_privhead(bh->b_data + 0x0200, ph3);
-	brelse(bh);
+	err = parse_privhead(data, ph3);
+	put_dev_sector(sect);
 	if (err != 1)
 		goto out;
 	err = compare_privheads(ph1, ph2);
@@ -807,27 +826,29 @@
  *
  * Return 1 on succes, 0 if device is not a dynamic disk and -1 on error.
  */
-static int create_db_partition(struct gendisk *hd, const kdev_t dev,
+static int create_db_partition(struct gendisk *hd, struct block_device *bdev,
 		const unsigned long first_sector, const int first_part_minor,
 		struct privhead *ph)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	int err;
 
-	if (!(bh = bread(dev, OFF_PRIVHEAD1, LDM_BLOCKSIZE))) {
+	data = read_dev_sector(bdev, OFF_PRIVHEAD1*2, &sect);
+	if (!data) {
 		printk(LDM_CRIT __FUNCTION__ "(): Device read failed.\n");
 		return -1;
 	}
-	if (BE64(bh->b_data) != MAGIC_PRIVHEAD) {
+	if (BE64(data) != MAGIC_PRIVHEAD) {
 		ldm_debug("Cannot find PRIVHEAD structure. Not a dynamic disk "
 				"or corrupt LDM database.\n");
 		return 0;
 	}
-	err = parse_privhead(bh->b_data, ph);
+	err = parse_privhead(data, ph);
 	if (err == 1)
 		err = create_partition(hd, first_part_minor, first_sector +
 				ph->config_start, ph->config_size);
-	brelse(bh);
+	put_dev_sector(sect);
 	return err;
 }
 
@@ -842,23 +863,23 @@
  *
  * Return 1 if @dev is a dynamic disk, 0 if not and -1 on error.
  */
-static int validate_partition_table(const kdev_t dev)
+static int validate_partition_table(struct block_device *bdev)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	struct partition *p;
 	int i, nr_sfs;
 
-	if (!(bh = bread(dev, 0, LDM_BLOCKSIZE))) {
-		if (warn_no_part)
-			printk(LDM_ERR "Unable to read partition table.\n");
+	data = read_dev_sector(bdev, 0, &sect);
+	if (!data)
 		return -1;
-	}
-	if (*(u16*)(bh->b_data + 0x01FE) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
+
+	if (*(u16*)(data + 0x01FE) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
 		ldm_debug("No MS-DOS partition found.\n");
 		goto no_msdos_partition;
 	}
 	nr_sfs = 0;
-	p = (struct partition*)(bh->b_data + 0x01BE);
+	p = (struct partition*)(data + 0x01BE);
 	for (i = 0; i < 4; i++) {
 		if (!SYS_IND(p+i) || SYS_IND(p+i) == WIN2K_EXTENDED_PARTITION)
 			continue;
@@ -871,12 +892,12 @@
 	if (!nr_sfs)
 		goto not_dynamic_disk;
 	ldm_debug("Parsed partition table successfully.\n");
-	brelse(bh);
+	put_dev_sector(sect);
 	return 1;
 not_dynamic_disk:
 	ldm_debug("Found basic MS-DOS partition, not a dynamic disk.\n");
 no_msdos_partition:
-	brelse(bh);
+	put_dev_sector(sect);
 	return 0;
 }
 
@@ -904,67 +925,54 @@
  *	 0 if @dev is not a dynamic disk,
  *	-1 if an error occured.
  */
-int ldm_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
-		int first_part_minor)
+int ldm_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sector, int first_part_minor)
 {
-	kdev_t devdb;
 	struct privhead *ph  = NULL;
 	struct tocblock *toc = NULL;
 	struct vmdb     *vm  = NULL;
 	struct ldmdisk  *dk  = NULL;
+	unsigned long db_first;
 	int err;
 
 	if (!hd)
 		return 0;
-	err = (int)get_ptable_blocksize(dev);
-	if (err != LDM_BLOCKSIZE) {	/* 1024 bytes */
-		ldm_debug("Expected a blocksize of %d bytes, got %d instead.\n",
-				LDM_BLOCKSIZE, get_ptable_blocksize(dev));
-		return 0;
-	}
-	err = get_hardsect_size(dev); 
-	if (err != 512) {
-		ldm_debug("Expected a sector size of %d bytes, got %d "
-				"instead.\n", 512, get_hardsect_size(dev));
-		return 0;
-	}
 	/* Check the partition table. */
-	err = validate_partition_table(dev);
+	err = validate_partition_table(bdev);
 	if (err != 1)
 		return err;
 	if (!(ph = (struct privhead*)kmalloc(sizeof(*ph), GFP_KERNEL)))
 		goto no_mem;
 	/* Create the LDM database device. */
-	err = create_db_partition(hd, dev, first_sector, first_part_minor, ph);
+	err = create_db_partition(hd, bdev, first_sector, first_part_minor, ph);
 	if (err != 1)
 		goto out;
-	/* For convenience, work with the LDM database device from now on. */
-	devdb = MKDEV(MAJOR(dev), first_part_minor);
+	db_first = hd->part[first_part_minor].start_sect;
 	/* Check the backup privheads. */
-	err = validate_privheads(devdb, ph);
+	err = validate_privheads(bdev, ph, db_first);
 	if (err != 1)
 		goto out;
 	/* Check the table of contents and its backups. */
 	if (!(toc = (struct tocblock*)kmalloc(sizeof(*toc), GFP_KERNEL)))
 		goto no_mem;
-	err = validate_tocblocks(devdb, toc);
+	err = validate_tocblocks(bdev, toc, db_first);
 	if (err != 1)
 		goto out;
 	/* Check the vmdb. */
 	if (!(vm = (struct vmdb*)kmalloc(sizeof(*vm), GFP_KERNEL)))
 		goto no_mem;
-	err = validate_vmdb(devdb, vm);
+	err = validate_vmdb(bdev, vm, db_first);
 	if (err != 1)
 		goto out;
 	/* Find the object id for @dev in the LDM database. */
 	if (!(dk = (struct ldmdisk*)kmalloc(sizeof(*dk), GFP_KERNEL)))
 		goto no_mem;
-	err = get_disk_objid(devdb, vm, ph, dk);
+	err = get_disk_objid(bdev, vm, ph, dk, db_first);
 	if (err != 1)
 		goto out;
 	/* Finally, create the data partition devices. */
 	err = create_data_partitions(hd, first_sector, first_part_minor +
-			LDM_FIRST_PART_OFFSET, devdb, vm, ph, dk);
+			LDM_FIRST_PART_OFFSET, bdev, vm, ph, dk, db_first);
 	if (err == 1)
 		ldm_debug("Parsed LDM database successfully.\n");
 out:
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/ldm.h linux/fs/partitions/ldm.h
--- v2.4.10/linux/fs/partitions/ldm.h	Mon Aug 27 12:41:46 2001
+++ linux/fs/partitions/ldm.h	Tue Oct  9 15:23:56 2001
@@ -144,8 +144,8 @@
 	u64	num_sectors;
 };
 
-int ldm_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
-		int first_part_minor);
+int ldm_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sector, int first_part_minor);
 
 #endif /* _FS_PT_LDM_H_ */
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/mac.c linux/fs/partitions/mac.c
--- v2.4.10/linux/fs/partitions/mac.c	Sun Sep 17 09:51:57 2000
+++ linux/fs/partitions/mac.c	Mon Oct  1 20:03:26 2001
@@ -20,7 +20,7 @@
 #include "check.h"
 #include "mac.h"
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
 extern void note_bootable_part(kdev_t dev, int part, int goodness);
 #endif
 
@@ -36,69 +36,54 @@
 		stg[i] = 0;
 }
 
-int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec, int first_part_minor)
+int mac_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long fsec, int first_part_minor)
 {
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	int blk, blocks_in_map;
-	int dev_bsize, dev_pos, pos;
 	unsigned secsize;
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
 	int found_root = 0;
 	int found_root_goodness = 0;
 #endif
 	struct mac_partition *part;
 	struct mac_driver_desc *md;
 
-	dev_bsize = get_ptable_blocksize(dev);
-	dev_pos = 0;
 	/* Get 0th block and look at the first partition map entry. */
-	if ((bh = bread(dev, 0, dev_bsize)) == 0) {
-	    printk("%s: error reading partition table\n",
-		   kdevname(dev));
-	    return -1;
-	}
-	md = (struct mac_driver_desc *) bh->b_data;
+	md = (struct mac_driver_desc *) read_dev_sector(bdev, 0, &sect);
+	if (!md)
+		return -1;
 	if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
-		brelse(bh);
+		put_dev_sector(sect);
 		return 0;
 	}
 	secsize = be16_to_cpu(md->block_size);
-	if (secsize >= dev_bsize) {
-		brelse(bh);
-		dev_pos = secsize;
-		if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
-			printk("%s: error reading Mac partition table\n",
-			       kdevname(dev));
-			return -1;
-		}
-	}
-	part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);
+	put_dev_sector(sect);
+	data = read_dev_sector(bdev, secsize/512, &sect);
+	if (!data)
+		return -1;
+	part = (struct mac_partition *) (data + secsize%512);
 	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
-		brelse(bh);
+		put_dev_sector(sect);
 		return 0;		/* not a MacOS disk */
 	}
 	printk(" [mac]");
 	blocks_in_map = be32_to_cpu(part->map_count);
 	for (blk = 1; blk <= blocks_in_map; ++blk) {
-		pos = blk * secsize;
-		if (pos >= dev_pos + dev_bsize) {
-			brelse(bh);
-			dev_pos = pos;
-			if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {
-				printk("%s: error reading partition table\n",
-				       kdevname(dev));
-				return -1;
-			}
-		}
-		part = (struct mac_partition *) (bh->b_data + pos - dev_pos);
+		int pos = blk * secsize;
+		put_dev_sector(sect);
+		data = read_dev_sector(bdev, pos/512, &sect);
+		if (!data)
+			return -1;
+		part = (struct mac_partition *) (data + pos%512);
 		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
 			break;
-		blocks_in_map = be32_to_cpu(part->map_count);
 		add_gd_partition(hd, first_part_minor,
 			fsec + be32_to_cpu(part->start_block) * (secsize/512),
 			be32_to_cpu(part->block_count) * (secsize/512));
 
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
 		/*
 		 * If this is the first bootable partition, tell the
 		 * setup code, in case it wants to make this the root.
@@ -139,15 +124,17 @@
 				found_root_goodness = goodness;
 			}
 		}
-#endif /* CONFIG_PPC */
+#endif /* CONFIG_ALL_PPC */
 
 		++first_part_minor;
 	}
-#ifdef CONFIG_PPC
+#ifdef CONFIG_ALL_PPC
 	if (found_root_goodness)
-		note_bootable_part(dev, found_root, found_root_goodness);
+		note_bootable_part(to_kdev_t(bdev->bd_dev),
+					found_root, found_root_goodness);
 #endif
-	brelse(bh);
+
+	put_dev_sector(sect);
 	printk("\n");
 	return 1;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/mac.h linux/fs/partitions/mac.h
--- v2.4.10/linux/fs/partitions/mac.h	Thu Aug 12 12:26:06 1999
+++ linux/fs/partitions/mac.h	Mon Oct  1 20:03:26 2001
@@ -41,4 +41,4 @@
     /* ... more stuff */
 };
 
-int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec, int first_part_minor);
+int mac_partition(struct gendisk *hd, struct block_device *bdev, unsigned long fsec, int first_part_minor);
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/msdos.c linux/fs/partitions/msdos.c
--- v2.4.10/linux/fs/partitions/msdos.c	Sun Aug 12 13:28:00 2001
+++ linux/fs/partitions/msdos.c	Mon Oct  1 20:03:26 2001
@@ -40,8 +40,6 @@
 extern void md_autodetect_dev(kdev_t dev);
 #endif
 
-static int current_minor;
-
 /*
  * Many architectures don't like unaligned accesses, which is
  * frequently the case with the nr_sects and start_sect partition
@@ -88,7 +86,8 @@
 #define MSDOS_LABEL_MAGIC2	0xAA
 
 static inline int
-msdos_magic_present(unsigned char *p) {
+msdos_magic_present(unsigned char *p)
+{
 	return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2);
 }
 
@@ -103,35 +102,38 @@
  * only for the actual data partitions.
  */
 
-static void extended_partition(struct gendisk *hd, kdev_t dev)
+static void extended_partition(struct gendisk *hd, struct block_device *bdev,
+				int minor, int *current_minor)
 {
-	struct buffer_head *bh;
 	struct partition *p;
+	Sector sect;
+	unsigned char *data;
 	unsigned long first_sector, first_size, this_sector, this_size;
 	int mask = (1 << hd->minor_shift) - 1;
-	int sector_size = get_hardsect_size(dev) / 512;
+	int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512;
 	int loopct = 0;		/* number of links followed
 				   without finding a data partition */
 	int i;
 
-	first_sector = hd->part[MINOR(dev)].start_sect;
-	first_size = hd->part[MINOR(dev)].nr_sects;
+	first_sector = hd->part[minor].start_sect;
+	first_size = hd->part[minor].nr_sects;
 	this_sector = first_sector;
 
 	while (1) {
 		if (++loopct > 100)
 			return;
-		if ((current_minor & mask) == 0)
+		if ((*current_minor & mask) == 0)
 			return;
-		if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
+		data = read_dev_sector(bdev, this_sector, &sect);
+		if (!data)
 			return;
 
-		if (!msdos_magic_present(bh->b_data + 510))
-			goto done;
+		if (!msdos_magic_present(data + 510))
+			goto done; 
 
-		p = (struct partition *) (bh->b_data + 0x1be);
+		p = (struct partition *) (data + 0x1be);
 
-		this_size = hd->part[MINOR(dev)].nr_sects;
+		this_size = hd->part[minor].nr_sects;
 
 		/*
 		 * Usually, the first entry is the real data partition,
@@ -146,30 +148,34 @@
 		 * First process the data partition(s)
 		 */
 		for (i=0; i<4; i++, p++) {
+			unsigned long offs, size, next;
 			if (!NR_SECTS(p) || is_extended_partition(p))
 				continue;
 
 			/* Check the 3rd and 4th entries -
 			   these sometimes contain random garbage */
-			if (i >= 2
-				&& START_SECT(p) + NR_SECTS(p) > this_size
-				&& (this_sector + START_SECT(p) < first_sector ||
-				    this_sector + START_SECT(p) + NR_SECTS(p) >
-				     first_sector + first_size))
-				continue;
+			offs = START_SECT(p)*sector_size;
+			size = NR_SECTS(p)*sector_size;
+			next = this_sector + offs;
+			if (i >= 2) {
+				if (offs + size > this_size)
+					continue;
+				if (next < first_sector)
+					continue;
+				if (next + size > first_sector + first_size)
+					continue;
+			}
 
-			add_gd_partition(hd, current_minor,
-					 this_sector+START_SECT(p)*sector_size,
-					 NR_SECTS(p)*sector_size);
+			add_gd_partition(hd, *current_minor, next, size);
 #if CONFIG_BLK_DEV_MD
 			if (SYS_IND(p) == LINUX_RAID_PARTITION) {
-			    md_autodetect_dev(MKDEV(hd->major,current_minor));
+			    md_autodetect_dev(MKDEV(hd->major,*current_minor));
 			}
 #endif
 
-			current_minor++;
+			(*current_minor)++;
 			loopct = 0;
-			if ((current_minor & mask) == 0)
+			if ((*current_minor & mask) == 0)
 				goto done;
 		}
 		/*
@@ -184,61 +190,52 @@
 		 */
 		p -= 4;
 		for (i=0; i<4; i++, p++)
-			if(NR_SECTS(p) && is_extended_partition(p))
+			if (NR_SECTS(p) && is_extended_partition(p))
 				break;
 		if (i == 4)
 			goto done;	 /* nothing left to do */
 
-		hd->part[current_minor].nr_sects = NR_SECTS(p) * sector_size; /* JSt */
-		hd->part[current_minor].start_sect = first_sector + START_SECT(p) * sector_size;
 		this_sector = first_sector + START_SECT(p) * sector_size;
-		dev = MKDEV(hd->major, current_minor);
-
-		/* Use bforget(), as we have changed the disk geometry */
-		bforget(bh);
+		minor = *current_minor;
+		put_dev_sector(sect);
 	}
 done:
-	bforget(bh);
+	put_dev_sector(sect);
 }
 
-static inline struct buffer_head *
-get_partition_table_block(struct gendisk *hd, int minor, int blocknr) {
-	kdev_t dev = MKDEV(hd->major, minor);
-	return bread(dev, blocknr, get_ptable_blocksize(dev));
-}
-
-#ifdef CONFIG_SOLARIS_X86_PARTITION
-
 /* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also
    indicates linux swap.  Be careful before believing this is Solaris. */
 
 static void
-solaris_x86_partition(struct gendisk *hd, int minor) {
-	long offset = hd->part[minor].start_sect;
+solaris_x86_partition(struct gendisk *hd, struct block_device *bdev,
+		int minor, int *current_minor)
+{
 
-	struct buffer_head *bh;
+#ifdef CONFIG_SOLARIS_X86_PARTITION
+	long offset = hd->part[minor].start_sect;
+	Sector sect;
 	struct solaris_x86_vtoc *v;
 	struct solaris_x86_slice *s;
 	int mask = (1 << hd->minor_shift) - 1;
 	int i;
 	char buf[40];
 
-	if(!(bh = get_partition_table_block(hd, minor, 0)))
+	v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, &sect);
+	if (!v)
 		return;
-	v = (struct solaris_x86_vtoc *)(bh->b_data + 512);
-	if(le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) {
-		brelse(bh);
+	if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) {
+		put_dev_sector(sect);
 		return;
 	}
 	printk(" %s: <solaris:", partition_name(hd, minor, buf));
-	if(le32_to_cpu(v->v_version) != 1) {
+	if (le32_to_cpu(v->v_version) != 1) {
 		printk("  cannot handle version %d vtoc>\n",
 			le32_to_cpu(v->v_version));
-		brelse(bh);
+		put_dev_sector(sect);
 		return;
 	}
-	for(i=0; i<SOLARIS_X86_NUMSLICE; i++) {
-		if ((current_minor & mask) == 0)
+	for (i=0; i<SOLARIS_X86_NUMSLICE; i++) {
+		if ((*current_minor & mask) == 0)
 			break;
 		s = &v->v_slice[i];
 
@@ -249,23 +246,25 @@
 		 * one but add_gd_partition starts relative to sector
 		 * zero of the disk.  Therefore, must add the offset
 		 * of the current partition */
-		add_gd_partition(hd, current_minor, le32_to_cpu(s->s_start)+offset,
+		add_gd_partition(hd, *current_minor,
+				 le32_to_cpu(s->s_start)+offset,
 				 le32_to_cpu(s->s_size));
-		current_minor++;
+		(*current_minor)++;
 	}
-	brelse(bh);
+	put_dev_sector(sect);
 	printk(" >\n");
-}
 #endif
+}
 
 #ifdef CONFIG_BSD_DISKLABEL
 static void
-check_and_add_bsd_partition(struct gendisk *hd,
-			    struct bsd_partition *bsd_p, int minor) {
+check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p,
+	int minor, int *current_minor)
+{
 	struct hd_struct *lin_p;
 		/* check relative position of partitions.  */
 	for (lin_p = hd->part + 1 + minor;
-	     lin_p - hd->part - minor < current_minor; lin_p++) {
+	     lin_p - hd->part - minor < *current_minor; lin_p++) {
 			/* no relationship -> try again */
 		if (lin_p->start_sect + lin_p->nr_sects <= le32_to_cpu(bsd_p->p_offset) ||
 		    lin_p->start_sect >= le32_to_cpu(bsd_p->p_offset) + le32_to_cpu(bsd_p->p_size))
@@ -297,232 +296,290 @@
 	} /* if the bsd partition is not currently known to linux, we end
 	   * up here 
 	   */
-	add_gd_partition(hd, current_minor, le32_to_cpu(bsd_p->p_offset),
+	add_gd_partition(hd, *current_minor, le32_to_cpu(bsd_p->p_offset),
 			 le32_to_cpu(bsd_p->p_size));
-	current_minor++;
+	(*current_minor)++;
 }
 
 /* 
  * Create devices for BSD partitions listed in a disklabel, under a
  * dos-like partition. See extended_partition() for more information.
  */
-static void bsd_disklabel_partition(struct gendisk *hd, int minor, int type) {
-	struct buffer_head *bh;
+static void do_bsd_partition(struct gendisk *hd, struct block_device *bdev,
+	int minor, int *current_minor, char *name, int max_partitions)
+{
+	long offset = hd->part[minor].start_sect;
+	Sector sect;
 	struct bsd_disklabel *l;
 	struct bsd_partition *p;
-	int max_partitions;
 	int mask = (1 << hd->minor_shift) - 1;
 	char buf[40];
 
-	if (!(bh = get_partition_table_block(hd, minor, 0)))
+	l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, &sect);
+	if (!l)
 		return;
-	l = (struct bsd_disklabel *) (bh->b_data+512);
 	if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) {
-		brelse(bh);
+		put_dev_sector(sect);
 		return;
 	}
-	printk(" %s:", partition_name(hd, minor, buf));
-	printk((type == OPENBSD_PARTITION) ? " <openbsd:" :
-	       (type == NETBSD_PARTITION) ? " <netbsd:" : " <bsd:");
+	printk(" %s: <%s", partition_name(hd, minor, buf), name);
 
-	max_partitions = ((type == OPENBSD_PARTITION) ? OPENBSD_MAXPARTITIONS
-			                              : BSD_MAXPARTITIONS);
 	if (le16_to_cpu(l->d_npartitions) < max_partitions)
 		max_partitions = le16_to_cpu(l->d_npartitions);
 	for (p = l->d_partitions; p - l->d_partitions <  max_partitions; p++) {
-		if ((current_minor & mask) == 0)
+		if ((*current_minor & mask) == 0)
 			break;
-
-		if (p->p_fstype != BSD_FS_UNUSED) 
-			check_and_add_bsd_partition(hd, p, minor);
+		if (p->p_fstype == BSD_FS_UNUSED) 
+			continue;
+		check_and_add_bsd_partition(hd, p, minor, current_minor);
 	}
+	put_dev_sector(sect);
+	printk(" >\n");
+}
+#endif
 
-	/* Use bforget(), as we have changed the disk setup */
-	bforget(bh);
+static void bsd_partition(struct gendisk *hd, struct block_device *bdev,
+	int minor, int *current_minor)
+{
+#ifdef CONFIG_BSD_DISKLABEL
+	do_bsd_partition(hd, bdev, minor, current_minor, "bsd",
+		BSD_MAXPARTITIONS);
+#endif
+}
 
-	printk(" >\n");
+static void netbsd_partition(struct gendisk *hd, struct block_device *bdev,
+		int minor, int *current_minor)
+{
+#ifdef CONFIG_BSD_DISKLABEL
+	do_bsd_partition(hd, bdev, minor, current_minor, "netbsd",
+			BSD_MAXPARTITIONS);
+#endif
 }
+
+static void openbsd_partition(struct gendisk *hd, struct block_device *bdev,
+		int minor, int *current_minor)
+{
+#ifdef CONFIG_BSD_DISKLABEL
+	do_bsd_partition(hd, bdev, minor, current_minor,
+			"openbsd", OPENBSD_MAXPARTITIONS);
 #endif
+}
 
-#ifdef CONFIG_UNIXWARE_DISKLABEL
 /*
  * Create devices for Unixware partitions listed in a disklabel, under a
  * dos-like partition. See extended_partition() for more information.
  */
-static void unixware_partition(struct gendisk *hd, int minor) {
-	struct buffer_head *bh;
+static void unixware_partition(struct gendisk *hd, struct block_device *bdev,
+		int minor, int *current_minor)
+{
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+	long offset = hd->part[minor].start_sect;
+	Sector sect;
 	struct unixware_disklabel *l;
 	struct unixware_slice *p;
 	int mask = (1 << hd->minor_shift) - 1;
 	char buf[40];
 
-	if (!(bh = get_partition_table_block(hd, minor, 14)))
+	l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, &sect);
+	if (!l)
 		return;
-	l = (struct unixware_disklabel *) (bh->b_data+512);
 	if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
 	    le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
-		brelse(bh);
+		put_dev_sector(sect);
 		return;
 	}
 	printk(" %s: <unixware:", partition_name(hd, minor, buf));
 	p = &l->vtoc.v_slice[1];
 	/* I omit the 0th slice as it is the same as whole disk. */
 	while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
-		if ((current_minor & mask) == 0)
+		if ((*current_minor & mask) == 0)
 			break;
 
 		if (p->s_label != UNIXWARE_FS_UNUSED) {
-			add_gd_partition(hd, current_minor, START_SECT(p),
+			add_gd_partition(hd, *current_minor, START_SECT(p),
 					 NR_SECTS(p));
-			current_minor++;
+			(*current_minor)++;
 		}
 		p++;
 	}
-	/* Use bforget, as we have changed the disk setup */
-	bforget(bh);
+	put_dev_sector(sect);
 	printk(" >\n");
-}
 #endif
+}
 
-#ifdef CONFIG_MINIX_SUBPARTITION
 /*
  * Minix 2.0.0/2.0.2 subpartition support.
  * Anand Krishnamurthy <anandk@wiproge.med.ge.com>
  * Rajeev V. Pillai    <rajeevvp@yahoo.com>
  */
-static void minix_partition(struct gendisk *hd, int minor)
+static void minix_partition(struct gendisk *hd, struct block_device *bdev,
+		int minor, int *current_minor)
 {
-	struct buffer_head *bh;
+#ifdef CONFIG_MINIX_SUBPARTITION
+	long offset = hd->part[minor].start_sect;
+	Sector sect;
+	unsigned char *data;
 	struct partition *p;
 	int mask = (1 << hd->minor_shift) - 1;
 	int i;
 	char buf[40];
 
-	if (!(bh = get_partition_table_block(hd, minor, 0)))
+	data = read_dev_sector(bdev, offset, &sect);
+	if (!data)
 		return;
-	bh->b_state = 0;
 
-	p = (struct partition *)(bh->b_data + 0x1be);
+	p = (struct partition *)(data + 0x1be);
 
 	/* The first sector of a Minix partition can have either
 	 * a secondary MBR describing its subpartitions, or
 	 * the normal boot sector. */
-	if (msdos_magic_present (bh->b_data + 510) &&
+	if (msdos_magic_present (data + 510) &&
 	    SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */
 
 		printk(" %s: <minix:", partition_name(hd, minor, buf));
 		for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) {
-			if ((current_minor & mask) == 0)
+			if ((*current_minor & mask) == 0)
 				break;
 			/* add each partition in use */
 			if (SYS_IND(p) == MINIX_PARTITION) {
-				add_gd_partition(hd, current_minor,
+				add_gd_partition(hd, *current_minor,
 					      START_SECT(p), NR_SECTS(p));
-				current_minor++;
+				(*current_minor)++;
 			}
 		}
 		printk(" >\n");
 	}
-	brelse(bh);
-}
+	put_dev_sector(sect);
 #endif /* CONFIG_MINIX_SUBPARTITION */
- 
-int msdos_partition(struct gendisk *hd, kdev_t dev,
-		    unsigned long first_sector, int first_part_minor) {
-	int i, minor = current_minor = first_part_minor;
-	struct buffer_head *bh;
-	struct partition *p;
-	unsigned char *data;
-	int mask = (1 << hd->minor_shift) - 1;
-	int sector_size = get_hardsect_size(dev) / 512;
-#ifdef CONFIG_BLK_DEV_IDE
-	int tested_for_xlate = 0;
+}
 
-read_mbr:
-#endif /* CONFIG_BLK_DEV_IDE */
-	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
-		if (warn_no_part) printk(" unable to read partition table\n");
-		return -1;
-	}
-	data = bh->b_data;
+static struct {
+	unsigned char id;
+	void (*parse)(struct gendisk *, struct block_device *, int, int *);
+} subtypes[] = {
+	{BSD_PARTITION, bsd_partition},
+	{NETBSD_PARTITION, netbsd_partition},
+	{OPENBSD_PARTITION, openbsd_partition},
+	{MINIX_PARTITION, minix_partition},
+	{UNIXWARE_PARTITION, unixware_partition},
+	{SOLARIS_X86_PARTITION, solaris_x86_partition},
+	{0, NULL},
+};
+/*
+ * Look for various forms of IDE disk geometry translation
+ */
+static int handle_ide_mess(struct block_device *bdev)
+{
 #ifdef CONFIG_BLK_DEV_IDE
-check_table:
-#endif /* CONFIG_BLK_DEV_IDE */
-	/* Use bforget(), because we may have changed the disk geometry */
+	Sector sect;
+	unsigned char *data;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
+	unsigned int sig;
+	int heads = 0;
+	struct partition *p;
+	int i;
+	/*
+	 * The i386 partition handling programs very often
+	 * make partitions end on cylinder boundaries.
+	 * There is no need to do so, and Linux fdisk doesnt always
+	 * do this, and Windows NT on Alpha doesnt do this either,
+	 * but still, this helps to guess #heads.
+	 */
+	data = read_dev_sector(bdev, 0, &sect);
+	if (!data)
+		return -1;
 	if (!msdos_magic_present(data + 510)) {
-		bforget(bh);
+		put_dev_sector(sect);
 		return 0;
 	}
+	sig = le16_to_cpu(*(unsigned short *)(data + 2));
 	p = (struct partition *) (data + 0x1be);
+	for (i = 0; i < 4; i++) {
+		struct partition *q = &p[i];
+		if (NR_SECTS(q)) {
+			if ((q->sector & 63) == 1 &&
+			    (q->end_sector & 63) == 63)
+				heads = q->end_head + 1;
+			break;
+		}
+	}
+	if (SYS_IND(p) == EZD_PARTITION) {
+		/*
+		 * Accesses to sector 0 must go to sector 1 instead.
+		 */
+		if (ide_xlate_1024(dev, -1, heads, " [EZD]"))
+			goto reread;
+	} else if (SYS_IND(p) == DM6_PARTITION) {
 
-#ifdef CONFIG_BLK_DEV_IDE
-	if (!tested_for_xlate++) {	/* Do this only once per disk */
 		/*
-		 * Look for various forms of IDE disk geometry translation
+		 * Everything on the disk is offset by 63 sectors,
+		 * including a "new" MBR with its own partition table.
 		 */
-		unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
-		int heads = 0;
+		if (ide_xlate_1024(dev, 1, heads, " [DM6:DDO]"))
+			goto reread;
+	} else if (sig <= 0x1ae &&
+		   data[sig] == 0xAA && data[sig+1] == 0x55 &&
+		   (data[sig+2] & 1)) {
+		/* DM6 signature in MBR, courtesy of OnTrack */
+		(void) ide_xlate_1024 (dev, 0, heads, " [DM6:MBR]");
+	} else if (SYS_IND(p) == DM6_AUX1PARTITION ||
+		   SYS_IND(p) == DM6_AUX3PARTITION) {
 		/*
-		 * The i386 partition handling programs very often
-		 * make partitions end on cylinder boundaries.
-		 * There is no need to do so, and Linux fdisk doesnt always
-		 * do this, and Windows NT on Alpha doesnt do this either,
-		 * but still, this helps to guess #heads.
+		 * DM6 on other than the first (boot) drive
 		 */
-		for (i = 0; i < 4; i++) {
-			struct partition *q = &p[i];
-			if (NR_SECTS(q)) {
-				if ((q->sector & 63) == 1 &&
-				    (q->end_sector & 63) == 63)
-					heads = q->end_head + 1;
-				break;
-			}
-		}
-		if (SYS_IND(p) == EZD_PARTITION) {
-			/*
-			 * Accesses to sector 0 must go to sector 1 instead.
-			 */
-			if (ide_xlate_1024(dev, -1, heads, " [EZD]")) {
-				data += 512;
-				goto check_table;
-			}
-		} else if (SYS_IND(p) == DM6_PARTITION) {
-
-			/*
-			 * Everything on the disk is offset by 63 sectors,
-			 * including a "new" MBR with its own partition table.
-			 */
-			if (ide_xlate_1024(dev, 1, heads, " [DM6:DDO]")) {
-				bforget(bh);
-				goto read_mbr;	/* start over with new MBR */
-			}
-		} else if (sig <= 0x1ae &&
-			   data[sig] == 0xAA && data[sig+1] == 0x55 &&
-			   (data[sig+2] & 1)) {
-			/* DM6 signature in MBR, courtesy of OnTrack */
-			(void) ide_xlate_1024 (dev, 0, heads, " [DM6:MBR]");
-		} else if (SYS_IND(p) == DM6_AUX1PARTITION ||
-			   SYS_IND(p) == DM6_AUX3PARTITION) {
-			/*
-			 * DM6 on other than the first (boot) drive
-			 */
-			(void) ide_xlate_1024(dev, 0, heads, " [DM6:AUX]");
-		} else {
-			(void) ide_xlate_1024(dev, 2, heads, " [PTBL]");
-		}
-	}
+		(void) ide_xlate_1024(dev, 0, heads, " [DM6:AUX]");
+	} else {
+		(void) ide_xlate_1024(dev, 2, heads, " [PTBL]");
+	}
+	put_dev_sector(sect);
+	return 1;
+
+reread:
+	put_dev_sector(sect);
+	/* Flush the cache */
+	invalidate_bdev(bdev, 1);
+	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
 #endif /* CONFIG_BLK_DEV_IDE */
+	return 1;
+}
+ 
+int msdos_partition(struct gendisk *hd, struct block_device *bdev,
+		    unsigned long first_sector, int first_part_minor)
+{
+	int i, minor = first_part_minor;
+	Sector sect;
+	struct partition *p;
+	unsigned char *data;
+	int mask = (1 << hd->minor_shift) - 1;
+	int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512;
+	int current_minor = first_part_minor;
+	int err;
+
+	err = handle_ide_mess(bdev);
+	if (err <= 0)
+		return err;
+	data = read_dev_sector(bdev, 0, &sect);
+	if (!data)
+		return -1;
+	if (!msdos_magic_present(data + 510)) {
+		put_dev_sector(sect);
+		return 0;
+	}
+	p = (struct partition *) (data + 0x1be);
 
-	/* Look for partitions in two passes:
-	   First find the primary partitions, and the DOS-type extended partitions.
-	   On the second pass look inside *BSD and Unixware and Solaris partitions. */
+	/*
+	 * Look for partitions in two passes:
+	 * First find the primary and DOS-type extended partitions.
+	 * On the second pass look inside *BSD, Unixware and Solaris partitions.
+	 */
 
-	current_minor += 4;  /* first "extra" minor (for extended partitions) */
+	current_minor += 4;
 	for (i=1 ; i<=4 ; minor++,i++,p++) {
 		if (!NR_SECTS(p))
 			continue;
-		add_gd_partition(hd, minor, first_sector+START_SECT(p)*sector_size,
-				 NR_SECTS(p)*sector_size);
+		add_gd_partition(hd, minor,
+				first_sector+START_SECT(p)*sector_size,
+				NR_SECTS(p)*sector_size);
 #if CONFIG_BLK_DEV_MD
 		if (SYS_IND(p) == LINUX_RAID_PARTITION) {
 			md_autodetect_dev(MKDEV(hd->major,minor));
@@ -530,20 +587,12 @@
 #endif
 		if (is_extended_partition(p)) {
 			printk(" <");
-			/*
-			 * If we are rereading the partition table, we need
-			 * to set the size of the partition so that we will
-			 * be able to bread the block containing the extended
-			 * partition info.
-			 */
-			hd->sizes[minor] = hd->part[minor].nr_sects 
-			  	>> (BLOCK_SIZE_BITS - 9);
-			extended_partition(hd, MKDEV(hd->major, minor));
-			printk(" >");
 			/* prevent someone doing mkfs or mkswap on an
 			   extended partition, but leave room for LILO */
 			if (hd->part[minor].nr_sects > 2)
 				hd->part[minor].nr_sects = 2;
+			extended_partition(hd, bdev, minor, &current_minor);
+			printk(" >");
 		}
 	}
 
@@ -567,29 +616,18 @@
 	minor -= 4;
 	p = (struct partition *) (0x1be + data);
 	for (i=1 ; i<=4 ; minor++,i++,p++) {
+		unsigned char id = SYS_IND(p);
+		int n;
+
 		if (!NR_SECTS(p))
 			continue;
-#ifdef CONFIG_BSD_DISKLABEL
-		if (SYS_IND(p) == BSD_PARTITION ||
-		    SYS_IND(p) == NETBSD_PARTITION ||
-		    SYS_IND(p) == OPENBSD_PARTITION)
-			bsd_disklabel_partition(hd, minor, SYS_IND(p));
-#endif
-#ifdef CONFIG_MINIX_SUBPARTITION
-		if (SYS_IND(p) == MINIX_PARTITION) {
-			minix_partition(hd, minor);
-		}
-#endif
-#ifdef CONFIG_UNIXWARE_DISKLABEL
-		if (SYS_IND(p) == UNIXWARE_PARTITION)
-			unixware_partition(hd, minor);
-#endif
-#ifdef CONFIG_SOLARIS_X86_PARTITION
-		if(SYS_IND(p) == SOLARIS_X86_PARTITION)
-			solaris_x86_partition(hd, minor);
-#endif
-	}
 
-	bforget(bh);
+		for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++)
+			;
+
+		if (subtypes[n].parse)
+			subtypes[n].parse(hd, bdev, minor, &current_minor);
+	}
+	put_dev_sector(sect);
 	return 1;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/msdos.h linux/fs/partitions/msdos.h
--- v2.4.10/linux/fs/partitions/msdos.h	Thu Aug 12 12:26:06 1999
+++ linux/fs/partitions/msdos.h	Mon Oct  1 20:03:26 2001
@@ -4,6 +4,6 @@
 
 #define MSDOS_LABEL_MAGIC		0xAA55
 
-int msdos_partition(struct gendisk *hd, kdev_t dev,
+int msdos_partition(struct gendisk *hd, struct block_device *bdev,
 		    unsigned long first_sector, int first_part_minor);
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/osf.c linux/fs/partitions/osf.c
--- v2.4.10/linux/fs/partitions/osf.c	Fri Feb 16 16:02:37 2001
+++ linux/fs/partitions/osf.c	Mon Oct  1 20:03:26 2001
@@ -17,12 +17,13 @@
 #include "check.h"
 #include "osf.h"
 
-int osf_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
-		  int current_minor)
+int osf_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sector, int current_minor)
 {
 	int i;
+	Sector sect;
+	unsigned char *data;
 	int mask = (1 << hd->minor_shift) - 1;
-	struct buffer_head *bh;
 	struct disklabel {
 		u32 d_magic;
 		u16 d_type,d_subtype;
@@ -56,18 +57,18 @@
 	} * label;
 	struct d_partition * partition;
 
-	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
-		if (warn_no_part) printk("unable to read partition table\n");
+	data = read_dev_sector(bdev, 0, &sect);
+	if (!data)
 		return -1;
-	}
-	label = (struct disklabel *) (bh->b_data+64);
+
+	label = (struct disklabel *) (data+64);
 	partition = label->d_partitions;
 	if (le32_to_cpu(label->d_magic) != DISKLABELMAGIC) {
-		brelse(bh);
+		put_dev_sector(sect);
 		return 0;
 	}
 	if (le32_to_cpu(label->d_magic2) != DISKLABELMAGIC) {
-		brelse(bh);
+		put_dev_sector(sect);
 		return 0;
 	}
 	for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) {
@@ -80,7 +81,7 @@
 		current_minor++;
 	}
 	printk("\n");
-	brelse(bh);
+	put_dev_sector(sect);
 	return 1;
 }
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/osf.h linux/fs/partitions/osf.h
--- v2.4.10/linux/fs/partitions/osf.h	Thu Aug 12 12:26:06 1999
+++ linux/fs/partitions/osf.h	Mon Oct  1 20:03:26 2001
@@ -4,6 +4,6 @@
 
 #define DISKLABELMAGIC (0x82564557UL)
 
-int osf_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
-		  int current_minor);
+int osf_partition(struct gendisk *hd, struct block_device *bdev,
+		unsigned long first_sector, int current_minor);
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/sgi.c linux/fs/partitions/sgi.c
--- v2.4.10/linux/fs/partitions/sgi.c	Sun Mar 12 19:39:39 2000
+++ linux/fs/partitions/sgi.c	Mon Oct  1 20:03:26 2001
@@ -17,11 +17,12 @@
 #include "check.h"
 #include "sgi.h"
 
-int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int current_minor)
+int sgi_partition(struct gendisk *hd, struct block_device *bdev, unsigned long first_sector, int current_minor)
 {
 	int i, csum, magic;
 	unsigned int *ui, start, blocks, cs;
-	struct buffer_head *bh;
+	Sector sect;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
 	struct sgi_disklabel {
 		int magic_mushroom;         /* Big fat spliff... */
 		short root_part_num;        /* Root partition number */
@@ -43,17 +44,15 @@
 	} *label;
 	struct sgi_partition *p;
 
-	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
-		if (warn_no_part) printk(KERN_WARNING "Dev %s: unable to read partition table\n", kdevname(dev));
+	label = (struct sgi_disklabel *) read_dev_sector(bdev, 0, &sect);
+	if (!label)
 		return -1;
-	}
-	label = (struct sgi_disklabel *) bh->b_data;
 	p = &label->partitions[0];
 	magic = label->magic_mushroom;
 	if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {
 		/*printk("Dev %s SGI disklabel: bad magic %08x\n",
-		       kdevname(dev), magic);*/
-		brelse(bh);
+		       bdevname(dev), magic);*/
+		put_dev_sector(sect);
 		return 0;
 	}
 	ui = ((unsigned int *) (label + 1)) - 1;
@@ -63,8 +62,8 @@
 	}
 	if(csum) {
 		printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n",
-		       kdevname(dev));
-		brelse(bh);
+		       bdevname(dev));
+		put_dev_sector(sect);
 		return 0;
 	}
 	/* All SGI disk labels have 16 partitions, disks under Linux only
@@ -81,6 +80,6 @@
 		current_minor++;
 	}
 	printk("\n");
-	brelse(bh);
+	put_dev_sector(sect);
 	return 1;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/sgi.h linux/fs/partitions/sgi.h
--- v2.4.10/linux/fs/partitions/sgi.h	Thu Aug 12 12:26:06 1999
+++ linux/fs/partitions/sgi.h	Mon Oct  1 20:03:26 2001
@@ -2,7 +2,7 @@
  *  fs/partitions/sgi.h
  */
 
-extern int sgi_partition(struct gendisk *hd, kdev_t dev,
+extern int sgi_partition(struct gendisk *hd, struct block_device *bdev,
 	 unsigned long first_sector, int first_part_minor);
 
 #define SGI_LABEL_MAGIC 0x0be5a941
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/sun.c linux/fs/partitions/sun.c
--- v2.4.10/linux/fs/partitions/sun.c	Wed Feb 16 15:42:06 2000
+++ linux/fs/partitions/sun.c	Mon Oct  1 20:03:26 2001
@@ -19,11 +19,12 @@
 #include "check.h"
 #include "sun.h"
 
-int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor)
+int sun_partition(struct gendisk *hd, struct block_device *bdev, unsigned long first_sector, int first_part_minor)
 {
 	int i, csum;
 	unsigned short *ush;
-	struct buffer_head *bh;
+	Sector sect;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
 	struct sun_disklabel {
 		unsigned char info[128];   /* Informative text string */
 		unsigned char spare[292];  /* Boot information etc. */
@@ -47,27 +48,25 @@
 	struct sun_partition *p;
 	unsigned long spc;
 
-	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
-		if (warn_no_part) printk(KERN_WARNING "Dev %s: unable to read partition table\n",
-		       kdevname(dev));
+	label = (struct sun_disklabel *)read_dev_sector(bdev, 0, &sect);
+	if (!label)
 		return -1;
-	}
-	label = (struct sun_disklabel *) bh->b_data;
+
 	p = label->partitions;
 	if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
 /*		printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n",
-		       kdevname(dev), be16_to_cpu(label->magic)); */
-		brelse(bh);
+		       bdevname(dev), be16_to_cpu(label->magic)); */
+		put_dev_sector(sect);
 		return 0;
 	}
 	/* Look at the checksum */
 	ush = ((unsigned short *) (label+1)) - 1;
-	for(csum = 0; ush >= ((unsigned short *) label);)
+	for (csum = 0; ush >= ((unsigned short *) label);)
 		csum ^= *ush--;
 	if(csum) {
 		printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
-		       kdevname(dev));
-		brelse(bh);
+		       bdevname(dev));
+		put_dev_sector(sect);
 		return 0;
 	}
 	/* All Sun disks have 8 partition entries */
@@ -83,7 +82,6 @@
 		first_part_minor++;
 	}
 	printk("\n");
-	brelse(bh);
+	put_dev_sector(sect);
 	return 1;
 }
-
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/sun.h linux/fs/partitions/sun.h
--- v2.4.10/linux/fs/partitions/sun.h	Thu Aug 12 12:26:06 1999
+++ linux/fs/partitions/sun.h	Mon Oct  1 20:03:26 2001
@@ -4,6 +4,6 @@
 
 #define SUN_LABEL_MAGIC          0xDABE
 
-int sun_partition(struct gendisk *hd, kdev_t dev,
+int sun_partition(struct gendisk *hd, struct block_device *bdev,
 		  unsigned long first_sector, int first_part_minor);
 
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/ultrix.c linux/fs/partitions/ultrix.c
--- v2.4.10/linux/fs/partitions/ultrix.c	Sun Jul  9 22:21:41 2000
+++ linux/fs/partitions/ultrix.c	Mon Oct  1 20:03:26 2001
@@ -14,11 +14,12 @@
 
 #include "check.h"
 
-int ultrix_partition(struct gendisk *hd, kdev_t dev,
+int ultrix_partition(struct gendisk *hd, struct block_device *bdev,
                             unsigned long first_sector, int first_part_minor)
 {
 	int i;
-	struct buffer_head *bh;
+	Sector sect;
+	unsigned char *data;
 	struct ultrix_disklabel {
 		s32	pt_magic;	/* magic no. indicating part. info exits */
 		s32	pt_valid;	/* set by driver if pt is current */
@@ -31,18 +32,11 @@
 #define PT_MAGIC	0x032957	/* Partition magic number */
 #define PT_VALID	1		/* Indicates if struct is valid */
 
-#define	SBLOCK	((unsigned long)((16384 - sizeof(struct ultrix_disklabel)) \
-                  /get_ptable_blocksize(dev)))
-
-	bh = bread (dev, SBLOCK, get_ptable_blocksize(dev));
-	if (!bh) {
-		if (warn_no_part) printk (" unable to read block 0x%lx\n", SBLOCK);
+	data = read_dev_sector(bdev, (16384 - sizeof(*label))/512, &sect);
+	if (!data)
 		return -1;
-	}
 	
-	label = (struct ultrix_disklabel *)(bh->b_data
-                                            + get_ptable_blocksize(dev)
-                                            - sizeof(struct ultrix_disklabel));
+	label = (struct ultrix_disklabel *)(data + 512 - sizeof(*label));
 
 	if (label->pt_magic == PT_MAGIC && label->pt_valid == PT_VALID) {
 		for (i=0; i<8; i++, first_part_minor++)
@@ -50,11 +44,11 @@
 				add_gd_partition(hd, first_part_minor, 
 					      label->pt_part[i].pi_blkoff,
 					      label->pt_part[i].pi_nblocks);
-		brelse(bh);
+		put_dev_sector(sect);
 		printk ("\n");
 		return 1;
 	} else {
-		brelse(bh);
+		put_dev_sector(sect);
 		return 0;
 	}
 }
diff -u --recursive --new-file v2.4.10/linux/fs/partitions/ultrix.h linux/fs/partitions/ultrix.h
--- v2.4.10/linux/fs/partitions/ultrix.h	Sun Jul  9 22:21:41 2000
+++ linux/fs/partitions/ultrix.h	Mon Oct  1 20:03:26 2001
@@ -2,6 +2,6 @@
  *  fs/partitions/ultrix.h
  */
 
-int ultrix_partition(struct gendisk *hd, kdev_t dev,
+int ultrix_partition(struct gendisk *hd, struct block_device *bdev,
                      unsigned long first_sector, int first_part_minor);
 
diff -u --recursive --new-file v2.4.10/linux/fs/pipe.c linux/fs/pipe.c
--- v2.4.10/linux/fs/pipe.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/pipe.c	Fri Sep 28 18:03:48 2001
@@ -476,7 +476,7 @@
 
 static struct inode * get_pipe_inode(void)
 {
-	struct inode *inode = get_empty_inode();
+	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
 
 	if (!inode)
 		goto fail_inode;
@@ -485,7 +485,6 @@
 		goto fail_iput;
 	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 	inode->i_fop = &rdwr_pipe_fops;
-	inode->i_sb = pipe_mnt->mnt_sb;
 
 	/*
 	 * Mark the inode dirty from the very beginning,
diff -u --recursive --new-file v2.4.10/linux/fs/proc/inode.c linux/fs/proc/inode.c
--- v2.4.10/linux/fs/proc/inode.c	Tue Apr 17 23:16:39 2001
+++ linux/fs/proc/inode.c	Sun Sep 30 12:26:08 2001
@@ -209,3 +209,4 @@
 	iput(root_inode);
 	return NULL;
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/qnx4/inode.c linux/fs/qnx4/inode.c
--- v2.4.10/linux/fs/qnx4/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/qnx4/inode.c	Sun Sep 30 12:26:08 2001
@@ -511,3 +511,5 @@
 
 module_init(init_qnx4_fs)
 module_exit(exit_qnx4_fs)
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/fs/ramfs/inode.c linux/fs/ramfs/inode.c
--- v2.4.10/linux/fs/ramfs/inode.c	Tue May 22 09:31:25 2001
+++ linux/fs/ramfs/inode.c	Sun Sep 30 12:26:08 2001
@@ -4,6 +4,7 @@
  * Copyright (C) 2000 Linus Torvalds.
  *               2000 Transmeta Corp.
  *
+ * Usage limits added by David Gibson, Linuxcare Australia.
  * This file is released under the GPL.
  */
 
@@ -348,3 +349,5 @@
 
 module_init(init_ramfs_fs)
 module_exit(exit_ramfs_fs)
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/bitmap.c linux/fs/reiserfs/bitmap.c
--- v2.4.10/linux/fs/reiserfs/bitmap.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/bitmap.c	Mon Oct  8 11:52:58 2001
@@ -68,23 +68,6 @@
 
 #endif /* CONFIG_REISERFS_CHECK */
 
-#if 0
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-int is_used (struct super_block * s, unsigned long block)
-{
-    int i, j;
-
-    i = block / (s->s_blocksize << 3);
-    j = block % (s->s_blocksize << 3);
-    if (reiserfs_test_le_bit(j, SB_AP_BITMAP (s)[i]->b_data))
-	return 1;
-    return 0;
-  
-}
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#endif
-
-
 /* get address of corresponding bit (bitmap block number and offset in it) */
 static inline void get_bit_address (struct super_block * s, unsigned long block, int * bmap_nr, int * offset)
 {
@@ -109,13 +92,8 @@
     struct buffer_head ** apbh;
     int nr, offset;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (!s)
-	reiserfs_panic (s, "vs-4060: reiserfs_free_block: trying to free block on nonexistent device");
-
-    if (is_reusable (s, block, 1) == 0)
-	reiserfs_panic (s, "vs-4070: reiserfs_free_block: can not free such block");
-#endif
+  RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
+  RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");
 
   rs = SB_DISK_SUPER_BLOCK (s);
   sbh = SB_BUFFER_WITH_SB (s);
@@ -317,17 +295,12 @@
 	   priority 0 */
 	return NO_DISK_SPACE;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (!s)
-	reiserfs_panic (s, "vs-4090: reiserfs_new_blocknrs: trying to get new block from nonexistent device");
-    
-    if (search_start == MAX_B_NUM)
-	reiserfs_panic (s, "vs-4100: reiserfs_new_blocknrs: we are optimizing location based on "
-			"the bogus location of a temp buffer (%lu).", search_start);
-    
-    if (amount_needed < 1 || amount_needed > 2) 
-	reiserfs_panic (s, "vs-4110: reiserfs_new_blocknrs: amount_needed parameter incorrect (%d)", amount_needed);
-#endif /* CONFIG_REISERFS_CHECK */
+  RFALSE( !s, "vs-4090: trying to get new block from nonexistent device");
+  RFALSE( search_start == MAX_B_NUM,
+	  "vs-4100: we are optimizing location based on "
+	  "the bogus location of a temp buffer (%lu).", search_start);
+  RFALSE( amount_needed < 1 || amount_needed > 2,
+	  "vs-4110: amount_needed parameter incorrect (%d)", amount_needed);
 
   /* We continue the while loop if another process snatches our found
    * free block from us after we find it but before we successfully
@@ -337,10 +310,8 @@
   while (amount_needed--) {
     /* skip over any blocknrs already gotten last time. */
     if (*(free_blocknrs) != 0) {
-#ifdef CONFIG_REISERFS_CHECK
-      if (is_reusable (s, *free_blocknrs, 1) == 0)
-	reiserfs_panic(s, "vs-4120: reiserfs_new_blocknrs: bad blocknr on free_blocknrs list");
-#endif /* CONFIG_REISERFS_CHECK */
+      RFALSE( is_reusable (s, *free_blocknrs, 1) == 0, 
+	      "vs-4120: bad blocknr on free_blocknrs list");
       free_blocknrs++;
       continue;
     }
@@ -414,10 +385,9 @@
 
     reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[i], 1) ;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (buffer_locked (SB_AP_BITMAP (s)[i]) || is_reusable (s, search_start, 0) == 0)
-	reiserfs_panic (s, "vs-4140: reiserfs_new_blocknrs: bitmap block is locked or bad block number found");
-#endif
+    RFALSE( buffer_locked (SB_AP_BITMAP (s)[i]) || 
+	    is_reusable (s, search_start, 0) == 0,
+	    "vs-4140: bitmap block is locked or bad block number found");
 
     /* if this bit was already set, we've scheduled, and someone else
     ** has allocated it.  loop around and try again
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/buffer2.c linux/fs/reiserfs/buffer2.c
--- v2.4.10/linux/fs/reiserfs/buffer2.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/buffer2.c	Mon Oct  8 11:52:58 2001
@@ -109,11 +109,9 @@
   *pp_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, n_new_blocknumber, p_s_sb->s_blocksize);
   if ( buffer_uptodate(*pp_s_new_bh) ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( buffer_dirty(*pp_s_new_bh) || (*pp_s_new_bh)->b_dev == NODEV ) {
-      reiserfs_panic(p_s_sb, "PAP-14080: get_new_buffer: invalid uptodate buffer %b for the new block", *pp_s_new_bh);
-    }
-#endif
+    RFALSE( buffer_dirty(*pp_s_new_bh) || (*pp_s_new_bh)->b_dev == NODEV,
+	    "PAP-14080: invalid uptodate buffer %b for the new block", 
+	    *pp_s_new_bh);
 
     /* Free path buffers to prevent deadlock. */
     /* It is possible that this process has the buffer, which this function is getting, already in
@@ -158,12 +156,9 @@
   else {
     ;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (atomic_read (&((*pp_s_new_bh)->b_count)) != 1) {
-      reiserfs_panic(p_s_sb,"PAP-14100: get_new_buffer: not uptodate buffer %b for the new block has b_count more than one",
-		     *pp_s_new_bh);
-    }
-#endif
+    RFALSE( atomic_read (&((*pp_s_new_bh)->b_count)) != 1,
+	    "PAP-14100: not uptodate buffer %b for the new block has b_count more than one",
+	    *pp_s_new_bh);
 
   }
   return (n_ret_value | n_repeat);
@@ -310,12 +305,10 @@
     n_repeat |= SCHEDULE_OCCURRED;
   }
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( atomic_read (&((*pp_s_new_bh)->b_count)) != 1 || buffer_dirty (*pp_s_new_bh)) {
-    reiserfs_panic(p_s_sb,"PAP-14100: get_new_buffer: not free or dirty buffer %b for the new block",
-		   *pp_s_new_bh);
-  }
-#endif
+  RFALSE( atomic_read (&((*pp_s_new_bh)->b_count)) != 1 || 
+	  buffer_dirty (*pp_s_new_bh),
+	  "PAP-14100: not free or dirty buffer %b for the new block", 
+	  *pp_s_new_bh);
 
   return n_repeat;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/dir.c linux/fs/reiserfs/dir.c
--- v2.4.10/linux/fs/reiserfs/dir.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/dir.c	Mon Oct  8 11:52:58 2001
@@ -102,24 +102,18 @@
 	ih = de.de_ih;
 	store_ih (&tmp_ih, ih);
 		
-#ifdef CONFIG_REISERFS_CHECK
 	/* we must have found item, that is item of this directory, */
-	if (COMP_SHORT_KEYS (&(ih->ih_key), &pos_key))
-	    reiserfs_panic (inode->i_sb, "vs-9000: reiserfs_readdir: "
-			    "found item %h does not match to dir we readdir %k",
-			    ih, &pos_key);
-      
-	if (item_num > B_NR_ITEMS (bh) - 1)
-	    reiserfs_panic (inode->i_sb, "vs-9005: reiserfs_readdir: "
-			    "item_num == %d, item amount == %d",
-			    item_num, B_NR_ITEMS (bh));
+	RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key),
+		"vs-9000: found item %h does not match to dir we readdir %k",
+		ih, &pos_key);
+	RFALSE( item_num > B_NR_ITEMS (bh) - 1,
+		"vs-9005 item_num == %d, item amount == %d", 
+		item_num, B_NR_ITEMS (bh));
       
 	/* and entry must be not more than number of entries in the item */
-	if (I_ENTRY_COUNT (ih) < entry_num)
-	    reiserfs_panic (inode->i_sb, "vs-9010: reiserfs_readdir: "
-			    "entry number is too big %d (%d)",
-			    entry_num, I_ENTRY_COUNT (ih));
-#endif	/* CONFIG_REISERFS_CHECK */
+	RFALSE( I_ENTRY_COUNT (ih) < entry_num,
+		"vs-9010: entry number is too big %d (%d)", 
+		entry_num, I_ENTRY_COUNT (ih));
 
 	if (search_res == POSITION_FOUND || entry_num < I_ENTRY_COUNT (ih)) {
 	    /* go through all entries in the directory item beginning from the entry, that has been found */
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/do_balan.c linux/fs/reiserfs/do_balan.c
--- v2.4.10/linux/fs/reiserfs/do_balan.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/do_balan.c	Mon Oct  8 11:52:58 2001
@@ -90,18 +90,12 @@
     int n;
     struct item_head * ih;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( tb->FR[0] && B_LEVEL (tb->FR[0]) != DISK_LEAF_NODE_LEVEL + 1)
-	reiserfs_panic (tb->tb_sb,
-			"vs- 12000: balance_leaf_when_delete:level: wrong FR %z\n", tb->FR[0]);
-    if ( tb->blknum[0] > 1 )
-	reiserfs_panic (tb->tb_sb,
-			"PAP-12005: balance_leaf_when_delete: "
-			"tb->blknum == %d, can not be > 1", tb->blknum[0]);
-	
-    if ( ! tb->blknum[0] && ! PATH_H_PPARENT(tb->tb_path, 0))
-	reiserfs_panic (tb->tb_sb, "PAP-12010: balance_leaf_when_delete: tree can not be empty");
-#endif
+    RFALSE( tb->FR[0] && B_LEVEL (tb->FR[0]) != DISK_LEAF_NODE_LEVEL + 1,
+	    "vs- 12000: level: wrong FR %z\n", tb->FR[0]);
+    RFALSE( tb->blknum[0] > 1,
+	    "PAP-12005: tb->blknum == %d, can not be > 1", tb->blknum[0]);
+    RFALSE( ! tb->blknum[0] && ! PATH_H_PPARENT(tb->tb_path, 0),
+	    "PAP-12010: tree can not be empty");
 
     ih = B_N_PITEM_HEAD (tbS0, item_pos);
 
@@ -110,10 +104,9 @@
     switch (flag) {
     case M_DELETE:   /* delete item in S[0] */
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (le16_to_cpu (ih->ih_item_len) + IH_SIZE != -tb->insert_size [0])
-	    reiserfs_panic (tb->tb_sb, "vs-12013: balance_leaf_when_delete: "
-			    "mode Delete, insert size %d, ih to be deleted %h", ih);
+	 RFALSE( le16_to_cpu (ih->ih_item_len) + IH_SIZE != -tb->insert_size [0],
+		 "vs-12013: mode Delete, insert size %d, ih to be deleted %h", 
+		 ih);
 
 #if 0 /* rigth delim key not supported */
 	if ( ! item_pos && (! tb->L[0] || COMP_KEYS(B_PRIGHT_DELIM_KEY(tb->L[0]), B_N_PKEY(tbS0, 0))) ) {
@@ -126,8 +119,6 @@
 	}
 #endif
 
-#endif
-
 	bi.tb = tb;
 	bi.bi_bh = tbS0;
 	bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
@@ -152,13 +143,8 @@
 	    }
 	} 
 
-#ifdef CONFIG_REISERFS_CHECK
-#if 0
-	if (! item_pos && (!tb->CFL[0] || !tb->L[0]))
-#endif
-	    if (! item_pos && !tb->CFL[0])
-		reiserfs_panic (tb->tb_sb, "PAP-12020: balance_leaf_when_delete: tb->CFL[0]==%p, tb->L[0]==%p", tb->CFL[0], tb->L[0]);
-#endif
+	RFALSE( ! item_pos && !tb->CFL[0],
+		"PAP-12020: tb->CFL[0]==%p, tb->L[0]==%p", tb->CFL[0], tb->L[0]);
     
 	break;
 
@@ -182,10 +168,9 @@
 	    tb->insert_size[0] = -1;
 	    leaf_cut_from_buffer (&bi, item_pos, pos_in_item, -tb->insert_size[0]);
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if (! item_pos && ! pos_in_item && ! tb->CFL[0])
-		reiserfs_panic (tb->tb_sb, "PAP-12030: balance_leaf_when_delete: can not change delimiting key. CFL[0]=%p", tb->CFL[0]);
-#endif /* CONFIG_REISERFS_CHECK */
+	    RFALSE( ! item_pos && ! pos_in_item && ! tb->CFL[0],
+		    "PAP-12030: can not change delimiting key. CFL[0]=%p", 
+		    tb->CFL[0]);
 
 	    if ( ! item_pos && ! pos_in_item && tb->CFL[0] ) {
 		replace_key(tb, tb->CFL[0],tb->lkey[0],tbS0,0);
@@ -197,10 +182,8 @@
 	} else {
 	    leaf_cut_from_buffer (&bi, item_pos, pos_in_item, -tb->insert_size[0]);
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if (! ih->ih_item_len)
-		reiserfs_panic (tb->tb_sb, "PAP-12035: balance_leaf_when_delete: cut must leave non-zero dynamic length of item");
-#endif /* CONFIG_REISERFS_CHECK */
+	    RFALSE( ! ih->ih_item_len,
+		    "PAP-12035: cut must leave non-zero dynamic length of item");
 	}
 	break;
     }
@@ -259,12 +242,8 @@
 		return -1;
 	    }
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if ( tb->rnum[0] != 0 )
-		reiserfs_panic (tb->tb_sb, "PAP-12045: balance_leaf_when_delete: "
-				"rnum must be 0 (%d)", tb->rnum[0]);
-#endif /* CONFIG_REISERFS_CHECK */
-
+	    RFALSE( tb->rnum[0] != 0, 
+		    "PAP-12045: rnum must be 0 (%d)", tb->rnum[0]);
 	    /* all contents of L[0] and S[0] will be in L[0] */
 	    leaf_shift_left(tb, n, -1);
 
@@ -277,21 +256,18 @@
 	}
 	/* a part of contents of S[0] will be in L[0] and the rest part of S[0] will be in R[0] */
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (( tb->lnum[0] + tb->rnum[0] < n ) || ( tb->lnum[0] + tb->rnum[0] > n+1 ))
-	    reiserfs_panic (tb->tb_sb, "PAP-12050: balance_leaf_when_delete: "
-			    "rnum(%d) and lnum(%d) and item number in S[0] are not consistent",
-			    tb->rnum[0], tb->lnum[0], n);
-
-	if (( tb->lnum[0] + tb->rnum[0] == n ) && (tb->lbytes != -1 || tb->rbytes != -1))
-	    reiserfs_panic (tb->tb_sb, "PAP-12055: balance_leaf_when_delete: "
-			    "bad rbytes (%d)/lbytes (%d) parameters when items are not split", 
-			    tb->rbytes, tb->lbytes);
-	if (( tb->lnum[0] + tb->rnum[0] == n + 1 ) && (tb->lbytes < 1 || tb->rbytes != -1))
-	    reiserfs_panic (tb->tb_sb, "PAP-12060: balance_leaf_when_delete: "
-			    "bad rbytes (%d)/lbytes (%d) parameters when items are split", 
-			    tb->rbytes, tb->lbytes);
-#endif
+	RFALSE( ( tb->lnum[0] + tb->rnum[0] < n ) || 
+		( tb->lnum[0] + tb->rnum[0] > n+1 ),
+		"PAP-12050: rnum(%d) and lnum(%d) and item number(%d) in S[0] are not consistent",
+		tb->rnum[0], tb->lnum[0], n);
+	RFALSE( ( tb->lnum[0] + tb->rnum[0] == n ) && 
+		(tb->lbytes != -1 || tb->rbytes != -1),
+		"PAP-12055: bad rbytes (%d)/lbytes (%d) parameters when items are not split", 
+		tb->rbytes, tb->lbytes);
+	RFALSE( ( tb->lnum[0] + tb->rnum[0] == n + 1 ) && 
+		(tb->lbytes < 1 || tb->rbytes != -1),
+		"PAP-12060: bad rbytes (%d)/lbytes (%d) parameters when items are split", 
+		tb->rbytes, tb->lbytes);
 
 	leaf_shift_left (tb, tb->lnum[0], tb->lbytes);
 	leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
@@ -315,12 +291,8 @@
 	return 0;
     }
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( tb->rnum[0] )
-	reiserfs_panic (tb->tb_sb, "PAP-12065: balance_leaf_when_delete: "
-			"bad rnum parameter must be 0 (%d)", tb->rnum[0]);
-#endif
-
+    RFALSE( tb->rnum[0], 
+	    "PAP-12065: bad rnum parameter must be 0 (%d)", tb->rnum[0]);
     return 0;
 }
 
@@ -394,11 +366,8 @@
 		    int new_item_len;
 		    int version;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if (!is_direct_le_ih (ih))
-			reiserfs_panic (tb->tb_sb, "PAP-12075: balance_leaf: " 
-					"only direct inserted item can be broken. %h", ih);
-#endif
+		    RFALSE( !is_direct_le_ih (ih),
+			    "PAP-12075: only direct inserted item can be broken. %h", ih);
 		    ret_val = leaf_shift_left (tb, tb->lnum[0]-1, -1);
 		    /* when reading the if conditions preceding the subsequent preserve_shifted
 		       lines understand that their goal is to determine if all that we are
@@ -415,12 +384,9 @@
 		    /* Calculate and check item length to insert to L[0] */
 		    ih->ih_item_len -= new_item_len;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( (int)(ih->ih_item_len) <= 0 )
-			reiserfs_panic(tb->tb_sb, "PAP-12080: balance_leaf: "
-				       "there is nothing to insert into L[0]: ih_item_len=%d",
-				       (int)ih->ih_item_len);
-#endif
+		    RFALSE( (int)(ih->ih_item_len) <= 0,
+			    "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d",
+			    (int)ih->ih_item_len);
 
 		    /* Insert new item into L[0] */
 		    bi.tb = tb;
@@ -443,12 +409,9 @@
 		    else
 			zeros_num -= tb->lbytes;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( (int)(ih->ih_item_len) <= 0 )
-			reiserfs_panic(tb->tb_sb, "PAP-12085: balance_leaf: "
-				       "there is nothing to insert into S[0]: ih_item_len=%d",
-				       (int)ih->ih_item_len);
-#endif
+		    RFALSE( (int)(ih->ih_item_len) <= 0,
+			    "PAP-12085: there is nothing to insert into S[0]: ih_item_len=%d",
+			    (int)ih->ih_item_len);
 		} else {
 		    /* new item in whole falls into L[0] */
 		    /* Shift lnum[0]-1 items to L[0] */
@@ -481,11 +444,8 @@
 		    /* we must shift the part of the appended item */
 		    if ( is_direntry_le_ih (B_N_PITEM_HEAD (tbS0, item_pos))) {
 
-#ifdef CONFIG_REISERFS_CHECK
-			if ( zeros_num )
-			    reiserfs_panic(tb->tb_sb, "PAP-12090: balance_leaf: illegal parameter in case of a directory");
-#endif
-            
+			RFALSE( zeros_num,
+				"PAP-12090: illegal parameter in case of a directory");
 			/* directory item */
 			if ( tb->lbytes > pos_in_item ) {
 			    /* new directory entry falls into L[0] */
@@ -535,18 +495,12 @@
 		    }
 		    else {
 			/* regular object */
-
-#ifdef CONFIG_REISERFS_CHECK
-			if ( tb->lbytes  <= 0 )
-			    reiserfs_panic(tb->tb_sb, "PAP-12095: balance_leaf: " 
-					   "there is nothing to shift to L[0]. lbytes=%d",
-					   tb->lbytes);
-			if ( pos_in_item != B_N_PITEM_HEAD(tbS0, item_pos)->ih_item_len )
-			    reiserfs_panic(tb->tb_sb, "PAP-12100: balance_leaf: " 
-					   "incorrect position to paste: item_len=%d, pos_in_item=%d",
-					   B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len, pos_in_item);
-#endif
-
+			RFALSE( tb->lbytes <= 0,
+				"PAP-12095: there is nothing to shift to L[0]. lbytes=%d",
+				tb->lbytes);
+			RFALSE( pos_in_item != B_N_PITEM_HEAD(tbS0, item_pos)->ih_item_len,
+				"PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d",
+				B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len, pos_in_item);
 			if ( tb->lbytes >= pos_in_item ) {
 			    /* appended item will be in L[0] in whole */
 			    int l_n;
@@ -557,13 +511,9 @@
 			    /* Calculate new insert_size[0] */
 			    tb->insert_size[0] -= l_n;
 
-#ifdef CONFIG_REISERFS_CHECK
-			    if ( tb->insert_size[0] <= 0 )
-				reiserfs_panic(tb->tb_sb, "PAP-12105: balance_leaf: " 
-					       "there is nothing to paste into L[0]. insert_size=%d",
-					       tb->insert_size[0]);
-#endif
-
+			    RFALSE( tb->insert_size[0] <= 0,
+				    "PAP-12105: there is nothing to paste into L[0]. insert_size=%d",
+				    tb->insert_size[0]);
 			    ret_val =  leaf_shift_left(tb,tb->lnum[0], 
 						       B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len);
 #if 0/*preserve list*/
@@ -581,12 +531,11 @@
 				l_n,body, zeros_num > l_n ? l_n : zeros_num
 				);
 
-#ifdef CONFIG_REISERFS_CHECK
-			    if (l_n && is_indirect_le_ih(B_N_PITEM_HEAD(tb->L[0],
-									n + item_pos - ret_val)))
-				reiserfs_panic(tb->tb_sb, "PAP-12110: balance_leaf: "
-					       "pasting more than 1 unformatted node pointer into indirect item");
-#endif
+			    RFALSE( l_n && 
+				    is_indirect_le_ih(B_N_PITEM_HEAD
+						      (tb->L[0],
+						       n + item_pos - ret_val)),
+				    "PAP-12110: pasting more than 1 unformatted node pointer into indirect item");
 
 			    /* 0-th item in S0 can be only of DIRECT type when l_n != 0*/
 			    {
@@ -598,18 +547,10 @@
 			      set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
 						   le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + l_n);
 			    }
-#if 0
-			    set_le_key_k_offset (B_PRIGHT_DELIM_KEY(tb->L[0]), le_key_k_offset (B_PRIGHT_DELIM_KEY(tb->L[0])) + l_n);
-#endif
 			    /*    k_offset (B_N_PKEY (tbS0, 0)) += l_n;
 				  k_offset (B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) += l_n;
 				  k_offset (B_PRIGHT_DELIM_KEY(tb->L[0])) += l_n;*/
 
-#ifdef NO_CONFIG_REISERFS_CHECK /* journal victim */
-			    if (!buffer_dirty (tbS0) || !buffer_dirty (tb->CFL[0]) || !buffer_dirty (tb->L[0]))
-				reiserfs_panic(tb->tb_sb, "PAP-12115: balance_leaf: L, CLF and S must be dirty already");
-#endif
-
 			    /* Calculate new body, position in item and insert_size[0] */
 			    if ( l_n > zeros_num ) {
 				body += (l_n - zeros_num);
@@ -619,26 +560,24 @@
 				zeros_num -= l_n;
 			    pos_in_item = 0;	
 
-#ifdef CONFIG_REISERFS_CHECK	
-			    if (comp_short_le_keys (B_N_PKEY(tbS0,0),
-						    B_N_PKEY(tb->L[0],B_NR_ITEMS(tb->L[0])-1)) ||
-				!op_is_left_mergeable (B_N_PKEY (tbS0, 0), tbS0->b_size) ||
-				!op_is_left_mergeable(B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]), tbS0->b_size))
-				reiserfs_panic (tb->tb_sb, "PAP-12120: balance_leaf: "
-						"item must be merge-able with left neighboring item");
-#endif
-
+			    RFALSE( comp_short_le_keys 
+				    (B_N_PKEY(tbS0,0),
+				     B_N_PKEY(tb->L[0],B_NR_ITEMS(tb->L[0])-1)) ||
+				
+				    !op_is_left_mergeable 
+				    (B_N_PKEY (tbS0, 0), tbS0->b_size) ||
+				    !op_is_left_mergeable
+				    (B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]), 
+				     tbS0->b_size),
+				    "PAP-12120: item must be merge-able with left neighboring item");
 			}
 			else /* only part of the appended item will be in L[0] */
 			{
 			    /* Calculate position in item for append in S[0] */
 			    pos_in_item -= tb->lbytes;
 
-#ifdef CONFIG_REISERFS_CHECK
-			    if ( pos_in_item <= 0 )
-				reiserfs_panic(tb->tb_sb, "PAP-12125: balance_leaf: "
-					       "no place for paste. pos_in_item=%d", pos_in_item);
-#endif
+			    RFALSE( pos_in_item <= 0,
+				    "PAP-12125: no place for paste. pos_in_item=%d", pos_in_item);
 
 			    /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
 			    leaf_shift_left(tb,tb->lnum[0],tb->lbytes);
@@ -723,11 +662,9 @@
 		    int version;
 		    loff_t offset;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( !is_direct_le_ih (ih) )
-			reiserfs_panic(tb->tb_sb, "PAP-12135: balance_leaf: "
-				       "only direct item can be split. (%h)", ih);
-#endif
+		    RFALSE( !is_direct_le_ih (ih),
+			    "PAP-12135: only direct item can be split. (%h)", 
+			    ih);
 
 		    leaf_shift_right(tb,tb->rnum[0]-1,-1);
 #if 0/*preserve list*/
@@ -828,24 +765,18 @@
 		    { /* we append to directory item */
 			int entry_count;
 
-#ifdef CONFIG_REISERFS_CHECK
-			if ( zeros_num )
-			    reiserfs_panic(tb->tb_sb, "PAP-12145: balance_leaf: illegal parametr in case of a directory");
-#endif
-
+			RFALSE( zeros_num,
+				"PAP-12145: illegal parametr in case of a directory");
 			entry_count = I_ENTRY_COUNT(B_N_PITEM_HEAD(tbS0, item_pos));
 			if ( entry_count - tb->rbytes < pos_in_item )
 			    /* new directory entry falls into R[0] */
 			{
 			    int paste_entry_position;
 
-#ifdef CONFIG_REISERFS_CHECK
-			    if ( tb->rbytes - 1 >= entry_count || ! tb->insert_size[0] )
-				reiserfs_panic(tb->tb_sb, "PAP-12150: balance_leaf: "
-					       "no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d",
-					       tb->rbytes, entry_count);
-#endif
-
+			    RFALSE( tb->rbytes - 1 >= entry_count || 
+				    ! tb->insert_size[0],
+				    "PAP-12150: no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d",
+				    tb->rbytes, entry_count);
 			    /* Shift rnum[0]-1 items in whole. Shift rbytes-1 directory entries from directory item number rnum[0] */
 			    leaf_shift_right(tb,tb->rnum[0],tb->rbytes - 1);
 #if 0/*preserve list*/
@@ -899,11 +830,9 @@
 			if ( (n_shift = tb->rbytes - tb->insert_size[0]) < 0 )
 			    n_shift = 0;
 
-#ifdef CONFIG_REISERFS_CHECK
-			if (pos_in_item != B_N_PITEM_HEAD (tbS0, item_pos)->ih_item_len)
-			    reiserfs_panic(tb->tb_sb,"PAP-12155: balance_leaf: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
-					   pos_in_item, B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len);
-#endif
+			RFALSE( pos_in_item != B_N_PITEM_HEAD (tbS0, item_pos)->ih_item_len,
+				"PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
+				pos_in_item, B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len);
 
 			leaf_shift_right(tb,tb->rnum[0],n_shift);
 #if 0/*preserve list*/
@@ -954,10 +883,8 @@
 
 			if (is_indirect_le_ih (B_N_PITEM_HEAD(tb->R[0],0))) {
 
-#ifdef CONFIG_REISERFS_CHECK
-			    if (n_rem)
-				reiserfs_panic(tb->tb_sb, "PAP-12160: balance_leaf: paste more than one unformatted node pointer");
-#endif
+			    RFALSE( n_rem,
+				    "PAP-12160: paste more than one unformatted node pointer");
 
 			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), ((struct unfm_nodeinfo*)body)->unfm_freespace);
 			}
@@ -995,11 +922,8 @@
 			    );
 			if ( ! pos_in_item ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-			    if ( item_pos - n + tb->rnum[0] )
-				reiserfs_panic (tb->tb_sb, "PAP-12165: balance_leaf: " 
-						"directory item must be first item of node when pasting is in 0th position");
-#endif
+			    RFALSE( item_pos - n + tb->rnum[0],
+				    "PAP-12165: directory item must be first item of node when pasting is in 0th position");
 
 			    /* update delimiting keys */
 			    replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
@@ -1032,43 +956,18 @@
     }	/* tb->rnum[0] > 0 */
 
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( tb->blknum[0] > 3 )  
-	reiserfs_panic (tb->tb_sb, "PAP-12180: balance_leaf: blknum can not be %d. It must be <= 3",  tb->blknum[0]);
-
-    if ( tb->blknum[0] < 0 )  
-	reiserfs_panic (tb->tb_sb, "PAP-12185: balance_leaf: blknum can not be %d. It must be >= 0",  tb->blknum[0]);
-#endif
+    RFALSE( tb->blknum[0] > 3,
+	    "PAP-12180: blknum can not be %d. It must be <= 3",  tb->blknum[0]);
+    RFALSE( tb->blknum[0] < 0,
+	    "PAP-12185: blknum can not be %d. It must be >= 0",  tb->blknum[0]);
 
     /* if while adding to a node we discover that it is possible to split
        it in two, and merge the left part into the left neighbor and the
        right part into the right neighbor, eliminating the node */
     if ( tb->blknum[0] == 0 ) { /* node S[0] is empty now */
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( ! tb->lnum[0] || ! tb->rnum[0] )
-	    reiserfs_panic(tb->tb_sb, "PAP-12190: balance_leaf: lnum and rnum must not be zero");
-#if 0
-	if (COMP_KEYS (B_N_PKEY(tb->R[0], 0), B_PRIGHT_DELIM_KEY(tbS0)))
-	    reiserfs_panic (tb->tb_sb, "vs-12192: balance_leaf: S[0] is being removed from the tree, it has incorrect right delimiting key");
-#endif
-#endif
-
-#if 0
-	/* if insertion was done before 0-th position in R[0], right
-	   delimiting key of the tb->L[0]'s and left delimiting key are
-	   not set correctly */
-	if (tb->L[0]) {
-	    copy_key(B_PRIGHT_DELIM_KEY(tb->L[0]), B_PRIGHT_DELIM_KEY(tbS0));
-	    reiserfs_mark_buffer_dirty (tb->L[0], 0);
-	}
-
-	if (tb->CFL[0]) {
-	    copy_key (B_N_PDELIM_KEY (tb->CFL[0], tb->lkey[0]), B_PRIGHT_DELIM_KEY(tbS0));
-	    reiserfs_mark_buffer_dirty (tb->CFL[0], 0);
-	}
-#endif
-    
+	RFALSE( ! tb->lnum[0] || ! tb->rnum[0],
+		"PAP-12190: lnum and rnum must not be zero");
 	/* if insertion was done before 0-th position in R[0], right
 	   delimiting key of the tb->L[0]'s and left delimiting key are
 	   not set correctly */
@@ -1094,10 +993,7 @@
     sbytes[1] = tb->s2bytes;
     for( i = tb->blknum[0] - 2; i >= 0; i-- ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (!snum[i])
-	    reiserfs_panic(tb->tb_sb,"PAP-12200: balance_leaf: snum[%d] == %d. Must be > 0", i, snum[i]);
-#endif /* CONFIG_REISERFS_CHECK */
+	RFALSE( !snum[i], "PAP-12200: snum[%d] == %d. Must be > 0", i, snum[i]);
 
 	/* here we shift from S to S_new nodes */
 
@@ -1120,14 +1016,11 @@
 		    const char * r_body;
 		    int version;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( !is_direct_le_ih(ih) )
+		    RFALSE( !is_direct_le_ih(ih),
 			/* The items which can be inserted are:
 			   Stat_data item, direct item, indirect item and directory item which consist of only two entries "." and "..".
 			   These items must not be broken except for a direct one. */
-			reiserfs_panic(tb->tb_sb, "PAP-12205: balance_leaf: "
-				       "non-direct item can not be broken when inserting");
-#endif
+			    "PAP-12205: non-direct item can not be broken when inserting");
 
 		    /* Move snum[i]-1 items from S[0] to S_new[i] */
 		    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i] - 1, -1, S_new[i]);
@@ -1210,10 +1103,7 @@
 		{ /* we must shift part of the appended item */
 		    struct item_head * aux_ih;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( ih )
-			reiserfs_panic (tb->tb_sb, "PAP-12210: balance_leaf: ih must be 0");
-#endif /* CONFIG_REISERFS_CHECK */
+		    RFALSE( ih, "PAP-12210: ih must be 0");
 
 		    if ( is_direntry_le_ih (aux_ih = B_N_PITEM_HEAD(tbS0,item_pos))) {
 			/* we append to directory item */
@@ -1225,14 +1115,11 @@
 			if ( entry_count - sbytes[i] < pos_in_item  && pos_in_item <= entry_count ) {
 			    /* new directory entry falls into S_new[i] */
 		  
-#ifdef CONFIG_REISERFS_CHECK
-			    if ( ! tb->insert_size[0] )
-				reiserfs_panic (tb->tb_sb, "PAP-12215: balance_leaif: insert_size is already 0");
-			    if ( sbytes[i] - 1 >= entry_count )
-				reiserfs_panic (tb->tb_sb, "PAP-12220: balance_leaf: "
-						"there are no so much entries (%d), only %d",
-						sbytes[i] - 1, entry_count);
-#endif
+			    RFALSE( ! tb->insert_size[0],
+				    "PAP-12215: insert_size is already 0");
+			    RFALSE( sbytes[i] - 1 >= entry_count,
+				    "PAP-12220: there are no so much entries (%d), only %d",
+				    sbytes[i] - 1, entry_count);
 
 			    /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
 			    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i]-1, S_new[i]);
@@ -1268,11 +1155,9 @@
 			int n_shift, n_rem, r_zeros_number;
 			const char * r_body;
 
-#ifdef CONFIG_REISERFS_CHECK
-			if ( pos_in_item != B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len ||
-			     tb->insert_size[0] <= 0 )
-			    reiserfs_panic (tb->tb_sb, "PAP-12225: balance_leaf: item too short or insert_size <= 0");
-#endif
+			RFALSE( pos_in_item != B_N_PITEM_HEAD(tbS0,item_pos)->ih_item_len ||
+				tb->insert_size[0] <= 0,
+				"PAP-12225: item too short or insert_size <= 0");
 
 			/* Calculate number of bytes which must be shifted from appended item */
 			n_shift = sbytes[i] - tb->insert_size[0];
@@ -1340,12 +1225,9 @@
 		    tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
 #endif
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( ret_val )
-			reiserfs_panic (tb->tb_sb, "PAP-12240: balance_leaf: "
-					"unexpected value returned by leaf_move_items (%d)",
-					ret_val);
-#endif /* CONFIG_REISERFS_CHECK */
+		    RFALSE( ret_val,
+			    "PAP-12240: unexpected value returned by leaf_move_items (%d)",
+			    ret_val);
 
 		    /* paste into item */
 		    bi.tb = tb;
@@ -1387,14 +1269,11 @@
 	memcpy (insert_key + i,B_N_PKEY(S_new[i],0),KEY_SIZE);
 	insert_ptr[i] = S_new[i];
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (atomic_read (&(S_new[i]->b_count)) != 1) {
-	    if (atomic_read(&(S_new[i]->b_count)) != 2 ||
-	      !(buffer_journaled(S_new[i]) || buffer_journal_dirty(S_new[i]))) {
-	      reiserfs_panic (tb->tb_sb, "PAP-12247: balance_leaf: S_new[%d] : (%b)\n", i, S_new[i]);
-	    }
-	}
-#endif
+	RFALSE( (atomic_read (&(S_new[i]->b_count)) != 1) &&
+		(atomic_read(&(S_new[i]->b_count)) != 2 ||
+		 !(buffer_journaled(S_new[i]) || 
+		   buffer_journal_dirty(S_new[i]))), 
+		"PAP-12247: S_new[%d] : (%b)\n", i, S_new[i]);
 
 #if 0
 	/* update right_delimiting_key fields */
@@ -1452,10 +1331,8 @@
 	    if (is_direntry_le_ih (pasted)) {
 		if ( pos_in_item >= 0 && pos_in_item <= le16_to_cpu (pasted->u.ih_entry_count) ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( ! tb->insert_size[0] )
-			reiserfs_panic (tb->tb_sb, "PAP-12260: balance_leaf: insert_size is 0 already");
-#endif /* CONFIG_REISERFS_CHECK */
+		    RFALSE( ! tb->insert_size[0], 
+			    "PAP-12260: insert_size is 0 already");
 
 		    /* prepare space */
 		    bi.tb = tb;
@@ -1479,12 +1356,8 @@
 			body + DEH_SIZE, tb->insert_size[0]
 			);
 		    if ( ! item_pos && ! pos_in_item ) {
-
-#ifdef CONFIG_REISERFS_CHECK
-			if (!tb->CFL[0] || !tb->L[0])
-			    reiserfs_panic (tb->tb_sb, "PAP-12270: balance_leaf: CFL[0]/L[0] must be specified");
-#endif /* CONFIG_REISERFS_CHECK */
-
+			RFALSE( !tb->CFL[0] || !tb->L[0], 
+				"PAP-12270: CFL[0]/L[0] must be specified");
 			if (tb->CFL[0]) {
 			    replace_key(tb, tb->CFL[0], tb->lkey[0],tbS0,0);
 
@@ -1500,12 +1373,9 @@
 		}
 	    } else { /* regular object */
 		if ( pos_in_item == pasted->ih_item_len ) {
-
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( tb->insert_size[0] <= 0 )
-			reiserfs_panic (tb->tb_sb,
-					"PAP-12275: balance_leaf: insert size must not be %d", tb->insert_size[0]);
-#endif /* CONFIG_REISERFS_CHECK */
+		    RFALSE( tb->insert_size[0] <= 0,
+			    "PAP-12275: insert size must not be %d", 
+			    tb->insert_size[0]);
 		    bi.tb = tb;
 		    bi.bi_bh = tbS0;
 		    bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
@@ -1514,13 +1384,9 @@
 
 		    if (is_indirect_le_ih (pasted)) {
 
-#ifdef CONFIG_REISERFS_CHECK
-			if ( tb->insert_size[0] != UNFM_P_SIZE )
-			    reiserfs_panic (tb->tb_sb,
-					    "PAP-12280: balance_leaf: insert_size for indirect item must be %d, not %d",
-					    UNFM_P_SIZE, tb->insert_size[0]);
-#endif /* CONFIG_REISERFS_CHECK */
-
+			RFALSE( tb->insert_size[0] != UNFM_P_SIZE,
+				"PAP-12280: insert_size for indirect item must be %d, not %d",
+				UNFM_P_SIZE, tb->insert_size[0]);
 			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
 		    }
 		    tb->insert_size[0] = 0;
@@ -1557,10 +1423,7 @@
 {
     struct block_head * blkh;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (bi->bi_bh == NULL)
-	reiserfs_panic (0, "PAP-12295: make_empty_node: pointer to the buffer is NULL");
-#endif
+    RFALSE( bi->bi_bh == NULL, "PAP-12295: pointer to the buffer is NULL");
 
     (blkh = B_BLK_HEAD(bi->bi_bh))->blk_nr_item = cpu_to_le16 (0);
     blkh->blk_free_space = cpu_to_le16 (MAX_CHILD_SIZE(bi->bi_bh));
@@ -1646,21 +1509,17 @@
 		  struct buffer_head * src, int n_src)
 {
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (dest == NULL || src == NULL)
-	reiserfs_panic (0, "vs-12305: replace_key: sourse or destination buffer is 0 (src=%p, dest=%p)", src, dest);
-
-    if ( ! B_IS_KEYS_LEVEL (dest) )
-	reiserfs_panic (0, "vs-12310: replace_key: invalid level (%z) for destination buffer. dest must be leaf",
-			dest);
-
-    if (n_dest < 0 || n_src < 0)
-	reiserfs_panic (0, "vs-12315: replace_key: src(%d) or dest(%d) key number less than 0", n_src, n_dest);
-
-    if (n_dest >= B_NR_ITEMS(dest) || n_src >= B_NR_ITEMS(src))
-	reiserfs_panic (0, "vs-12320: replace_key: src(%d(%d)) or dest(%d(%d)) key number is too big",
-			n_src, B_NR_ITEMS(src), n_dest, B_NR_ITEMS(dest));
-#endif	/* CONFIG_REISERFS_CHECK */
+    RFALSE( dest == NULL || src == NULL,
+	    "vs-12305: source or destination buffer is 0 (src=%p, dest=%p)",
+	    src, dest);
+    RFALSE( ! B_IS_KEYS_LEVEL (dest),
+	    "vs-12310: invalid level (%z) for destination buffer. dest must be leaf",
+	    dest);
+    RFALSE( n_dest < 0 || n_src < 0,
+	    "vs-12315: src(%d) or dest(%d) key number < 0", n_src, n_dest);
+    RFALSE( n_dest >= B_NR_ITEMS(dest) || n_src >= B_NR_ITEMS(src),
+	    "vs-12320: src(%d(%d)) or dest(%d(%d)) key number is too big",
+	    n_src, B_NR_ITEMS(src), n_dest, B_NR_ITEMS(dest));
    
     if (B_IS_ITEMS_LEVEL (src))
 	/* source buffer contains leaf node */
@@ -1679,11 +1538,9 @@
 {
   int Sh_position = PATH_H_POSITION (tb->tb_path, h + 1);
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (PATH_H_PPARENT (tb->tb_path, h) == 0 || tb->FL[h] == 0)
-    reiserfs_panic (tb->tb_sb, "vs-12325: get_left_neighbor_position: FL[%d](%p) or F[%d](%p) does not exist", 
-		    h, tb->FL[h], h, PATH_H_PPARENT (tb->tb_path, h));
-#endif
+  RFALSE( PATH_H_PPARENT (tb->tb_path, h) == 0 || tb->FL[h] == 0,
+	  "vs-12325: FL[%d](%p) or F[%d](%p) does not exist", 
+	  h, tb->FL[h], h, PATH_H_PPARENT (tb->tb_path, h));
 
   if (Sh_position == 0)
     return B_NR_ITEMS (tb->FL[h]);
@@ -1696,11 +1553,9 @@
 {
   int Sh_position = PATH_H_POSITION (tb->tb_path, h + 1);
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (PATH_H_PPARENT (tb->tb_path, h) == 0 || tb->FR[h] == 0)
-    reiserfs_panic (tb->tb_sb, "vs-12330: get_right_neighbor_position: F[%d](%p) or FR[%d](%p) does not exist", 
-		    h, PATH_H_PPARENT (tb->tb_path, h), h, tb->FR[h]);
-#endif
+  RFALSE( PATH_H_PPARENT (tb->tb_path, h) == 0 || tb->FR[h] == 0,
+	  "vs-12330: F[%d](%p) or FR[%d](%p) does not exist", 
+	  h, PATH_H_PPARENT (tb->tb_path, h), h, tb->FR[h]);
 
   if (Sh_position == B_NR_ITEMS (PATH_H_PPARENT (tb->tb_path, h)))
     return 0;
@@ -1717,17 +1572,14 @@
   struct disk_child * dc;
   int i;
 
-  if (!bh)
-    reiserfs_panic (s, "PAP-12336: check_internal_node: bh == 0");
+  RFALSE( !bh, "PAP-12336: bh == 0");
 
   if (!bh || !B_IS_IN_TREE (bh))
     return;
  
-  if (!buffer_dirty (bh) && 
-      !(buffer_journaled(bh) || buffer_journal_dirty(bh))) {
-    reiserfs_panic (s, "PAP-12337: check_internal_node: buffer (%b) must be dirty", bh);
-  }
-
+  RFALSE( !buffer_dirty (bh) && 
+	  !(buffer_journaled(bh) || buffer_journal_dirty(bh)),
+	  "PAP-12337: buffer (%b) must be dirty", bh);
   dc = B_N_CHILD (bh, 0);
 
   for (i = 0; i <= B_NR_ITEMS (bh); i ++, dc ++) {
@@ -1875,18 +1727,13 @@
 
     /* store_print_tb (tb); */
 
-#ifdef CONFIG_REISERFS_CHECK
-
     /* do not delete, just comment it out */
 /*    print_tb(flag, PATH_LAST_POSITION(tb->tb_path), tb->tb_path->pos_in_item, tb, 
 	     "check");*/
-
-    if (check_before_balancing (tb))
-	reiserfs_panic (tb->tb_sb, "PAP-12340: do_balance: locked buffers in TB");
-
+    RFALSE( check_before_balancing (tb), "PAP-12340: locked buffers in TB");
+#ifdef CONFIG_REISERFS_CHECK
     cur_tb = tb;
-    
-#endif /* CONFIG_REISERFS_CHECK */
+#endif
 }
 
 
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/fix_node.c linux/fs/reiserfs/fix_node.c
--- v2.4.10/linux/fs/reiserfs/fix_node.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/fix_node.c	Mon Oct  8 11:52:58 2001
@@ -65,19 +65,14 @@
 
   if (mode == M_INSERT) {
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (new_num == 0)
-      reiserfs_panic (0,"vs-8005: old_item_num: for INSERT mode and item number of inserted item");
-#endif
+    RFALSE( new_num == 0, 
+	    "vs-8005: for INSERT mode and item number of inserted item");
 
     return new_num - 1;
   }
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (mode != M_DELETE)
-      reiserfs_panic (0, "vs-8010: old_item_num: mode must be M_DELETE (mode = \'%c\'", mode);
-#endif
-
+  RFALSE( mode != M_DELETE,
+	  "vs-8010: old_item_num: mode must be M_DELETE (mode = \'%c\'", mode);
   /* delete mode */
   return new_num + 1;
 }
@@ -156,37 +151,14 @@
     if (vn->vn_mode == M_INSERT) {
 	struct virtual_item * vi = vn->vn_vi + vn->vn_affected_item_num;
       
-#ifdef CONFIG_REISERFS_CHECK
-	if (vn->vn_ins_ih == 0)
-	    reiserfs_panic (0, "vs-8040: create_virtual_node: item header of inserted item is not specified");
-#endif
-
+	RFALSE( vn->vn_ins_ih == 0,
+		"vs-8040: item header of inserted item is not specified");
 	vi->vi_item_len = tb->insert_size[0];
 	vi->vi_ih = vn->vn_ins_ih;
 	vi->vi_item = vn->vn_data;
 	vi->vi_uarea = vn->vn_free_ptr;
 	
 	op_create_vi (vn, vi, 0/*not pasted or cut*/, tb->insert_size [0]);
-#if 0
-	switch (type/*le_key_k_type (ih_version (vn->vn_ins_ih), &(vn->vn_ins_ih->ih_key))*/) {
-	case TYPE_STAT_DATA:
-	    vn->vn_vi[vn->vn_affected_item_num].vi_type |= VI_TYPE_STAT_DATA;
-	    break;
-	case TYPE_DIRECT:
-	    vn->vn_vi[vn->vn_affected_item_num].vi_type |= VI_TYPE_DIRECT;
-	    break;
-	case TYPE_INDIRECT:
-	    vn->vn_vi[vn->vn_affected_item_num].vi_type |= VI_TYPE_INDIRECT;
-	    break;
-	default:
-	    /* inseted item is directory (it must be item with "." and "..") */
-	    vn->vn_vi[vn->vn_affected_item_num].vi_type |= 
-	    	(VI_TYPE_DIRECTORY | VI_TYPE_FIRST_DIRECTORY_ITEM | VI_TYPE_INSERTED_DIRECTORY_ITEM);
-      
-	    /* this directory item can not be split, so do not set sizes of entries */
-	    break;
-	}
-#endif
     }
   
     /* set right merge flag we take right delimiting key and check whether it is a mergeable item */
@@ -227,10 +199,7 @@
     struct virtual_item * vi;
     int d_size, ih_size;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (cur_free < 0)
-	reiserfs_panic (0, "vs-8050: check_left: cur_free (%d) < 0", cur_free);
-#endif
+    RFALSE( cur_free < 0, "vs-8050: cur_free (%d) < 0", cur_free);
 
     /* internal level */
     if (h > 0) {	
@@ -247,19 +216,15 @@
 	return;
     }
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (!PATH_H_PPARENT (tb->tb_path, 0))
-	reiserfs_panic (0, "vs-8055: check_left: parent does not exist or invalid");
-#endif
+    RFALSE( !PATH_H_PPARENT (tb->tb_path, 0),
+	    "vs-8055: parent does not exist or invalid");
 
     vi = vn->vn_vi;
     if ((unsigned int)cur_free >= (vn->vn_size - ((vi->vi_type & VI_TYPE_LEFT_MERGEABLE) ? IH_SIZE : 0))) {
 	/* all contents of S[0] fits into L[0] */
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE)
-	    reiserfs_panic (0, "vs-8055: check_left: invalid mode or balance condition failed");
-#endif
+	RFALSE( vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE,
+		"vs-8055: invalid mode or balance condition failed");
 
 	tb->lnum[0] = vn->vn_nr_item;
 	tb->lbytes = -1;
@@ -313,10 +278,7 @@
     struct virtual_item * vi;
     int d_size, ih_size;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (cur_free < 0)
-	reiserfs_panic (tb->tb_sb, "vs-8070: check_right: cur_free < 0");
-#endif
+    RFALSE( cur_free < 0, "vs-8070: cur_free < 0");
     
     /* internal level */
     if (h > 0) {
@@ -333,19 +295,15 @@
 	return;
     }
   
-#ifdef CONFIG_REISERFS_CHECK
-    if (!PATH_H_PPARENT (tb->tb_path, 0))
-	reiserfs_panic (tb->tb_sb, "vs-8075: check_right: parent does not exist or invalid");
-#endif
+    RFALSE( !PATH_H_PPARENT (tb->tb_path, 0),
+	    "vs-8075: parent does not exist or invalid");
   
     vi = vn->vn_vi + vn->vn_nr_item - 1;
     if ((unsigned int)cur_free >= (vn->vn_size - ((vi->vi_type & VI_TYPE_RIGHT_MERGEABLE) ? IH_SIZE : 0))) {
 	/* all contents of S[0] fits into R[0] */
 	
-#ifdef CONFIG_REISERFS_CHECK
-	if (vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE)
-	    reiserfs_panic (tb->tb_sb, "vs-8080: check_right: invalid mode or balance condition failed");
-#endif
+	RFALSE( vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE,
+		"vs-8080: invalid mode or balance condition failed");
 
 	tb->rnum[h] = vn->vn_nr_item;
 	tb->rbytes = -1;
@@ -422,14 +380,12 @@
     split_item_positions[0] = -1;
     split_item_positions[1] = -1;
 
-#ifdef CONFIG_REISERFS_CHECK
     /* We only create additional nodes if we are in insert or paste mode
        or we are in replace mode at the internal level. If h is 0 and
        the mode is M_REPLACE then in fix_nodes we change the mode to
        paste or insert before we get here in the code.  */
-    if ( tb->insert_size[h] < 0  || (mode != M_INSERT && mode != M_PASTE))
-	reiserfs_panic (0, "vs-8100: get_num_ver: insert_size < 0 in overflow");
-#endif
+    RFALSE( tb->insert_size[h] < 0  || (mode != M_INSERT && mode != M_PASTE),
+	    "vs-8100: insert_size < 0 in overflow");
 
     max_node_size = MAX_CHILD_SIZE (PATH_H_PBUFFER (tb->tb_path, h));
 
@@ -469,11 +425,7 @@
 	struct virtual_item * vi = vn->vn_vi + i;
 	int skip_from_end = ((i == end_item) ? end_bytes : 0);
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (needed_nodes > 3) {
-	    reiserfs_panic (tb->tb_sb, "vs-8105: get_num_ver: too many nodes are needed");
-	}
-#endif
+	RFALSE( needed_nodes > 3, "vs-8105: too many nodes are needed");
 
 	/* get size of current item */
 	current_item_size = vi->vi_item_len;
@@ -495,12 +447,10 @@
 	if (current_item_size > max_node_size) {
 	    /* virtual item length is longer, than max size of item in
                a node. It is impossible for direct item */
-#ifdef CONFIG_REISERFS_CHECK
-	    if (is_direct_le_ih (vi->vi_ih))
-		reiserfs_panic (tb->tb_sb, "vs-8110: get_num_ver: "
-				"direct item length is %d. It can not be longer than %d", 
-				current_item_size, max_node_size);
-#endif
+	    RFALSE( is_direct_le_ih (vi->vi_ih),
+		    "vs-8110: "
+		    "direct item length is %d. It can not be longer than %d",
+		    current_item_size, max_node_size);
 	    /* we will try to split it */
 	    flow = 1;
 	}
@@ -691,10 +641,8 @@
 	/* there was only one item and it will be deleted */
 	struct item_head * ih;
     
-#ifdef CONFIG_REISERFS_CHECK
-    if (B_NR_ITEMS (S0) != 1)
-      reiserfs_panic (0, "vs-8125: are_leaves_removable: item number must be 1: it is %d", B_NR_ITEMS(S0));
-#endif
+    RFALSE( B_NR_ITEMS (S0) != 1,
+	    "vs-8125: item number must be 1: it is %d", B_NR_ITEMS(S0));
 
     ih = B_N_PITEM_HEAD (S0, 0);
     if (tb->CFR[0] && !comp_short_le_keys (&(ih->ih_key), B_N_PDELIM_KEY (tb->CFR[0], tb->rkey[0])))
@@ -708,13 +656,11 @@
 	       we can save ih_size */
 	    ih_size = IH_SIZE;
 	    
-#ifdef CONFIG_REISERFS_CHECK
 	    /* we might check that left neighbor exists and is of the
 	       same directory */
-	    if (le_key_k_offset (ih_version (ih), &(ih->ih_key)) == DOT_OFFSET)
-		reiserfs_panic (tb->tb_sb, "vs-8130: are_leaves_removable: "
-				"first directory item can not be removed until directory is not empty");
-#endif
+	    RFALSE( le_key_k_offset 
+		    (ih_version (ih), &(ih->ih_key)) == DOT_OFFSET,
+		    "vs-8130: first directory item can not be removed until directory is not empty");
       }
     
   }
@@ -852,10 +798,8 @@
   for ( p_n_blocknr = a_n_blocknrs, n_counter = 0; n_counter < n_amount_needed;
 	p_n_blocknr++, n_counter++ ) { 
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! *p_n_blocknr )
-      reiserfs_panic(p_s_sb, "PAP-8135: get_empty_nodes: reiserfs_new_blocknrs failed when got new blocks");
-#endif
+    RFALSE( ! *p_n_blocknr,
+	    "PAP-8135: reiserfs_new_blocknrs failed when got new blocks");
 
     p_s_new_bh = reiserfs_getblk(p_s_sb->s_dev, *p_n_blocknr, p_s_sb->s_blocksize);
     if (atomic_read (&(p_s_new_bh->b_count)) > 1) {
@@ -873,15 +817,13 @@
 	wait_buffer_until_released (p_s_new_bh);
       }
     }
-#ifdef CONFIG_REISERFS_CHECK
-    if (atomic_read (&(p_s_new_bh->b_count)) != 1 || buffer_dirty (p_s_new_bh)) {
-      if (atomic_read(&(p_s_new_bh->b_count)) > 2 || 
-          !(buffer_journaled(p_s_new_bh) || buffer_journal_dirty(p_s_new_bh))) {
-	reiserfs_panic(p_s_sb,"PAP-8140: get_empty_nodes: not free or dirty buffer %b for the new block",
-		     p_s_new_bh);
-      }
-    }
-#endif
+    RFALSE( (atomic_read (&(p_s_new_bh->b_count)) != 1 || 
+	     buffer_dirty (p_s_new_bh)) && 
+	    (atomic_read(&(p_s_new_bh->b_count)) > 2 || 
+	     !(buffer_journaled(p_s_new_bh) || 
+	       buffer_journal_dirty(p_s_new_bh))),
+	    "PAP-8140: not free or dirty buffer %b for the new block", 
+	    p_s_new_bh);
     
     /* Put empty buffers into the array. */
     if (p_s_tb->FEB[p_s_tb->cur_blknum])
@@ -958,13 +900,13 @@
   /* Calculate father of the node to be balanced. */
   p_s_father = PATH_H_PBUFFER(p_s_tb->tb_path, n_h + 1);
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( ! p_s_father || ! B_IS_IN_TREE (p_s_father) || ! B_IS_IN_TREE (p_s_tb->FL[n_h]) ||
-       ! buffer_uptodate (p_s_father) || ! buffer_uptodate (p_s_tb->FL[n_h]) ) {
-    reiserfs_panic (p_s_sb, "vs-8165: is_left_neighbor_in_cache: F[h] (%b) or FL[h] (%b) is invalid",
-		    p_s_father, p_s_tb->FL[n_h]);
-  }
-#endif
+  RFALSE( ! p_s_father || 
+	  ! B_IS_IN_TREE (p_s_father) || 
+	  ! B_IS_IN_TREE (p_s_tb->FL[n_h]) ||
+	  ! buffer_uptodate (p_s_father) || 
+	  ! buffer_uptodate (p_s_tb->FL[n_h]),
+	  "vs-8165: F[h] (%b) or FL[h] (%b) is invalid", 
+	  p_s_father, p_s_tb->FL[n_h]);
 
 
   /* Get position of the pointer to the left neighbor into the left father. */
@@ -975,12 +917,8 @@
   /* Look for the left neighbor in the cache. */
   if ( (left = get_hash_table(p_s_sb->s_dev, n_left_neighbor_blocknr, p_s_sb->s_blocksize)) ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( buffer_uptodate (left) && ! B_IS_IN_TREE(left) ) {
-      reiserfs_panic(p_s_sb, "vs-8170: is_left_neighbor_in_cache: left neighbor (%b %z) is not in the tree",
-		     left, left);
-    }
-#endif
+    RFALSE( buffer_uptodate (left) && ! B_IS_IN_TREE(left),
+	    "vs-8170: left neighbor (%b %z) is not in the tree", left, left);
     put_bh(left) ;
     return 1;
   }
@@ -997,28 +935,6 @@
 {
     // call item specific function for this key
     item_ops[cpu_key_k_type (p_s_key)]->decrement_key (p_s_key);
-    
-
-#if 0 /* this works wrong when key is key of second part of tail: it
-         sets key to be of indirect type. It looks like it makes no
-         harm but it is unclear */
-
-  unsigned long * p_n_key_field = (unsigned long *)p_s_key + REISERFS_FULL_KEY_LEN - 1;
-  int		  n_counter;
-
-  for( n_counter = 0; n_counter < REISERFS_FULL_KEY_LEN; n_counter++, p_n_key_field-- ) {
-      if ( *p_n_key_field ) {
-	  (*p_n_key_field)--;
-	  break;
-      }
-  }
-#ifdef CONFIG_REISERFS_CHECK
-  if ( n_counter == REISERFS_FULL_KEY_LEN )
-      reiserfs_panic(NULL, "PAP-8175: decrement_key: zero key");
-#endif
-
-#endif /*0*/
-
 }
 
 
@@ -1052,10 +968,8 @@
 
     n_counter = n_path_offset;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( n_counter < FIRST_PATH_ELEMENT_OFFSET )
-	reiserfs_panic(p_s_tb->tb_sb, "PAP-8180: get_far_parent: invalid path length");
-#endif
+    RFALSE( n_counter < FIRST_PATH_ELEMENT_OFFSET,
+	    "PAP-8180: invalid path length");
 
   
     for ( ; n_counter > FIRST_PATH_ELEMENT_OFFSET; n_counter--  )  {
@@ -1091,11 +1005,9 @@
 	return REPEAT_SEARCH;
     }
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( B_LEVEL (*pp_s_com_father) <= DISK_LEAF_NODE_LEVEL ) {
-	reiserfs_panic(p_s_tb->tb_sb, "PAP-8185: get_far_parent: (%b %z) level too small", *pp_s_com_father, *pp_s_com_father);
-    }
-#endif
+    RFALSE( B_LEVEL (*pp_s_com_father) <= DISK_LEAF_NODE_LEVEL,
+	    "PAP-8185: (%b %z) level too small", 
+	    *pp_s_com_father, *pp_s_com_father);
 
     /* Check whether the common parent is locked. */
 
@@ -1130,15 +1042,10 @@
 
     *pp_s_father = PATH_PLAST_BUFFER(&s_path_to_neighbor_father);
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( B_LEVEL (*pp_s_father) != n_h + 1 ) {
-	reiserfs_panic(p_s_tb->tb_sb, "PAP-8190: get_far_parent: (%b %z) level too small", *pp_s_father, *pp_s_father);
-    }
-  
-    if ( s_path_to_neighbor_father.path_length < FIRST_PATH_ELEMENT_OFFSET )
-	reiserfs_panic(0, "PAP-8192: get_far_parent: path length is too small");
-
-#endif
+    RFALSE( B_LEVEL (*pp_s_father) != n_h + 1,
+	    "PAP-8190: (%b %z) level too small", *pp_s_father, *pp_s_father);
+    RFALSE( s_path_to_neighbor_father.path_length < FIRST_PATH_ELEMENT_OFFSET,
+	    "PAP-8192: path length is too small");
 
     s_path_to_neighbor_father.path_length--;
     decrement_counters_in_path(&s_path_to_neighbor_father);
@@ -1198,11 +1105,9 @@
     decrement_bcount(p_s_tb->CFL[n_h]);
     p_s_tb->CFL[n_h] = p_s_curcf; /* New initialization of CFL[n_h]. */
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ((p_s_curf && !B_IS_IN_TREE (p_s_curf)) || (p_s_curcf && !B_IS_IN_TREE (p_s_curcf))) {
-	reiserfs_panic (p_s_tb->tb_sb, "PAP-8195: get_parents: FL (%b) or CFL (%b) is invalid", p_s_curf, p_s_curcf);
-    }
-#endif
+    RFALSE( (p_s_curf && !B_IS_IN_TREE (p_s_curf)) || 
+	    (p_s_curcf && !B_IS_IN_TREE (p_s_curcf)),
+	    "PAP-8195: FL (%b) or CFL (%b) is invalid", p_s_curf, p_s_curcf);
 
 /* Get parent FR[n_h] of R[n_h]. */
 
@@ -1237,10 +1142,10 @@
 			B_PRIGHT_DELIM_KEY (PATH_H_PBUFFER(p_s_path, n_h)), B_N_PDELIM_KEY (p_s_tb->CFR[n_h], p_s_tb->rkey[n_h]));
     }
 #endif
-    if ((p_s_curf && !B_IS_IN_TREE (p_s_curf)) || (p_s_curcf && !B_IS_IN_TREE (p_s_curcf))) {
-	reiserfs_panic (p_s_tb->tb_sb, "PAP-8205: get_parents: FR (%b) or CFR (%b) is invalid", p_s_curf, p_s_curcf);
-    }
 #endif
+    RFALSE( (p_s_curf && !B_IS_IN_TREE (p_s_curf)) || 
+	    (p_s_curcf && !B_IS_IN_TREE (p_s_curcf)),
+	    "PAP-8205: FR (%b) or CFR (%b) is invalid", p_s_curf, p_s_curcf);
 
     return CARRY_ON;
 }
@@ -1400,15 +1305,14 @@
 	return CARRY_ON;
     }
 
-#ifdef CONFIG_REISERFS_CHECK
     /* this checks balance condition, that any two neighboring nodes can not fit in one node */
-    if ( h && ( tb->lnum[h] >= vn->vn_nr_item + 1 || tb->rnum[h] >= vn->vn_nr_item + 1) )
-	reiserfs_panic (tb->tb_sb, "vs-8220: ip_check_balance: tree is not balanced on internal level");
-
-    if ( ! h && ((tb->lnum[h] >= vn->vn_nr_item && (tb->lbytes == -1)) ||
-		 (tb->rnum[h] >= vn->vn_nr_item && (tb->rbytes == -1)) ))
-	reiserfs_panic(tb->tb_sb, "vs-8225: ip_check_balance: tree is not balanced on leaf level");
-#endif
+    RFALSE( h && 
+	    ( tb->lnum[h] >= vn->vn_nr_item + 1 || 
+	      tb->rnum[h] >= vn->vn_nr_item + 1),
+	    "vs-8220: tree is not balanced on internal level");
+    RFALSE( ! h && ((tb->lnum[h] >= vn->vn_nr_item && (tb->lbytes == -1)) ||
+		    (tb->rnum[h] >= vn->vn_nr_item && (tb->rbytes == -1)) ),
+	    "vs-8225: tree is not balanced on leaf level");
 
     /* all contents of S[0] can be moved into its neighbors
        S[0] will be removed after balancing. */
@@ -1553,10 +1457,11 @@
 	/* we can win TWO or ONE nodes by shifting in both directions */
 	if (lrnver < lnver && lrnver < rnver)
 	{
-#ifdef CONFIG_REISERFS_CHECK
-	    if (h && (tb->lnum[h] != 1 || tb->rnum[h] != 1 || lrnver != 1 || rnver != 2 || lnver != 2 || h != 1))
-		reiserfs_panic (0, "vs-8230: check_balance: bad h");
-#endif
+	    RFALSE( h && 
+		    (tb->lnum[h] != 1 || 
+		     tb->rnum[h] != 1 || 
+		     lrnver != 1 || rnver != 2 || lnver != 2 || h != 1),
+		    "vs-8230: bad h");
 	    if (lrset == LR_SHIFT_FLOW)
 		set_parameters (tb, h, tb->lnum[h], tb->rnum[h], lrnver, snum012 + lrset,
 				tb->lbytes, tb->rbytes);
@@ -1757,10 +1662,7 @@
     }
 
   /* For internal nodes try to borrow item from a neighbor */
-#ifdef CONFIG_REISERFS_CHECK
-  if (!tb->FL[h] && !tb->FR[h])
-    reiserfs_panic (0, "vs-8235: dc_check_balance_internal: trying to borrow for root");
-#endif
+  RFALSE( !tb->FL[h] && !tb->FR[h], "vs-8235: trying to borrow for root");
 
   /* Borrow one or two items from caching neighbor */
   if (is_left_neighbor_in_cache (tb,h) || !tb->FR[h])
@@ -1818,10 +1720,8 @@
   if ( ! F0 )
     {  /* S[0] is the root now. */
 
-#ifdef CONFIG_REISERFS_CHECK
-      if ( -levbytes >= maxsize - B_FREE_SPACE (S0) )
-	reiserfs_panic (tb->tb_sb, "vs-8240: dc_check_balance_leaf: attempt to create empty buffer tree");
-#endif
+      RFALSE( -levbytes >= maxsize - B_FREE_SPACE (S0),
+	      "vs-8240: attempt to create empty buffer tree");
 
       set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
       return NO_BALANCING_NEEDED;
@@ -1853,10 +1753,7 @@
 	((tb->rnum[0] - ((tb->rbytes == -1) ? 0 : 1)) < vn->vn_nr_item) || /* S can not be merged with R */
 	!tb->FR[h]) {
       
-#ifdef CONFIG_REISERFS_CHECK
-      if (!tb->FL[h])
-	reiserfs_panic (0, "vs-8245: dc_check_balance_leaf: FL[h] must exist");
-#endif
+      RFALSE( !tb->FL[h], "vs-8245: dc_check_balance_leaf: FL[h] must exist");
 
       /* set parameter to merge S[0] with its left neighbor */
       set_parameters (tb, h, -1, 0, 0, NULL, -1, -1);
@@ -1896,11 +1793,7 @@
  */
 static int dc_check_balance (struct tree_balance * tb, int h)
 {
-
-#ifdef CONFIG_REISERFS_CHECK
- if ( ! (PATH_H_PBUFFER (tb->tb_path, h)) )
-   reiserfs_panic(tb->tb_sb, "vs-8250: dc_check_balance: S is not initialized");
-#endif
+ RFALSE( ! (PATH_H_PBUFFER (tb->tb_path, h)), "vs-8250: S is not initialized");
 
  if ( h )
    return dc_check_balance_internal (tb, h);
@@ -1947,10 +1840,8 @@
   vn->vn_ins_ih = ins_ih;
   vn->vn_data = data;
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (mode == M_INSERT && !vn->vn_ins_ih)
-    reiserfs_panic (0, "vs-8255: check_balance: ins_ih can not be 0 in insert mode");
-#endif
+  RFALSE( mode == M_INSERT && !vn->vn_ins_ih,
+	  "vs-8255: ins_ih can not be 0 in insert mode");
 
  if ( tb->insert_size[h] > 0 )
    /* Calculate balance parameters when size of node is increasing. */
@@ -1975,10 +1866,8 @@
     /* We are in the root or in the new root. */
     if ( n_path_offset <= FIRST_PATH_ELEMENT_OFFSET ) {
 	
-#ifdef CONFIG_REISERFS_CHECK
-	if ( n_path_offset < FIRST_PATH_ELEMENT_OFFSET - 1 )
-	    reiserfs_panic(p_s_tb->tb_sb, "PAP-8260: get_direct_parent: illegal offset in the path");
-#endif
+	RFALSE( n_path_offset < FIRST_PATH_ELEMENT_OFFSET - 1,
+		"PAP-8260: illegal offset in the path");
 
 	if ( PATH_OFFSET_PBUFFER(p_s_path, FIRST_PATH_ELEMENT_OFFSET)->b_blocknr ==
 	     SB_ROOT_BLOCK (p_s_tb->tb_sb) ) {
@@ -2031,10 +1920,9 @@
 	/* We need left neighbor to balance S[n_h]. */
 	p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset);
 	
-#ifdef CONFIG_REISERFS_CHECK
-	if ( p_s_bh == p_s_tb->FL[n_h] && ! PATH_OFFSET_POSITION(p_s_tb->tb_path, n_path_offset) )
-	    reiserfs_panic (p_s_tb->tb_sb, "PAP-8270: get_neighbors: invalid position in the parent");
-#endif
+	RFALSE( p_s_bh == p_s_tb->FL[n_h] && 
+		! PATH_OFFSET_POSITION(p_s_tb->tb_path, n_path_offset),
+		"PAP-8270: invalid position in the parent");
 
 	n_child_position = ( p_s_bh == p_s_tb->FL[n_h] ) ? p_s_tb->lkey[n_h] : B_NR_ITEMS (p_s_tb->FL[n_h]);
 	n_son_number = B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position);
@@ -2046,16 +1934,14 @@
 	    return REPEAT_SEARCH;
 	}
 	
-#ifdef CONFIG_REISERFS_CHECK
-	if ( ! B_IS_IN_TREE(p_s_tb->FL[n_h]) || n_child_position > B_NR_ITEMS(p_s_tb->FL[n_h]) ||
-	     B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position) != p_s_bh->b_blocknr )
-	    reiserfs_panic (p_s_tb->tb_sb, "PAP-8275: get_neighbors: invalid parent");
-	if ( ! B_IS_IN_TREE(p_s_bh) )
-	    reiserfs_panic (p_s_tb->tb_sb, "PAP-8280: get_neighbors: invalid child");
-
-	if (! n_h && B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - B_N_CHILD (p_s_tb->FL[0],n_child_position)->dc_size)
-	    reiserfs_panic (p_s_tb->tb_sb, "PAP-8290: get_neighbors: invalid child size of left neighbor");
-#endif
+	RFALSE( ! B_IS_IN_TREE(p_s_tb->FL[n_h]) || 
+		n_child_position > B_NR_ITEMS(p_s_tb->FL[n_h]) ||
+		B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position) != 
+		p_s_bh->b_blocknr, "PAP-8275: invalid parent");
+	RFALSE( ! B_IS_IN_TREE(p_s_bh), "PAP-8280: invalid child");
+	RFALSE( ! n_h && 
+		B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - B_N_CHILD (p_s_tb->FL[0],n_child_position)->dc_size,
+		"PAP-8290: invalid child size of left neighbor");
 
 	decrement_bcount(p_s_tb->L[n_h]);
 	p_s_tb->L[n_h] = p_s_bh;
@@ -2065,10 +1951,9 @@
     if ( p_s_tb->rnum[n_h] ) { /* We need right neighbor to balance S[n_path_offset]. */
 	p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset);
 	
-#ifdef CONFIG_REISERFS_CHECK
-	if ( p_s_bh == p_s_tb->FR[n_h] && PATH_OFFSET_POSITION(p_s_tb->tb_path, n_path_offset) >= B_NR_ITEMS(p_s_bh) )
-	    reiserfs_panic (p_s_tb->tb_sb, "PAP-8295: get_neighbors: invalid position in the parent");
-#endif
+	RFALSE( p_s_bh == p_s_tb->FR[n_h] && 
+		PATH_OFFSET_POSITION(p_s_tb->tb_path, n_path_offset) >= B_NR_ITEMS(p_s_bh),
+		"PAP-8295: invalid position in the parent");
 
 	n_child_position = ( p_s_bh == p_s_tb->FR[n_h] ) ? p_s_tb->rkey[n_h] + 1 : 0;
 	n_son_number = B_N_CHILD_NUM(p_s_tb->FR[n_h], n_child_position);
@@ -2082,12 +1967,10 @@
 	decrement_bcount(p_s_tb->R[n_h]);
 	p_s_tb->R[n_h] = p_s_bh;
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (! n_h && B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - B_N_CHILD (p_s_tb->FR[0],n_child_position)->dc_size) {
-	    reiserfs_panic (p_s_tb->tb_sb, "PAP-8300: get_neighbors: invalid child size of right neighbor (%d != %d - %d)",
-			    B_FREE_SPACE (p_s_bh), MAX_CHILD_SIZE (p_s_bh), B_N_CHILD (p_s_tb->FR[0],n_child_position)->dc_size);
-	}
-#endif
+	RFALSE( ! n_h && B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - B_N_CHILD (p_s_tb->FR[0],n_child_position)->dc_size,
+		"PAP-8300: invalid child size of right neighbor (%d != %d - %d)",
+		B_FREE_SPACE (p_s_bh), MAX_CHILD_SIZE (p_s_bh), 
+		B_N_CHILD (p_s_tb->FR[0],n_child_position)->dc_size);
 	
     }
     return CARRY_ON;
@@ -2236,6 +2119,11 @@
     }
   }
 }
+#else
+static void tb_buffer_sanity_check (struct super_block * p_s_sb,
+				    struct buffer_head * p_s_bh, 
+				    const char *descr, int level)
+{;}
 #endif
 
 static void clear_all_dirty_bits(struct super_block *s, 
@@ -2282,27 +2170,21 @@
 	    if (p_s_tb->lnum[i] ) {
 
 		if ( p_s_tb->L[i] ) {
-#ifdef CONFIG_REISERFS_CHECK
 		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->L[i], "L", i);
-#endif
 		    clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->L[i]) ;
 		    if ( buffer_locked (p_s_tb->L[i]) )
 			locked = p_s_tb->L[i];
 		}
 
 		if ( !locked && p_s_tb->FL[i] ) {
-#ifdef CONFIG_REISERFS_CHECK
 		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FL[i], "FL", i);
-#endif
 		    clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FL[i]) ;
 		    if ( buffer_locked (p_s_tb->FL[i]) )
 			locked = p_s_tb->FL[i];
 		}
 
 		if ( !locked && p_s_tb->CFL[i] ) {
-#ifdef CONFIG_REISERFS_CHECK
 		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFL[i], "CFL", i);
-#endif
 		    clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFL[i]) ;
 		    if ( buffer_locked (p_s_tb->CFL[i]) )
 			locked = p_s_tb->CFL[i];
@@ -2313,9 +2195,7 @@
 	    if ( !locked && (p_s_tb->rnum[i]) ) {
 
 		if ( p_s_tb->R[i] ) {
-#ifdef CONFIG_REISERFS_CHECK
 		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->R[i], "R", i);
-#endif
 		    clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->R[i]) ;
 		    if ( buffer_locked (p_s_tb->R[i]) )
 			locked = p_s_tb->R[i];
@@ -2323,18 +2203,14 @@
 
        
 		if ( !locked && p_s_tb->FR[i] ) {
-#ifdef CONFIG_REISERFS_CHECK
 		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FR[i], "FR", i);
-#endif
 		    clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FR[i]) ;
 		    if ( buffer_locked (p_s_tb->FR[i]) )
 			locked = p_s_tb->FR[i];
 		}
 
 		if ( !locked && p_s_tb->CFR[i] ) {
-#ifdef CONFIG_REISERFS_CHECK
 		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFR[i], "CFR", i);
-#endif
 		    clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFR[i]) ;
 		    if ( buffer_locked (p_s_tb->CFR[i]) )
 			locked = p_s_tb->CFR[i];
@@ -2536,10 +2412,8 @@
 	    /* We have a positive insert size but no nodes exist on this
 	       level, this means that we are creating a new root. */
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if ( p_s_tb->blknum[n_h] != 1 )
-		reiserfs_panic(p_s_tb->tb_sb,"PAP-8350: fix_nodes: creating new empty root");
-#endif /* CONFIG_REISERFS_CHECK */
+	    RFALSE( p_s_tb->blknum[n_h] != 1,
+		    "PAP-8350: creating new empty root");
 
 	    if ( n_h < MAX_HEIGHT - 1 )
 		p_s_tb->insert_size[n_h + 1] = 0;
@@ -2552,10 +2426,8 @@
 		       and a new node (S[n_h+1]) will be created to
 		       become the root node.  */
 	  
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( n_h == MAX_HEIGHT - 1 )
-			reiserfs_panic(p_s_tb->tb_sb, "PAP-8355: fix_nodes: attempt to create too high of a tree");
-#endif /* CONFIG_REISERFS_CHECK */
+		    RFALSE( n_h == MAX_HEIGHT - 1,
+			    "PAP-8355: attempt to create too high of a tree");
 
 		    p_s_tb->insert_size[n_h + 1] = (DC_SIZE + KEY_SIZE) * (p_s_tb->blknum[n_h] - 1) + DC_SIZE;
 		}
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/ibalance.c linux/fs/reiserfs/ibalance.c
--- v2.4.10/linux/fs/reiserfs/ibalance.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/ibalance.c	Mon Oct  8 11:52:58 2001
@@ -36,10 +36,8 @@
 						struct buffer_head ** cf
 						)
 {
-#ifdef CONFIG_REISERFS_CHECK
     memset (dest_bi, 0, sizeof (struct buffer_info));
     memset (src_bi, 0, sizeof (struct buffer_info));
-#endif
     /* define dest, src, dest parent, dest position */
     switch (shift_mode) {
     case INTERNAL_SHIFT_FROM_S_TO_L:	/* used in internal_shift_left */
@@ -144,13 +142,11 @@
 
     nr = le16_to_cpu ((blkh = B_BLK_HEAD(cur))->blk_nr_item);
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (count > 2)
-	reiserfs_panic (0, "internal_insert_childs", "too many children (%d) are to be inserted", count);
-    if (B_FREE_SPACE (cur) < count * (KEY_SIZE + DC_SIZE))
-	reiserfs_panic (0, "internal_insert_childs", "no enough free space (%d), needed %d bytes", 
-			B_FREE_SPACE (cur), count * (KEY_SIZE + DC_SIZE));
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( count > 2,
+	    "too many children (%d) are to be inserted", count);
+    RFALSE( B_FREE_SPACE (cur) < count * (KEY_SIZE + DC_SIZE),
+	    "no enough free space (%d), needed %d bytes", 
+	    B_FREE_SPACE (cur), count * (KEY_SIZE + DC_SIZE));
 
     /* prepare space for count disk_child */
     dc = B_N_CHILD(cur,to+1);
@@ -213,43 +209,29 @@
   struct key * key;
   struct disk_child * dc;
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (cur == NULL)
-    reiserfs_panic (0, "internal_delete_pointers_items1: buffer is 0");
-	
-  if (del_num < 0)
-    reiserfs_panic (0, "internal_delete_pointers_items2",
-		    "negative number of items (%d) can not be deleted", del_num);
-
-  if (first_p < 0 || first_p + del_num > B_NR_ITEMS (cur) + 1 || first_i < 0)
-    reiserfs_panic (0, "internal_delete_pointers_items3",
-		    "first pointer order (%d) < 0 or "
-		    "no so many pointers (%d), only (%d) or "
-		    "first key order %d < 0", first_p, 
-		    first_p + del_num, B_NR_ITEMS (cur) + 1, first_i);
-#endif /* CONFIG_REISERFS_CHECK */
+  RFALSE( cur == NULL, "buffer is 0");
+  RFALSE( del_num < 0, 
+	  "negative number of items (%d) can not be deleted", del_num);
+  RFALSE( first_p < 0 || first_p + del_num > B_NR_ITEMS (cur) + 1 || first_i < 0,
+	  "first pointer order (%d) < 0 or "
+	  "no so many pointers (%d), only (%d) or "
+	  "first key order %d < 0", first_p, 
+	  first_p + del_num, B_NR_ITEMS (cur) + 1, first_i);
   if ( del_num == 0 )
     return;
 
   nr = le16_to_cpu ((blkh = B_BLK_HEAD(cur))->blk_nr_item);
 
   if ( first_p == 0 && del_num == nr + 1 ) {
-#ifdef CONFIG_REISERFS_CHECK
-    if ( first_i != 0 )
-      reiserfs_panic (0, "internal_delete_pointers_items5",
-		      "first deleted key must have order 0, not %d", first_i);
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( first_i != 0, "1st deleted key must have order 0, not %d", first_i);
     make_empty_node (cur_bi);
     return;
   }
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (first_i + del_num > B_NR_ITEMS (cur)) {
-    printk("first_i = %d del_num = %d\n",first_i,del_num);
-    reiserfs_panic (0, "internal_delete_pointers_items4: :"
-		    "no so many keys (%d) in the node (%b)(%z)", first_i + del_num, cur, cur);
-  }
-#endif /* CONFIG_REISERFS_CHECK */
+  RFALSE( first_i + del_num > B_NR_ITEMS (cur),
+	  "first_i = %d del_num = %d "
+	  "no so many keys (%d) in the node (%b)(%z)", 
+	  first_i, del_num, first_i + del_num, cur, cur);
 
 
   /* deleting */
@@ -315,25 +297,16 @@
 
   nr_src = B_NR_ITEMS (src);
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( dest == NULL || src == NULL )
-    reiserfs_panic (0, "internal_copy_pointers_items", "src (%p) or dest (%p) buffer is 0", src, dest);
-
-  if (last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST)
-    reiserfs_panic (0, "internal_copy_pointers_items",
-		    "invalid last_first parameter (%d)", last_first);
-
-  if ( nr_src < cpy_num - 1 )
-    reiserfs_panic (0, "internal_copy_pointers_items", "no so many items (%d) in src (%d)", cpy_num, nr_src);
-
-  if ( cpy_num < 0 )
-    reiserfs_panic (0, "internal_copy_pointers_items", "cpy_num less than 0 (%d)", cpy_num);
-
-  if (cpy_num - 1 + B_NR_ITEMS(dest) > (int)MAX_NR_KEY(dest))
-    reiserfs_panic (0, "internal_copy_pointers_items",
-		    "cpy_num (%d) + item number in dest (%d) can not be more than MAX_NR_KEY(%d)",
-		    cpy_num, B_NR_ITEMS(dest), MAX_NR_KEY(dest));
-#endif
+  RFALSE( dest == NULL || src == NULL, 
+	  "src (%p) or dest (%p) buffer is 0", src, dest);
+  RFALSE( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
+	  "invalid last_first parameter (%d)", last_first);
+  RFALSE( nr_src < cpy_num - 1, 
+	  "no so many items (%d) in src (%d)", cpy_num, nr_src);
+  RFALSE( cpy_num < 0, "cpy_num less than 0 (%d)", cpy_num);
+  RFALSE( cpy_num - 1 + B_NR_ITEMS(dest) > (int)MAX_NR_KEY(dest),
+	  "cpy_num (%d) + item number in dest (%d) can not be > MAX_NR_KEY(%d)",
+	  cpy_num, B_NR_ITEMS(dest), MAX_NR_KEY(dest));
 
   if ( cpy_num == 0 )
     return;
@@ -427,23 +400,18 @@
     struct block_head * blkh;
     struct key * key;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (dest == NULL || src == NULL)
-	reiserfs_panic (0, "internal_insert_key", "sourse(%p) or dest(%p) buffer is 0", src, dest);
-
-    if (dest_position_before < 0 || src_position < 0)
-	reiserfs_panic (0, "internal_insert_key", "source(%d) or dest(%d) key number less than 0", 
-			src_position, dest_position_before);
-
-    if (dest_position_before > B_NR_ITEMS (dest) || src_position >= B_NR_ITEMS(src))
-	reiserfs_panic (0, "internal_insert_key", 
-			"invalid position in dest (%d (key number %d)) or in src (%d (key number %d))",
-			dest_position_before, B_NR_ITEMS (dest), src_position, B_NR_ITEMS(src));
-
-    if (B_FREE_SPACE (dest) < KEY_SIZE)
-	reiserfs_panic (0, "internal_insert_key", 
-			"no enough free space (%d) in dest buffer", B_FREE_SPACE (dest));
-#endif
+    RFALSE( dest == NULL || src == NULL,
+	    "source(%p) or dest(%p) buffer is 0", src, dest);
+    RFALSE( dest_position_before < 0 || src_position < 0,
+	    "source(%d) or dest(%d) key number less than 0", 
+	    src_position, dest_position_before);
+    RFALSE( dest_position_before > B_NR_ITEMS (dest) || 
+	    src_position >= B_NR_ITEMS(src),
+	    "invalid position in dest (%d (key number %d)) or in src (%d (key number %d))",
+	    dest_position_before, B_NR_ITEMS (dest), 
+	    src_position, B_NR_ITEMS(src));
+    RFALSE( B_FREE_SPACE (dest) < KEY_SIZE,
+	    "no enough free space (%d) in dest buffer", B_FREE_SPACE (dest));
 
     nr = le16_to_cpu ((blkh=B_BLK_HEAD(dest))->blk_nr_item);
 
@@ -557,11 +525,10 @@
     /* insert delimiting key from common father of dest and src to dest node into position 0 */
     internal_insert_key (&dest_bi, 0, cf, d_key_position);
     if (nr == pointer_amount - 1) {
-#ifdef CONFIG_REISERFS_CHECK
-      if ( src_bi.bi_bh != PATH_H_PBUFFER (tb->tb_path, h)/*tb->S[h]*/ || dest_bi.bi_bh != tb->R[h])
-	reiserfs_panic (tb->tb_sb, "internal_shift_right", "src (%p) must be == tb->S[h](%p) when it disappears",
-			src_bi.bi_bh, PATH_H_PBUFFER (tb->tb_path, h));
-#endif
+	 RFALSE( src_bi.bi_bh != PATH_H_PBUFFER (tb->tb_path, h)/*tb->S[h]*/ || 
+		 dest_bi.bi_bh != tb->R[h],
+		 "src (%p) must be == tb->S[h](%p) when it disappears",
+		 src_bi.bi_bh, PATH_H_PBUFFER (tb->tb_path, h));
       /* when S[h] disappers replace left delemiting key as well */
       if (tb->CFL[h])
 	replace_key (tb, cf, d_key_position, tb->CFL[h], tb->lkey[h]);
@@ -620,11 +587,8 @@
 
     internal_delete_childs (&bi, child_pos, -insert_num);
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( tb->blknum[h] > 1 )
-	reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", "tb->blknum[%d]=%d when insert_size < 0",
-			h, tb->blknum[h]);
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( tb->blknum[h] > 1,
+	    "tb->blknum[%d]=%d when insert_size < 0", h, tb->blknum[h]);
 
     n = B_NR_ITEMS(tbSh);
 
@@ -633,14 +597,9 @@
 	    /* node S[h] (root of the tree) is empty now */
 	    struct buffer_head *new_root;
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if (n || B_FREE_SPACE (tbSh) != MAX_CHILD_SIZE(tbSh) - DC_SIZE)
-		reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", "buffer must have only 0 keys (%d)",
-				n);
-
-	    if (bi.bi_parent)
-		reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", "root has parent (%p)", bi.bi_parent);
-#endif /* CONFIG_REISERFS_CHECK */
+	    RFALSE( n || B_FREE_SPACE (tbSh) != MAX_CHILD_SIZE(tbSh) - DC_SIZE,
+		    "buffer must have only 0 keys (%d)", n);
+	    RFALSE( bi.bi_parent, "root has parent (%p)", bi.bi_parent);
 		
 	    /* choose a new root */
 	    if ( ! tb->L[h-1] || ! B_NR_ITEMS(tb->L[h-1]) )
@@ -669,11 +628,9 @@
 
     if ( tb->L[h] && tb->lnum[h] == -B_NR_ITEMS(tb->L[h]) - 1 ) { /* join S[h] with L[h] */
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( tb->rnum[h] != 0 )
-	    reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", "invalid tb->rnum[%d]==%d when joining S[h] with L[h]",
-			    h, tb->rnum[h]);
-#endif /* CONFIG_REISERFS_CHECK */
+	RFALSE( tb->rnum[h] != 0,
+		"invalid tb->rnum[%d]==%d when joining S[h] with L[h]",
+		h, tb->rnum[h]);
 
 	internal_shift_left (INTERNAL_SHIFT_FROM_S_TO_L, tb, h, n + 1);
 	reiserfs_invalidate_buffer(tb, tbSh);
@@ -682,11 +639,9 @@
     }
 
     if ( tb->R[h] &&  tb->rnum[h] == -B_NR_ITEMS(tb->R[h]) - 1 ) { /* join S[h] with R[h] */
-#ifdef CONFIG_REISERFS_CHECK
-	if ( tb->lnum[h] != 0 )
-	    reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", "invalid tb->lnum[%d]==%d when joining S[h] with R[h]",
-			    h, tb->lnum[h]);
-#endif /* CONFIG_REISERFS_CHECK */
+	RFALSE( tb->lnum[h] != 0,
+		"invalid tb->lnum[%d]==%d when joining S[h] with R[h]",
+		h, tb->lnum[h]);
 
 	internal_shift_right (INTERNAL_SHIFT_FROM_S_TO_R, tb, h, n + 1);
 
@@ -695,33 +650,25 @@
     }
 
     if ( tb->lnum[h] < 0 ) { /* borrow from left neighbor L[h] */
-#ifdef CONFIG_REISERFS_CHECK
-	if ( tb->rnum[h] != 0 )
-	    reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", "invalid tb->rnum[%d]==%d when borrow from L[h]",
-			    h, tb->rnum[h]);
-#endif /* CONFIG_REISERFS_CHECK */
+	RFALSE( tb->rnum[h] != 0,
+		"wrong tb->rnum[%d]==%d when borrow from L[h]", h, tb->rnum[h]);
 	/*internal_shift_right (tb, h, tb->L[h], tb->CFL[h], tb->lkey[h], tb->S[h], -tb->lnum[h]);*/
 	internal_shift_right (INTERNAL_SHIFT_FROM_L_TO_S, tb, h, -tb->lnum[h]);
 	return;
     }
 
     if ( tb->rnum[h] < 0 ) { /* borrow from right neighbor R[h] */
-#ifdef CONFIG_REISERFS_CHECK
-	if ( tb->lnum[h] != 0 )
-	    reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", "invalid tb->lnum[%d]==%d when borrow from R[h]",
-			    h, tb->lnum[h]);
-#endif /* CONFIG_REISERFS_CHECK */
+	 RFALSE( tb->lnum[h] != 0,
+		 "invalid tb->lnum[%d]==%d when borrow from R[h]", 
+		 h, tb->lnum[h]);
 	internal_shift_left (INTERNAL_SHIFT_FROM_R_TO_S, tb, h, -tb->rnum[h]);/*tb->S[h], tb->CFR[h], tb->rkey[h], tb->R[h], -tb->rnum[h]);*/
 	return;
     }
 
     if ( tb->lnum[h] > 0 ) { /* split S[h] into two parts and put them into neighbors */
-#ifdef CONFIG_REISERFS_CHECK
-	if ( tb->rnum[h] == 0 || tb->lnum[h] + tb->rnum[h] != n + 1 )
-	    reiserfs_panic (tb->tb_sb, "balance_internal_when_delete", 
-			    "invalid tb->lnum[%d]==%d or tb->rnum[%d]==%d when S[h](item number == %d) is split between them",
-			    h, tb->lnum[h], h, tb->rnum[h], n);
-#endif /* CONFIG_REISERFS_CHECK */
+	RFALSE( tb->rnum[h] == 0 || tb->lnum[h] + tb->rnum[h] != n + 1,
+		"invalid tb->lnum[%d]==%d or tb->rnum[%d]==%d when S[h](item number == %d) is split between them",
+		h, tb->lnum[h], h, tb->rnum[h], n);
 
 	internal_shift_left (INTERNAL_SHIFT_FROM_S_TO_L, tb, h, tb->lnum[h]);/*tb->L[h], tb->CFL[h], tb->lkey[h], tb->S[h], tb->lnum[h]);*/
 	internal_shift_right (INTERNAL_SHIFT_FROM_S_TO_R, tb, h, tb->rnum[h]);
@@ -742,11 +689,9 @@
 		      struct item_head * key
 		      )
 {
-#ifdef CONFIG_REISERFS_CHECK
-  if (tb->L[h] == NULL || tb->CFL[h] == NULL)
-    reiserfs_panic (tb->tb_sb, "replace_lkey: 12255: "
-		    "L[h](%p) and CFL[h](%p) must exist in replace_lkey", tb->L[h], tb->CFL[h]);
-#endif
+   RFALSE( tb->L[h] == NULL || tb->CFL[h] == NULL,
+	   "L[h](%p) and CFL[h](%p) must exist in replace_lkey", 
+	   tb->L[h], tb->CFL[h]);
 
   if (B_NR_ITEMS(PATH_H_PBUFFER(tb->tb_path, h)) == 0)
     return;
@@ -764,15 +709,12 @@
 		      struct item_head * key
 		      )
 {
-#ifdef CONFIG_REISERFS_CHECK
-  if (tb->R[h] == NULL || tb->CFR[h] == NULL)
-    reiserfs_panic (tb->tb_sb, "replace_rkey: 12260: "
-		    "R[h](%p) and CFR[h](%p) must exist in replace_rkey", tb->R[h], tb->CFR[h]);
-
-  if (B_NR_ITEMS(tb->R[h]) == 0)
-    reiserfs_panic (tb->tb_sb, "replace_rkey: 12265: "
-		    "R[h] can not be empty if it exists (item number=%d)", B_NR_ITEMS(tb->R[h]));
-#endif
+  RFALSE( tb->R[h] == NULL || tb->CFR[h] == NULL,
+	  "R[h](%p) and CFR[h](%p) must exist in replace_rkey", 
+	  tb->R[h], tb->CFR[h]);
+  RFALSE( B_NR_ITEMS(tb->R[h]) == 0,
+	  "R[h] can not be empty if it exists (item number=%d)", 
+	  B_NR_ITEMS(tb->R[h]));
 
   memcpy (B_N_PDELIM_KEY(tb->CFR[h],tb->rkey[h]), key, KEY_SIZE);
 
@@ -810,10 +752,7 @@
     struct buffer_head * new_insert_ptr = NULL;
     struct item_head * new_insert_key_addr = insert_key;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( h < 1 )      
-	reiserfs_panic (tb->tb_sb, "balance_internal", "h (%d) can not be < 1 on internal level", h);
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( h < 1, "h (%d) can not be < 1 on internal level", h);
 
     order = ( tbSh ) ? PATH_H_POSITION (tb->tb_path, h + 1)/*tb->S[h]->b_item_order*/ : 0;
 
@@ -822,16 +761,12 @@
     insert_num = tb->insert_size[h]/((int)(KEY_SIZE + DC_SIZE));
 
     /* Check whether insert_num is proper **/
-#ifdef CONFIG_REISERFS_CHECK
-    if ( insert_num < -2  ||  insert_num > 2 )
-	reiserfs_panic (tb->tb_sb, "balance_internal",
-			"incorrect number of items inserted to the internal node (%d)", insert_num);
-
-    if ( h > 1  && (insert_num > 1 || insert_num < -1) )
-	reiserfs_panic (tb->tb_sb, "balance_internal",
-			"incorrect number of items (%d) inserted to the internal node on a level (h=%d) higher than last internal level", 
-			insert_num, h);
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( insert_num < -2  ||  insert_num > 2,
+	    "incorrect number of items inserted to the internal node (%d)", 
+	    insert_num);
+    RFALSE( h > 1  && (insert_num > 1 || insert_num < -1),
+	    "incorrect number of items (%d) inserted to the internal node on a level (h=%d) higher than last internal level", 
+	    insert_num, h);
 
     /* Make balance in case insert_num < 0 */
     if ( insert_num < 0 ) {
@@ -951,19 +886,12 @@
     }
 
     /** Fill new node that appears instead of S[h] **/
-#ifdef CONFIG_REISERFS_CHECK
-    if ( tb->blknum[h] > 2 )
-	reiserfs_panic(0, "balance_internal", "blknum can not be > 2 for internal level");
-    if ( tb->blknum[h] < 0 )
-	reiserfs_panic(0, "balance_internal", "blknum can not be < 0");
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( tb->blknum[h] > 2, "blknum can not be > 2 for internal level");
+    RFALSE( tb->blknum[h] < 0, "blknum can not be < 0");
 
     if ( ! tb->blknum[h] )
     { /* node S[h] is empty now */
-#ifdef CONFIG_REISERFS_CHECK
-	if ( ! tbSh )
-	    reiserfs_panic(0,"balance_internal", "S[h] is equal NULL");
-#endif /* CONFIG_REISERFS_CHECK */
+	RFALSE( ! tbSh, "S[h] is equal NULL");
 
 	/* do what is needed for buffer thrown from tree */
 	reiserfs_invalidate_buffer(tb,tbSh);
@@ -1081,13 +1009,10 @@
 	/* new_insert_ptr = node_pointer to S_new */
 	new_insert_ptr = S_new;
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( buffer_locked(S_new) || atomic_read (&(S_new->b_count)) != 1)
-	    if (buffer_locked(S_new) || atomic_read(&(S_new->b_count)) > 2 ||
-		!(buffer_journaled(S_new) || buffer_journal_dirty(S_new))) {
-		reiserfs_panic (tb->tb_sb, "cm-00001: balance_internal: bad S_new (%b)", S_new);
-	    }
-#endif /* CONFIG_REISERFS_CHECK */
+	RFALSE(( buffer_locked(S_new) || atomic_read (&(S_new->b_count)) != 1) &&
+	       (buffer_locked(S_new) || atomic_read(&(S_new->b_count)) > 2 ||
+		!(buffer_journaled(S_new) || buffer_journal_dirty(S_new))),
+	       "cm-00001: bad S_new (%b)", S_new);
 
 	// S_new is released in unfix_nodes
     }
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
--- v2.4.10/linux/fs/reiserfs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/inode.c	Mon Oct  8 11:52:58 2001
@@ -758,11 +758,8 @@
 	    struct cpu_key tmp_key;
 	    struct unfm_nodeinfo un = {0, 0};
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if (pos_in_item != le16_to_cpu (ih->ih_item_len) / UNFM_P_SIZE)
-		reiserfs_panic (inode->i_sb, "vs-: reiserfs_get_block: "
-				"invalid position for append");
-#endif
+	    RFALSE( pos_in_item != le16_to_cpu (ih->ih_item_len) / UNFM_P_SIZE,
+		    "vs-804: invalid position for append");
 	    /* indirect item has to be appended, set up key of that position */
 	    make_cpu_key (&tmp_key, inode,
 			  le_key_k_offset (version, &(ih->ih_key)) + op_bytes_number (ih, inode->i_sb->s_blocksize),
@@ -1428,7 +1425,6 @@
     }
 
     sb = dir->i_sb;
-    inode->i_sb = sb;
     inode->i_flags = 0;//inode->i_sb->s_flags;
 
     /* item head of new item */
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/item_ops.c linux/fs/reiserfs/item_ops.c
--- v2.4.10/linux/fs/reiserfs/item_ops.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/item_ops.c	Mon Oct  8 11:52:58 2001
@@ -489,10 +489,8 @@
     if (mode == M_CUT)
 	return virtual_entry_num + 1;
 
-#ifdef CONFIG_REISERFS_CHECK  
-    if (mode != M_PASTE || virtual_entry_num == 0)
-	reiserfs_panic (0, "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'", mode);
-#endif
+    RFALSE( mode != M_PASTE || virtual_entry_num == 0,
+	    "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'", mode);
     
     return virtual_entry_num - 1;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
--- v2.4.10/linux/fs/reiserfs/journal.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/journal.c	Mon Oct  8 11:52:58 2001
@@ -2004,12 +2004,8 @@
   int old_trans_id  ;
 
   reiserfs_check_lock_depth("journal_begin") ;
-#ifdef CONFIG_REISERFS_CHECK
-  if (p_s_sb->s_flags & MS_RDONLY) {
-    printk("clm-2078: calling journal_begin on readonly FS\n") ;
-    BUG() ;
-  }
-#endif
+  RFALSE( p_s_sb->s_flags & MS_RDONLY, 
+	  "clm-2078: calling journal_begin on readonly FS") ;
 
   if (reiserfs_dont_log(p_s_sb)) {
     th->t_super = p_s_sb ; /* others will check this for the don't log flag */
@@ -2641,12 +2637,8 @@
     }
     set_bit(BH_JPrepared, &bh->b_state) ;
     if (wait) {
-#ifdef CONFIG_REISERFS_CHECK
-      if (buffer_locked(bh) && cur_tb != NULL) {
-	printk("reiserfs_prepare_for_journal, waiting while do_balance was running\n") ;
-        BUG() ;
-      }
-#endif
+      RFALSE( buffer_locked(bh) && cur_tb != NULL,
+	      "waiting while do_balance was running\n") ;
       wait_on_buffer(bh) ;
     }
     retry_count++ ;
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/lbalance.c linux/fs/reiserfs/lbalance.c
--- v2.4.10/linux/fs/reiserfs/lbalance.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/lbalance.c	Mon Oct  8 11:52:58 2001
@@ -37,10 +37,7 @@
 
     ih = B_N_PITEM_HEAD (source, item_num);
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (!is_direntry_le_ih (ih))
-	reiserfs_panic(0, "vs-10000: leaf_copy_dir_entries: item must be directory item");
-#endif
+    RFALSE( !is_direntry_le_ih (ih), "vs-10000: item must be directory item");
 
     /* length of all record to be copied and first byte of the last of them */
     deh = B_I_DEH (source, ih);
@@ -126,10 +123,7 @@
       /* there is nothing to merge */
       return 0;
       
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! ih->ih_item_len )
-      reiserfs_panic (0, "vs-10010: leaf_copy_boundary_item: item can not have empty dynamic length");
-#endif
+    RFALSE( ! ih->ih_item_len, "vs-10010: item can not have empty length");
       
     if ( is_direntry_le_ih (ih) ) {
       if ( bytes_or_entries == -1 )
@@ -162,12 +156,9 @@
 			  );
       
     if (is_indirect_le_ih (dih)) {
-#ifdef CONFIG_REISERFS_CHECK
-      if (get_ih_free_space (dih))
-	reiserfs_panic (0, "vs-10030: leaf_copy_boundary_item: " 
-			"merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
-			ih);
-#endif
+      RFALSE( get_ih_free_space (dih),
+	      "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zero free space", 
+	      ih);
       if (bytes_or_entries == le16_to_cpu (ih->ih_item_len))
 	set_ih_free_space (dih, get_ih_free_space (ih));
     }
@@ -202,21 +193,17 @@
      don't create new item header
      */
   
-#ifdef CONFIG_REISERFS_CHECK  
-  if (is_indirect_le_ih(ih) && get_ih_free_space (ih))
-    reiserfs_panic (0, "vs-10040: leaf_copy_boundary_item: " 
-		    "merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
+  RFALSE( is_indirect_le_ih(ih) && get_ih_free_space (ih),
+	  "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
 		    ih);
-#endif
 
   if ( bytes_or_entries == -1 ) {
     /* bytes_or_entries = length of last item body of SOURCE */
     bytes_or_entries = ih->ih_item_len;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (le_ih_k_offset (dih) != le_ih_k_offset (ih) + op_bytes_number (ih, src->b_size))
-      reiserfs_panic (0, "vs-10050: leaf_copy_boundary_item: items %h and %h do not match", ih, dih);
-#endif
+    RFALSE( le_ih_k_offset (dih) != 
+	    le_ih_k_offset (ih) + op_bytes_number (ih, src->b_size),
+	    "vs-10050: items %h and %h do not match", ih, dih);
 
     /* change first item key of the DEST */
     set_le_ih_k_offset (dih, le_ih_k_offset (ih));
@@ -226,26 +213,20 @@
     set_le_ih_k_type (dih, le_ih_k_type (ih));
   } else {
     /* merge to right only part of item */
-#ifdef CONFIG_REISERFS_CHECK
-    if ( le16_to_cpu (ih->ih_item_len) <= bytes_or_entries )
-      reiserfs_panic (0, "vs-10060: leaf_copy_boundary_item: no so much bytes %lu (needed %lu)",
-		      ih->ih_item_len, bytes_or_entries);
-#endif
+    RFALSE( le16_to_cpu (ih->ih_item_len) <= bytes_or_entries,
+	    "vs-10060: no so much bytes %lu (needed %lu)",
+	    ih->ih_item_len, bytes_or_entries);
     
     /* change first item key of the DEST */
     if ( is_direct_le_ih (dih) ) {
-#ifdef CONFIG_REISERFS_CHECK
-      if (le_ih_k_offset (dih) <= (unsigned long)bytes_or_entries)
-	reiserfs_panic (0, "vs-10070: leaf_copy_boundary_item: dih %h, bytes_or_entries(%d)", 
-			dih, bytes_or_entries);
-#endif
+      RFALSE( le_ih_k_offset (dih) <= (unsigned long)bytes_or_entries,
+	      "vs-10070: dih %h, bytes_or_entries(%d)", dih, bytes_or_entries);
       set_le_ih_k_offset (dih, le_ih_k_offset (dih) - bytes_or_entries);
     } else {
-#ifdef CONFIG_REISERFS_CHECK
-      if (le_ih_k_offset (dih) <= (bytes_or_entries / UNFM_P_SIZE) * dest->b_size )
-	reiserfs_panic (0, "vs-10080: leaf_copy_boundary_item: dih %h, bytes_or_entries(%d)",
-			dih, (bytes_or_entries/UNFM_P_SIZE)*dest->b_size);
-#endif
+      RFALSE( le_ih_k_offset (dih) <= 
+	      (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
+	      "vs-10080: dih %h, bytes_or_entries(%d)",
+	      dih, (bytes_or_entries/UNFM_P_SIZE)*dest->b_size);
       set_le_ih_k_offset (dih, le_ih_k_offset (dih) - ((bytes_or_entries / UNFM_P_SIZE) * dest->b_size));
     }
   }
@@ -270,27 +251,17 @@
     struct block_head * blkh;
     struct item_head * ih;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (last_first != LAST_TO_FIRST  && last_first != FIRST_TO_LAST) 
-	reiserfs_panic (0, "vs-10090: leaf_copy_items_entirely: bad last_first parameter %d", last_first);
-
-    if (B_NR_ITEMS (src) - first < cpy_num)
-	reiserfs_panic (0, "vs-10100: leaf_copy_items_entirely: too few items in source %d, required %d from %d",
-			B_NR_ITEMS(src), cpy_num, first);
-
-    if (cpy_num < 0)
-	reiserfs_panic (0, "vs-10110: leaf_copy_items_entirely: can not copy negative amount of items");
-
-    if ( ! dest_bi )
-	reiserfs_panic (0, "vs-10120: leaf_copy_items_entirely: can not copy negative amount of items");
-#endif
+    RFALSE( last_first != LAST_TO_FIRST  && last_first != FIRST_TO_LAST,
+	    "vs-10090: bad last_first parameter %d", last_first);
+    RFALSE( B_NR_ITEMS (src) - first < cpy_num,
+	    "vs-10100: too few items in source %d, required %d from %d",
+	    B_NR_ITEMS(src), cpy_num, first);
+    RFALSE( cpy_num < 0, "vs-10110: can not copy negative amount of items");
+    RFALSE( ! dest_bi, "vs-10120: can not copy negative amount of items");
 
     dest = dest_bi->bi_bh;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! dest )
-	reiserfs_panic (0, "vs-10130: leaf_copy_items_entirely: can not copy negative amount of items");
-#endif
+    RFALSE( ! dest, "vs-10130: can not copy negative amount of items");
 
     if (cpy_num == 0)
 	return;
@@ -303,13 +274,9 @@
     /* location of head of first new item */
     ih = B_N_PITEM_HEAD (dest, dest_before);
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (le16_to_cpu (blkh->blk_free_space) < cpy_num * IH_SIZE) {
-	reiserfs_panic (0, "vs-10140: leaf_copy_items_entirely: "
-			"not enough free space for headers %d (needed %d)",
-			B_FREE_SPACE (dest), cpy_num * IH_SIZE);
-    }
-#endif
+    RFALSE( le16_to_cpu (blkh->blk_free_space) < cpy_num * IH_SIZE,
+	    "vs-10140: not enough free space for headers %d (needed %d)",
+	    B_FREE_SPACE (dest), cpy_num * IH_SIZE);
 
     /* prepare space for headers */
     memmove (ih + cpy_num, ih, (nr-dest_before) * IH_SIZE);
@@ -330,12 +297,9 @@
     last_inserted_loc = ih[cpy_num-1].ih_item_location;
 
     /* check free space */
-#ifdef CONFIG_REISERFS_CHECK
-    if (le16_to_cpu (blkh->blk_free_space) < j - last_inserted_loc) {
-	reiserfs_panic (0, "vs-10150: leaf_copy_items_entirely: not enough free space for items %d (needed %d)",
-			le16_to_cpu (blkh->blk_free_space), j - last_inserted_loc);
-    }
-#endif
+    RFALSE( le16_to_cpu (blkh->blk_free_space) < j - last_inserted_loc,
+	    "vs-10150: not enough free space for items %d (needed %d)",
+	    le16_to_cpu (blkh->blk_free_space), j - last_inserted_loc);
 
     memmove (dest->b_data + last_loc,
 	     dest->b_data + last_loc + j - last_inserted_loc,
@@ -352,13 +316,9 @@
     do_balance_mark_leaf_dirty (dest_bi->tb, dest, 0);
 
     if (dest_bi->bi_parent) {
-#ifdef CONFIG_REISERFS_CHECK
-	if (B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_block_number != dest->b_blocknr) {
-	    reiserfs_panic (0, "vs-10160: leaf_copy_items_entirely: "
-			    "block number in bh does not match to field in disk_child structure %lu and %lu",
-			    dest->b_blocknr, B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_block_number);
-	}
-#endif
+	RFALSE( B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_block_number != dest->b_blocknr,
+		"vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
+		dest->b_blocknr, B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_block_number);
 	B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position)->dc_size +=
 	    j - last_inserted_loc + IH_SIZE * cpy_num;
     
@@ -375,10 +335,7 @@
     struct buffer_head * dest = dest_bi->bi_bh;
     struct item_head * ih;
   
-#ifdef CONFIG_REISERFS_CHECK  
-    if ( cpy_bytes == -1 ) 
-	reiserfs_panic (0, "vs-10170: leaf_item_bottle: bytes == - 1 means: do not split item");
-#endif
+    RFALSE( cpy_bytes == -1, "vs-10170: bytes == - 1 means: do not split item");
 
     if ( last_first == FIRST_TO_LAST ) {
 	/* if ( if item in position item_num in buffer SOURCE is directory item ) */
@@ -394,19 +351,15 @@
 	    memcpy (&n_ih, ih, IH_SIZE);
 	    n_ih.ih_item_len = cpu_to_le16 (cpy_bytes);
 	    if (is_indirect_le_ih (ih)) {
-#ifdef CONFIG_REISERFS_CHECK
-		if (cpy_bytes == le16_to_cpu (ih->ih_item_len) && get_ih_free_space (ih))
-		    reiserfs_panic (0, "vs-10180: leaf_item_bottle: " 
-				    "when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
-				    get_ih_free_space (ih));
-#endif
+		RFALSE( cpy_bytes == le16_to_cpu (ih->ih_item_len) && 
+			get_ih_free_space (ih),
+			"vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
+			get_ih_free_space (ih));
 		set_ih_free_space (&n_ih, 0);
 	    }
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if (op_is_left_mergeable (&(ih->ih_key), src->b_size))
-		reiserfs_panic (0, "vs-10190: leaf_item_bottle: bad mergeability of item %h", ih);
-#endif
+	    RFALSE( op_is_left_mergeable (&(ih->ih_key), src->b_size),
+		    "vs-10190: bad mergeability of item %h", ih);
 	    n_ih.ih_version = ih->ih_version;;
 	    leaf_insert_into_buf (dest_bi, B_NR_ITEMS(dest), &n_ih, B_N_PITEM (src, item_num), 0);
 	}
@@ -429,10 +382,8 @@
 		set_ih_free_space (&n_ih, MAX_US_INT);
 	    } else {
 		/* indirect item */
-#ifdef CONFIG_REISERFS_CHECK
-		if (!cpy_bytes && get_ih_free_space (ih))
-		    reiserfs_panic (0, "vs-10200: leaf_item_bottle: ih->ih_free_space must be 0 when indirect item will be appended");
-#endif
+		RFALSE( !cpy_bytes && get_ih_free_space (ih),
+			"vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
 		set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + (le16_to_cpu (ih->ih_item_len) - cpy_bytes) / UNFM_P_SIZE * dest->b_size);
 		set_le_ih_k_type (&n_ih, TYPE_INDIRECT);
 		set_ih_free_space (&n_ih, get_ih_free_space (ih));
@@ -458,19 +409,12 @@
   int pos, i, src_nr_item, bytes;
 
   dest = dest_bi->bi_bh;
-#ifdef CONFIG_REISERFS_CHECK
-  if (!dest || !src)
-    reiserfs_panic (0, "vs-10210: leaf_copy_items: !dest || !src");
-  
-  if ( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST )
-    reiserfs_panic (0, "vs-10220: leaf_copy_items: last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
-
-  if ( B_NR_ITEMS(src) < cpy_num )
-    reiserfs_panic (0, "vs-10230: leaf_copy_items: No enough items: %d, required %d", B_NR_ITEMS(src), cpy_num);
-
- if ( cpy_num < 0 )
-    reiserfs_panic (0, "vs-10240: leaf_copy_items: cpy_num < 0 (%d)", cpy_num);
-#endif
+  RFALSE( !dest || !src, "vs-10210: !dest || !src");
+  RFALSE( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
+	  "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
+  RFALSE( B_NR_ITEMS(src) < cpy_num,
+	  "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src), cpy_num);
+  RFALSE( cpy_num < 0,"vs-10240: cpy_num < 0 (%d)", cpy_num);
 
  if ( cpy_num == 0 )
    return 0;
@@ -537,10 +481,8 @@
 					struct buffer_info * src_bi, int * first_last,
 					struct buffer_head * Snew)
 {
-#ifdef CONFIG_REISERFS_CHECK
     memset (dest_bi, 0, sizeof (struct buffer_info));
     memset (src_bi, 0, sizeof (struct buffer_info));
-#endif
 
     /* define dest, src, dest parent, dest position */
     switch (shift_mode) {
@@ -607,12 +549,9 @@
     default:
 	reiserfs_panic (0, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode);
     }
-#ifdef CONFIG_REISERFS_CHECK
-    if (src_bi->bi_bh == 0 || dest_bi->bi_bh == 0) {
-	reiserfs_panic (0, "vs-10260: leaf_define_dest_src_etc: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
-			shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
-    }
-#endif
+    RFALSE( src_bi->bi_bh == 0 || dest_bi->bi_bh == 0,
+	    "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
+	    shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
 }
 
 
@@ -650,10 +589,10 @@
   if ( shift_num ) {
     if (B_NR_ITEMS (S0) == 0) { /* number of items in S[0] == 0 */
 
+      RFALSE( shift_bytes != -1,
+	      "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)", 
+	      shift_bytes);
 #ifdef CONFIG_REISERFS_CHECK
-      if ( shift_bytes != -1 )
-	reiserfs_panic (tb->tb_sb, "vs-10270: leaf_shift_left: S0 is empty now, but shift_bytes != -1 (%d)", shift_bytes);
-
       if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
 	print_cur_tb ("vs-10275");
 	reiserfs_panic (tb->tb_sb, "vs-10275: leaf_shift_left: balance condition corrupted (%c)", tb->tb_mode);
@@ -675,14 +614,11 @@
       /* change right_delimiting_key field in L0's block header */
       copy_key (B_PRIGHT_DELIM_KEY(tb->L[0]), B_N_PKEY (S0, 0));
 #endif
-#ifdef CONFIG_REISERFS_CHECK
-      if (shift_bytes != -1 && !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0))
-				 && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) {
-	if (!op_is_left_mergeable (B_N_PKEY (S0, 0), S0->b_size)) {
-	  reiserfs_panic (tb->tb_sb, "vs-10280: leaf_shift_left: item must be mergeable");
-	}
-      }
-#endif
+      RFALSE( (shift_bytes != -1 && 
+	       !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0))
+		 && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) &&
+	      (!op_is_left_mergeable (B_N_PKEY (S0, 0), S0->b_size)),
+	      "vs-10280: item must be mergeable");
     }
   }
   
@@ -741,17 +677,12 @@
     struct buffer_head * bh;
     int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh);
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( !bh )
-	reiserfs_panic (0, "leaf_delete_items: 10155: bh is not defined");
-
-    if ( del_num < 0 )
-	reiserfs_panic (0, "leaf_delete_items: 10160: del_num can not be < 0. del_num==%d", del_num);
-
-    if ( first < 0 || first + del_num > item_amount )
-	reiserfs_panic (0, "leaf_delete_items: 10165: invalid number of first item to be deleted (%d) or "
-			"no so much items (%d) to delete (only %d)", first, first + del_num, item_amount);
-#endif
+    RFALSE( !bh, "10155: bh is not defined");
+    RFALSE( del_num < 0, "10160: del_num can not be < 0. del_num==%d", del_num);
+    RFALSE( first < 0 || first + del_num > item_amount,
+	    "10165: invalid number of first item to be deleted (%d) or "
+	    "no so much items (%d) to delete (only %d)", 
+	    first, first + del_num, item_amount);
 
     if ( del_num == 0 )
 	return;
@@ -814,16 +745,14 @@
 
     nr = le16_to_cpu ((blkh = B_BLK_HEAD (bh))->blk_nr_item);
 
-#ifdef CONFIG_REISERFS_CHECK
     /* check free space */
-    if (le16_to_cpu (blkh->blk_free_space) < le16_to_cpu (inserted_item_ih->ih_item_len) + IH_SIZE)
-	reiserfs_panic (0, "leaf_insert_into_buf: 10170: "
-			"not enough free space in block %z, new item %h",
-			bh, inserted_item_ih);
-    if (zeros_number > inserted_item_ih->ih_item_len)
-	reiserfs_panic (0, "vs-10172: leaf_insert_into_buf: "
-			"zero number == %d, item length == %d", zeros_number, inserted_item_ih->ih_item_len);
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( le16_to_cpu (blkh->blk_free_space) < 
+	    le16_to_cpu (inserted_item_ih->ih_item_len) + IH_SIZE,
+	    "not enough free space in block %z, new item %h",
+	    bh, inserted_item_ih);
+    RFALSE( zeros_number > inserted_item_ih->ih_item_len,
+	    "vs-10172: zero number == %d, item length == %d", 
+	    zeros_number, inserted_item_ih->ih_item_len);
 
 
     /* get item new item must be inserted before */
@@ -886,11 +815,11 @@
 
     nr = le16_to_cpu ((blkh = B_BLK_HEAD(bh))->blk_nr_item);
 
-#ifdef CONFIG_REISERFS_CHECK
     /* check free space */
-    if (le16_to_cpu (blkh->blk_free_space) < paste_size)
-	reiserfs_panic (0, "leaf_paste_in_buffer: 10175: not enough free space: needed %d, available %d",
-			paste_size, le16_to_cpu (blkh->blk_free_space));
+    RFALSE( le16_to_cpu (blkh->blk_free_space) < paste_size,
+	    "10175: not enough free space: needed %d, available %d",
+	    paste_size, le16_to_cpu (blkh->blk_free_space));
+#ifdef CONFIG_REISERFS_CHECK
     if (zeros_number > paste_size) {
 	print_cur_tb ("10177");
 	reiserfs_panic (0, "vs-10177: leaf_paste_in_buffer: zero number == %d, paste_size == %d",
@@ -965,16 +894,12 @@
   int i;
 
 
-#ifdef CONFIG_REISERFS_CHECK
   /* make sure, that item is directory and there are enough entries to
      remove */
-  if (!is_direntry_le_ih (ih))
-    reiserfs_panic (0, "leaf_cut_entries: 10180: item is not directory item");
-
-  if (I_ENTRY_COUNT(ih) < from + del_count)
-    reiserfs_panic (0, "leaf_cut_entries: 10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
-		    I_ENTRY_COUNT(ih), from, del_count);
-#endif
+  RFALSE( !is_direntry_le_ih (ih), "10180: item is not directory item");
+  RFALSE( I_ENTRY_COUNT(ih) < from + del_count,
+	  "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
+	  I_ENTRY_COUNT(ih), from, del_count);
 
   if (del_count == 0)
     return 0;
@@ -1042,25 +967,19 @@
         cut_size = leaf_cut_entries (bh, ih, pos_in_item, cut_size);
         if (pos_in_item == 0) {
 	        /* change key */
-#ifdef CONFIG_REISERFS_CHECK
-            if (cut_item_num)
-                reiserfs_panic (0, "leaf_cut_from_buffer: 10190: " 
+	    RFALSE( cut_item_num,
                     "when 0-th enrty of item is cut, that item must be first in the node, not %d-th", cut_item_num);
-#endif
             /* change item key by key of first entry in the item */
 	    set_le_ih_k_offset (ih, le32_to_cpu (B_I_DEH (bh, ih)->deh_offset));
             /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE);*/
 	    }
     } else {
         /* item is direct or indirect */
-#ifdef CONFIG_REISERFS_CHECK
-        if (is_statdata_le_ih (ih))
-	        reiserfs_panic (0, "leaf_cut_from_buffer: 10195: item is stat data");
-
-        if (pos_in_item && pos_in_item + cut_size != le16_to_cpu (ih->ih_item_len) )
-            reiserfs_panic (0, "cut_from_buf: 10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
+	RFALSE( is_statdata_le_ih (ih), "10195: item is stat data");
+	RFALSE( pos_in_item && 
+		pos_in_item + cut_size != le16_to_cpu (ih->ih_item_len),
+		"invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
                 pos_in_item, cut_size, le16_to_cpu (ih->ih_item_len));
-#endif
 
         /* shift item body to left if cut is from the head of item */
         if (pos_in_item == 0) {
@@ -1072,10 +991,9 @@
 		set_le_ih_k_offset (ih, le_ih_k_offset (ih) + cut_size);
             else {
 		set_le_ih_k_offset (ih, le_ih_k_offset (ih) + (cut_size / UNFM_P_SIZE) * bh->b_size);
-#ifdef CONFIG_REISERFS_CHECK
-                if ( le16_to_cpu (ih->ih_item_len) == cut_size && get_ih_free_space (ih) )
-                    reiserfs_panic (0, "leaf_cut_from_buf: 10205: invalid ih_free_space (%h)", ih);
-#endif
+		RFALSE( le16_to_cpu (ih->ih_item_len) == cut_size && 
+			get_ih_free_space (ih),
+			"10205: invalid ih_free_space (%h)", ih);
 	        }
 	    }
     }
@@ -1130,23 +1048,16 @@
     struct block_head * blkh;
     struct item_head * ih;
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (bh == NULL)
-    reiserfs_panic (0, "leaf_delete_items_entirely: 10210: buffer is 0");
-
-  if (del_num < 0)
-    reiserfs_panic (0, "leaf_delete_items_entirely: 10215: del_num less than 0 (%d)", del_num);
-#endif /* CONFIG_REISERFS_CHECK */
+  RFALSE( bh == NULL, "10210: buffer is 0");
+  RFALSE( del_num < 0, "10215: del_num less than 0 (%d)", del_num);
 
   if (del_num == 0)
     return;
 
   nr = le16_to_cpu ((blkh = B_BLK_HEAD(bh))->blk_nr_item);
 
-#ifdef CONFIG_REISERFS_CHECK
-  if (first < 0 || first + del_num > nr)
-    reiserfs_panic (0, "leaf_delete_items_entirely: 10220: first=%d, number=%d, there is %d items", first, del_num, nr);
-#endif /* CONFIG_REISERFS_CHECK */
+  RFALSE( first < 0 || first + del_num > nr,
+	  "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
 
   if (first == 0 && del_num == nr) {
     /* this does not work */
@@ -1213,15 +1124,11 @@
 
     ih = B_N_PITEM_HEAD(bh, item_num);
 
-#ifdef CONFIG_REISERFS_CHECK
   /* make sure, that item is directory, and there are enough records in it */
-  if (!is_direntry_le_ih (ih))
-    reiserfs_panic (0, "leaf_paste_entries: 10225: item is not directory item");
-
-  if (I_ENTRY_COUNT (ih) < before)
-    reiserfs_panic (0, "leaf_paste_entries: 10230: there are no entry we paste entries before. entry_count = %d, before = %d",
-		    I_ENTRY_COUNT (ih), before);
-#endif
+  RFALSE( !is_direntry_le_ih (ih), "10225: item is not directory item");
+  RFALSE( I_ENTRY_COUNT (ih) < before,
+	  "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
+	  I_ENTRY_COUNT (ih), before);
 
 
   /* first byte of dest item */
@@ -1268,13 +1175,6 @@
   /* change item key if neccessary (when we paste before 0-th entry */
   if (!before)
     {
-#ifdef CONFIG_REISERFS_CHECK
-/*
-      if ( old_entry_num && COMP_SHORT_KEYS ((unsigned long *)&ih->ih_key.k_offset,
-					     &(new_dehs->deh_offset)) <= 0)
-	reiserfs_panic (0, "leaf_paste_entries: 10235: new key must be less, that old key");
-*/
-#endif
 	set_le_ih_k_offset (ih, le32_to_cpu (new_dehs->deh_offset));
 /*      memcpy (&ih->ih_key.k_offset, 
 		       &new_dehs->deh_offset, SHORT_KEY_SIZE);*/
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/namei.c linux/fs/reiserfs/namei.c
--- v2.4.10/linux/fs/reiserfs/namei.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/namei.c	Mon Oct  8 11:52:58 2001
@@ -245,10 +245,8 @@
 	i --;
     }
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (de->de_deh != B_I_DEH (de->de_bh, de->de_ih))
-	reiserfs_panic (0, "vs-7010: linear_search_in_dir_item: array of entry headers not found");
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( de->de_deh != B_I_DEH (de->de_bh, de->de_ih),
+	    "vs-7010: array of entry headers not found");
 
     deh += i;
 
@@ -290,11 +288,8 @@
 	// so, this is a bug
 	return NAME_NOT_FOUND;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if (de->de_item_num)
-	reiserfs_panic (0, "vs-7015: linear_search_in_dir_item: "
-			"two diritems of the same directory in one node?");
-#endif /* CONFIG_REISERFS_CHECK */
+    RFALSE( de->de_item_num,
+	    "vs-7015: two diritems of the same directory in one node?");
 
     return GOTO_PREVIOUS_ITEM;
 }
@@ -533,7 +528,7 @@
     struct reiserfs_transaction_handle th ;
 
 
-    inode = get_empty_inode() ;
+    inode = new_inode(dir->i_sb) ;
     if (!inode) {
 	return -ENOMEM ;
     }
@@ -586,7 +581,7 @@
     struct reiserfs_transaction_handle th ;
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
 
-    inode = get_empty_inode() ;
+    inode = new_inode(dir->i_sb) ;
     if (!inode) {
 	return -ENOMEM ;
     }
@@ -638,7 +633,7 @@
     struct reiserfs_transaction_handle th ;
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
 
-    inode = get_empty_inode() ;
+    inode = new_inode(dir->i_sb) ;
     if (!inode) {
 	return -ENOMEM ;
     }
@@ -859,7 +854,7 @@
     int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; 
 
 
-    inode = get_empty_inode() ;
+    inode = new_inode(dir->i_sb) ;
     if (!inode) {
 	return -ENOMEM ;
     }
@@ -1149,14 +1144,9 @@
 	    continue;
 	}
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (S_ISDIR(old_inode->i_mode) && 
-	    (!entry_points_to_object ("..", 2, &dot_dot_de, old_dir) || 
-	     !reiserfs_buffer_prepared(dot_dot_de.de_bh))) {
-	    // this should be not changed
-	    BUG ();
-	}
-#endif	
+	RFALSE( S_ISDIR(old_inode->i_mode) && 
+		(!entry_points_to_object ("..", 2, &dot_dot_de, old_dir) || 
+		 !reiserfs_buffer_prepared(dot_dot_de.de_bh)), "" );
 
 	break;
     }
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/objectid.c linux/fs/reiserfs/objectid.c
--- v2.4.10/linux/fs/reiserfs/objectid.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/objectid.c	Mon Oct  8 11:52:58 2001
@@ -26,6 +26,9 @@
     // FIXME: add something else here
 }
 
+#else
+static void check_objectid_map (struct super_block * s, __u32 * map)
+{;}
 #endif
 
 
@@ -53,9 +56,7 @@
     __u32 unused_objectid;
 
 
-#ifdef CONFIG_REISERFS_CHECK
     check_objectid_map (s, map);
-#endif
 
     reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
                                 /* comment needed -Hans */
@@ -101,9 +102,7 @@
     int i = 0;
 
     //return;
-#ifdef CONFIG_REISERFS_CHECK
     check_objectid_map (s, map);
-#endif
 
     reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
     journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s)); 
@@ -129,13 +128,10 @@
 		//disk_sb->s_oid_cursize -= 2;
 		rs->s_oid_cursize = cpu_to_le16 (le16_to_cpu (rs->s_oid_cursize) - 2);
 
-#ifdef CONFIG_REISERFS_CHECK
-		if (le16_to_cpu (rs->s_oid_cursize) < 2 || 
-		    le16_to_cpu (rs->s_oid_cursize) > le16_to_cpu (rs->s_oid_maxsize))
-		    reiserfs_panic (s, "vs-15005: reiserfs_release_objectid: "
-				    "objectid map corrupted cur_size == %d (max == %d)",
-				    le16_to_cpu (rs->s_oid_cursize), le16_to_cpu (rs->s_oid_maxsize));
-#endif
+		RFALSE( le16_to_cpu (rs->s_oid_cursize) < 2 || 
+			le16_to_cpu (rs->s_oid_cursize) > le16_to_cpu (rs->s_oid_maxsize),
+			"vs-15005: objectid map corrupted cur_size == %d (max == %d)",
+			le16_to_cpu (rs->s_oid_cursize), le16_to_cpu (rs->s_oid_maxsize));
 	    }
 	    return;
 	}
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/stree.c linux/fs/reiserfs/stree.c
--- v2.4.10/linux/fs/reiserfs/stree.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/stree.c	Mon Oct  8 11:52:58 2001
@@ -65,13 +65,8 @@
 inline int B_IS_IN_TREE (struct buffer_head * p_s_bh)
 {
 
-#ifdef CONFIG_REISERFS_CHECK
-
-  if ( B_LEVEL (p_s_bh) > MAX_HEIGHT ) {
-    reiserfs_panic(0, "PAP-1010: B_IS_IN_TREE: block (%b) has too big level (%z)",
-		   p_s_bh, p_s_bh);
-  }
-#endif
+  RFALSE( B_LEVEL (p_s_bh) > MAX_HEIGHT,
+	  "PAP-1010: block (%b) has too big level (%z)", p_s_bh, p_s_bh);
 
   return ( B_LEVEL (p_s_bh) != FREE_LEVEL );
 }
@@ -312,18 +307,14 @@
   int                   n_position, n_path_offset = p_s_chk_path->path_length;
   struct buffer_head  * p_s_parent;
   
-#ifdef CONFIG_REISERFS_CHECK
-  if ( n_path_offset < FIRST_PATH_ELEMENT_OFFSET )
-    reiserfs_panic(p_s_sb,"PAP-5010: get_lkey: illegal offset in the path");
-#endif
+  RFALSE( n_path_offset < FIRST_PATH_ELEMENT_OFFSET, 
+	  "PAP-5010: illegal offset in the path");
 
   /* While not higher in path than first element. */
   while ( n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! buffer_uptodate(PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
-      reiserfs_panic(p_s_sb, "PAP-5020: get_lkey: parent is not uptodate");
-#endif
+    RFALSE( ! buffer_uptodate(PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
+	    "PAP-5020: parent is not uptodate");
 
     /* Parent at the path is not in the tree now. */
     if ( ! B_IS_IN_TREE(p_s_parent = PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
@@ -356,17 +347,13 @@
     			n_path_offset = p_s_chk_path->path_length;
   struct buffer_head  * p_s_parent;
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( n_path_offset < FIRST_PATH_ELEMENT_OFFSET )
-    reiserfs_panic(p_s_sb,"PAP-5030: get_rkey: illegal offset in the path");
-#endif
+  RFALSE( n_path_offset < FIRST_PATH_ELEMENT_OFFSET,
+	  "PAP-5030: illegal offset in the path");
 
   while ( n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! buffer_uptodate(PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
-      reiserfs_panic(p_s_sb, "PAP-5040: get_rkey: parent is not uptodate");
-#endif
+    RFALSE( ! buffer_uptodate(PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
+	    "PAP-5040: parent is not uptodate");
 
     /* Parent at the path is not in the tree now. */
     if ( ! B_IS_IN_TREE(p_s_parent = PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
@@ -401,15 +388,12 @@
                       struct super_block  * p_s_sb        /* Super block pointer.           */
 		      ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( ! p_s_key || p_s_chk_path->path_length < FIRST_PATH_ELEMENT_OFFSET ||
-       p_s_chk_path->path_length > MAX_HEIGHT )
-    reiserfs_panic(p_s_sb, "PAP-5050: key_in_buffer:  pointer to the key(%p) is NULL or illegal path length(%d)",
-		   p_s_key, p_s_chk_path->path_length);
-  
-  if ( PATH_PLAST_BUFFER(p_s_chk_path)->b_dev == NODEV )
-    reiserfs_panic(p_s_sb, "PAP-5060: key_in_buffer: device must not be NODEV");
-#endif
+  RFALSE( ! p_s_key || p_s_chk_path->path_length < FIRST_PATH_ELEMENT_OFFSET ||
+	  p_s_chk_path->path_length > MAX_HEIGHT,
+	  "PAP-5050: pointer to the key(%p) is NULL or illegal path length(%d)",
+	  p_s_key, p_s_chk_path->path_length);
+  RFALSE( PATH_PLAST_BUFFER(p_s_chk_path)->b_dev == NODEV,
+	  "PAP-5060: device must not be NODEV");
 
   if ( COMP_KEYS(get_lkey(p_s_chk_path, p_s_sb), p_s_key) == 1 )
     /* left delimiting key is bigger, that the key we look for */
@@ -441,11 +425,9 @@
             ) {
   int n_path_offset = p_s_search_path->path_length;
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET ||
-       n_path_offset > EXTENDED_MAX_HEIGHT - 1 )
-    reiserfs_panic(NULL, "PAP-5080: decrement_counters_in_path: illegal path offset of %d", n_path_offset);
-#endif
+  RFALSE( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET ||
+	  n_path_offset > EXTENDED_MAX_HEIGHT - 1,
+	  "PAP-5080: illegal path offset of %d", n_path_offset);
 
   while ( n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET ) {
     struct buffer_head * bh;
@@ -458,12 +440,8 @@
 
 
 int reiserfs_check_path(struct path *p) {
-#ifdef CONFIG_REISERFS_CHECK 
-  if (p->path_length != ILLEGAL_PATH_ELEMENT_OFFSET) {
-    reiserfs_warning("check_path, path not properly relsed\n") ;
-    BUG() ;
-  }
-#endif
+  RFALSE( p->path_length != ILLEGAL_PATH_ELEMENT_OFFSET,
+	  "path not properly relsed") ;
   return 0 ;
 }
 
@@ -479,10 +457,8 @@
       ) {
   int n_path_offset = p_s_search_path->path_length;
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET )
-    reiserfs_panic(NULL, "clm-4000: pathrelse: illegal path offset");
-#endif
+  RFALSE( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET, 
+	  "clm-4000: illegal path offset");
   
   while ( n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET )  {
     reiserfs_restore_prepared_buffer(s, PATH_OFFSET_PBUFFER(p_s_search_path, 
@@ -498,10 +474,8 @@
       ) {
   int n_path_offset = p_s_search_path->path_length;
 
-#ifdef CONFIG_REISERFS_CHECK
-  if ( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET )
-    reiserfs_panic(NULL, "PAP-5090: pathrelse: illegal path offset");
-#endif
+  RFALSE( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET,
+	  "PAP-5090: illegal path offset");
   
   while ( n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET )  
     brelse(PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--));
@@ -742,15 +716,13 @@
 	    continue;
 	}
 
+	RFALSE( ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
+		"PAP-5130: key is not in the buffer");
 #ifdef CONFIG_REISERFS_CHECK
-
-	if ( ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb) )
-	    reiserfs_panic(p_s_sb, "PAP-5130: search_by_key: key is not in the buffer");
 	if ( cur_tb ) {
 	    print_cur_tb ("5140");
 	    reiserfs_panic(p_s_sb, "PAP-5140: search_by_key: schedule occurred in do_balance!");
 	}
-
 #endif
 
 	// make sure, that the node contents look like a node of
@@ -765,13 +737,9 @@
 	/* ok, we have acquired next formatted node in the tree */
 	n_node_level = B_LEVEL (p_s_bh);
 
-#ifdef CONFIG_REISERFS_CHECK
-
-	if (n_node_level < n_stop_level)
-	    reiserfs_panic (p_s_sb, "vs-5152: search_by_key: tree level is less than stop level (%d)",
-			    n_node_level, n_stop_level);
-
-#endif
+	RFALSE( n_node_level < n_stop_level,
+		"vs-5152: tree level is less than stop level (%d)",
+		n_node_level, n_stop_level);
 
 	n_retval = bin_search (p_s_key, B_N_PITEM_HEAD(p_s_bh, 0), B_NR_ITEMS(p_s_bh),
 			       ( n_node_level == DISK_LEAF_NODE_LEVEL ) ? IH_SIZE : KEY_SIZE, &(p_s_last_element->pe_position));
@@ -840,20 +808,17 @@
 	return retval;
     if ( retval == ITEM_FOUND )  {
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( ! B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path),
-			      PATH_LAST_POSITION(p_s_search_path))->ih_item_len )
-	    reiserfs_panic(p_s_sb, "PAP-5165: search_for_position_by_key: item length equals zero");
-#endif
+	RFALSE( ! B_N_PITEM_HEAD
+		(PATH_PLAST_BUFFER(p_s_search_path),
+		 PATH_LAST_POSITION(p_s_search_path))->ih_item_len,
+		"PAP-5165: item length equals zero");
 
 	pos_in_item(p_s_search_path) = 0;
 	return POSITION_FOUND;
     }
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( ! PATH_LAST_POSITION(p_s_search_path) )
-	reiserfs_panic(p_s_sb, "PAP-5170: search_for_position_by_key: position equals zero");
-#endif
+    RFALSE( ! PATH_LAST_POSITION(p_s_search_path), 
+	    "PAP-5170: position equals zero");
 
     /* Item is not found. Set path to the previous item. */
     p_le_ih = B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path), --PATH_LAST_POSITION(p_s_search_path));
@@ -863,22 +828,6 @@
 	return FILE_NOT_FOUND;
     }
 
-#if 0
-/*#ifdef CONFIG_REISERFS_CHECK*/
-
-  /* we expect to find stat data or item of the same type */
-    if ( ! is_statdata_le_ih(p_le_ih) && ((is_indirect_cpu_key(p_cpu_key) && ! is_indirect_le_ih(p_le_ih)) ||
-					  (is_direct_cpu_key(p_cpu_key) && ! is_direct_le_ih(p_le_ih))) ) {
-	print_block (PATH_PLAST_BUFFER(p_s_search_path), PRINT_LEAF_ITEMS, 
-		     PATH_LAST_POSITION (p_s_search_path) - 2,
-		     PATH_LAST_POSITION (p_s_search_path) + 2);
-	reiserfs_panic(p_s_sb, "PAP-5190: search_for_position_by_key: "
-		       "found item %h type does not match to the expected one %k",
-		       p_le_ih, p_cpu_key);
-    }
-/*#endif*/
-#endif
-
     // FIXME: quite ugly this far
 
     item_offset = le_ih_k_offset (p_le_ih);
@@ -1006,11 +955,8 @@
 {
     if (le_ih_k_offset (le_ih) == DOT_OFFSET && 
 	new_file_length == max_reiserfs_offset (inode)) {
-#ifdef CONFIG_REISERFS_CHECK
-	if (ih_entry_count (le_ih) != 2)
-	    reiserfs_panic(inode->i_sb,"PAP-5220: prepare_for_delete_or_cut: "
-			   "incorrect empty directory item (%h)", le_ih);
-#endif
+	RFALSE( ih_entry_count (le_ih) != 2,
+		"PAP-5220: incorrect empty directory item (%h)", le_ih);
 	*cut_size = -(IH_SIZE + le16_to_cpu (le_ih->ih_item_len));
 	return M_DELETE; /* Delete the directory item containing "." and ".." entry. */
     }
@@ -1054,10 +1000,8 @@
     /* Stat_data item. */
     if ( is_statdata_le_ih (p_le_ih) ) {
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( n_new_file_length != max_reiserfs_offset (inode) )
-	    reiserfs_panic(p_s_sb, "PAP-5210: prepare_for_delete_or_cut: mode must be M_DELETE");
-#endif
+	RFALSE( n_new_file_length != max_reiserfs_offset (inode),
+		"PAP-5210: mode must be M_DELETE");
 
 	*p_n_cut_size = -(IH_SIZE + le16_to_cpu (p_le_ih->ih_item_len));
 	return M_DELETE;
@@ -1098,13 +1042,11 @@
 	    /* Calculate number of unformatted nodes in this item. */
 	    n_unfm_number = I_UNFM_NUM(&s_ih);
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if ( ! is_indirect_le_ih(&s_ih) || ! n_unfm_number ||
-		 pos_in_item (p_s_path) + 1 !=  n_unfm_number ) {
-		printk("n_unfm_number = %d *p_n_pos_in_item = %d\n",n_unfm_number, pos_in_item (p_s_path));
-		reiserfs_panic(p_s_sb, "PAP-5240: prepare_for_delete_or_cut: illegal item %h", &s_ih);
-	    }
-#endif
+	    RFALSE( ! is_indirect_le_ih(&s_ih) || ! n_unfm_number ||
+		    pos_in_item (p_s_path) + 1 !=  n_unfm_number,
+		    "PAP-5240: illegal item %h "
+		    "n_unfm_number = %d *p_n_pos_in_item = %d", 
+		    &s_ih, n_unfm_number, pos_in_item (p_s_path));
 
 	    /* Calculate balance mode and position in the item to remove unformatted nodes. */
 	    if ( n_new_file_length == max_reiserfs_offset (inode) ) {/* Case of delete. */
@@ -1122,10 +1064,8 @@
 		    /* indirect item must be truncated starting from *p_n_pos_in_item-th position */
 		    pos_in_item (p_s_path) = (n_new_file_length + n_blk_size - le_ih_k_offset (&s_ih) ) >> p_s_sb->s_blocksize_bits;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    if ( pos_in_item (p_s_path) > n_unfm_number ) 
-			reiserfs_panic(p_s_sb, "PAP-5250: prepare_for_delete_or_cut: illegal position in the item");
-#endif
+		    RFALSE( pos_in_item (p_s_path) > n_unfm_number,
+			    "PAP-5250: illegal position in the item");
 
 		    /* Either convert last unformatted node of indirect item to direct item or increase
 		       its free space.  */
@@ -1140,10 +1080,8 @@
 		}
 	    }
 
-#ifdef CONFIG_REISERFS_CHECK
-	    if ( n_unfm_number <= pos_in_item (p_s_path) ) 
-		reiserfs_panic(p_s_sb, "PAP-5260: prepare_for_delete_or_cut: illegal position in the indirect item");
-#endif
+	    RFALSE( n_unfm_number <= pos_in_item (p_s_path),
+		    "PAP-5260: illegal position in the indirect item");
 
 	    /* pointers to be cut */
 	    n_unfm_number -= pos_in_item (p_s_path);
@@ -1169,11 +1107,9 @@
 		    need_research = 1 ;
 		    break;
 		}
-#ifdef CONFIG_REISERFS_CHECK
-		if (p_n_unfm_pointer < (__u32 *)B_I_PITEM(p_s_bh, &s_ih) ||
-		    p_n_unfm_pointer > (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1)
-		    reiserfs_panic (p_s_sb, "vs-5265: prepare_for_delete_or_cut: pointer out of range");
-#endif
+		RFALSE( p_n_unfm_pointer < (__u32 *)B_I_PITEM(p_s_bh, &s_ih) ||
+			p_n_unfm_pointer > (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1,
+			"vs-5265: pointer out of range");
 
 		if ( ! *p_n_unfm_pointer )  { /* Hole, nothing to remove. */
 		    if ( ! n_retry )
@@ -1221,13 +1157,12 @@
 		if ( ! n_retry )
 		    (*p_n_removed)++;
       
-#ifdef CONFIG_REISERFS_CHECK
-		if ( p_s_un_bh && (*p_n_unfm_pointer != p_s_un_bh->b_blocknr ))
+		RFALSE( p_s_un_bh && 
+			(*p_n_unfm_pointer != p_s_un_bh->b_blocknr ),
 		    // note: minix_truncate allows that. As truncate is
 		    // protected by down (inode->i_sem), two truncates can not
 		    // co-exist
-		    reiserfs_panic(p_s_sb, "PAP-5280: prepare_for_delete_or_cut: blocks numbers are different");	
-#endif
+			"PAP-5280: blocks numbers are different");	
 
 		tmp = *p_n_unfm_pointer;
 		*p_n_unfm_pointer = 0;
@@ -1251,9 +1186,8 @@
 	    if ( n_retry ) {
 		/* There is block in use. Wait, they should release it soon */
 
+		RFALSE( *p_n_removed >= n_unfm_number, "PAP-5290: illegal case");
 #ifdef CONFIG_REISERFS_CHECK
-		if ( *p_n_removed >= n_unfm_number )
-		    reiserfs_panic(p_s_sb, "PAP-5290: prepare_for_delete_or_cut: illegal case");
 		if ( !(++n_repeat_counter % 500000) ) {
 		    reiserfs_warning("PAP-5300: prepare_for_delete_or_cut: (pid %u): "
 				     "could not delete item %k in (%d) iterations. New file length %Lu. (inode %Ld), Still trying\n",
@@ -1275,15 +1209,10 @@
 	} while ( (*p_n_removed < n_unfm_number || need_research) &&
 		  search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND );
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( *p_n_removed < n_unfm_number )
-	    reiserfs_panic(p_s_sb, "PAP-5310: prepare_for_delete_or_cut: indirect item is not found");
-
-	if (item_moved (&s_ih, p_s_path) ) {
-	    printk("prepare_for_delete_or_cut: after while, comp failed, retry\n") ;
-	    BUG ();
-	}
-#endif
+	RFALSE( *p_n_removed < n_unfm_number, 
+		"PAP-5310: indirect item is not found");
+	RFALSE( item_moved (&s_ih, p_s_path), 
+		"after while, comp failed, retry") ;
 
 	if (c_mode == M_CUT)
 	    pos_in_item (p_s_path) *= UNFM_P_SIZE;
@@ -1375,10 +1304,7 @@
 #endif
 	    prepare_for_delete_or_cut(th, p_s_inode, p_s_path, p_s_item_key, &n_removed, &n_del_size, max_reiserfs_offset (p_s_inode));
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( c_mode != M_DELETE )
-	    reiserfs_panic(p_s_sb, "PAP-5320: reiserfs_delete_item: mode must be M_DELETE");
-#endif
+	RFALSE( c_mode != M_DELETE, "PAP-5320: mode must be M_DELETE");
 
 	copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
 	s_del_balance.insert_size[0] = n_del_size;
@@ -1597,19 +1523,14 @@
 	/* look for the last byte of the tail */
 	if (search_for_position_by_key (inode->i_sb, &tail_key, path) == POSITION_NOT_FOUND)
 	    reiserfs_panic (inode->i_sb, "vs-5615: indirect_to_direct_roll_back: found invalid item");
-#ifdef CONFIG_REISERFS_CHECK
-	if (path->pos_in_item != PATH_PITEM_HEAD (path)->ih_item_len - 1)
-	    reiserfs_panic (inode->i_sb, "vs-5616: indirect_to_direct_roll_back: appended bytes found");
-#endif
+	RFALSE( path->pos_in_item != PATH_PITEM_HEAD (path)->ih_item_len - 1,
+		"vs-5616: appended bytes found");
 	PATH_LAST_POSITION (path) --;
 	
 	removed = reiserfs_delete_item (th, path, &tail_key, inode, 0/*unbh not needed*/);
-#ifdef CONFIG_REISERFS_CHECK
-	if (removed <= 0 || removed > tail_len)
-	    reiserfs_panic (inode->i_sb, "vs-5617: indirect_to_direct_roll_back: "
-			    "there was tail %d bytes, removed item length %d bytes",
-			    tail_len, removed);
-#endif
+	RFALSE( removed <= 0 || removed > tail_len,
+		"vs-5617: there was tail %d bytes, removed item length %d bytes",
+		tail_len, removed);
 	tail_len -= removed;
 	set_cpu_key_k_offset (&tail_key, cpu_key_k_offset (&tail_key) - removed);
     }
@@ -1657,10 +1578,7 @@
 	if ( c_mode == M_CONVERT )  {
 	    /* convert last unformatted node to direct item or leave
                tail in the unformatted node */
-#ifdef CONFIG_REISERFS_CHECK
-	    if ( n_ret_value != CARRY_ON )
-		reiserfs_panic (p_s_sb, "PAP-5570: reiserfs_cut_from_item: can not convert twice");
-#endif
+	    RFALSE( n_ret_value != CARRY_ON, "PAP-5570: can not convert twice");
 
 	    n_ret_value = maybe_indirect_to_direct (th, p_s_inode, page, p_s_path, p_s_item_key,
 						    n_new_file_size, &c_mode);
@@ -1724,10 +1642,7 @@
 
     /* go ahead and perform balancing */
     
-#ifdef CONFIG_REISERFS_CHECK
-    if ( c_mode == M_PASTE || c_mode == M_INSERT )
-	reiserfs_panic (p_s_sb, "PAP-5640: reiserfs_cut_from_item: illegal mode");
-#endif
+    RFALSE( c_mode == M_PASTE || c_mode == M_INSERT, "illegal mode");
 
     /* Calculate number of bytes that need to be cut from the item. */
     if (retval2 == -1)
@@ -1880,13 +1795,9 @@
 	    return;
 	}
 
-#ifdef CONFIG_REISERFS_CHECK
-	if ( n_deleted > n_file_size ){
-	    reiserfs_panic (p_s_inode->i_sb, "PAP-5670: reiserfs_truncate_file: "
-			    "reiserfs_truncate_file returns too big number: deleted %d, file_size %lu, item_key %k",
-			    n_deleted, n_file_size, &s_item_key);
-	}
-#endif
+	RFALSE( n_deleted > n_file_size,
+		"PAP-5670: reiserfs_truncate_file returns too big number: deleted %d, file_size %lu, item_key %k",
+		n_deleted, n_file_size, &s_item_key);
 
 	/* Change key to search the last file item. */
 	n_file_size -= n_deleted;
@@ -1918,12 +1829,9 @@
     } while ( n_file_size > ROUND_UP (n_new_file_size) &&
 	      search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path) == POSITION_FOUND )  ;
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( n_file_size > ROUND_UP (n_new_file_size) )
-	reiserfs_panic (p_s_inode->i_sb, "PAP-5680: reiserfs_truncate_file: "
-			"truncate did not finish: new_file_size %Ld, current %Ld, oid %d\n",
-			n_new_file_size, n_file_size, s_item_key.on_disk_key.k_objectid);
-#endif
+    RFALSE( n_file_size > ROUND_UP (n_new_file_size),
+	    "PAP-5680: truncate did not finish: new_file_size %Ld, current %Ld, oid %d\n",
+	    n_new_file_size, n_file_size, s_item_key.on_disk_key.k_objectid);
 
     if (update_timestamps) {
 	// this is truncate, not file closing
diff -u --recursive --new-file v2.4.10/linux/fs/reiserfs/tail_conversion.c linux/fs/reiserfs/tail_conversion.c
--- v2.4.10/linux/fs/reiserfs/tail_conversion.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/reiserfs/tail_conversion.c	Mon Oct  8 11:52:58 2001
@@ -92,12 +92,9 @@
 	    reiserfs_panic (sb, "PAP-14050: direct2indirect: "
 			    "direct item (%k) not found", &end_key);
 	p_le_ih = PATH_PITEM_HEAD (path);
-#ifdef CONFIG_REISERFS_CHECK
-	if (!is_direct_le_ih (p_le_ih))
-	    reiserfs_panic (sb, "vs-14055: direct2indirect: "
-			    "direct item expected(%k), found %h", 
-				&end_key, p_le_ih);
-#endif
+	RFALSE( !is_direct_le_ih (p_le_ih),
+		"vs-14055: direct item expected(%k), found %h", 
+		&end_key, p_le_ih);
 	tail_size = (le_ih_k_offset (p_le_ih) & (n_blk_size - 1))
 	    + ih_item_len(p_le_ih) - 1;
 
diff -u --recursive --new-file v2.4.10/linux/fs/romfs/inode.c linux/fs/romfs/inode.c
--- v2.4.10/linux/fs/romfs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/romfs/inode.c	Sun Sep 30 12:26:08 2001
@@ -548,3 +548,4 @@
 
 module_init(init_romfs_fs)
 module_exit(exit_romfs_fs)
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/ChangeLog linux/fs/smbfs/ChangeLog
--- v2.4.10/linux/fs/smbfs/ChangeLog	Tue Jul  3 17:08:21 2001
+++ linux/fs/smbfs/ChangeLog	Tue Oct  2 17:03:34 2001
@@ -1,5 +1,30 @@
 ChangeLog for smbfs.
 
+2001-09-17 Urban Widmark <urban@teststation.com>
+
+	* proc.c: Use 4096 (was 512) as the blocksize for better write
+	  performance (patch originally by Jan Kratochvil)
+	* proc.c: Skip disconnect smb, allows umount on unreachable servers.
+	* proc.c: Go back to the interruptible sleep as reconnects seem to
+	  handle it now.
+	* *.c: use autogenerated and private proto.h
+
+2000-11-22 Igor Zhbanov <bsg@uniyar.ac.ru>
+
+	* proc.c: fixed date_unix2dos for dates earlier than 01/01/1980
+	  and date_dos2unix for date==0 (from 2.2)
+
+2001-07-13 Rob Radez <rob@osinvestor.com>
+
+	* proc.c: make smb_errno return negative error values
+
+2001-07-09 Jochen Dolze <dolze@epcnet.de>
+
+	* inode.c: smb_statfs always returned success.
+	* proc.c, ioctl.c: Allow smbmount to signal failure to reconnect with
+	  a NULL argument to SMB_IOC_NEWCONN (speeds up error detection).
+	* proc.c: Add some of the missing error codes to smb_errno
+
 2001-06-12 Urban Widmark <urban@teststation.com>
 
 	* proc.c: replace the win95-flush fix with smb_seek, when needed.
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/Makefile linux/fs/smbfs/Makefile
--- v2.4.10/linux/fs/smbfs/Makefile	Fri Feb 16 16:04:24 2001
+++ linux/fs/smbfs/Makefile	Tue Oct  2 17:03:34 2001
@@ -23,3 +23,19 @@
 #EXTRA_CFLAGS += -Werror
 
 include $(TOPDIR)/Rules.make
+
+#
+# Maintainer rules
+#
+
+# getopt.c not included. It is intentionally separate
+SRC = proc.c dir.c cache.c sock.c inode.c file.c ioctl.c
+
+proto:
+	-rm -f proto.h
+	@echo >  proto2.h "/*"
+	@echo >> proto2.h " *  Autogenerated with cproto on: " `date`
+	@echo >> proto2.h " */"
+	@echo >> proto2.h ""
+	cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
+	mv proto2.h proto.h
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/cache.c linux/fs/smbfs/cache.c
--- v2.4.10/linux/fs/smbfs/cache.c	Fri Mar 23 11:50:52 2001
+++ linux/fs/smbfs/cache.c	Tue Oct  2 17:03:34 2001
@@ -20,6 +20,7 @@
 #include <asm/page.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 /*
  * Force the next attempt to use the cache to be a timeout.
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/dir.c linux/fs/smbfs/dir.c
--- v2.4.10/linux/fs/smbfs/dir.c	Tue May 15 13:40:55 2001
+++ linux/fs/smbfs/dir.c	Tue Oct  2 17:03:34 2001
@@ -18,6 +18,7 @@
 #include <linux/smbno.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 static int smb_readdir(struct file *, void *, filldir_t);
 static int smb_dir_open(struct inode *, struct file *);
@@ -452,8 +453,7 @@
 	if (!inode)
 		goto out_no_inode;
 
-	if (have_id)
-	{
+	if (have_id) {
 		inode->u.smbfs_i.fileid = fileid;
 		inode->u.smbfs_i.access = SMB_O_RDWR;
 		inode->u.smbfs_i.open = server->generation;
@@ -465,8 +465,7 @@
 out_no_inode:
 	error = -EACCES;
 out_close:
-	if (have_id)
-	{
+	if (have_id) {
 		PARANOIA("%s/%s failed, error=%d, closing %u\n",
 			 DENTRY_PATH(dentry), error, fileid);
 		smb_close_fileid(dentry, fileid);
@@ -562,12 +561,10 @@
 	 */
 	if (old_dentry->d_inode)
 		smb_close(old_dentry->d_inode);
-	if (new_dentry->d_inode)
-	{
+	if (new_dentry->d_inode) {
 		smb_close(new_dentry->d_inode);
 		error = smb_proc_unlink(new_dentry);
-		if (error)
-		{
+		if (error) {
 			VERBOSE("unlink %s/%s, error=%d\n",
 				DENTRY_PATH(new_dentry), error);
 			goto out;
@@ -579,8 +576,7 @@
 	smb_invalid_dir_cache(old_dir);
 	smb_invalid_dir_cache(new_dir);
 	error = smb_proc_mv(old_dentry, new_dentry);
-	if (!error)
-	{
+	if (!error) {
 		smb_renew_times(old_dentry);
 		smb_renew_times(new_dentry);
 	}
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/file.c linux/fs/smbfs/file.c
--- v2.4.10/linux/fs/smbfs/file.c	Mon Aug 27 12:41:46 2001
+++ linux/fs/smbfs/file.c	Tue Oct  2 17:03:34 2001
@@ -24,6 +24,7 @@
 #include <linux/smb_fs.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 static int
 smb_fsync(struct file *file, struct dentry * dentry, int datasync)
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- v2.4.10/linux/fs/smbfs/inode.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/smbfs/inode.c	Tue Oct  2 17:03:34 2001
@@ -32,6 +32,7 @@
 
 #include "smb_debug.h"
 #include "getopt.h"
+#include "proto.h"
 
 /* Always pick a default string */
 #ifdef CONFIG_SMB_NLS_REMOTE
@@ -259,7 +260,7 @@
 }
 
 /* FIXME: flags and has_arg could probably be merged. */
-struct option opts[] = {
+static struct option opts[] = {
 	{ "version",	1, 0, 'v' },
 	{ "win95",	0, SMB_MOUNT_WIN95, 1 },
 	{ "oldattr",	0, SMB_MOUNT_OLDATTR, 1 },
@@ -344,7 +345,6 @@
 	struct smb_sb_info *server = &(sb->u.smbfs_sb);
 
 	if (server->sock_file) {
-		smb_proc_disconnect(server);
 		smb_dont_catch_keepalive(server);
 		fput(server->sock_file);
 	}
@@ -353,23 +353,24 @@
 	       kill_proc(server->conn_pid, SIGTERM, 1);
 
 	smb_kfree(server->mnt);
-	smb_kfree(sb->u.smbfs_sb.temp_buf);
+	smb_kfree(server->temp_buf);
 	if (server->packet)
 		smb_vfree(server->packet);
 
-	if(sb->u.smbfs_sb.remote_nls) {
-		unload_nls(sb->u.smbfs_sb.remote_nls);
-		sb->u.smbfs_sb.remote_nls = NULL;
-	}
-	if(sb->u.smbfs_sb.local_nls) {
-		unload_nls(sb->u.smbfs_sb.local_nls);
-		sb->u.smbfs_sb.local_nls = NULL;
+	if (server->remote_nls) {
+		unload_nls(server->remote_nls);
+		server->remote_nls = NULL;
+	}
+	if (server->local_nls) {
+		unload_nls(server->local_nls);
+		server->local_nls = NULL;
 	}
 }
 
 struct super_block *
 smb_read_super(struct super_block *sb, void *raw_data, int silent)
 {
+	struct smb_sb_info *server = &sb->u.smbfs_sb;
 	struct smb_mount_data_kernel *mnt;
 	struct smb_mount_data *oldmnt;
 	struct inode *root_inode;
@@ -389,34 +390,34 @@
 	sb->s_magic = SMB_SUPER_MAGIC;
 	sb->s_op = &smb_sops;
 
-	sb->u.smbfs_sb.mnt = NULL;
-	sb->u.smbfs_sb.sock_file = NULL;
-	init_MUTEX(&sb->u.smbfs_sb.sem);
-	init_waitqueue_head(&sb->u.smbfs_sb.wait);
-	sb->u.smbfs_sb.conn_pid = 0;
-	sb->u.smbfs_sb.state = CONN_INVALID; /* no connection yet */
-	sb->u.smbfs_sb.generation = 0;
-	sb->u.smbfs_sb.packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE);
-	sb->u.smbfs_sb.packet = smb_vmalloc(sb->u.smbfs_sb.packet_size);
-	if (!sb->u.smbfs_sb.packet)
+	server->mnt = NULL;
+	server->sock_file = NULL;
+	init_MUTEX(&server->sem);
+	init_waitqueue_head(&server->wait);
+	server->conn_pid = 0;
+	server->state = CONN_INVALID; /* no connection yet */
+	server->generation = 0;
+	server->packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE);
+	server->packet = smb_vmalloc(server->packet_size);
+	if (!server->packet)
 		goto out_no_mem;
 
 	/* Allocate the global temp buffer */
-	sb->u.smbfs_sb.temp_buf = smb_kmalloc(2*SMB_MAXPATHLEN+20, GFP_KERNEL);
-	if (!sb->u.smbfs_sb.temp_buf)
+	server->temp_buf = smb_kmalloc(2*SMB_MAXPATHLEN+20, GFP_KERNEL);
+	if (!server->temp_buf)
 		goto out_no_temp;
 
 	/* Setup NLS stuff */
-	sb->u.smbfs_sb.remote_nls = NULL;
-	sb->u.smbfs_sb.local_nls = NULL;
-	sb->u.smbfs_sb.name_buf = sb->u.smbfs_sb.temp_buf + SMB_MAXPATHLEN + 20;
+	server->remote_nls = NULL;
+	server->local_nls = NULL;
+	server->name_buf = server->temp_buf + SMB_MAXPATHLEN + 20;
 
 	/* Allocate the mount data structure */
 	/* FIXME: merge this with the other malloc and get a whole page? */
 	mnt = smb_kmalloc(sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
 	if (!mnt)
 		goto out_no_mount;
-	sb->u.smbfs_sb.mnt = mnt;
+	server->mnt = mnt;
 
 	memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
 	strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
@@ -447,9 +448,7 @@
 
 		mnt->mounted_uid = current->uid;
 	}
-	smb_setcodepage(&sb->u.smbfs_sb, &mnt->codepage);
-	if (!sb->u.smbfs_sb.convert)
-		PARANOIA("convert funcptr was NULL!\n");
+	smb_setcodepage(server, &mnt->codepage);
 
 	/*
 	 * Display the enabled options
@@ -463,7 +462,7 @@
 	/*
 	 * Keep the super block locked while we get the root inode.
 	 */
-	smb_init_root_dirent(&(sb->u.smbfs_sb), &root);
+	smb_init_root_dirent(server, &root);
 	root_inode = smb_iget(sb, &root);
 	if (!root_inode)
 		goto out_no_root;
@@ -478,13 +477,13 @@
 out_no_root:
 	iput(root_inode);
 out_bad_option:
-	smb_kfree(sb->u.smbfs_sb.mnt);
+	smb_kfree(server->mnt);
 out_no_mount:
-	smb_kfree(sb->u.smbfs_sb.temp_buf);
+	smb_kfree(server->temp_buf);
 out_no_temp:
-	smb_vfree(sb->u.smbfs_sb.packet);
+	smb_vfree(server->packet);
 out_no_mem:
-	if (!sb->u.smbfs_sb.mnt)
+	if (!server->mnt)
 		printk(KERN_ERR "smb_read_super: allocation failure\n");
 	goto out_fail;
 out_wrong_data:
@@ -499,11 +498,11 @@
 static int
 smb_statfs(struct super_block *sb, struct statfs *buf)
 {
-	smb_proc_dskattr(sb, buf);
+	int result = smb_proc_dskattr(sb, buf);
 
 	buf->f_type = SMB_SUPER_MAGIC;
 	buf->f_namelen = SMB_MAXPATHLEN;
-	return 0;
+	return result;
 }
 
 int
@@ -532,8 +531,7 @@
 	if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask))
 		goto out;
 
-	if ((attr->ia_valid & ATTR_SIZE) != 0)
-	{
+	if ((attr->ia_valid & ATTR_SIZE) != 0) {
 		VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
 			DENTRY_PATH(dentry),
 			(long) inode->i_size, (long) attr->ia_size);
@@ -558,20 +556,17 @@
 	smb_get_inode_attr(inode, &fattr);
 
 	changed = 0;
-	if ((attr->ia_valid & ATTR_MTIME) != 0)
-	{
+	if ((attr->ia_valid & ATTR_MTIME) != 0) {
 		fattr.f_mtime = attr->ia_mtime;
 		changed = 1;
 	}
-	if ((attr->ia_valid & ATTR_ATIME) != 0)
-	{
+	if ((attr->ia_valid & ATTR_ATIME) != 0) {
 		fattr.f_atime = attr->ia_atime;
 		/* Earlier protocols don't have an access time */
 		if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
 			changed = 1;
 	}
-	if (changed)
-	{
+	if (changed) {
 		error = smb_proc_settime(dentry, &fattr);
 		if (error)
 			goto out;
@@ -582,27 +577,22 @@
 	 * Check for mode changes ... we're extremely limited in
 	 * what can be set for SMB servers: just the read-only bit.
 	 */
-	if ((attr->ia_valid & ATTR_MODE) != 0)
-	{
+	if ((attr->ia_valid & ATTR_MODE) != 0) {
 		VERBOSE("%s/%s mode change, old=%x, new=%x\n",
 			DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode);
 		changed = 0;
-		if (attr->ia_mode & S_IWUSR)
-		{
-			if (fattr.attr & aRONLY)
-			{
+		if (attr->ia_mode & S_IWUSR) {
+			if (fattr.attr & aRONLY) {
 				fattr.attr &= ~aRONLY;
 				changed = 1;
 			}
 		} else {
-			if (!(fattr.attr & aRONLY))
-			{
+			if (!(fattr.attr & aRONLY)) {
 				fattr.attr |= aRONLY;
 				changed = 1;
 			}
 		}
-		if (changed)
-		{
+		if (changed) {
 			error = smb_proc_setattr(dentry, &fattr);
 			if (error)
 				goto out;
@@ -653,3 +643,4 @@
 
 module_init(init_smb_fs)
 module_exit(exit_smb_fs)
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/ioctl.c linux/fs/smbfs/ioctl.c
--- v2.4.10/linux/fs/smbfs/ioctl.c	Tue May 15 13:40:55 2001
+++ linux/fs/smbfs/ioctl.c	Tue Oct  2 17:03:34 2001
@@ -19,6 +19,8 @@
 
 #include <asm/uaccess.h>
 
+#include "proto.h"
+
 int
 smb_ioctl(struct inode *inode, struct file *filp,
 	  unsigned int cmd, unsigned long arg)
@@ -37,9 +39,11 @@
 		break;
 
 	case SMB_IOC_NEWCONN:
-		/* require an argument == smb_conn_opt, else it is EINVAL */
-		if (!arg)
+		/* arg is smb_conn_opt, or NULL if no connection was made */
+		if (!arg) {
+			result = smb_wakeup(server);
 			break;
+		}
 
 		result = -EFAULT;
 		if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- v2.4.10/linux/fs/smbfs/proc.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/smbfs/proc.c	Sun Oct  7 16:47:43 2001
@@ -23,16 +23,18 @@
 #include <linux/smb_mount.h>
 
 #include <asm/string.h>
+#include <asm/div64.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 
 /* Features. Undefine if they cause problems, this should perhaps be a
    config option. */
 #define SMBFS_POSIX_UNLINK 1
 
-/* Allow smb_retry to be interrupted. Not sure of the benefit ... */
-/* #define SMB_RETRY_INTR */
+/* Allow smb_retry to be interrupted. */
+#define SMB_RETRY_INTR
 
 #define SMB_VWV(packet)  ((packet) + SMB_HEADER_LEN)
 #define SMB_CMD(packet)  (*(packet+8))
@@ -43,6 +45,9 @@
 #define SMB_DIRINFO_SIZE 43
 #define SMB_STATUS_SIZE  21
 
+#define SMB_ST_BLKSIZE	(PAGE_SIZE)
+#define SMB_ST_BLKSHIFT	(PAGE_SHIFT)
+
 static int
 smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
 		     struct smb_fattr *);
@@ -137,8 +142,7 @@
 	return len;
 }
 
-static int setcodepage(struct smb_sb_info *server,
-		       struct nls_table **p, char *name)
+static int setcodepage(struct nls_table **p, char *name)
 {
 	struct nls_table *nls;
 
@@ -160,16 +164,20 @@
 /* Handles all changes to codepage settings. */
 int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp)
 {
-	int n;
+	int n = 0;
 
 	smb_lock_server(server);
 
-	n = setcodepage(server, &server->local_nls, cp->local_name);
+	/* Don't load any nls_* at all, if no remote is requested */
+	if (!*cp->remote_name)
+		goto out;
+
+	n = setcodepage(&server->local_nls, cp->local_name);
 	if (n != 0)
 		goto out;
-	n = setcodepage(server, &server->remote_nls, cp->remote_name);
+	n = setcodepage(&server->remote_nls, cp->remote_name);
 	if (n != 0)
-		setcodepage(server, &server->local_nls, NULL);
+		setcodepage(&server->local_nls, NULL);
 
 out:
 	if (server->local_nls != NULL && server->remote_nls != NULL)
@@ -188,7 +196,7 @@
 /*                                                                           */
 /*****************************************************************************/
 
-__u8 *
+static __u8 *
 smb_encode_smb_length(__u8 * p, __u32 len)
 {
 	*p = 0;
@@ -308,7 +316,9 @@
 	int month, year;
 	time_t secs;
 
-	month = ((date >> 5) & 15) - 1;
+	/* first subtract and mask after that... Otherwise, if
+	   date == 0, bad things happen */
+	month = ((date >> 5) - 1) & 15;
 	year = date >> 9;
 	secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
 	    ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
@@ -327,6 +337,9 @@
 	int day, year, nl_day, month;
 
 	unix_date = utc2local(server, unix_date);
+	if (unix_date < 315532800)
+		unix_date = 315532800;
+
 	*time = (unix_date % 60) / 2 +
 		(((unix_date / 60) % 60) << 5) +
 		(((unix_date / 3600) % 24) << 11);
@@ -350,57 +363,20 @@
 
 /* The following are taken from fs/ntfs/util.c */
 
+#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
+
 /*
  * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
  * into Unix UTC (based 1970-01-01, in seconds).
- *
- * This is very gross because
- * 1: We must do 64-bit division on a 32-bit machine
- * 2: We can't use libgcc for long long operations in the kernel
- * 3: Floating point math in the kernel would corrupt user data
  */
 static time_t
-smb_ntutc2unixutc(struct smb_sb_info *server, u64 ntutc)
+smb_ntutc2unixutc(u64 ntutc)
 {
-	const unsigned int D = 10000000;
-	unsigned int H = (unsigned int)(ntutc >> 32);
-	unsigned int L = (unsigned int)ntutc;
-	unsigned int numerator2;
-	unsigned int lowseconds;
-	unsigned int result;
-
-	/*
-	 * It is best to subtract 0x019db1ded53e8000 first.
-	 * Then the 1601-based date becomes a 1970-based date.
-	 */
-	if (L < (unsigned)0xd53e8000) H--;
-	L -= (unsigned)0xd53e8000;
-	H -= (unsigned)0x019db1de;
-
-	/*
-	 * Now divide 64-bit numbers on a 32-bit machine :-)
-	 * With the subtraction already done, the result fits in 32 bits.
-	 * The numerator fits in 56 bits and the denominator fits
-	 * in 24 bits, so we can shift by 8 bits to make this work.
-	 */
-
-	numerator2  = (H<<8) | (L>>24);
-	result      = (numerator2 / D);   /* shifted 24 right!! */
-	lowseconds  = result << 24;
-
-	numerator2  = ((numerator2-result*D)<<8) | ((L>>16)&0xff);
-	result      = (numerator2 / D);   /* shifted 16 right!! */
-	lowseconds |= result << 16;
-
-	numerator2  = ((numerator2-result*D)<<8) | ((L>>8)&0xff);
-	result      = (numerator2 / D);   /* shifted 8 right!! */
-	lowseconds |= result << 8;
-
-	numerator2  = ((numerator2-result*D)<<8) | (L&0xff);
-	result      = (numerator2 / D);   /* not shifted */
-	lowseconds |= result;
-
-	return lowseconds;
+	/* FIXME: what about the timezone difference? */
+	/* Subtract the NTFS time offset, then convert to 1s intervals. */
+	u64 t = ntutc - NTFS_TIME_OFFSET;
+	do_div(t, 10000000);
+	return (time_t)t;
 }
 
 #if 0
@@ -409,7 +385,7 @@
 smb_unixutc2ntutc(struct smb_sb_info *server, time_t t)
 {
 	/* Note: timezone conversion is probably wrong. */
-	return ((utc2local(server, t) + (u64)(369*365+89)*24*3600) * 10000000);
+	return ((u64)utc2local(server, t)) * 10000000 + NTFS_TIME_OFFSET;
 }
 #endif
 
@@ -519,6 +495,9 @@
 	return size;
 }
 
+/*
+ * Convert SMB error codes to -E... errno values.
+ */
 int
 smb_errno(struct smb_sb_info *server)
 {
@@ -529,110 +508,117 @@
 	VERBOSE("errcls %d  code %d  from command 0x%x\n",
 		errcls, error, SMB_CMD(server->packet));
 
-	if (errcls == ERRDOS)
-		switch (error)
-		{
+	if (errcls == ERRDOS) {
+		switch (error) {
 		case ERRbadfunc:
-			return EINVAL;
+			return -EINVAL;
 		case ERRbadfile:
 		case ERRbadpath:
-			return ENOENT;
+			return -ENOENT;
 		case ERRnofids:
-			return EMFILE;
+			return -EMFILE;
 		case ERRnoaccess:
-			return EACCES;
+			return -EACCES;
 		case ERRbadfid:
-			return EBADF;
+			return -EBADF;
 		case ERRbadmcb:
-			return EREMOTEIO;
+			return -EREMOTEIO;
 		case ERRnomem:
-			return ENOMEM;
+			return -ENOMEM;
 		case ERRbadmem:
-			return EFAULT;
+			return -EFAULT;
 		case ERRbadenv:
 		case ERRbadformat:
-			return EREMOTEIO;
+			return -EREMOTEIO;
 		case ERRbadaccess:
-			return EACCES;
+			return -EACCES;
 		case ERRbaddata:
-			return E2BIG;
+			return -E2BIG;
 		case ERRbaddrive:
-			return ENXIO;
+			return -ENXIO;
 		case ERRremcd:
-			return EREMOTEIO;
+			return -EREMOTEIO;
 		case ERRdiffdevice:
-			return EXDEV;
-		case ERRnofiles:	/* Why is this mapped to 0?? */
-			return 0;
+			return -EXDEV;
+		case ERRnofiles:
+			return -ENOENT;
 		case ERRbadshare:
-			return ETXTBSY;
+			return -ETXTBSY;
 		case ERRlock:
-			return EDEADLK;
+			return -EDEADLK;
 		case ERRfilexists:
-			return EEXIST;
-		case 87:		/* should this map to 0?? */
-			return 0;	/* Unknown error!! */
-		case 123:		/* Invalid name?? e.g. .tmp* */
-			return ENOENT;
-		case 145:		/* Win NT 4.0: non-empty directory? */
-			return ENOTEMPTY;
-			/* This next error seems to occur on an mv when
-			 * the destination exists */
-		case 183:
-			return EEXIST;
+			return -EEXIST;
+		case ERROR_INVALID_PARAMETER:
+			return -EINVAL;
+		case ERROR_DISK_FULL:
+			return -ENOSPC;
+		case ERROR_INVALID_NAME:
+			return -ENOENT;
+		case ERROR_DIR_NOT_EMPTY:
+			return -ENOTEMPTY;
+		case ERROR_NOT_LOCKED:
+                       return -ENOLCK;
+		case ERROR_ALREADY_EXISTS:
+			return -EEXIST;
 		default:
 			class = "ERRDOS";
 			goto err_unknown;
-	} else if (errcls == ERRSRV)
-		switch (error)
-		{
+		}
+	} else if (errcls == ERRSRV) {
+		switch (error) {
 		/* N.B. This is wrong ... EIO ? */
 		case ERRerror:
-			return ENFILE;
+			return -ENFILE;
 		case ERRbadpw:
-			return EINVAL;
+			return -EINVAL;
 		case ERRbadtype:
-			return EIO;
+			return -EIO;
 		case ERRaccess:
-			return EACCES;
+			return -EACCES;
 		/*
 		 * This is a fatal error, as it means the "tree ID"
 		 * for this connection is no longer valid. We map
 		 * to a special error code and get a new connection.
 		 */
 		case ERRinvnid:
-			return EBADSLT;
+			return -EBADSLT;
 		default:
 			class = "ERRSRV";
 			goto err_unknown;
-	} else if (errcls == ERRHRD)
-		switch (error)
-		{
+		}
+	} else if (errcls == ERRHRD) {
+		switch (error) {
 		case ERRnowrite:
-			return EROFS;
+			return -EROFS;
 		case ERRbadunit:
-			return ENODEV;
+			return -ENODEV;
 		case ERRnotready:
-			return EUCLEAN;
+			return -EUCLEAN;
 		case ERRbadcmd:
 		case ERRdata:
-			return EIO;
+			return -EIO;
 		case ERRbadreq:
-			return ERANGE;
+			return -ERANGE;
 		case ERRbadshare:
-			return ETXTBSY;
+			return -ETXTBSY;
 		case ERRlock:
-			return EDEADLK;
+			return -EDEADLK;
+		case ERRdiskfull:
+			return -ENOSPC;
 		default:
 			class = "ERRHRD";
 			goto err_unknown;
-	} else if (errcls == ERRCMD)
+		}
+	} else if (errcls == ERRCMD) {
 		class = "ERRCMD";
+	} else if (errcls == SUCCESS) {
+		return 0;	/* This is the only valid 0 return */
+	}
 
 err_unknown:
 	printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
 	       class, error, SMB_CMD(server->packet));
-	return EIO;
+	return -EIO;
 }
 
 /*
@@ -749,12 +735,10 @@
 	}
 
 	/*
-	 * Check for server errors.  The current smb_errno() routine
-	 * is squashing some error codes, but I don't think this is
-	 * correct: after a server error the packet won't be valid.
+	 * Check for server errors.
 	 */
 	if (s->rcls != 0) {
-		result = -smb_errno(s);
+		result = smb_errno(s);
 		if (!result)
 			printk(KERN_DEBUG "smb_request_ok: rcls=%d, err=%d mapped to 0\n",
 				s->rcls, s->err);
@@ -850,17 +834,23 @@
 
 out:
 	smb_unlock_server(server);
+	smb_wakeup(server);
+	return error;
+
+out_putf:
+	fput(filp);
+	goto out;
+}
 
+int
+smb_wakeup(struct smb_sb_info *server)
+{
 #ifdef SMB_RETRY_INTR
 	wake_up_interruptible(&server->wait);
 #else
 	wake_up(&server->wait);
 #endif
-	return error;
-
-out_putf:
-	fput(filp);
-	goto out;
+	return 0;
 }
 
 /* smb_setup_header: We completely set up the packet. You only have to
@@ -1490,7 +1480,7 @@
 	fattr->f_nlink = 1;
 	fattr->f_uid = server->mnt->uid;
 	fattr->f_gid = server->mnt->gid;
-	fattr->f_blksize = 512;
+	fattr->f_blksize = SMB_ST_BLKSIZE;
 }
 
 static void
@@ -1500,18 +1490,16 @@
 	if (fattr->attr & aDIR)
 	{
 		fattr->f_mode = server->mnt->dir_mode;
-		fattr->f_size = 512;
+		fattr->f_size = SMB_ST_BLKSIZE;
 	}
 	/* Check the read-only flag */
 	if (fattr->attr & aRONLY)
 		fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
 
+	/* How many 512 byte blocks do we need for this file? */
 	fattr->f_blocks = 0;
-	if ((fattr->f_blksize != 0) && (fattr->f_size != 0))
-	{
-		fattr->f_blocks =
-		    (fattr->f_size - 1) / fattr->f_blksize + 1;
-	}
+	if (fattr->f_size != 0)
+		fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9);
 	return;
 }
 
@@ -1770,9 +1758,9 @@
 		if (len && qname->name[len-1] == '\0')
 			len--;
 
-		fattr->f_ctime = smb_ntutc2unixutc(server, LVAL(p, 8));
-		fattr->f_atime = smb_ntutc2unixutc(server, LVAL(p, 16));
-		fattr->f_mtime = smb_ntutc2unixutc(server, LVAL(p, 24));
+		fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8));
+		fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16));
+		fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24));
 		/* change time (32) */
 		fattr->f_size = DVAL(p, 40);
 		/* alloc size (48) */
@@ -1940,7 +1928,7 @@
                 }
 
 		if (server->rcls != 0) {
-			result = -smb_errno(server);
+			result = smb_errno(server);
 			PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",
 				 mask, result, server->rcls, server->err);
 			break;
@@ -2104,7 +2092,7 @@
 	}
 	if (server->rcls != 0)
 	{ 
-		result = -smb_errno(server);
+		result = smb_errno(server);
 #ifdef SMBFS_PARANOIA
 		if (result != -ENOENT)
 			PARANOIA("error for %s, rcls=%d, err=%d\n",
@@ -2227,7 +2215,7 @@
 	{
 		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
 			&param[6], result, server->rcls, server->err);
-		result = -smb_errno(server);
+		result = smb_errno(server);
 		goto out;
 	}
 	result = -ENOENT;
@@ -2490,7 +2478,7 @@
 	}
 	result = 0;
 	if (server->rcls != 0)
-		result = -smb_errno(server);
+		result = smb_errno(server);
 
 out:
 	return result;
@@ -2559,6 +2547,7 @@
 	struct smb_sb_info *server = &(sb->u.smbfs_sb);
 	int result;
 	char *p;
+	long unit;
 
 	smb_lock_server(server);
 
@@ -2571,23 +2560,13 @@
 		goto out;
 	}
 	p = SMB_VWV(server->packet);
-	attr->f_blocks = WVAL(p, 0);
-	attr->f_bsize  = WVAL(p, 2) * WVAL(p, 4);
-	attr->f_bavail = attr->f_bfree = WVAL(p, 6);
+	unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT;
+	attr->f_blocks = WVAL(p, 0) * unit;
+	attr->f_bsize  = SMB_ST_BLKSIZE;
+	attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit;
 	result = 0;
 
 out:
-	smb_unlock_server(server);
-	return result;
-}
-
-int
-smb_proc_disconnect(struct smb_sb_info *server)
-{
-	int result;
-	smb_lock_server(server);
-	smb_setup_header(server, SMBtdis, 0, 0);
-	result = smb_request_ok(server, SMBtdis, 0, 0);
 	smb_unlock_server(server);
 	return result;
 }
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/proto.h linux/fs/smbfs/proto.h
--- v2.4.10/linux/fs/smbfs/proto.h	Wed Dec 31 16:00:00 1969
+++ linux/fs/smbfs/proto.h	Tue Oct  2 17:03:34 2001
@@ -0,0 +1,63 @@
+/*
+ *  Autogenerated with cproto on:  Tue Oct 2 20:40:54 CEST 2001
+ */
+
+/* proc.c */
+extern int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp);
+extern __u32 smb_len(__u8 *p);
+extern int smb_get_rsize(struct smb_sb_info *server);
+extern int smb_get_wsize(struct smb_sb_info *server);
+extern int smb_errno(struct smb_sb_info *server);
+extern int smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt);
+extern int smb_wakeup(struct smb_sb_info *server);
+extern __u8 *smb_setup_header(struct smb_sb_info *server, __u8 command, __u16 wct, __u16 bcc);
+extern int smb_open(struct dentry *dentry, int wish);
+extern int smb_close(struct inode *ino);
+extern int smb_close_fileid(struct dentry *dentry, __u16 fileid);
+extern int smb_proc_read(struct inode *inode, off_t offset, int count, char *data);
+extern int smb_proc_write(struct inode *inode, off_t offset, int count, const char *data);
+extern int smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid);
+extern int smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry);
+extern int smb_proc_mkdir(struct dentry *dentry);
+extern int smb_proc_rmdir(struct dentry *dentry);
+extern int smb_proc_unlink(struct dentry *dentry);
+extern int smb_proc_flush(struct smb_sb_info *server, __u16 fileid);
+extern int smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length);
+extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
+extern int smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir, struct smb_cache_control *ctl);
+extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
+extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
+extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr);
+extern int smb_proc_dskattr(struct super_block *sb, struct statfs *attr);
+/* dir.c */
+extern struct file_operations smb_dir_operations;
+extern struct inode_operations smb_dir_inode_operations;
+extern void smb_new_dentry(struct dentry *dentry);
+extern void smb_renew_times(struct dentry *dentry);
+/* cache.c */
+extern void smb_invalid_dir_cache(struct inode *dir);
+extern void smb_invalidate_dircache_entries(struct dentry *parent);
+extern struct dentry *smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos);
+extern int smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, struct smb_cache_control *ctrl, struct qstr *qname, struct smb_fattr *entry);
+/* sock.c */
+extern int smb_valid_socket(struct inode *inode);
+extern int smb_catch_keepalive(struct smb_sb_info *server);
+extern int smb_dont_catch_keepalive(struct smb_sb_info *server);
+extern void smb_close_socket(struct smb_sb_info *server);
+extern int smb_round_length(int len);
+extern int smb_request(struct smb_sb_info *server);
+extern int smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, int ldata, unsigned char *data, int lparam, unsigned char *param, int *lrdata, unsigned char **rdata, int *lrparam, unsigned char **rparam);
+/* inode.c */
+extern struct inode *smb_iget(struct super_block *sb, struct smb_fattr *fattr);
+extern void smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr);
+extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr);
+extern void smb_invalidate_inodes(struct smb_sb_info *server);
+extern int smb_revalidate_inode(struct dentry *dentry);
+extern struct super_block *smb_read_super(struct super_block *sb, void *raw_data, int silent);
+extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
+/* file.c */
+extern struct address_space_operations smb_file_aops;
+extern struct file_operations smb_file_operations;
+extern struct inode_operations smb_file_inode_operations;
+/* ioctl.c */
+extern int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
diff -u --recursive --new-file v2.4.10/linux/fs/smbfs/sock.c linux/fs/smbfs/sock.c
--- v2.4.10/linux/fs/smbfs/sock.c	Tue May 15 13:40:55 2001
+++ linux/fs/smbfs/sock.c	Tue Oct  2 17:03:34 2001
@@ -27,6 +27,7 @@
 #include <asm/uaccess.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 
 static int
@@ -674,7 +675,7 @@
 	 */
 	if (server->rcls) {
 		int error = smb_errno(server);
-		if (error == EBADSLT) {
+		if (error == -EBADSLT) {
 			printk(KERN_ERR "smb_request: tree ID invalid\n");
 			result = error;
 			goto bad_conn;
@@ -866,7 +867,7 @@
 	 */
 	if (server->rcls) {
 		int error = smb_errno(server);
-		if (error == EBADSLT) {
+		if (error == -EBADSLT) {
 			printk(KERN_ERR "smb_request: tree ID invalid\n");
 			result = error;
 			goto bad_conn;
diff -u --recursive --new-file v2.4.10/linux/fs/super.c linux/fs/super.c
--- v2.4.10/linux/fs/super.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/super.c	Fri Oct  5 13:05:55 2001
@@ -42,19 +42,11 @@
 #define __NO_VERSION__
 #include <linux/module.h>
 
-/*
- * We use a semaphore to synchronize all mount/umount
- * activity - imagine the mess if we have a race between
- * unmounting a filesystem and re-mounting it (or something
- * else).
- */
-static DECLARE_MUTEX(mount_sem);
-
 extern void wait_for_keypress(void);
 
 extern int root_mountflags;
 
-static int do_remount_sb(struct super_block *sb, int flags, char * data);
+int do_remount_sb(struct super_block *sb, int flags, void * data);
 
 /* this is initialized in init/main.c */
 kdev_t ROOT_DEV;
@@ -279,371 +271,13 @@
 	return fs;
 }
 
-static LIST_HEAD(vfsmntlist);
-
-static struct list_head *mount_hashtable;
-static int hash_mask, hash_bits;
-static kmem_cache_t *mnt_cache; 
-
-static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
-{
-	unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
-	tmp += ((unsigned long) dentry / L1_CACHE_BYTES);
-	tmp = tmp + (tmp >> hash_bits);
-	return tmp & hash_mask;
-}
-
-struct vfsmount *alloc_vfsmnt(void)
-{
-	struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL); 
-	if (mnt) {
-		memset(mnt, 0, sizeof(struct vfsmount));
-		atomic_set(&mnt->mnt_count,1);
-		INIT_LIST_HEAD(&mnt->mnt_hash);
-		INIT_LIST_HEAD(&mnt->mnt_child);
-		INIT_LIST_HEAD(&mnt->mnt_mounts);
-		INIT_LIST_HEAD(&mnt->mnt_list);
-		mnt->mnt_owner = current->uid;
-	}
-	return mnt;
-}
-
-struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
-{
-	struct list_head * head = mount_hashtable + hash(mnt, dentry);
-	struct list_head * tmp = head;
-	struct vfsmount *p;
-
-	for (;;) {
-		tmp = tmp->next;
-		p = NULL;
-		if (tmp == head)
-			break;
-		p = list_entry(tmp, struct vfsmount, mnt_hash);
-		if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry)
-			break;
-	}
-	return p;
-}
-
-static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
-{
-	old_nd->dentry = mnt->mnt_mountpoint;
-	old_nd->mnt = mnt->mnt_parent;
-	mnt->mnt_parent = mnt;
-	mnt->mnt_mountpoint = mnt->mnt_root;
-	list_del_init(&mnt->mnt_child);
-	list_del_init(&mnt->mnt_hash);
-	old_nd->dentry->d_mounted--;
-}
-
-static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
-{
-	mnt->mnt_parent = mntget(nd->mnt);
-	mnt->mnt_mountpoint = dget(nd->dentry);
-	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
-	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
-	nd->dentry->d_mounted++;
-}
-
-/**
- *	add_vfsmnt - add a new mount node
- *	@nd: location of mountpoint or %NULL if we want a root node
- *	@root: root of (sub)tree to be mounted
- *	@dev_name: device name to show in /proc/mounts or %NULL (for "none").
- *
- *	This is VFS idea of mount. New node is allocated, bound to a tree
- *	we are mounting and optionally (OK, usually) registered as mounted
- *	on a given mountpoint. Returns a pointer to new node or %NULL in
- *	case of failure.
- *
- *	Potential reason for failure (aside of trivial lack of memory) is a
- *	deleted mountpoint. Caller must hold ->i_zombie on mountpoint
- *	dentry (if any).
- */
-
-static struct vfsmount *add_vfsmnt(struct dentry *root, const char *dev_name)
-{
-	struct vfsmount *mnt;
-	struct super_block *sb = root->d_inode->i_sb;
-	char *name;
-
-	mnt = alloc_vfsmnt();
-	if (!mnt)
-		goto out;
-
-	/* It may be NULL, but who cares? */
-	if (dev_name) {
-		name = kmalloc(strlen(dev_name)+1, GFP_KERNEL);
-		if (name) {
-			strcpy(name, dev_name);
-			mnt->mnt_devname = name;
-		}
-	}
-	mnt->mnt_sb = sb;
-	mnt->mnt_root = dget(root);
-	mnt->mnt_mountpoint = mnt->mnt_root;
-	mnt->mnt_parent = mnt;
-
-	spin_lock(&dcache_lock);
-	list_add(&mnt->mnt_list, vfsmntlist.prev);
-	spin_unlock(&dcache_lock);
-out:
-	return mnt;
-}
-
-static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root)
-{
-	char *name = old->mnt_devname;
-	struct vfsmount *mnt = alloc_vfsmnt();
-	struct super_block *sb = old->mnt_sb;
-
-	if (!mnt)
-		goto out;
-
-	if (name) {
-		mnt->mnt_devname = kmalloc(strlen(name)+1, GFP_KERNEL);
-		if (mnt->mnt_devname)
-			strcpy(mnt->mnt_devname, name);
-	}
-	mnt->mnt_sb = sb;
-	mnt->mnt_root = dget(root);
-	mnt->mnt_mountpoint = mnt->mnt_root;
-	mnt->mnt_parent = mnt;
-	mnt->mnt_flags = old->mnt_flags;
-
-	atomic_inc(&sb->s_active);
-out:
-	return mnt;
-}
-
-static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
-{
-	if (mnt->mnt_sb->s_flags & MS_NOUSER)
-		return -EINVAL;
-
-	if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
-	      S_ISDIR(mnt->mnt_root->d_inode->i_mode))
-		return -ENOTDIR;
-
-	down(&nd->dentry->d_inode->i_zombie);
-	if (IS_DEADDIR(nd->dentry->d_inode))
-		goto fail1;
-
-	spin_lock(&dcache_lock);
-	if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
-		goto fail;
-
-	attach_mnt(mnt, nd);
-	list_add(&mnt->mnt_list, vfsmntlist.prev);
-	spin_unlock(&dcache_lock);
-	up(&nd->dentry->d_inode->i_zombie);
-	mntget(mnt);
-	return 0;
-fail:
-	spin_unlock(&dcache_lock);
-fail1:
-	up(&nd->dentry->d_inode->i_zombie);
-	return -ENOENT;
-}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-static void move_vfsmnt(struct vfsmount *mnt,
-			struct nameidata *nd, 
-			const char *dev_name)
-{
-	struct nameidata parent_nd;
-	char *new_devname = NULL;
-
-	if (dev_name) {
-		new_devname = kmalloc(strlen(dev_name)+1, GFP_KERNEL);
-		if (new_devname)
-			strcpy(new_devname, dev_name);
-	}
-
-	spin_lock(&dcache_lock);
-	detach_mnt(mnt, &parent_nd);
-	attach_mnt(mnt, nd);
-
-	if (new_devname) {
-		if (mnt->mnt_devname)
-			kfree(mnt->mnt_devname);
-		mnt->mnt_devname = new_devname;
-	}
-	spin_unlock(&dcache_lock);
-
-	/* put the old stuff */
-	if (parent_nd.mnt != mnt)
-		path_release(&parent_nd);
-}
-#endif
-
-static void kill_super(struct super_block *);
-
-void __mntput(struct vfsmount *mnt)
-{
-	struct super_block *sb = mnt->mnt_sb;
-
-	dput(mnt->mnt_root);
-	if (mnt->mnt_devname)
-		kfree(mnt->mnt_devname);
-	kmem_cache_free(mnt_cache, mnt);
-	kill_super(sb);
-}
-
-/* Use octal escapes, like mount does, for embedded spaces etc. */
-static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
-
-static int
-mangle(const unsigned char *s, char *buf, int len) {
-        char *sp;
-        int n;
-
-        sp = buf;
-        while(*s && sp-buf < len-3) {
-                for (n = 0; n < sizeof(need_escaping); n++) {
-                        if (*s == need_escaping[n]) {
-                                *sp++ = '\\';
-                                *sp++ = '0' + ((*s & 0300) >> 6);
-                                *sp++ = '0' + ((*s & 070) >> 3);
-                                *sp++ = '0' + (*s & 07);
-                                goto next;
-                        }
-                }
-                *sp++ = *s;
-        next:
-                s++;
-        }
-        return sp - buf;	/* no trailing NUL */
-}
-
-static struct proc_fs_info {
-	int flag;
-	char *str;
-} fs_info[] = {
-	{ MS_SYNCHRONOUS, ",sync" },
-	{ MS_MANDLOCK, ",mand" },
-	{ MS_NOATIME, ",noatime" },
-	{ MS_NODIRATIME, ",nodiratime" },
-	{ 0, NULL }
-};
-
-static struct proc_fs_info mnt_info[] = {
-	{ MNT_NOSUID, ",nosuid" },
-	{ MNT_NODEV, ",nodev" },
-	{ MNT_NOEXEC, ",noexec" },
-	{ 0, NULL }
-};
-
-static struct proc_nfs_info {
-	int flag;
-	char *str;
-	char *nostr;
-} nfs_info[] = {
-	{ NFS_MOUNT_SOFT, ",soft", ",hard" },
-	{ NFS_MOUNT_INTR, ",intr", "" },
-	{ NFS_MOUNT_POSIX, ",posix", "" },
-	{ NFS_MOUNT_TCP, ",tcp", ",udp" },
-	{ NFS_MOUNT_NOCTO, ",nocto", "" },
-	{ NFS_MOUNT_NOAC, ",noac", "" },
-	{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
-	{ NFS_MOUNT_BROKEN_SUID, ",broken_suid", "" },
-	{ 0, NULL, NULL }
-};
-
-int get_filesystem_info( char *buf )
-{
-	struct list_head *p;
-	struct proc_fs_info *fs_infop;
-	struct proc_nfs_info *nfs_infop;
-	struct nfs_server *nfss;
-	int len, prevlen;
-	char *path, *buffer = (char *) __get_free_page(GFP_KERNEL);
-
-	if (!buffer) return 0;
-	len = prevlen = 0;
-
-#define FREEROOM	((int)PAGE_SIZE-200-len)
-#define MANGLE(s)	len += mangle((s), buf+len, FREEROOM);
-
-	for (p = vfsmntlist.next; p != &vfsmntlist; p = p->next) {
-		struct vfsmount *tmp = list_entry(p, struct vfsmount, mnt_list);
-		path = d_path(tmp->mnt_root, tmp, buffer, PAGE_SIZE);
-		if (!path)
-			continue;
-		MANGLE(tmp->mnt_devname ? tmp->mnt_devname : "none");
-		buf[len++] = ' ';
-		MANGLE(path);
-		buf[len++] = ' ';
-		MANGLE(tmp->mnt_sb->s_type->name);
-		len += sprintf(buf+len, " %s",
-			       tmp->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
-		for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
-			if (tmp->mnt_sb->s_flags & fs_infop->flag)
-				MANGLE(fs_infop->str);
-		}
-		for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
-			if (tmp->mnt_flags & fs_infop->flag)
-				MANGLE(fs_infop->str);
-		}
-		if (!strcmp("nfs", tmp->mnt_sb->s_type->name)) {
-			nfss = &tmp->mnt_sb->u.nfs_sb.s_server;
-			len += sprintf(buf+len, ",v%d", nfss->rpc_ops->version);
-
-			len += sprintf(buf+len, ",rsize=%d", nfss->rsize);
-
-			len += sprintf(buf+len, ",wsize=%d", nfss->wsize);
-#if 0
-			if (nfss->timeo != 7*HZ/10) {
-				len += sprintf(buf+len, ",timeo=%d",
-					       nfss->timeo*10/HZ);
-			}
-			if (nfss->retrans != 3) {
-				len += sprintf(buf+len, ",retrans=%d",
-					       nfss->retrans);
-			}
-#endif
-			if (nfss->acregmin != 3*HZ) {
-				len += sprintf(buf+len, ",acregmin=%d",
-					       nfss->acregmin/HZ);
-			}
-			if (nfss->acregmax != 60*HZ) {
-				len += sprintf(buf+len, ",acregmax=%d",
-					       nfss->acregmax/HZ);
-			}
-			if (nfss->acdirmin != 30*HZ) {
-				len += sprintf(buf+len, ",acdirmin=%d",
-					       nfss->acdirmin/HZ);
-			}
-			if (nfss->acdirmax != 60*HZ) {
-				len += sprintf(buf+len, ",acdirmax=%d",
-					       nfss->acdirmax/HZ);
-			}
-			for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
-				char *str;
-				if (nfss->flags & nfs_infop->flag)
-					str = nfs_infop->str;
-				else
-					str = nfs_infop->nostr;
-				MANGLE(str);
-			}
-			len += sprintf(buf+len, ",addr=");
-			MANGLE(nfss->hostname);
-		}
-		len += sprintf(buf + len, " 0 0\n");
-		if (FREEROOM <= 3) {
-			len = prevlen;
-			len += sprintf(buf+len, "# truncated\n");
-			break;
-		}
-		prevlen = len;
-	}
-
-	free_page((unsigned long) buffer);
-	return len;
-#undef MANGLE
-#undef FREEROOM
-}
+struct vfsmount *alloc_vfsmnt(void);
+void free_vfsmnt(struct vfsmount *mnt);
+void set_devname(struct vfsmount *mnt, const char *name);
+
+/* Will go away */
+extern struct vfsmount *root_vfsmnt;
+extern int graft_tree(struct vfsmount *mnt, struct nameidata *nd);
 
 static inline void __put_super(struct super_block *sb)
 {
@@ -759,9 +393,7 @@
         struct statfs sbuf;
 	int err = -EINVAL;
 
-	lock_kernel();
         s = get_super(to_kdev_t(dev));
-	unlock_kernel();
         if (s == NULL)
                 goto out;
 	err = vfs_statfs(s, &sbuf);
@@ -1082,7 +714,7 @@
 	}
 }
 
-static void kill_super(struct super_block *sb)
+void kill_super(struct super_block *sb)
 {
 	struct block_device *bdev;
 	kdev_t dev;
@@ -1144,7 +776,7 @@
  * is used as a reference - file system type and the device are ignored.
  */
 
-static int do_remount_sb(struct super_block *sb, int flags, char *data)
+int do_remount_sb(struct super_block *sb, int flags, void *data)
 {
 	int retval;
 	
@@ -1177,234 +809,6 @@
 	return 0;
 }
 
-/*
- * Doesn't take quota and stuff into account. IOW, in some cases it will
- * give false negatives. The main reason why it's here is that we need
- * a non-destructive way to look for easily umountable filesystems.
- */
-int may_umount(struct vfsmount *mnt)
-{
-	if (atomic_read(&mnt->mnt_count) > 2)
-		return -EBUSY;
-	return 0;
-}
-
-static int do_umount(struct vfsmount *mnt, int flags)
-{
-	struct super_block * sb = mnt->mnt_sb;
-	struct nameidata parent_nd;
-
-	/*
-	 * No sense to grab the lock for this test, but test itself looks
-	 * somewhat bogus. Suggestions for better replacement?
-	 * Ho-hum... In principle, we might treat that as umount + switch
-	 * to rootfs. GC would eventually take care of the old vfsmount.
-	 * The problem being: we have to implement rootfs and GC for that ;-)
-	 * Actually it makes sense, especially if rootfs would contain a
-	 * /reboot - static binary that would close all descriptors and
-	 * call reboot(9). Then init(8) could umount root and exec /reboot.
-	 */
-	if (mnt == current->fs->rootmnt) {
-		int retval = 0;
-		/*
-		 * Special case for "unmounting" root ...
-		 * we just try to remount it readonly.
-		 */
-		if (!(sb->s_flags & MS_RDONLY)) {
-			down_write(&sb->s_umount);
-			retval = do_remount_sb(sb, MS_RDONLY, 0);
-			up_write(&sb->s_umount);
-		}
-		return retval;
-	}
-
-	spin_lock(&dcache_lock);
-
-	if (atomic_read(&sb->s_active) > 1) {
-		if (atomic_read(&mnt->mnt_count) > 2) {
-			spin_unlock(&dcache_lock);
-			return -EBUSY;
-		}
-		detach_mnt(mnt, &parent_nd);
-		list_del(&mnt->mnt_list);
-		spin_unlock(&dcache_lock);
-		mntput(mnt);
-		if (parent_nd.mnt != mnt)
-			path_release(&parent_nd);
-		return 0;
-	}
-	spin_unlock(&dcache_lock);
-
-	/*
-	 * Before checking whether the filesystem is still busy,
-	 * make sure the kernel doesn't hold any quota files open
-	 * on the device. If the umount fails, too bad -- there
-	 * are no quotas running any more. Just turn them on again.
-	 */
-	DQUOT_OFF(sb);
-	acct_auto_close(sb->s_dev);
-
-	/*
-	 * If we may have to abort operations to get out of this
-	 * mount, and they will themselves hold resources we must
-	 * allow the fs to do things. In the Unix tradition of
-	 * 'Gee thats tricky lets do it in userspace' the umount_begin
-	 * might fail to complete on the first run through as other tasks
-	 * must return, and the like. Thats for the mount program to worry
-	 * about for the moment.
-	 */
-
-	if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
-		sb->s_op->umount_begin(sb);
-
-	/* Something might grab it again - redo checks */
-
-	spin_lock(&dcache_lock);
-	if (atomic_read(&mnt->mnt_count) > 2) {
-		spin_unlock(&dcache_lock);
-		return -EBUSY;
-	}
-
-	/* OK, that's the point of no return */
-	detach_mnt(mnt, &parent_nd);
-	list_del(&mnt->mnt_list);
-	spin_unlock(&dcache_lock);
-	mntput(mnt);
-	if (parent_nd.mnt != mnt)
-		path_release(&parent_nd);
-	return 0;
-}
-
-/*
- * Now umount can handle mount points as well as block devices.
- * This is important for filesystems which use unnamed block devices.
- *
- * We now support a flag for forced unmount like the other 'big iron'
- * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD
- */
-
-asmlinkage long sys_umount(char * name, int flags)
-{
-	struct nameidata nd;
-	char *kname;
-	int retval;
-
-	kname = getname(name);
-	retval = PTR_ERR(kname);
-	if (IS_ERR(kname))
-		goto out;
-	retval = 0;
-	if (path_init(kname, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd))
-		retval = path_walk(kname, &nd);
-	putname(kname);
-	if (retval)
-		goto out;
-	retval = -EINVAL;
-	if (nd.dentry != nd.mnt->mnt_root)
-		goto dput_and_out;
-
-	retval = -EPERM;
-	if (!capable(CAP_SYS_ADMIN) && current->uid!=nd.mnt->mnt_owner)
-		goto dput_and_out;
-
-	down(&mount_sem);
-	lock_kernel();
-	retval = do_umount(nd.mnt, flags);
-	unlock_kernel();
-	path_release(&nd);
-	up(&mount_sem);
-	goto out;
-dput_and_out:
-	path_release(&nd);
-out:
-	return retval;
-}
-
-/*
- *	The 2.0 compatible umount. No flags. 
- */
- 
-asmlinkage long sys_oldumount(char * name)
-{
-	return sys_umount(name,0);
-}
-
-static int mount_is_safe(struct nameidata *nd)
-{
-	if (capable(CAP_SYS_ADMIN))
-		return 0;
-	return -EPERM;
-#ifdef notyet
-	if (S_ISLNK(nd->dentry->d_inode->i_mode))
-		return -EPERM;
-	if (nd->dentry->d_inode->i_mode & S_ISVTX) {
-		if (current->uid != nd->dentry->d_inode->i_uid)
-			return -EPERM;
-	}
-	if (permission(nd->dentry->d_inode, MAY_WRITE))
-		return -EPERM;
-	return 0;
-#endif
-}
-
-/*
- * do loopback mount.
- */
-static int do_loopback(struct nameidata *nd, char *old_name)
-{
-	struct nameidata old_nd;
-	struct vfsmount *mnt;
-	int err;
-
-	err = mount_is_safe(nd);
-	if (err)
-		return err;
-
-	if (!old_name || !*old_name)
-		return -EINVAL;
-
-	if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
-		err = path_walk(old_name, &old_nd);
-	if (err)
-		return err;
-
-	down(&mount_sem);
-	err = -ENOMEM;
-	mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
-	if (mnt) {
-		err = graft_tree(mnt, nd);
-		mntput(mnt);
-	}
-	up(&mount_sem);
-	path_release(&old_nd);
-	return err;
-}
-
-/*
- * change filesystem flags. dir should be a physical root of filesystem.
- * If you've mounted a non-root directory somewhere and want to do remount
- * on it - tough luck.
- */
-
-static int do_remount(struct nameidata *nd,int flags,int mnt_flags,char *data)
-{
-	int err;
-	struct super_block * sb = nd->mnt->mnt_sb;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (nd->dentry != nd->mnt->mnt_root)
-		return -EINVAL;
-
-	down_write(&sb->s_umount);
-	err = do_remount_sb(sb, flags, data);
-	if (!err)
-		nd->mnt->mnt_flags=mnt_flags;
-	up_write(&sb->s_umount);
-	return err;
-}
-
 struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data)
 {
 	struct file_system_type * fstype;
@@ -1429,12 +833,7 @@
 		mnt = ERR_PTR(-ENOMEM);
 		goto fs_out;
 	}
-	if (name) {
-		mnt->mnt_devname = kmalloc(strlen(name)+1, GFP_KERNEL);
-		if (mnt->mnt_devname)
-			strcpy(mnt->mnt_devname, name);
-	}
-
+	set_devname(mnt, name);
 	/* get locked superblock */
 	if (fstype->fs_flags & FS_REQUIRES_DEV)
 		sb = get_sb_bdev(fstype, name, flags, data);
@@ -1444,9 +843,7 @@
 		sb = get_sb_nodev(fstype, flags, data);
 
 	if (IS_ERR(sb)) {
-		if (mnt->mnt_devname)
-			kfree(mnt->mnt_devname);
-		kmem_cache_free(mnt_cache, mnt);
+		free_vfsmnt(mnt);
 		mnt = (struct vfsmount *)sb;
 		goto fs_out;
 	}
@@ -1468,168 +865,9 @@
 	return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
 }
 
-static int do_add_mount(struct nameidata *nd, char *type, int flags,
-			int mnt_flags, char *name, void *data)
-{
-	struct vfsmount *mnt = do_kern_mount(type, flags, name, data);
-	int retval = PTR_ERR(mnt);
-
-	if (IS_ERR(mnt))
-		goto out;
-
-	mnt->mnt_flags = mnt_flags;
-
-	down(&mount_sem);
-	/* Something was mounted here while we slept */
-	while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
-		;
-
-	/* Refuse the same filesystem on the same mount point */
-	if (nd->mnt->mnt_sb == mnt->mnt_sb && nd->mnt->mnt_root == nd->dentry)
-		retval = -EBUSY;
-	else
-		retval = graft_tree(mnt, nd);
-	up(&mount_sem);
-	mntput(mnt);
-out:
-	return retval;
-}
-
-static int copy_mount_options (const void *data, unsigned long *where)
-{
-	int i;
-	unsigned long page;
-	unsigned long size;
-	
-	*where = 0;
-	if (!data)
-		return 0;
-
-	if (!(page = __get_free_page(GFP_KERNEL)))
-		return -ENOMEM;
-
-	/* We only care that *some* data at the address the user
-	 * gave us is valid.  Just in case, we'll zero
-	 * the remainder of the page.
-	 */
-	/* copy_from_user cannot cross TASK_SIZE ! */
-	size = TASK_SIZE - (unsigned long)data;
-	if (size > PAGE_SIZE)
-		size = PAGE_SIZE;
-
-	i = size - copy_from_user((void *)page, data, size);
-	if (!i) {
-		free_page(page); 
-		return -EFAULT;
-	}
-	if (i != PAGE_SIZE)
-		memset((char *)page + i, 0, PAGE_SIZE - i);
-	*where = page;
-	return 0;
-}
-
-/*
- * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
- * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
- *
- * data is a (void *) that can point to any structure up to
- * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
- * information (or be NULL).
- *
- * Pre-0.97 versions of mount() didn't have a flags word.
- * When the flags word was introduced its top half was required
- * to have the magic value 0xC0ED, and this remained so until 2.4.0-test9.
- * Therefore, if this magic number is present, it carries no information
- * and must be discarded.
- */
-long do_mount(char * dev_name, char * dir_name, char *type_page,
-		  unsigned long flags, void *data_page)
-{
-	struct nameidata nd;
-	int retval = 0;
-	int mnt_flags = 0;
-
-	/* Discard magic */
-	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
-		flags &= ~MS_MGC_MSK;
-
-	/* Basic sanity checks */
-
-	if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE))
-		return -EINVAL;
-	if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))
-		return -EINVAL;
-
-	/* Separate the per-mountpoint flags */
-	if (flags & MS_NOSUID)
-		mnt_flags |= MNT_NOSUID;
-	if (flags & MS_NODEV)
-		mnt_flags |= MNT_NODEV;
-	if (flags & MS_NOEXEC)
-		mnt_flags |= MNT_NOEXEC;
-	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
-
-	/* ... and get the mountpoint */
-	if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
-		retval = path_walk(dir_name, &nd);
-	if (retval)
-		return retval;
-
-	if (flags & MS_REMOUNT)
-		retval = do_remount(&nd, flags&~MS_REMOUNT, mnt_flags,
-				  (char *)data_page);
-	else if (flags & MS_BIND)
-		retval = do_loopback(&nd, dev_name);
-	else
-		retval = do_add_mount(&nd, type_page, flags, mnt_flags,
-				      dev_name, data_page);
-	path_release(&nd);
-	return retval;
-}
-
-asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
-			  unsigned long flags, void * data)
-{
-	int retval;
-	unsigned long data_page;
-	unsigned long type_page;
-	unsigned long dev_page;
-	char *dir_page;
-
-	retval = copy_mount_options (type, &type_page);
-	if (retval < 0)
-		return retval;
-
-	dir_page = getname(dir_name);
-	retval = PTR_ERR(dir_page);
-	if (IS_ERR(dir_page))
-		goto out1;
-
-	retval = copy_mount_options (dev_name, &dev_page);
-	if (retval < 0)
-		goto out2;
-
-	retval = copy_mount_options (data, &data_page);
-	if (retval < 0)
-		goto out3;
-
-	lock_kernel();
-	retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
-			  flags, (void*)data_page);
-	unlock_kernel();
-	free_page(data_page);
-
-out3:
-	free_page(dev_page);
-out2:
-	putname(dir_page);
-out1:
-	free_page(type_page);
-	return retval;
-}
-
 void __init mount_root(void)
 {
+	struct nameidata root_nd;
 	struct file_system_type * fs_type;
 	struct super_block * sb;
 	struct vfsmount *vfsmnt;
@@ -1639,6 +877,7 @@
 	void *handle;
 	char path[64];
 	int path_start = -1;
+	char *name = "/dev/root";
 
 #ifdef CONFIG_ROOT_NFS
 	void *data;
@@ -1776,13 +1015,24 @@
 		fs_type->name,
 		(sb->s_flags & MS_RDONLY) ? " readonly" : "");
 	if (path_start >= 0) {
+		name = path + path_start;
 		devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
-				  path + 5 + path_start, NULL, NULL);
-		memcpy (path + path_start, "/dev/", 5);
-		vfsmnt = add_vfsmnt(sb->s_root, path + path_start);
+				  name + 5, NULL, NULL);
+		memcpy (name, "/dev/", 5);
 	}
-	else
-		vfsmnt = add_vfsmnt(sb->s_root, "/dev/root");
+	vfsmnt = alloc_vfsmnt();
+	if (!vfsmnt)
+		panic("VFS: alloc_vfsmnt failed for root fs");
+
+	set_devname(vfsmnt, name);
+	vfsmnt->mnt_sb = sb;
+	vfsmnt->mnt_root = dget(sb->s_root);
+
+	root_nd.mnt = root_vfsmnt;
+	root_nd.dentry = root_vfsmnt->mnt_sb->s_root;
+	graft_tree(vfsmnt, &root_nd);
+	mntput(vfsmnt);
+
 	/* FIXME: if something will try to umount us right now... */
 	if (vfsmnt) {
 		set_fs_root(current->fs, vfsmnt, sb->s_root);
@@ -1791,274 +1041,4 @@
 			bdput(bdev); /* sb holds a reference */
 		return;
 	}
-	panic("VFS: add_vfsmnt failed for root fs");
-}
-
-
-static void chroot_fs_refs(struct dentry *old_root,
-			   struct vfsmount *old_rootmnt,
-			   struct dentry *new_root,
-			   struct vfsmount *new_rootmnt)
-{
-	struct task_struct *p;
-	struct fs_struct *fs;
-
-	read_lock(&tasklist_lock);
-	for_each_task(p) {
-		task_lock(p);
-		fs = p->fs;
-		if (fs) {
-			atomic_inc(&fs->count);
-			task_unlock(p);
-			if (fs->root==old_root && fs->rootmnt==old_rootmnt)
-				set_fs_root(fs, new_rootmnt, new_root);
-			if (fs->pwd==old_root && fs->pwdmnt==old_rootmnt)
-				set_fs_pwd(fs, new_rootmnt, new_root);
-			put_fs_struct(fs);
-		} else
-			task_unlock(p);
-	}
-	read_unlock(&tasklist_lock);
-}
-
-/*
- * Moves the current root to put_root, and sets root/cwd of all processes
- * which had them on the old root to new_root.
- *
- * Note:
- *  - we don't move root/cwd if they are not at the root (reason: if something
- *    cared enough to change them, it's probably wrong to force them elsewhere)
- *  - it's okay to pick a root that isn't the root of a file system, e.g.
- *    /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
- *    though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
- *    first.
- */
-
-asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
-{
-	struct dentry *root;
-	struct vfsmount *root_mnt;
-	struct vfsmount *tmp;
-	struct nameidata new_nd, old_nd, parent_nd, root_parent;
-	char *name;
-	int error;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	lock_kernel();
-
-	name = getname(new_root);
-	error = PTR_ERR(name);
-	if (IS_ERR(name))
-		goto out0;
-	error = 0;
-	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
-		error = path_walk(name, &new_nd);
-	putname(name);
-	if (error)
-		goto out0;
-
-	name = getname(put_old);
-	error = PTR_ERR(name);
-	if (IS_ERR(name))
-		goto out0;
-	error = 0;
-	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
-		error = path_walk(name, &old_nd);
-	putname(name);
-	if (error)
-		goto out1;
-
-	read_lock(&current->fs->lock);
-	root_mnt = mntget(current->fs->rootmnt);
-	root = dget(current->fs->root);
-	read_unlock(&current->fs->lock);
-	down(&mount_sem);
-	down(&old_nd.dentry->d_inode->i_zombie);
-	error = -ENOENT;
-	if (IS_DEADDIR(new_nd.dentry->d_inode))
-		goto out2;
-	if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry))
-		goto out2;
-	if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry))
-		goto out2;
-	error = -EBUSY;
-	if (new_nd.mnt == root_mnt || old_nd.mnt == root_mnt)
-		goto out2; /* loop */
-	error = -EINVAL;
-	if (root_mnt->mnt_root != root)
-		goto out2;
-	if (new_nd.mnt->mnt_root != new_nd.dentry)
-		goto out2; /* not a mountpoint */
-	tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
-	spin_lock(&dcache_lock);
-	if (tmp != new_nd.mnt) {
-		for (;;) {
-			if (tmp->mnt_parent == tmp)
-				goto out3;
-			if (tmp->mnt_parent == new_nd.mnt)
-				break;
-			tmp = tmp->mnt_parent;
-		}
-		if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry))
-			goto out3;
-	} else if (!is_subdir(old_nd.dentry, new_nd.dentry))
-		goto out3;
-	detach_mnt(new_nd.mnt, &parent_nd);
-	detach_mnt(root_mnt, &root_parent);
-	attach_mnt(root_mnt, &old_nd);
-	if (root_parent.mnt != root_mnt)
-		attach_mnt(new_nd.mnt, &root_parent);
-	spin_unlock(&dcache_lock);
-	chroot_fs_refs(root,root_mnt,new_nd.dentry,new_nd.mnt);
-	error = 0;
-	if (root_parent.mnt != root_mnt)
-		path_release(&root_parent);
-	if (parent_nd.mnt != new_nd.mnt)
-		path_release(&parent_nd);
-out2:
-	up(&old_nd.dentry->d_inode->i_zombie);
-	up(&mount_sem);
-	dput(root);
-	mntput(root_mnt);
-	path_release(&old_nd);
-out1:
-	path_release(&new_nd);
-out0:
-	unlock_kernel();
-	return error;
-out3:
-	spin_unlock(&dcache_lock);
-	goto out2;
-}
-
-
-#ifdef CONFIG_BLK_DEV_INITRD
-
-int __init change_root(kdev_t new_root_dev,const char *put_old)
-{
-	struct vfsmount *old_rootmnt;
-	struct nameidata devfs_nd, nd;
-	int error = 0;
-
-	read_lock(&current->fs->lock);
-	old_rootmnt = mntget(current->fs->rootmnt);
-	read_unlock(&current->fs->lock);
-	/*  First unmount devfs if mounted  */
-	if (path_init("/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
-		error = path_walk("/dev", &devfs_nd);
-	if (!error) {
-		if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
-		    devfs_nd.dentry == devfs_nd.mnt->mnt_root) {
-			down(&mount_sem);
-			do_umount(devfs_nd.mnt, 0);
-			path_release(&devfs_nd);
-			up(&mount_sem);
-		} else 
-			path_release(&devfs_nd);
-	}
-	ROOT_DEV = new_root_dev;
-	mount_root();
-#if 1
-	shrink_dcache();
-	printk("change_root: old root has d_count=%d\n", 
-	       atomic_read(&old_rootmnt->mnt_root->d_count));
-#endif
-	mount_devfs_fs ();
-	/*
-	 * Get the new mount directory
-	 */
-	error = 0;
-	if (path_init(put_old, LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
-		error = path_walk(put_old, &nd);
-	if (error) {
-		int blivet;
-		struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
-
-		atomic_inc(&ramdisk->bd_count);
-		blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
-		printk(KERN_NOTICE "Trying to unmount old root ... ");
-		if (!blivet) {
-			blivet = do_umount(old_rootmnt, 0);
-			mntput(old_rootmnt);
-			if (!blivet) {
-				int ioctl_err;
-
-				ioctl_err = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
-				if (ioctl_err)
-					printk("failed to release ramdisk %d...", ioctl_err);
-				printk("okay\n");
-				error = 0;
-			}
-			blkdev_put(ramdisk, BDEV_FS);
-		}
-		if (blivet)
-			printk(KERN_ERR "error %d\n", blivet);
-		return error;
-	}
-	/* FIXME: we should hold i_zombie on nd.dentry */
-	move_vfsmnt(old_rootmnt, &nd, "/dev/root.old");
-	mntput(old_rootmnt);
-	path_release(&nd);
-	return 0;
-}
-
-#endif
-
-void __init mnt_init(unsigned long mempages)
-{
-	struct list_head *d;
-	unsigned long order;
-	unsigned int nr_hash;
-	int i;
-
-	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
-					0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!mnt_cache)
-		panic("Cannot create vfsmount cache");
-
-	mempages >>= (16 - PAGE_SHIFT);
-	mempages *= sizeof(struct list_head);
-	for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
-		;
-
-	do {
-		mount_hashtable = (struct list_head *)
-			__get_free_pages(GFP_ATOMIC, order);
-	} while (mount_hashtable == NULL && --order >= 0);
-
-	if (!mount_hashtable)
-		panic("Failed to allocate mount hash table\n");
-
-	/*
-	 * Find the power-of-two list-heads that can fit into the allocation..
-	 * We don't guarantee that "sizeof(struct list_head)" is necessarily
-	 * a power-of-two.
-	 */
-	nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct list_head);
-	hash_bits = 0;
-	do {
-		hash_bits++;
-	} while ((nr_hash >> hash_bits) != 0);
-	hash_bits--;
-
-	/*
-	 * Re-calculate the actual number of entries and the mask
-	 * from the number of bits we can fit.
-	 */
-	nr_hash = 1UL << hash_bits;
-	hash_mask = nr_hash-1;
-
-	printk("Mount-cache hash table entries: %d (order: %ld, %ld bytes)\n",
-			nr_hash, order, (PAGE_SIZE << order));
-
-	/* And initialize the newly allocated array */
-	d = mount_hashtable;
-	i = nr_hash;
-	do {
-		INIT_LIST_HEAD(d);
-		d++;
-		i--;
-	} while (i);
 }
diff -u --recursive --new-file v2.4.10/linux/fs/sysv/super.c linux/fs/sysv/super.c
--- v2.4.10/linux/fs/sysv/super.c	Sun Sep 23 11:41:00 2001
+++ linux/fs/sysv/super.c	Sun Sep 30 12:26:08 2001
@@ -502,3 +502,4 @@
 
 module_init(init_sysv_fs)
 module_exit(exit_sysv_fs)
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/fs/udf/balloc.c linux/fs/udf/balloc.c
--- v2.4.10/linux/fs/udf/balloc.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/balloc.c	Fri Oct  5 12:23:53 2001
@@ -142,7 +142,7 @@
 	return slot;
 }
 
-static void udf_bitmap_free_blocks(const struct inode * inode,
+static void udf_bitmap_free_blocks(struct inode * inode,
 	struct udf_bitmap *bitmap, lb_addr bloc, Uint32 offset, Uint32 count)
 {
 	struct buffer_head * bh = NULL;
@@ -200,7 +200,7 @@
 		}
 		else
 		{
-			DQUOT_FREE_BLOCK(sb, inode, 1);
+			DQUOT_FREE_BLOCK(inode, 1);
 			if (UDF_SB_LVIDBH(sb))
 			{
 				UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -223,7 +223,7 @@
 	return;
 }
 
-static int udf_bitmap_prealloc_blocks(const struct inode * inode,
+static int udf_bitmap_prealloc_blocks(struct inode * inode,
 	struct udf_bitmap *bitmap, Uint16 partition, Uint32 first_block,
 	Uint32 block_count)
 {
@@ -265,12 +265,12 @@
 	{
 		if (!udf_test_bit(bit, bh->b_data))
 			goto out;
-		else if (DQUOT_PREALLOC_BLOCK(sb, inode, 1))
+		else if (DQUOT_PREALLOC_BLOCK(inode, 1))
 			goto out;
 		else if (!udf_clear_bit(bit, bh->b_data))
 		{
 			udf_debug("bit already cleared for block %d\n", bit);
-			DQUOT_FREE_BLOCK(sb, inode, 1);
+			DQUOT_FREE_BLOCK(inode, 1);
 			goto out;
 		}
 		block_count --;
@@ -293,7 +293,7 @@
 	return alloc_count;
 }
 
-static int udf_bitmap_new_block(const struct inode * inode,
+static int udf_bitmap_new_block(struct inode * inode,
 	struct udf_bitmap *bitmap, Uint16 partition, Uint32 goal, int *err)
 {
 	int newbit, bit=0, block, block_group, group_start;
@@ -404,7 +404,7 @@
 	/*
 	 * Check quota for allocation of this block.
 	 */
-	if (DQUOT_ALLOC_BLOCK(sb, inode, 1))
+	if (DQUOT_ALLOC_BLOCK(inode, 1))
 	{
 		unlock_super(sb);
 		*err = -EDQUOT;
@@ -439,7 +439,7 @@
 	return 0;
 }
 
-static void udf_table_free_blocks(const struct inode * inode,
+static void udf_table_free_blocks(struct inode * inode,
 	struct inode * table, lb_addr bloc, Uint32 offset, Uint32 count)
 {
 	struct super_block * sb;
@@ -475,7 +475,7 @@
 
 	/* We do this up front - There are some error conditions that could occure,
 	   but.. oh well */
-	DQUOT_FREE_BLOCK(sb, inode, count);
+	DQUOT_FREE_BLOCK(inode, count);
 	if (UDF_SB_LVIDBH(sb))
 	{
 		UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
@@ -690,7 +690,7 @@
 	return;
 }
 
-static int udf_table_prealloc_blocks(const struct inode * inode,
+static int udf_table_prealloc_blocks(struct inode * inode,
 	struct inode *table, Uint16 partition, Uint32 first_block,
 	Uint32 block_count)
 {
@@ -887,7 +887,7 @@
 	return newblock;
 }
 
-inline void udf_free_blocks(const struct inode * inode, lb_addr bloc,
+inline void udf_free_blocks(struct inode * inode, lb_addr bloc,
 	Uint32 offset, Uint32 count)
 {
 	if (UDF_SB_PARTFLAGS(inode->i_sb, bloc.partitionReferenceNum) & UDF_PART_FLAG_UNALLOC_BITMAP)
@@ -918,7 +918,7 @@
 		return;
 }
 
-inline int udf_prealloc_blocks(const struct inode * inode, Uint16 partition,
+inline int udf_prealloc_blocks(struct inode * inode, Uint16 partition,
 	Uint32 first_block, Uint32 block_count)
 {
 	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
@@ -949,7 +949,7 @@
 		return 0;
 }
 
-inline int udf_new_block(const struct inode * inode, Uint16 partition,
+inline int udf_new_block(struct inode * inode, Uint16 partition,
 	Uint32 goal, int *err)
 {
 	if (UDF_SB_PARTFLAGS(inode->i_sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
diff -u --recursive --new-file v2.4.10/linux/fs/udf/ialloc.c linux/fs/udf/ialloc.c
--- v2.4.10/linux/fs/udf/ialloc.c	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/ialloc.c	Fri Oct  5 12:25:45 2001
@@ -44,7 +44,7 @@
 	 * Note: we must free any quota before locking the superblock,
 	 * as writing the quota to disk may need the lock as well.
 	 */
-	DQUOT_FREE_INODE(sb, inode);
+	DQUOT_FREE_INODE(inode);
 	DQUOT_DROP(inode);
 
 	lock_super(sb);
@@ -70,7 +70,7 @@
 	udf_free_blocks(inode, UDF_I_LOCATION(inode), 0, 1);
 }
 
-struct inode * udf_new_inode (const struct inode *dir, int mode, int * err)
+struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
 {
 	struct super_block *sb;
 	struct inode * inode;
@@ -153,9 +153,10 @@
 	mark_inode_dirty(inode);
 
 	unlock_super(sb);
-	if (DQUOT_ALLOC_INODE(sb, inode))
+	if (DQUOT_ALLOC_INODE(inode))
 	{
-		sb->dq_op->drop(inode);
+		DQUOT_DROP(inode);
+		inode->i_flags |= S_NOQUOTA;
 		inode->i_nlink = 0;
 		iput(inode);
 		*err = -EDQUOT;
diff -u --recursive --new-file v2.4.10/linux/fs/udf/udfdecl.h linux/fs/udf/udfdecl.h
--- v2.4.10/linux/fs/udf/udfdecl.h	Tue Jul  3 17:08:21 2001
+++ linux/fs/udf/udfdecl.h	Fri Oct  5 12:23:53 2001
@@ -165,15 +165,15 @@
 
 /* ialloc.c */
 extern void udf_free_inode(struct inode *);
-extern struct inode * udf_new_inode (const struct inode *, int, int *);
+extern struct inode * udf_new_inode (struct inode *, int, int *);
 
 /* truncate.c */
 extern void udf_truncate_extents(struct inode *);
 
 /* balloc.c */
-extern void udf_free_blocks(const struct inode *, lb_addr, Uint32, Uint32);
-extern int udf_prealloc_blocks(const struct inode *, Uint16, Uint32, Uint32);
-extern int udf_new_block(const struct inode *, Uint16, Uint32, int *);
+extern void udf_free_blocks(struct inode *, lb_addr, Uint32, Uint32);
+extern int udf_prealloc_blocks(struct inode *, Uint16, Uint32, Uint32);
+extern int udf_new_block(struct inode *, Uint16, Uint32, int *);
 
 /* fsync.c */
 extern int udf_fsync_file(struct file *, struct dentry *, int);
diff -u --recursive --new-file v2.4.10/linux/fs/ufs/balloc.c linux/fs/ufs/balloc.c
--- v2.4.10/linux/fs/ufs/balloc.c	Sun Sep 23 11:41:01 2001
+++ linux/fs/ufs/balloc.c	Fri Oct  5 12:23:53 2001
@@ -85,7 +85,7 @@
 			"bit already cleared for fragment %u", i);
 	}
 	
-	DQUOT_FREE_BLOCK (sb, inode, count);
+	DQUOT_FREE_BLOCK (inode, count);
 	ADD_SWAB32(ucg->cg_cs.cs_nffree, count);
 	ADD_SWAB32(usb1->fs_cstotal.cs_nffree, count);
 	ADD_SWAB32(sb->fs_cs(cgno).cs_nffree, count);
@@ -187,7 +187,7 @@
 		ubh_setblock(UCPI_UBH, ucpi->c_freeoff, blkno);
 		if ((sb->u.ufs_sb.s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
 			ufs_clusteracct (sb, ucpi, blkno, 1);
-		DQUOT_FREE_BLOCK(sb, inode, uspi->s_fpb);
+		DQUOT_FREE_BLOCK(inode, uspi->s_fpb);
 		INC_SWAB32(ucg->cg_cs.cs_nbfree);
 		INC_SWAB32(usb1->fs_cstotal.cs_nbfree);
 		INC_SWAB32(sb->fs_cs(cgno).cs_nbfree);
@@ -451,7 +451,7 @@
 		INC_SWAB32(ucg->cg_frsum[fragsize - count]);
 	for (i = oldcount; i < newcount; i++)
 		ubh_clrbit (UCPI_UBH, ucpi->c_freeoff, fragno + i);
-	if(DQUOT_ALLOC_BLOCK(sb, inode, count)) {
+	if(DQUOT_ALLOC_BLOCK(inode, count)) {
 		*err = -EDQUOT;
 		return 0;
 	}
@@ -558,7 +558,7 @@
 		for (i = count; i < uspi->s_fpb; i++)
 			ubh_setbit (UCPI_UBH, ucpi->c_freeoff, goal + i);
 		i = uspi->s_fpb - count;
-		DQUOT_FREE_BLOCK(sb, inode, i);
+		DQUOT_FREE_BLOCK(inode, i);
 		ADD_SWAB32(ucg->cg_cs.cs_nffree, i);
 		ADD_SWAB32(usb1->fs_cstotal.cs_nffree, i);
 		ADD_SWAB32(sb->fs_cs(cgno).cs_nffree, i);
@@ -569,7 +569,7 @@
 	result = ufs_bitmap_search (sb, ucpi, goal, allocsize);
 	if (result == (unsigned)-1)
 		return 0;
-	if(DQUOT_ALLOC_BLOCK(sb, inode, count)) {
+	if(DQUOT_ALLOC_BLOCK(inode, count)) {
 		*err = -EDQUOT;
 		return 0;
 	}
@@ -639,7 +639,7 @@
 	ubh_clrblock (UCPI_UBH, ucpi->c_freeoff, blkno);
 	if ((sb->u.ufs_sb.s_flags & UFS_CG_MASK) == UFS_CG_44BSD)
 		ufs_clusteracct (sb, ucpi, blkno, -1);
-	if(DQUOT_ALLOC_BLOCK(sb, inode, uspi->s_fpb)) {
+	if(DQUOT_ALLOC_BLOCK(inode, uspi->s_fpb)) {
 		*err = -EDQUOT;
 		return (unsigned)-1;
 	}
diff -u --recursive --new-file v2.4.10/linux/fs/ufs/ialloc.c linux/fs/ufs/ialloc.c
--- v2.4.10/linux/fs/ufs/ialloc.c	Thu Nov 16 13:18:26 2000
+++ linux/fs/ufs/ialloc.c	Fri Oct  5 12:25:25 2001
@@ -100,7 +100,7 @@
 
 	is_directory = S_ISDIR(inode->i_mode);
 
-	DQUOT_FREE_INODE(sb, inode);
+	DQUOT_FREE_INODE(inode);
 	DQUOT_DROP(inode);
 
 	clear_inode (inode);
@@ -278,8 +278,9 @@
 
 	unlock_super (sb);
 
-	if(DQUOT_ALLOC_INODE(sb, inode)) {
-		sb->dq_op->drop(inode);
+	if (DQUOT_ALLOC_INODE(inode)) {
+		DQUOT_DROP(inode);
+		inode->i_flags |= S_NOQUOTA;
 		inode->i_nlink = 0;
 		iput(inode);
 		*err = -EDQUOT;
@@ -293,6 +294,7 @@
 
 failed:
 	unlock_super (sb);
+	make_bad_inode(inode);
 	iput (inode);
 	UFSD(("EXIT (FAILED)\n"))
 	return NULL;
diff -u --recursive --new-file v2.4.10/linux/fs/umsdos/inode.c linux/fs/umsdos/inode.c
--- v2.4.10/linux/fs/umsdos/inode.c	Sun Sep 23 11:41:01 2001
+++ linux/fs/umsdos/inode.c	Sun Sep 30 12:26:08 2001
@@ -475,3 +475,4 @@
 
 module_init(init_umsdos_fs)
 module_exit(exit_umsdos_fs)
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/cache.h linux/include/asm-alpha/cache.h
--- v2.4.10/linux/include/asm-alpha/cache.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-alpha/cache.h	Thu Oct  4 18:47:08 2001
@@ -7,7 +7,7 @@
 #include <linux/config.h>
 
 /* Bytes per L1 (data) cache line. */
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
 # define L1_CACHE_BYTES     64
 # define L1_CACHE_SHIFT     6
 #else
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/compiler.h linux/include/asm-alpha/compiler.h
--- v2.4.10/linux/include/asm-alpha/compiler.h	Sun May 20 12:11:39 2001
+++ linux/include/asm-alpha/compiler.h	Fri Oct  5 12:10:00 2001
@@ -72,13 +72,4 @@
   __asm__("stw %1,%0" : "=m"(mem) : "r"(val))
 #endif
 
-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
-   a mechanism by which the user can annotate likely branch directions and
-   expect the blocks to be reordered appropriately.  Define __builtin_expect
-   to nothing for earlier compilers.  */
-
-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
-#define __builtin_expect(x, expected_value) (x)
-#endif
-
 #endif /* __ALPHA_COMPILER_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/core_apecs.h linux/include/asm-alpha/core_apecs.h
--- v2.4.10/linux/include/asm-alpha/core_apecs.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/core_apecs.h	Thu Oct  4 18:47:08 2001
@@ -502,7 +502,7 @@
 	return addr + APECS_DENSE_MEM;
 }
 
-__EXTERN_INLINE void apecs_iounmap(unsigned addr)
+__EXTERN_INLINE void apecs_iounmap(unsigned long addr)
 {
 	return;
 }
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/mc146818rtc.h linux/include/asm-alpha/mc146818rtc.h
--- v2.4.10/linux/include/asm-alpha/mc146818rtc.h	Tue Jul 18 23:05:08 2000
+++ linux/include/asm-alpha/mc146818rtc.h	Thu Oct  4 18:47:08 2001
@@ -24,6 +24,4 @@
 outb_p((val),RTC_PORT(1)); \
 })
 
-#define RTC_IRQ 0		/* Don't support interrupt features.  */
-
 #endif /* __ASM_ALPHA_MC146818RTC_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- v2.4.10/linux/include/asm-alpha/page.h	Thu May 24 15:20:18 2001
+++ linux/include/asm-alpha/page.h	Fri Oct  5 12:22:07 2001
@@ -80,7 +80,7 @@
 	return order;
 }
 
-#endif /* !ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h
--- v2.4.10/linux/include/asm-alpha/pgtable.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/pgtable.h	Thu Oct  4 18:47:08 2001
@@ -178,8 +178,7 @@
 #error "EV6-only feature in a generic kernel"
 #endif
 #if defined(CONFIG_ALPHA_GENERIC) || \
-    ((defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)) && \
-     !defined(USE_48_BIT_KSEG))
+    (defined(CONFIG_ALPHA_EV6) && !defined(USE_48_BIT_KSEG))
 #define PHYS_TWIDDLE(phys) \
   ((((phys) & 0xc0000000000UL) == 0x40000000000UL) \
   ? ((phys) ^= 0xc0000000000UL) : (phys))
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
--- v2.4.10/linux/include/asm-alpha/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-alpha/processor.h	Fri Oct  5 12:11:05 2001
@@ -148,6 +148,8 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 #define ARCH_HAS_PREFETCH
 #define ARCH_HAS_PREFETCHW
 #define ARCH_HAS_SPINLOCK_PREFETCH
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/rwsem.h linux/include/asm-alpha/rwsem.h
--- v2.4.10/linux/include/asm-alpha/rwsem.h	Wed Jul 25 17:10:25 2001
+++ linux/include/asm-alpha/rwsem.h	Fri Oct  5 12:10:00 2001
@@ -12,7 +12,7 @@
 
 #ifdef __KERNEL__
 
-#include <asm/compiler.h>
+#include <linux/compiler.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h
--- v2.4.10/linux/include/asm-alpha/semaphore.h	Sun May 20 12:11:39 2001
+++ linux/include/asm-alpha/semaphore.h	Fri Oct  5 12:10:00 2001
@@ -11,7 +11,7 @@
 #include <asm/current.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
-#include <asm/compiler.h>
+#include <linux/compiler.h>
 #include <linux/wait.h>
 #include <linux/rwsem.h>
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v2.4.10/linux/include/asm-alpha/system.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-alpha/system.h	Thu Oct  4 18:47:08 2001
@@ -192,7 +192,7 @@
 #ifdef CONFIG_ALPHA_EV5
 #define implver() IMPLVER_EV5
 #endif
-#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
+#if defined(CONFIG_ALPHA_EV6)
 #define implver() IMPLVER_EV6
 #endif
 #endif
diff -u --recursive --new-file v2.4.10/linux/include/asm-arm/processor.h linux/include/asm-arm/processor.h
--- v2.4.10/linux/include/asm-arm/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-arm/processor.h	Fri Oct  5 12:11:05 2001
@@ -112,6 +112,8 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 /*
  * Create a new kernel thread
  */
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/bitops.h linux/include/asm-cris/bitops.h
--- v2.4.10/linux/include/asm-cris/bitops.h	Wed Jul 25 17:10:25 2001
+++ linux/include/asm-cris/bitops.h	Mon Oct  8 11:43:54 2001
@@ -19,6 +19,10 @@
 
 #include <asm/system.h>
 
+/* We use generic_ffs so get it; include guards resolve the possible
+   mutually inclusion.  */
+#include <linux/bitops.h>
+
 /*
  * Some hacks to defeat gcc over-optimizations..
  */
@@ -215,33 +219,62 @@
  */
 
 /*
+ * Helper functions for the core of the ff[sz] functions, wrapping the
+ * syntactically awkward asms.  The asms compute the number of leading
+ * zeroes of a bits-in-byte and byte-in-word and word-in-dword-swapped
+ * number.  They differ in that the first function also inverts all bits
+ * in the input.
+ */
+static __inline__ unsigned long cris_swapnwbrlz(unsigned long w)
+{
+	/* Let's just say we return the result in the same register as the
+	   input.  Saying we clobber the input but can return the result
+	   in another register:
+	   !  __asm__ ("swapnwbr %2\n\tlz %2,%0"
+	   !	      : "=r,r" (res), "=r,X" (dummy) : "1,0" (w));
+	   confuses gcc (sched.c, gcc from cris-dist-1.14).  */
+
+	unsigned long res;
+	__asm__ ("swapnwbr %0 \n\t"
+		 "lz %0,%0"
+		 : "=r" (res) : "0" (w));
+	return res;
+}
+
+static __inline__ unsigned long cris_swapwbrlz(unsigned long w)
+{
+	unsigned res;
+	__asm__ ("swapwbr %0 \n\t"
+		 "lz %0,%0"
+		 : "=r" (res)
+		 : "0" (w));
+	return res;
+}
+
+/*
  * ffz = Find First Zero in word. Undefined if no zero exists,
  * so code should check against ~0UL first..
  */
-static __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long w)
 {
-	unsigned long result = 0;
-	
-	while(word & 1) {
-		result++;
-		word >>= 1;
-	}
-	return result;
+	/* The generic_ffs function is used to avoid the asm when the
+	   argument is a constant.  */
+	return __builtin_constant_p (w)
+		? (~w ? (unsigned long) generic_ffs ((int) ~w) - 1 : 32)
+		: cris_swapnwbrlz (w);
 }
 
 /*
- * Find first one in word. Undefined if no one exists,
- * so code should check against 0UL first..
+ * Somewhat like ffz but the equivalent of generic_ffs: in contrast to
+ * ffz we return the first one-bit *plus one*.
  */
-static __inline__ unsigned long find_first_one(unsigned long word)
+static __inline__ unsigned long ffs(unsigned long w)
 {
-	unsigned long result = 0;
-	
-	while(!(word & 1)) {
-		result++;
-		word >>= 1;
-	}
-	return result;
+	/* The generic_ffs function is used to avoid the asm when the
+	   argument is a constant.  */
+	return __builtin_constant_p (w)
+		? (unsigned long) generic_ffs ((int) w)
+		: w ? cris_swapwbrlz (w) + 1 : 0;
 }
 
 /**
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/checksum.h linux/include/asm-cris/checksum.h
--- v2.4.10/linux/include/asm-cris/checksum.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-cris/checksum.h	Mon Oct  8 11:43:54 2001
@@ -1,4 +1,3 @@
-/* $Id: checksum.h,v 1.4 2001/06/28 03:58:36 hp Exp $ */
 /* TODO: csum_tcpudp_magic could be speeded up, and csum_fold as well */
 
 #ifndef _CRIS_CHECKSUM_H
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/current.h linux/include/asm-cris/current.h
--- v2.4.10/linux/include/asm-cris/current.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/current.h	Mon Oct  8 11:43:54 2001
@@ -6,7 +6,7 @@
 static inline struct task_struct * get_current(void)
 {
         struct task_struct *current;
-        __asm__("and.d sp,%0; ":"=r" (current) : "0" (~8191UL));
+        __asm__("and.d $sp,%0; ":"=r" (current) : "0" (~8191UL));
         return current;
  }
  
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/delay.h linux/include/asm-cris/delay.h
--- v2.4.10/linux/include/asm-cris/delay.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-cris/delay.h	Mon Oct  8 11:43:54 2001
@@ -1,5 +1,3 @@
-/* $Id: delay.h,v 1.5 2001/06/28 04:59:25 hp Exp $ */
-
 #ifndef _CRIS_DELAY_H
 #define _CRIS_DELAY_H
 
@@ -21,12 +19,12 @@
 extern __inline__ void __delay(int loops)
 {
 	__asm__ __volatile__ (
-			      "move.d %0,r9\n\t"
+			      "move.d %0,$r9\n\t"
 			      "beq 2f\n\t"
-			      "subq 1,r9\n\t"
+			      "subq 1,$r9\n\t"
 			      "1:\n\t"
 			      "bne 1b\n\t"
-			      "subq 1,r9\n"
+			      "subq 1,$r9\n"
 			      "2:"
 			      : : "g" (loops) : "r9");
 }
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/io.h linux/include/asm-cris/io.h
--- v2.4.10/linux/include/asm-cris/io.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-cris/io.h	Mon Oct  8 11:43:54 2001
@@ -10,16 +10,16 @@
 #ifdef CONFIG_SVINTO_SIM
   /* Let's use the ucsim interface since it lets us do write(2, ...) */
 #define SIMCOUT(s,len)							\
-  asm ("moveq 4,r1	\n\t"						\
-       "moveq 2,r10	\n\t"						\
-       "move.d %0,r11	\n\t"						\
-       "move.d %1,r12	\n\t"						\
-       "push irp	\n\t"						\
-       "move 0f,irp	\n\t"						\
+  asm ("moveq 4,$r9	\n\t"						\
+       "moveq 2,$r10	\n\t"						\
+       "move.d %0,$r11	\n\t"						\
+       "move.d %1,$r12	\n\t"						\
+       "push $irp	\n\t"						\
+       "move 0f,$irp	\n\t"						\
        "jump -6809	\n"						\
        "0:		\n\t"						\
-       "pop irp"							\
-       : : "rm" (s), "rm" (len) : "r1","r10","r11","r12","memory")
+       "pop $irp"							\
+       : : "rm" (s), "rm" (len) : "r9","r10","r11","r12","memory")
 #define TRACE_ON() __extension__ \
  ({ int _Foofoo; __asm__ volatile ("bmod [%0],%0" : "=r" (_Foofoo) : "0" \
 			       (255)); _Foofoo; })
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/irq.h linux/include/asm-cris/irq.h
--- v2.4.10/linux/include/asm-cris/irq.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-cris/irq.h	Mon Oct  8 11:43:54 2001
@@ -3,9 +3,6 @@
  *
  * Copyright (c) 2000, 2001 Axis Communications AB
  *
- * Authors:   Bjorn Wesen (bjornw@axis.com)
- *
- * $Id: irq.h,v 1.13 2001/07/06 18:52:08 hp Exp $
  */
 
 #ifndef _ASM_IRQ_H
@@ -101,25 +98,25 @@
 /* SAVE_ALL saves registers so they match pt_regs */
 
 #define SAVE_ALL \
-  "move irp,[sp=sp-16]\n\t" /* push instruction pointer and fake SBFS struct */ \
-  "push srp\n\t"       /* push subroutine return pointer */ \
-  "push dccr\n\t"      /* push condition codes */ \
-  "push mof\n\t"       /* push multiply overflow reg */ \
+  "move $irp,[$sp=$sp-16]\n\t" /* push instruction pointer and fake SBFS struct */ \
+  "push $srp\n\t"       /* push subroutine return pointer */ \
+  "push $dccr\n\t"      /* push condition codes */ \
+  "push $mof\n\t"       /* push multiply overflow reg */ \
   "di\n\t"             /* need to disable irq's at this point */\
-  "subq 14*4,sp\n\t"   /* make room for r0-r13 */ \
-  "movem r13,[sp]\n\t" /* push the r0-r13 registers */ \
-  "push r10\n\t"       /* push orig_r10 */ \
-  "clear.d [sp=sp-4]\n\t"  /* frametype - this is a normal stackframe */
+  "subq 14*4,$sp\n\t"   /* make room for r0-r13 */ \
+  "movem $r13,[$sp]\n\t" /* push the r0-r13 registers */ \
+  "push $r10\n\t"       /* push orig_r10 */ \
+  "clear.d [$sp=$sp-4]\n\t"  /* frametype - this is a normal stackframe */
 
   /* BLOCK_IRQ and UNBLOCK_IRQ do the same as mask_irq and unmask_irq in irq.c */
 
 #define BLOCK_IRQ(mask,nr) \
-  "move.d " #mask ",r0\n\t" \
-  "move.d r0,[0xb00000d8]\n\t" 
+  "move.d " #mask ",$r0\n\t" \
+  "move.d $r0,[0xb00000d8]\n\t" 
   
 #define UNBLOCK_IRQ(mask) \
-  "move.d " #mask ",r0\n\t" \
-  "move.d r0,[0xb00000dc]\n\t" 
+  "move.d " #mask ",$r0\n\t" \
+  "move.d $r0,[0xb00000dc]\n\t" 
 
 #define IRQ_NAME2(nr) nr##_interrupt(void)
 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
@@ -137,20 +134,20 @@
 void BAD_IRQ_NAME(nr); \
 __asm__ ( \
           ".text\n\t" \
-          "_IRQ" #nr "_interrupt:\n\t" \
+          "IRQ" #nr "_interrupt:\n\t" \
 	  SAVE_ALL \
-	  "_sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \
+	  "sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \
 	  BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ \
-	  "moveq "#nr",r10\n\t" \
-	  "move.d sp,r11\n\t" \
-	  "jsr _do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \
+	  "moveq "#nr",$r10\n\t" \
+	  "move.d $sp,$r11\n\t" \
+	  "jsr do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \
 	  UNBLOCK_IRQ(mask) \
-	  "moveq 0,r9\n\t" /* make ret_from_intr realise we came from an irq */ \
-	  "jump _ret_from_intr\n\t" \
-          "_bad_IRQ" #nr "_interrupt:\n\t" \
-	  "push r0\n\t" \
+	  "moveq 0,$r9\n\t" /* make ret_from_intr realise we came from an irq */ \
+	  "jump ret_from_intr\n\t" \
+          "bad_IRQ" #nr "_interrupt:\n\t" \
+	  "push $r0\n\t" \
 	  BLOCK_IRQ(mask,nr) \
-	  "pop r0\n\t" \
+	  "pop $r0\n\t" \
           "reti\n\t" \
           "nop\n");
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/module.h linux/include/asm-cris/module.h
--- v2.4.10/linux/include/asm-cris/module.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-cris/module.h	Mon Oct  8 11:43:54 2001
@@ -7,6 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
-#define arch_init_modules(x)	do { } while (0)
+#define arch_init_modules(x)    do { } while (0)
 
 #endif /* _ASM_CRIS_MODULE_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/pgtable.h linux/include/asm-cris/pgtable.h
--- v2.4.10/linux/include/asm-cris/pgtable.h	Tue May  1 16:05:00 2001
+++ linux/include/asm-cris/pgtable.h	Mon Oct  8 11:43:54 2001
@@ -3,6 +3,9 @@
  * HISTORY:
  *
  * $Log: pgtable.h,v $
+ * Revision 1.12  2001/08/11 00:28:00  bjornw
+ * PAGE_CHG_MASK and PAGE_NONE had somewhat untraditional values
+ *
  * Revision 1.11  2001/04/04 14:38:36  bjornw
  * Removed bad_pagetable handling and the _kernel functions
  *
@@ -215,9 +218,9 @@
 #define __WRITEABLE     (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
 
 #define _PAGE_TABLE     (_PAGE_PRESENT | __READABLE | __WRITEABLE)
-#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_SILENT_WRITE)
+#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED)
 
-#define PAGE_NONE       __pgprot(_PAGE_PRESENT | __READABLE)
+#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
 #define PAGE_SHARED     __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \
 				 _PAGE_ACCESSED)
 #define PAGE_COPY       __pgprot(_PAGE_PRESENT | __READABLE)  // | _PAGE_COW
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/processor.h linux/include/asm-cris/processor.h
--- v2.4.10/linux/include/asm-cris/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-cris/processor.h	Mon Oct  8 11:43:54 2001
@@ -12,13 +12,14 @@
 
 #include <linux/config.h>
 #include <asm/system.h>
+#include <asm/page.h>
 #include <asm/ptrace.h>
 
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
  */
-#define current_text_addr() ({void *pc; __asm__ ("move.d pc,%0" : "=rm" (pc)); pc; })
+#define current_text_addr() ({void *pc; __asm__ ("move.d $pc,%0" : "=rm" (pc)); pc; })
 
 /* CRIS has no problems with write protection */
 
@@ -140,5 +141,7 @@
 
 #define init_task       (init_task_union.task)
 #define init_stack      (init_task_union.stack)
+
+#define cpu_relax()	do { } while (0)
 
 #endif /* __ASM_CRIS_PROCESSOR_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/system.h linux/include/asm-cris/system.h
--- v2.4.10/linux/include/asm-cris/system.h	Tue May  1 16:05:00 2001
+++ linux/include/asm-cris/system.h	Mon Oct  8 11:43:54 2001
@@ -1,5 +1,3 @@
-/* $Id: system.h,v 1.4 2001/03/20 19:46:00 bjornw Exp $ */
-
 #ifndef __ASM_CRIS_SYSTEM_H
 #define __ASM_CRIS_SYSTEM_H
 
@@ -16,22 +14,30 @@
 #define switch_to(prev,next,last) last = resume(prev,next, \
 					 (int)&((struct task_struct *)0)->thread)
 
+/* read the CPU version register */
+
+static inline unsigned long rdvr(void) { 
+	unsigned long vr;
+	__asm__ volatile ("move $vr,%0" : "=rm" (vr));
+	return vr;
+}
+
 /* read/write the user-mode stackpointer */
 
-extern inline unsigned long rdusp(void) {
+static inline unsigned long rdusp(void) {
 	unsigned long usp;
-	__asm__ __volatile__("move usp,%0" : "=rm" (usp));
+	__asm__ __volatile__("move $usp,%0" : "=rm" (usp));
 	return usp;
 }
 
 #define wrusp(usp) \
-	__asm__ __volatile__("move %0,usp" : /* no outputs */ : "rm" (usp))
+	__asm__ __volatile__("move %0,$usp" : /* no outputs */ : "rm" (usp))
 
 /* read the current stackpointer */
 
-extern inline unsigned long rdsp(void) {
+static inline unsigned long rdsp(void) {
 	unsigned long sp;
-	__asm__ __volatile__("move.d sp,%0" : "=rm" (sp));
+	__asm__ __volatile__("move.d $sp,%0" : "=rm" (sp));
 	return sp;
 }
 
@@ -51,18 +57,18 @@
 #if 0
 /* use these and an oscilloscope to see the fraction of time we're running with IRQ's disabled */
 /* it assumes the LED's are on port 0x90000000 of course. */
-#define sti() __asm__ __volatile__ ( "ei\n\tpush r0\n\tmoveq 0,r0\n\tmove.d r0,[0x90000000]\n\tpop r0" );
-#define cli() __asm__ __volatile__ ( "di\n\tpush r0\n\tmove.d 0x40000,r0\n\tmove.d r0,[0x90000000]\n\tpop r0");
-#define save_flags(x) __asm__ __volatile__ ("move ccr,%0" : "=rm" (x) : : "memory");
-#define restore_flags(x) __asm__ __volatile__ ("move %0,ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush r0\n\tmoveq 0,r0\n\tmove.d r0,[0x90000000]\n\tpop r0\n1:\n" : : "r" (x) : "memory");
+#define sti() __asm__ __volatile__ ( "ei\n\tpush $r0\n\tmoveq 0,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0" );
+#define cli() __asm__ __volatile__ ( "di\n\tpush $r0\n\tmove.d 0x40000,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0");
+#define save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
+#define restore_flags(x) __asm__ __volatile__ ("move %0,$ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush $r0\n\tmoveq 0,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0\n1:\n" : : "r" (x) : "memory");
 #else
 #define __cli() __asm__ __volatile__ ( "di");
 #define __sti() __asm__ __volatile__ ( "ei" );
-#define __save_flags(x) __asm__ __volatile__ ("move ccr,%0" : "=rm" (x) : : "memory");
-#define __restore_flags(x) __asm__ __volatile__ ("move %0,ccr" : : "rm" (x) : "memory");
+#define __save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
+#define __restore_flags(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory");
 
 /* For spinlocks etc */
-#define local_irq_save(x) __asm__ __volatile__ ("move ccr,%0\n\tdi" : "=rm" (x) : : "memory"); 
+#define local_irq_save(x) __asm__ __volatile__ ("move $ccr,%0\n\tdi" : "=rm" (x) : : "memory"); 
 #define local_irq_restore(x) restore_flags(x)
 
 #define local_irq_disable()  cli()
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/tlb.h linux/include/asm-cris/tlb.h
--- v2.4.10/linux/include/asm-cris/tlb.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/tlb.h	Mon Oct  8 11:43:54 2001
@@ -0,0 +1 @@
+#include <asm-generic/tlb.h>
diff -u --recursive --new-file v2.4.10/linux/include/asm-cris/uaccess.h linux/include/asm-cris/uaccess.h
--- v2.4.10/linux/include/asm-cris/uaccess.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/uaccess.h	Mon Oct  8 11:43:54 2001
@@ -3,6 +3,12 @@
  *	       Hans-Peter Nilsson (hp@axis.com)
  *
  * $Log: uaccess.h,v $
+ * Revision 1.7  2001/10/02 12:44:52  hp
+ * Add support for 64-bit put_user/get_user
+ *
+ * Revision 1.6  2001/10/01 14:51:17  bjornw
+ * Added register prefixes and removed underscores
+ *
  * Revision 1.5  2000/10/25 03:33:21  hp
  * - Provide implementation for everything else but get_user and put_user;
  *   copying inline to/from user for constant length 0..16, 20, 24, and
@@ -36,7 +42,7 @@
 
    Check regularly...
 
-   Register r9 is chosen for temporaries, being a call-clobbered register
+   Register $r9 is chosen for temporaries, being a call-clobbered register
    first in line to be used (notably for local blocks), not colliding with
    parameter registers.  */
 
@@ -182,6 +188,7 @@
 	  case 1: __put_user_asm(x,ptr,retval,"move.b"); break;	\
 	  case 2: __put_user_asm(x,ptr,retval,"move.w"); break;	\
 	  case 4: __put_user_asm(x,ptr,retval,"move.d"); break;	\
+	  case 8: __put_user_asm_64(x,ptr,retval); break;	\
 	  default: __put_user_bad();				\
 	}							\
 } while (0)
@@ -211,6 +218,22 @@
 		: "=r" (err)					\
 		: "r" (x), "r" (addr), "g" (-EFAULT), "0" (err))
 
+#define __put_user_asm_64(x, addr, err)				\
+	__asm__ __volatile__(					\
+		"	move.d %M1,[%2]\n"			\
+		"2:	move.d %H1,[%2+4]\n"			\
+		"4:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"3:	move.d %3,%0\n"				\
+		"	jump 4b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.dword 2b,3b\n"				\
+		"	.dword 4b,3b\n"				\
+		"	.previous\n"				\
+		: "=r" (err)					\
+		: "r" (x), "r" (addr), "g" (-EFAULT), "0" (err))
+
 
 #define __get_user_nocheck(x,ptr,size)				\
 ({								\
@@ -239,6 +262,7 @@
 	  case 1: __get_user_asm(x,ptr,retval,"move.b"); break;	\
 	  case 2: __get_user_asm(x,ptr,retval,"move.w"); break;	\
 	  case 4: __get_user_asm(x,ptr,retval,"move.d"); break;	\
+	  case 8: __get_user_asm_64(x,ptr,retval); break;	\
 	  default: (x) = __get_user_bad();			\
 	}							\
 } while (0)
@@ -260,6 +284,23 @@
 		: "=r" (err), "=r" (x)			\
 		: "r" (addr), "g" (-EFAULT), "0" (err))
 
+#define __get_user_asm_64(x, addr, err)			\
+	__asm__ __volatile__(				\
+		"	move.d [%2],%M1\n"		\
+		"2:	move.d [%2+4],%H1\n"		\
+		"4:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+		"3:	move.d %3,%0\n"			\
+		"	moveq 0,%1\n"			\
+		"	jump 4b\n"			\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+		"	.dword 2b,3b\n"			\
+		"	.dword 4b,3b\n"			\
+		"	.previous\n"			\
+		: "=r" (err), "=r" (x)			\
+		: "r" (addr), "g" (-EFAULT), "0" (err))
+
 /* More complex functions.  Most are inline, but some call functions that
    live in lib/usercopy.c  */
 
@@ -305,13 +346,13 @@
 
 	__asm__ __volatile__ (
 		"	move.d %3,%0\n"
-		"	move.b [%2+],r9\n"
+		"	move.b [%2+],$r9\n"
 		"1:	beq 2f\n"
-		"	move.b r9,[%1+]\n"
+		"	move.b $r9,[%1+]\n"
 
 		"	subq 1,%0\n"
 		"	bne 1b\n"
-		"	move.b [%2+],r9\n"
+		"	move.b [%2+],$r9\n"
 
 		"2:	sub.d %3,%0\n"
 		"	neg.d %0,%0\n"
@@ -399,16 +440,16 @@
 
 #define __asm_copy_from_user_1(to, from, ret) \
 	__asm_copy_user_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"	\
-		"2:	move.b r9,[%0+]\n",	\
+		"	move.b [%1+],$r9\n"	\
+		"2:	move.b $r9,[%0+]\n",	\
 		"3:	addq 1,%2\n"		\
 		"	clear.b [%0+]\n",	\
 		"	.dword 2b,3b\n")
 
 #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_user_cont(to, from, ret,		\
-		"	move.w [%1+],r9\n"		\
-		"2:	move.w r9,[%0+]\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"2:	move.w $r9,[%0+]\n" COPY,	\
 		"3:	addq 2,%2\n"			\
 		"	clear.w [%0+]\n" FIXUP,		\
 		"	.dword 2b,3b\n" TENTRY)
@@ -418,16 +459,16 @@
 
 #define __asm_copy_from_user_3(to, from, ret)		\
 	__asm_copy_from_user_2x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"4:	move.b r9,[%0+]\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"4:	move.b $r9,[%0+]\n",		\
 		"5:	addq 1,%2\n"			\
 		"	clear.b [%0+]\n",		\
 		"	.dword 4b,5b\n")
 
 #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_user_cont(to, from, ret,		\
-		"	move.d [%1+],r9\n"		\
-		"2:	move.d r9,[%0+]\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"2:	move.d $r9,[%0+]\n" COPY,	\
 		"3:	addq 4,%2\n"			\
 		"	clear.d [%0+]\n" FIXUP,		\
 		"	.dword 2b,3b\n" TENTRY)
@@ -437,16 +478,16 @@
 
 #define __asm_copy_from_user_5(to, from, ret) \
 	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"4:	move.b r9,[%0+]\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"4:	move.b $r9,[%0+]\n",		\
 		"5:	addq 1,%2\n"			\
 		"	clear.b [%0+]\n",		\
 		"	.dword 4b,5b\n")
 
 #define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	move.w [%1+],r9\n"		\
-		"4:	move.w r9,[%0+]\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"4:	move.w $r9,[%0+]\n" COPY,	\
 		"5:	addq 2,%2\n"			\
 		"	clear.w [%0+]\n" FIXUP,		\
 		"	.dword 4b,5b\n" TENTRY)
@@ -456,16 +497,16 @@
 
 #define __asm_copy_from_user_7(to, from, ret) \
 	__asm_copy_from_user_6x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"6:	move.b r9,[%0+]\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"6:	move.b $r9,[%0+]\n",		\
 		"7:	addq 1,%2\n"			\
 		"	clear.b [%0+]\n",		\
 		"	.dword 6b,7b\n")
 
 #define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_4x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"4:	move.d r9,[%0+]\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"4:	move.d $r9,[%0+]\n" COPY,	\
 		"5:	addq 4,%2\n"			\
 		"	clear.d [%0+]\n" FIXUP,		\
 		"	.dword 4b,5b\n" TENTRY)
@@ -475,16 +516,16 @@
 
 #define __asm_copy_from_user_9(to, from, ret) \
 	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"6:	move.b r9,[%0+]\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"6:	move.b $r9,[%0+]\n",		\
 		"7:	addq 1,%2\n"			\
 		"	clear.b [%0+]\n",		\
 		"	.dword 6b,7b\n")
 
 #define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	move.w [%1+],r9\n"		\
-		"6:	move.w r9,[%0+]\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"6:	move.w $r9,[%0+]\n" COPY,	\
 		"7:	addq 2,%2\n"			\
 		"	clear.w [%0+]\n" FIXUP,		\
 		"	.dword 6b,7b\n" TENTRY)
@@ -494,16 +535,16 @@
 
 #define __asm_copy_from_user_11(to, from, ret)		\
 	__asm_copy_from_user_10x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"8:	move.b r9,[%0+]\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"8:	move.b $r9,[%0+]\n",		\
 		"9:	addq 1,%2\n"			\
 		"	clear.b [%0+]\n",		\
 		"	.dword 8b,9b\n")
 
 #define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_8x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"6:	move.d r9,[%0+]\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"6:	move.d $r9,[%0+]\n" COPY,	\
 		"7:	addq 4,%2\n"			\
 		"	clear.d [%0+]\n" FIXUP,		\
 		"	.dword 6b,7b\n" TENTRY)
@@ -513,16 +554,16 @@
 
 #define __asm_copy_from_user_13(to, from, ret) \
 	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"8:	move.b r9,[%0+]\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"8:	move.b $r9,[%0+]\n",		\
 		"9:	addq 1,%2\n"			\
 		"	clear.b [%0+]\n",		\
 		"	.dword 8b,9b\n")
 
 #define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	move.w [%1+],r9\n"		\
-		"8:	move.w r9,[%0+]\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"8:	move.w $r9,[%0+]\n" COPY,	\
 		"9:	addq 2,%2\n"			\
 		"	clear.w [%0+]\n" FIXUP,		\
 		"	.dword 8b,9b\n" TENTRY)
@@ -532,16 +573,16 @@
 
 #define __asm_copy_from_user_15(to, from, ret) \
 	__asm_copy_from_user_14x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"10:	move.b r9,[%0+]\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"10:	move.b $r9,[%0+]\n",		\
 		"11:	addq 1,%2\n"			\
 		"	clear.b [%0+]\n",		\
 		"	.dword 10b,11b\n")
 
 #define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_12x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"8:	move.d r9,[%0+]\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"8:	move.d $r9,[%0+]\n" COPY,	\
 		"9:	addq 4,%2\n"			\
 		"	clear.d [%0+]\n" FIXUP,		\
 		"	.dword 8b,9b\n" TENTRY)
@@ -551,8 +592,8 @@
 
 #define __asm_copy_from_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_16x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"10:	move.d r9,[%0+]\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"10:	move.d $r9,[%0+]\n" COPY,	\
 		"11:	addq 4,%2\n"			\
 		"	clear.d [%0+]\n" FIXUP,		\
 		"	.dword 10b,11b\n" TENTRY)
@@ -562,8 +603,8 @@
 
 #define __asm_copy_from_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_from_user_20x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"12:	move.d r9,[%0+]\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"12:	move.d $r9,[%0+]\n" COPY,	\
 		"13:	addq 4,%2\n"			\
 		"	clear.d [%0+]\n" FIXUP,		\
 		"	.dword 12b,13b\n" TENTRY)
@@ -575,15 +616,15 @@
 
 #define __asm_copy_to_user_1(to, from, ret)	\
 	__asm_copy_user_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"	\
-		"	move.b r9,[%0+]\n2:\n",	\
+		"	move.b [%1+],$r9\n"	\
+		"	move.b $r9,[%0+]\n2:\n",	\
 		"3:	addq 1,%2\n",		\
 		"	.dword 2b,3b\n")
 
 #define __asm_copy_to_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_user_cont(to, from, ret,		\
-		"	move.w [%1+],r9\n"		\
-		"	move.w r9,[%0+]\n2:\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"	move.w $r9,[%0+]\n2:\n" COPY,	\
 		"3:	addq 2,%2\n" FIXUP,		\
 		"	.dword 2b,3b\n" TENTRY)
 
@@ -592,15 +633,15 @@
 
 #define __asm_copy_to_user_3(to, from, ret) \
 	__asm_copy_to_user_2x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"	move.b r9,[%0+]\n4:\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"	move.b $r9,[%0+]\n4:\n",		\
 		"5:	addq 1,%2\n",			\
 		"	.dword 4b,5b\n")
 
 #define __asm_copy_to_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_user_cont(to, from, ret,		\
-		"	move.d [%1+],r9\n"		\
-		"	move.d r9,[%0+]\n2:\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"	move.d $r9,[%0+]\n2:\n" COPY,	\
 		"3:	addq 4,%2\n" FIXUP,		\
 		"	.dword 2b,3b\n" TENTRY)
 
@@ -609,15 +650,15 @@
 
 #define __asm_copy_to_user_5(to, from, ret) \
 	__asm_copy_to_user_4x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"	move.b r9,[%0+]\n4:\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"	move.b $r9,[%0+]\n4:\n",		\
 		"5:	addq 1,%2\n",			\
 		"	.dword 4b,5b\n")
 
 #define __asm_copy_to_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_to_user_4x_cont(to, from, ret,	\
-		"	move.w [%1+],r9\n"		\
-		"	move.w r9,[%0+]\n4:\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"	move.w $r9,[%0+]\n4:\n" COPY,	\
 		"5:	addq 2,%2\n" FIXUP,		\
 		"	.dword 4b,5b\n" TENTRY)
 
@@ -626,15 +667,15 @@
 
 #define __asm_copy_to_user_7(to, from, ret) \
 	__asm_copy_to_user_6x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"	move.b r9,[%0+]\n6:\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"	move.b $r9,[%0+]\n6:\n",		\
 		"7:	addq 1,%2\n",			\
 		"	.dword 6b,7b\n")
 
 #define __asm_copy_to_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_to_user_4x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"	move.d r9,[%0+]\n4:\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"	move.d $r9,[%0+]\n4:\n" COPY,	\
 		"5:	addq 4,%2\n"  FIXUP,		\
 		"	.dword 4b,5b\n" TENTRY)
 
@@ -643,15 +684,15 @@
 
 #define __asm_copy_to_user_9(to, from, ret) \
 	__asm_copy_to_user_8x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"	move.b r9,[%0+]\n6:\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"	move.b $r9,[%0+]\n6:\n",		\
 		"7:	addq 1,%2\n",			\
 		"	.dword 6b,7b\n")
 
 #define __asm_copy_to_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_to_user_8x_cont(to, from, ret,	\
-		"	move.w [%1+],r9\n"		\
-		"	move.w r9,[%0+]\n6:\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"	move.w $r9,[%0+]\n6:\n" COPY,	\
 		"7:	addq 2,%2\n" FIXUP,		\
 		"	.dword 6b,7b\n" TENTRY)
 
@@ -660,15 +701,15 @@
 
 #define __asm_copy_to_user_11(to, from, ret) \
 	__asm_copy_to_user_10x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"	move.b r9,[%0+]\n8:\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"	move.b $r9,[%0+]\n8:\n",		\
 		"9:	addq 1,%2\n",			\
 		"	.dword 8b,9b\n")
 
 #define __asm_copy_to_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_to_user_8x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"	move.d r9,[%0+]\n6:\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"	move.d $r9,[%0+]\n6:\n" COPY,	\
 		"7:	addq 4,%2\n" FIXUP,		\
 		"	.dword 6b,7b\n" TENTRY)
 
@@ -677,15 +718,15 @@
 
 #define __asm_copy_to_user_13(to, from, ret) \
 	__asm_copy_to_user_12x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"	move.b r9,[%0+]\n8:\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"	move.b $r9,[%0+]\n8:\n",		\
 		"9:	addq 1,%2\n",			\
 		"	.dword 8b,9b\n")
 
 #define __asm_copy_to_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_to_user_12x_cont(to, from, ret,	\
-		"	move.w [%1+],r9\n"		\
-		"	move.w r9,[%0+]\n8:\n" COPY,	\
+		"	move.w [%1+],$r9\n"		\
+		"	move.w $r9,[%0+]\n8:\n" COPY,	\
 		"9:	addq 2,%2\n" FIXUP,		\
 		"	.dword 8b,9b\n" TENTRY)
 
@@ -694,15 +735,15 @@
 
 #define __asm_copy_to_user_15(to, from, ret) \
 	__asm_copy_to_user_14x_cont(to, from, ret,	\
-		"	move.b [%1+],r9\n"		\
-		"	move.b r9,[%0+]\n10:\n",		\
+		"	move.b [%1+],$r9\n"		\
+		"	move.b $r9,[%0+]\n10:\n",		\
 		"11:	addq 1,%2\n",			\
 		"	.dword 10b,11b\n")
 
 #define __asm_copy_to_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_to_user_12x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"	move.d r9,[%0+]\n8:\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"	move.d $r9,[%0+]\n8:\n" COPY,	\
 		"9:	addq 4,%2\n" FIXUP,		\
 		"	.dword 8b,9b\n" TENTRY)
 
@@ -711,8 +752,8 @@
 
 #define __asm_copy_to_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
 	__asm_copy_to_user_16x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"	move.d r9,[%0+]\n10:\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"	move.d $r9,[%0+]\n10:\n" COPY,	\
 		"11:	addq 4,%2\n" FIXUP,		\
 		"	.dword 10b,11b\n" TENTRY)
 
@@ -721,8 +762,8 @@
 
 #define __asm_copy_to_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY)	\
 	__asm_copy_to_user_20x_cont(to, from, ret,	\
-		"	move.d [%1+],r9\n"		\
-		"	move.d r9,[%0+]\n12:\n" COPY,	\
+		"	move.d [%1+],$r9\n"		\
+		"	move.d $r9,[%0+]\n12:\n" COPY,	\
 		"13:	addq 4,%2\n" FIXUP,		\
 		"	.dword 12b,13b\n" TENTRY)
 
@@ -1034,17 +1075,17 @@
 	 */
 
 	__asm__ __volatile__ (
-		"	move.d %1,r9\n"
+		"	move.d %1,$r9\n"
 		"0:\n"
 		"	ble 1f\n"
-		"	subq 1,r9\n"
+		"	subq 1,$r9\n"
 
 		"	test.b [%0+]\n"
 		"	bne 0b\n"
-		"	test.d r9\n"
+		"	test.d $r9\n"
 		"1:\n"
 		"	move.d %1,%0\n"
-		"	sub.d r9,%0\n"
+		"	sub.d $r9,%0\n"
 		"2:\n"
 		"	.section .fixup,\"ax\"\n"
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/apic.h linux/include/asm-i386/apic.h
--- v2.4.10/linux/include/asm-i386/apic.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-i386/apic.h	Tue Oct  9 15:22:14 2001
@@ -64,6 +64,7 @@
 }
 
 extern int get_maxlvt(void);
+extern void clear_local_APIC(void);
 extern void connect_bsp_APIC (void);
 extern void disconnect_bsp_APIC (void);
 extern void disable_local_APIC (void);
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/highmem.h linux/include/asm-i386/highmem.h
--- v2.4.10/linux/include/asm-i386/highmem.h	Tue Aug  7 12:48:43 2001
+++ linux/include/asm-i386/highmem.h	Tue Oct  9 15:22:14 2001
@@ -26,8 +26,11 @@
 #include <asm/kmap_types.h>
 #include <asm/pgtable.h>
 
-/* undef for production */
+#ifdef CONFIG_DEBUG_HIGHMEM
 #define HIGHMEM_DEBUG 1
+#else
+#define HIGHMEM_DEBUG 0
+#endif
 
 /* declarations for highmem.c */
 extern unsigned long highstart_pfn, highend_pfn;
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/io.h linux/include/asm-i386/io.h
--- v2.4.10/linux/include/asm-i386/io.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-i386/io.h	Tue Oct  9 15:22:37 2001
@@ -36,75 +36,11 @@
   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   */
 
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
-#else
-#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
-#endif
-
-#ifdef REALLY_SLOW_IO
-#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
-#else
-#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
-#endif
-
-/*
- * Talk about misusing macros..
- */
-#define __OUT1(s,x) \
-static inline void out##s(unsigned x value, unsigned short port) {
-
-#define __OUT2(s,s1,s2) \
-__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
-
-#define __OUT(s,s1,x) \
-__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
-__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
-
-#define __IN1(s) \
-static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
-
-#define __IN2(s,s1,s2) \
-__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
-
-#define __IN(s,s1,i...) \
-__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-
-#define __INS(s) \
-static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
-{ __asm__ __volatile__ ("rep ; ins" #s \
-: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
-
-#define __OUTS(s) \
-static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
-{ __asm__ __volatile__ ("rep ; outs" #s \
-: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
-
-#define RETURN_TYPE unsigned char
-__IN(b,"")
-#undef RETURN_TYPE
-#define RETURN_TYPE unsigned short
-__IN(w,"")
-#undef RETURN_TYPE
-#define RETURN_TYPE unsigned int
-__IN(l,"")
-#undef RETURN_TYPE
-
-__OUT(b,"b",char)
-__OUT(w,"w",short)
-__OUT(l,,int)
-
-__INS(b)
-__INS(w)
-__INS(l)
-
-__OUTS(b)
-__OUTS(w)
-__OUTS(l)
-
 #define IO_SPACE_LIMIT 0xffff
 
+#define XQUAD_PORTIO_BASE 0xfe400000
+#define XQUAD_PORTIO_LEN  0x40000   /* 256k per quad. Only remapping 1st */
+
 #ifdef __KERNEL__
 
 #include <linux/vmalloc.h>
@@ -260,5 +196,111 @@
 #define dma_cache_wback_inv(_start,_size)	do { } while (0)
 
 #endif /* __KERNEL__ */
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
+#else
+#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
+#endif
+
+#ifdef REALLY_SLOW_IO
+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
+#else
+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+#ifdef CONFIG_MULTIQUAD
+extern void *xquad_portio;    /* Where the IO area was mapped */
+#endif /* CONFIG_MULTIQUAD */
+
+/*
+ * Talk about misusing macros..
+ */
+#define __OUT1(s,x) \
+static inline void out##s(unsigned x value, unsigned short port) {
+
+#define __OUT2(s,s1,s2) \
+__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
+
+#ifdef CONFIG_MULTIQUAD
+/* Make the default portio routines operate on quad 0 for now */
+#define __OUT(s,s1,x) \
+__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
+__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
+__OUTQ0(s,s,x) \
+__OUTQ0(s,s##_p,x) 
+#else
+#define __OUT(s,s1,x) \
+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
+__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} 
+#endif /* CONFIG_MULTIQUAD */
+
+#ifdef CONFIG_MULTIQUAD
+#define __OUTQ0(s,ss,x)    /* Do the equivalent of the portio op on quad 0 */ \
+static inline void out##ss(unsigned x value, unsigned short port) { \
+	if (xquad_portio) \
+		write##s(value, (unsigned long) xquad_portio + port); \
+	else               /* We're still in early boot, running on quad 0 */ \
+		out##ss##_local(value, port); \
+} 
+
+#define __INQ0(s,ss)       /* Do the equivalent of the portio op on quad 0 */ \
+static inline RETURN_TYPE in##ss(unsigned short port) { \
+	if (xquad_portio) \
+		return read##s((unsigned long) xquad_portio + port); \
+	else               /* We're still in early boot, running on quad 0 */ \
+		return in##ss##_local(port); \
+}
+#endif /* CONFIG_MULTIQUAD */
+
+#define __IN1(s) \
+static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
+
+#define __IN2(s,s1,s2) \
+__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
+
+#ifdef CONFIG_MULTIQUAD
+#define __IN(s,s1,i...) \
+__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__INQ0(s,s) \
+__INQ0(s,s##_p) 
+#else
+#define __IN(s,s1,i...) \
+__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
+__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } 
+#endif /* CONFIG_MULTIQUAD */
+
+#define __INS(s) \
+static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("rep ; ins" #s \
+: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+#define __OUTS(s) \
+static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("rep ; outs" #s \
+: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+#define RETURN_TYPE unsigned char
+__IN(b,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned short
+__IN(w,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned int
+__IN(l,"")
+#undef RETURN_TYPE
+
+__OUT(b,"b",char)
+__OUT(w,"w",short)
+__OUT(l,,int)
+
+__INS(b)
+__INS(w)
+__INS(l)
+
+__OUTS(b)
+__OUTS(w)
+__OUTS(l)
 
 #endif
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/io_apic.h linux/include/asm-i386/io_apic.h
--- v2.4.10/linux/include/asm-i386/io_apic.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-i386/io_apic.h	Tue Oct  9 15:22:13 2001
@@ -28,7 +28,8 @@
 
 struct IO_APIC_reg_01 {
 	__u32	version		:  8,
-		__reserved_2	:  8,
+		__reserved_2	:  7,
+		PRQ		:  1,
 		entries		:  8,
 		__reserved_1	:  8;
 } __attribute__ ((packed));
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/mpspec.h linux/include/asm-i386/mpspec.h
--- v2.4.10/linux/include/asm-i386/mpspec.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-i386/mpspec.h	Thu Oct  4 18:42:54 2001
@@ -156,7 +156,7 @@
  *	7	2 CPU MCA+PCI
  */
 
-#define MAX_IRQ_SOURCES 128
+#define MAX_IRQ_SOURCES 256
 #define MAX_MP_BUSSES 32
 enum mp_bustype {
 	MP_BUS_ISA = 1,
@@ -167,7 +167,7 @@
 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
 extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 
-extern unsigned int boot_cpu_id;
+extern unsigned int boot_cpu_physical_apicid;
 extern unsigned long phys_cpu_present_map;
 extern int smp_found_config;
 extern void find_smp_config (void);
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h
--- v2.4.10/linux/include/asm-i386/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-i386/processor.h	Tue Oct  9 15:22:14 2001
@@ -476,6 +476,8 @@
 	__asm__ __volatile__("rep;nop");
 }
 
+#define cpu_relax()	rep_nop()
+
 /* Prefetch instructions for Pentium III and AMD Athlon */
 #ifdef 	CONFIG_MPENTIUMIII
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v2.4.10/linux/include/asm-i386/smp.h	Sun Aug 12 13:28:00 2001
+++ linux/include/asm-i386/smp.h	Tue Oct  9 15:22:14 2001
@@ -4,14 +4,14 @@
 /*
  * We need the APIC definitions automatically as part of 'smp.h'
  */
-#ifndef ASSEMBLY
+#ifndef __ASSEMBLY__
 #include <linux/config.h>
 #include <linux/threads.h>
 #include <linux/ptrace.h>
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
-#ifndef ASSEMBLY
+#ifndef __ASSEMBLY__
 #include <asm/fixmap.h>
 #include <asm/bitops.h>
 #include <asm/mpspec.h>
@@ -23,7 +23,30 @@
 #endif
 
 #ifdef CONFIG_SMP
-#ifndef ASSEMBLY
+# ifdef CONFIG_MULTIQUAD
+#  define TARGET_CPUS 0xf     /* all CPUs in *THIS* quad */
+#  define INT_DELIVERY_MODE 0     /* physical delivery on LOCAL quad */
+# else
+#  define TARGET_CPUS cpu_online_map
+#  define INT_DELIVERY_MODE 1     /* logical delivery broadcast to all procs */
+# endif
+#else
+# define INT_DELIVERY_MODE 0     /* physical delivery on LOCAL quad */
+# define TARGET_CPUS 0x01
+#endif
+
+#ifndef clustered_apic_mode
+ #ifdef CONFIG_MULTIQUAD
+  #define clustered_apic_mode (1)
+  #define esr_disable (1)
+ #else /* !CONFIG_MULTIQUAD */
+  #define clustered_apic_mode (0)
+  #define esr_disable (0)
+ #endif /* CONFIG_MULTIQUAD */
+#endif 
+
+#ifdef CONFIG_SMP
+#ifndef __ASSEMBLY__
 
 /*
  * Private routines/data
@@ -59,8 +82,11 @@
  * Some lowlevel functions might want to know about
  * the real APIC ID <-> CPU # mapping.
  */
-extern volatile int x86_apicid_to_cpu[NR_CPUS];
-extern volatile int x86_cpu_to_apicid[NR_CPUS];
+#define MAX_APICID 256
+extern volatile int cpu_to_physical_apicid[NR_CPUS];
+extern volatile int physical_apicid_to_cpu[MAX_APICID];
+extern volatile int cpu_to_logical_apicid[NR_CPUS];
+extern volatile int logical_apicid_to_cpu[MAX_APICID];
 
 /*
  * General functions that each host system must provide.
@@ -83,7 +109,13 @@
 	return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID));
 }
 
-#endif /* !ASSEMBLY */
+extern __inline int logical_smp_processor_id(void)
+{
+	/* we don't want to mark this access volatile - bad code generation */
+	return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
+}
+
+#endif /* !__ASSEMBLY__ */
 
 #define NO_PROC_ID		0xFF		/* No processor magic marker */
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/smpboot.h linux/include/asm-i386/smpboot.h
--- v2.4.10/linux/include/asm-i386/smpboot.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-i386/smpboot.h	Tue Oct  9 15:22:13 2001
@@ -0,0 +1,62 @@
+#ifndef __ASM_SMPBOOT_H
+#define __ASM_SMPBOOT_H
+
+#ifndef clustered_apic_mode
+ #ifdef CONFIG_MULTIQUAD
+  #define clustered_apic_mode (1)
+ #else /* !CONFIG_MULTIQUAD */
+  #define clustered_apic_mode (0)
+ #endif /* CONFIG_MULTIQUAD */
+#endif 
+ 
+#ifdef CONFIG_MULTIQUAD
+ #define TRAMPOLINE_LOW phys_to_virt(0x8)
+ #define TRAMPOLINE_HIGH phys_to_virt(0xa)
+#else /* !CONFIG_MULTIQUAD */
+ #define TRAMPOLINE_LOW phys_to_virt(0x467)
+ #define TRAMPOLINE_HIGH phys_to_virt(0x469)
+#endif /* CONFIG_MULTIQUAD */
+
+#ifdef CONFIG_MULTIQUAD
+ #define boot_cpu_apicid boot_cpu_logical_apicid
+#else /* !CONFIG_MULTIQUAD */
+ #define boot_cpu_apicid boot_cpu_physical_apicid
+#endif /* CONFIG_MULTIQUAD */
+
+/*
+ * How to map from the cpu_present_map
+ */
+#ifdef CONFIG_MULTIQUAD
+ #define cpu_present_to_apicid(mps_cpu) ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) )
+#else /* !CONFIG_MULTIQUAD */
+ #define cpu_present_to_apicid(apicid) (apicid)
+#endif /* CONFIG_MULTIQUAD */
+
+/*
+ * Mappings between logical cpu number and logical / physical apicid
+ * The first four macros are trivial, but it keeps the abstraction consistent
+ */
+extern volatile int logical_apicid_2_cpu[];
+extern volatile int cpu_2_logical_apicid[];
+extern volatile int physical_apicid_2_cpu[];
+extern volatile int cpu_2_physical_apicid[];
+
+#define logical_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
+#define cpu_to_logical_apicid(cpu) cpu_2_logical_apicid[cpu]
+#define physical_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
+#define cpu_to_physical_apicid(cpu) cpu_2_physical_apicid[cpu]
+#ifdef CONFIG_MULTIQUAD			/* use logical IDs to bootstrap */
+#define boot_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
+#define cpu_to_boot_apicid(cpu) cpu_2_logical_apicid[cpu]
+#else /* !CONFIG_MULTIQUAD */		/* use physical IDs to bootstrap */
+#define boot_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
+#define cpu_to_boot_apicid(cpu) cpu_2_physical_apicid[cpu]
+#endif /* CONFIG_MULTIQUAD */
+
+
+#ifdef CONFIG_MULTIQUAD
+#else /* !CONFIG_MULTIQUAD */
+#endif /* CONFIG_MULTIQUAD */
+
+
+#endif
diff -u --recursive --new-file v2.4.10/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.4.10/linux/include/asm-i386/unistd.h	Fri Aug 11 14:39:23 2000
+++ linux/include/asm-i386/unistd.h	Mon Oct  8 10:40:16 2001
@@ -227,6 +227,8 @@
 #define __NR_madvise1		219	/* delete when C lib stub is removed */
 #define __NR_getdents64		220
 #define __NR_fcntl64		221
+#define __NR_security		223	/* syscall for security modules */
+#define __NR_gettid		224
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-ia64/module.h linux/include/asm-ia64/module.h
--- v2.4.10/linux/include/asm-ia64/module.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-ia64/module.h	Sun Sep 30 12:26:08 2001
@@ -14,7 +14,13 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		ia64_module_unmap(x)
 #define module_arch_init(x)	ia64_module_init(x)
-#define arch_init_modules(x)	do { } while (0)
+#define arch_init_modules(x)	{ 	static struct archdata archdata; \
+					register char *kernel_gp asm ("gp");\
+					archdata.gp = kernel_gp; \
+					kernel_module.archdata_start = (const char *) &archdata; \
+					kernel_module.archdata_end   = (const char *) (&archdata + 1); \
+				}
+		
 
 /*
  * This must match in size and layout the data created by
diff -u --recursive --new-file v2.4.10/linux/include/asm-ia64/processor.h linux/include/asm-ia64/processor.h
--- v2.4.10/linux/include/asm-ia64/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-ia64/processor.h	Fri Oct  5 12:11:05 2001
@@ -969,6 +969,8 @@
 	return result;
 }
 
+#define cpu_relax()	do { } while (0)
+
 
 #define ARCH_HAS_PREFETCH
 #define ARCH_HAS_PREFETCHW
diff -u --recursive --new-file v2.4.10/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h
--- v2.4.10/linux/include/asm-m68k/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-m68k/processor.h	Fri Oct  5 12:11:05 2001
@@ -155,4 +155,6 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 #endif
diff -u --recursive --new-file v2.4.10/linux/include/asm-mips/processor.h linux/include/asm-mips/processor.h
--- v2.4.10/linux/include/asm-mips/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-mips/processor.h	Fri Oct  5 12:11:05 2001
@@ -259,6 +259,8 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-mips64/processor.h linux/include/asm-mips64/processor.h
--- v2.4.10/linux/include/asm-mips64/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-mips64/processor.h	Fri Oct  5 12:11:05 2001
@@ -290,6 +290,8 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-parisc/processor.h linux/include/asm-parisc/processor.h
--- v2.4.10/linux/include/asm-parisc/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-parisc/processor.h	Fri Oct  5 12:11:05 2001
@@ -333,5 +333,7 @@
 #define init_task (init_task_union.task) 
 #define init_stack (init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 
 #endif /* __ASM_PARISC_PROCESSOR_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-ppc/commproc.h linux/include/asm-ppc/commproc.h
--- v2.4.10/linux/include/asm-ppc/commproc.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/commproc.h	Mon Oct  8 11:40:13 2001
@@ -0,0 +1,796 @@
+/*
+ * BK Id: SCCS/s.commproc.h 1.16 09/27/01 12:41:09 trini
+ */
+
+/*
+ * MPC8xx Communication Processor Module.
+ * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * This file contains structures and information for the communication
+ * processor channels.  Some CPM control and status is available
+ * throught the MPC8xx internal memory map.  See immap.h for details.
+ * This file only contains what I need for the moment, not the total
+ * CPM capabilities.  I (or someone else) will add definitions as they
+ * are needed.  -- Dan
+ *
+ * On the MBX board, EPPC-Bug loads CPM microcode into the first 512
+ * bytes of the DP RAM and relocates the I2C parameter area to the
+ * IDMA1 space.  The remaining DP RAM is available for buffer descriptors
+ * or other use.
+ */
+#ifndef __CPM_8XX__
+#define __CPM_8XX__
+
+#include <linux/config.h>
+#include <asm/8xx_immap.h>
+
+/* CPM Command register.
+*/
+#define CPM_CR_RST	((ushort)0x8000)
+#define CPM_CR_OPCODE	((ushort)0x0f00)
+#define CPM_CR_CHAN	((ushort)0x00f0)
+#define CPM_CR_FLG	((ushort)0x0001)
+
+/* Some commands (there are more...later)
+*/
+#define CPM_CR_INIT_TRX		((ushort)0x0000)
+#define CPM_CR_INIT_RX		((ushort)0x0001)
+#define CPM_CR_INIT_TX		((ushort)0x0002)
+#define CPM_CR_HUNT_MODE	((ushort)0x0003)
+#define CPM_CR_STOP_TX		((ushort)0x0004)
+#define CPM_CR_RESTART_TX	((ushort)0x0006)
+#define CPM_CR_SET_GADDR	((ushort)0x0008)
+
+/* Channel numbers.
+*/
+#define CPM_CR_CH_SCC1	((ushort)0x0000)
+#define CPM_CR_CH_I2C	((ushort)0x0001)	/* I2C and IDMA1 */
+#define CPM_CR_CH_SCC2	((ushort)0x0004)
+#define CPM_CR_CH_SPI	((ushort)0x0005)	/* SPI / IDMA2 / Timers */
+#define CPM_CR_CH_SCC3	((ushort)0x0008)
+#define CPM_CR_CH_SMC1	((ushort)0x0009)	/* SMC1 / DSP1 */
+#define CPM_CR_CH_SCC4	((ushort)0x000c)
+#define CPM_CR_CH_SMC2	((ushort)0x000d)	/* SMC2 / DSP2 */
+
+#define mk_cr_cmd(CH, CMD)	((CMD << 8) | (CH << 4))
+
+/* The dual ported RAM is multi-functional.  Some areas can be (and are
+ * being) used for microcode.  There is an area that can only be used
+ * as data ram for buffer descriptors, which is all we use right now.
+ * Currently the first 512 and last 256 bytes are used for microcode.
+ */
+#define CPM_DATAONLY_BASE	((uint)0x0800)
+#define CPM_DATAONLY_SIZE	((uint)0x0700)
+#define CPM_DP_NOSPACE		((uint)0x7fffffff)
+
+/* Export the base address of the communication processor registers
+ * and dual port ram.
+ */
+extern	cpm8xx_t	*cpmp;		/* Pointer to comm processor */
+uint		m8xx_cpm_dpalloc(uint size);
+uint		m8xx_cpm_hostalloc(uint size);
+void		m8xx_cpm_setbrg(uint brg, uint rate);
+
+/* Buffer descriptors used by many of the CPM protocols.
+*/
+typedef struct cpm_buf_desc {
+	ushort	cbd_sc;		/* Status and Control */
+	ushort	cbd_datlen;	/* Data length in buffer */
+	uint	cbd_bufaddr;	/* Buffer address in host memory */
+} cbd_t;
+
+#define BD_SC_EMPTY	((ushort)0x8000)	/* Receive is empty */
+#define BD_SC_READY	((ushort)0x8000)	/* Transmit is ready */
+#define BD_SC_WRAP	((ushort)0x2000)	/* Last buffer descriptor */
+#define BD_SC_INTRPT	((ushort)0x1000)	/* Interrupt on change */
+#define BD_SC_LAST	((ushort)0x0800)	/* Last buffer in frame */
+#define BD_SC_CM	((ushort)0x0200)	/* Continous mode */
+#define BD_SC_ID	((ushort)0x0100)	/* Rec'd too many idles */
+#define BD_SC_P		((ushort)0x0100)	/* xmt preamble */
+#define BD_SC_BR	((ushort)0x0020)	/* Break received */
+#define BD_SC_FR	((ushort)0x0010)	/* Framing error */
+#define BD_SC_PR	((ushort)0x0008)	/* Parity error */
+#define BD_SC_OV	((ushort)0x0002)	/* Overrun */
+#define BD_SC_CD	((ushort)0x0001)	/* ?? */
+
+/* Parameter RAM offsets.
+*/
+#define PROFF_SCC1	((uint)0x0000)
+#define PROFF_IIC	((uint)0x0080)
+#define PROFF_SCC2	((uint)0x0100)
+#define PROFF_SCC3	((uint)0x0200)
+#define PROFF_SMC1	((uint)0x0280)
+#define PROFF_SCC4	((uint)0x0300)
+#define PROFF_SMC2	((uint)0x0380)
+
+/* Define enough so I can at least use the serial port as a UART.
+ * The MBX uses SMC1 as the host serial port.
+ */
+typedef struct smc_uart {
+	ushort	smc_rbase;	/* Rx Buffer descriptor base address */
+	ushort	smc_tbase;	/* Tx Buffer descriptor base address */
+	u_char	smc_rfcr;	/* Rx function code */
+	u_char	smc_tfcr;	/* Tx function code */
+	ushort	smc_mrblr;	/* Max receive buffer length */
+	uint	smc_rstate;	/* Internal */
+	uint	smc_idp;	/* Internal */
+	ushort	smc_rbptr;	/* Internal */
+	ushort	smc_ibc;	/* Internal */
+	uint	smc_rxtmp;	/* Internal */
+	uint	smc_tstate;	/* Internal */
+	uint	smc_tdp;	/* Internal */
+	ushort	smc_tbptr;	/* Internal */
+	ushort	smc_tbc;	/* Internal */
+	uint	smc_txtmp;	/* Internal */
+	ushort	smc_maxidl;	/* Maximum idle characters */
+	ushort	smc_tmpidl;	/* Temporary idle counter */
+	ushort	smc_brklen;	/* Last received break length */
+	ushort	smc_brkec;	/* rcv'd break condition counter */
+	ushort	smc_brkcr;	/* xmt break count register */
+	ushort	smc_rmask;	/* Temporary bit mask */
+} smc_uart_t;
+
+/* Function code bits.
+*/
+#define SMC_EB	((u_char)0x10)	/* Set big endian byte order */
+
+/* SMC uart mode register.
+*/
+#define	SMCMR_REN	((ushort)0x0001)
+#define SMCMR_TEN	((ushort)0x0002)
+#define SMCMR_DM	((ushort)0x000c)
+#define SMCMR_SM_GCI	((ushort)0x0000)
+#define SMCMR_SM_UART	((ushort)0x0020)
+#define SMCMR_SM_TRANS	((ushort)0x0030)
+#define SMCMR_SM_MASK	((ushort)0x0030)
+#define SMCMR_PM_EVEN	((ushort)0x0100)	/* Even parity, else odd */
+#define SMCMR_REVD	SMCMR_PM_EVEN
+#define SMCMR_PEN	((ushort)0x0200)	/* Parity enable */
+#define SMCMR_BS	SMCMR_PEN
+#define SMCMR_SL	((ushort)0x0400)	/* Two stops, else one */
+#define SMCR_CLEN_MASK	((ushort)0x7800)	/* Character length */
+#define smcr_mk_clen(C)	(((C) << 11) & SMCR_CLEN_MASK)
+
+/* SMC2 as Centronics parallel printer.  It is half duplex, in that
+ * it can only receive or transmit.  The parameter ram values for
+ * each direction are either unique or properly overlap, so we can
+ * include them in one structure.
+ */
+typedef struct smc_centronics {
+	ushort	scent_rbase;
+	ushort	scent_tbase;
+	u_char	scent_cfcr;
+	u_char	scent_smask;
+	ushort	scent_mrblr;
+	uint	scent_rstate;
+	uint	scent_r_ptr;
+	ushort	scent_rbptr;
+	ushort	scent_r_cnt;
+	uint	scent_rtemp;
+	uint	scent_tstate;
+	uint	scent_t_ptr;
+	ushort	scent_tbptr;
+	ushort	scent_t_cnt;
+	uint	scent_ttemp;
+	ushort	scent_max_sl;
+	ushort	scent_sl_cnt;
+	ushort	scent_character1;
+	ushort	scent_character2;
+	ushort	scent_character3;
+	ushort	scent_character4;
+	ushort	scent_character5;
+	ushort	scent_character6;
+	ushort	scent_character7;
+	ushort	scent_character8;
+	ushort	scent_rccm;
+	ushort	scent_rccr;
+} smc_cent_t;
+
+/* Centronics Status Mask Register.
+*/
+#define SMC_CENT_F	((u_char)0x08)
+#define SMC_CENT_PE	((u_char)0x04)
+#define SMC_CENT_S	((u_char)0x02)
+
+/* SMC Event and Mask register.
+*/
+#define	SMCM_BRKE	((unsigned char)0x40)	/* When in UART Mode */
+#define	SMCM_BRK	((unsigned char)0x10)	/* When in UART Mode */
+#define	SMCM_TXE	((unsigned char)0x10)	/* When in Transparent Mode */
+#define	SMCM_BSY	((unsigned char)0x04)
+#define	SMCM_TX		((unsigned char)0x02)
+#define	SMCM_RX		((unsigned char)0x01)
+
+/* Baud rate generators.
+*/
+#define CPM_BRG_RST		((uint)0x00020000)
+#define CPM_BRG_EN		((uint)0x00010000)
+#define CPM_BRG_EXTC_INT	((uint)0x00000000)
+#define CPM_BRG_EXTC_CLK2	((uint)0x00004000)
+#define CPM_BRG_EXTC_CLK6	((uint)0x00008000)
+#define CPM_BRG_ATB		((uint)0x00002000)
+#define CPM_BRG_CD_MASK		((uint)0x00001ffe)
+#define CPM_BRG_DIV16		((uint)0x00000001)
+
+/* SCCs.
+*/
+#define SCC_GSMRH_IRP		((uint)0x00040000)
+#define SCC_GSMRH_GDE		((uint)0x00010000)
+#define SCC_GSMRH_TCRC_CCITT	((uint)0x00008000)
+#define SCC_GSMRH_TCRC_BISYNC	((uint)0x00004000)
+#define SCC_GSMRH_TCRC_HDLC	((uint)0x00000000)
+#define SCC_GSMRH_REVD		((uint)0x00002000)
+#define SCC_GSMRH_TRX		((uint)0x00001000)
+#define SCC_GSMRH_TTX		((uint)0x00000800)
+#define SCC_GSMRH_CDP		((uint)0x00000400)
+#define SCC_GSMRH_CTSP		((uint)0x00000200)
+#define SCC_GSMRH_CDS		((uint)0x00000100)
+#define SCC_GSMRH_CTSS		((uint)0x00000080)
+#define SCC_GSMRH_TFL		((uint)0x00000040)
+#define SCC_GSMRH_RFW		((uint)0x00000020)
+#define SCC_GSMRH_TXSY		((uint)0x00000010)
+#define SCC_GSMRH_SYNL16	((uint)0x0000000c)
+#define SCC_GSMRH_SYNL8		((uint)0x00000008)
+#define SCC_GSMRH_SYNL4		((uint)0x00000004)
+#define SCC_GSMRH_RTSM		((uint)0x00000002)
+#define SCC_GSMRH_RSYN		((uint)0x00000001)
+
+#define SCC_GSMRL_SIR		((uint)0x80000000)	/* SCC2 only */
+#define SCC_GSMRL_EDGE_NONE	((uint)0x60000000)
+#define SCC_GSMRL_EDGE_NEG	((uint)0x40000000)
+#define SCC_GSMRL_EDGE_POS	((uint)0x20000000)
+#define SCC_GSMRL_EDGE_BOTH	((uint)0x00000000)
+#define SCC_GSMRL_TCI		((uint)0x10000000)
+#define SCC_GSMRL_TSNC_3	((uint)0x0c000000)
+#define SCC_GSMRL_TSNC_4	((uint)0x08000000)
+#define SCC_GSMRL_TSNC_14	((uint)0x04000000)
+#define SCC_GSMRL_TSNC_INF	((uint)0x00000000)
+#define SCC_GSMRL_RINV		((uint)0x02000000)
+#define SCC_GSMRL_TINV		((uint)0x01000000)
+#define SCC_GSMRL_TPL_128	((uint)0x00c00000)
+#define SCC_GSMRL_TPL_64	((uint)0x00a00000)
+#define SCC_GSMRL_TPL_48	((uint)0x00800000)
+#define SCC_GSMRL_TPL_32	((uint)0x00600000)
+#define SCC_GSMRL_TPL_16	((uint)0x00400000)
+#define SCC_GSMRL_TPL_8		((uint)0x00200000)
+#define SCC_GSMRL_TPL_NONE	((uint)0x00000000)
+#define SCC_GSMRL_TPP_ALL1	((uint)0x00180000)
+#define SCC_GSMRL_TPP_01	((uint)0x00100000)
+#define SCC_GSMRL_TPP_10	((uint)0x00080000)
+#define SCC_GSMRL_TPP_ZEROS	((uint)0x00000000)
+#define SCC_GSMRL_TEND		((uint)0x00040000)
+#define SCC_GSMRL_TDCR_32	((uint)0x00030000)
+#define SCC_GSMRL_TDCR_16	((uint)0x00020000)
+#define SCC_GSMRL_TDCR_8	((uint)0x00010000)
+#define SCC_GSMRL_TDCR_1	((uint)0x00000000)
+#define SCC_GSMRL_RDCR_32	((uint)0x0000c000)
+#define SCC_GSMRL_RDCR_16	((uint)0x00008000)
+#define SCC_GSMRL_RDCR_8	((uint)0x00004000)
+#define SCC_GSMRL_RDCR_1	((uint)0x00000000)
+#define SCC_GSMRL_RENC_DFMAN	((uint)0x00003000)
+#define SCC_GSMRL_RENC_MANCH	((uint)0x00002000)
+#define SCC_GSMRL_RENC_FM0	((uint)0x00001000)
+#define SCC_GSMRL_RENC_NRZI	((uint)0x00000800)
+#define SCC_GSMRL_RENC_NRZ	((uint)0x00000000)
+#define SCC_GSMRL_TENC_DFMAN	((uint)0x00000600)
+#define SCC_GSMRL_TENC_MANCH	((uint)0x00000400)
+#define SCC_GSMRL_TENC_FM0	((uint)0x00000200)
+#define SCC_GSMRL_TENC_NRZI	((uint)0x00000100)
+#define SCC_GSMRL_TENC_NRZ	((uint)0x00000000)
+#define SCC_GSMRL_DIAG_LE	((uint)0x000000c0)	/* Loop and echo */
+#define SCC_GSMRL_DIAG_ECHO	((uint)0x00000080)
+#define SCC_GSMRL_DIAG_LOOP	((uint)0x00000040)
+#define SCC_GSMRL_DIAG_NORM	((uint)0x00000000)
+#define SCC_GSMRL_ENR		((uint)0x00000020)
+#define SCC_GSMRL_ENT		((uint)0x00000010)
+#define SCC_GSMRL_MODE_ENET	((uint)0x0000000c)
+#define SCC_GSMRL_MODE_DDCMP	((uint)0x00000009)
+#define SCC_GSMRL_MODE_BISYNC	((uint)0x00000008)
+#define SCC_GSMRL_MODE_V14	((uint)0x00000007)
+#define SCC_GSMRL_MODE_AHDLC	((uint)0x00000006)
+#define SCC_GSMRL_MODE_PROFIBUS	((uint)0x00000005)
+#define SCC_GSMRL_MODE_UART	((uint)0x00000004)
+#define SCC_GSMRL_MODE_SS7	((uint)0x00000003)
+#define SCC_GSMRL_MODE_ATALK	((uint)0x00000002)
+#define SCC_GSMRL_MODE_HDLC	((uint)0x00000000)
+
+#define SCC_TODR_TOD		((ushort)0x8000)
+
+/* SCC Event and Mask register.
+*/
+#define	SCCM_TXE	((unsigned char)0x10)
+#define	SCCM_BSY	((unsigned char)0x04)
+#define	SCCM_TX		((unsigned char)0x02)
+#define	SCCM_RX		((unsigned char)0x01)
+
+typedef struct scc_param {
+	ushort	scc_rbase;	/* Rx Buffer descriptor base address */
+	ushort	scc_tbase;	/* Tx Buffer descriptor base address */
+	u_char	scc_rfcr;	/* Rx function code */
+	u_char	scc_tfcr;	/* Tx function code */
+	ushort	scc_mrblr;	/* Max receive buffer length */
+	uint	scc_rstate;	/* Internal */
+	uint	scc_idp;	/* Internal */
+	ushort	scc_rbptr;	/* Internal */
+	ushort	scc_ibc;	/* Internal */
+	uint	scc_rxtmp;	/* Internal */
+	uint	scc_tstate;	/* Internal */
+	uint	scc_tdp;	/* Internal */
+	ushort	scc_tbptr;	/* Internal */
+	ushort	scc_tbc;	/* Internal */
+	uint	scc_txtmp;	/* Internal */
+	uint	scc_rcrc;	/* Internal */
+	uint	scc_tcrc;	/* Internal */
+} sccp_t;
+
+/* Function code bits.
+*/
+#define SCC_EB	((u_char)0x10)	/* Set big endian byte order */
+
+/* CPM Ethernet through SCCx.
+ */
+typedef struct scc_enet {
+	sccp_t	sen_genscc;
+	uint	sen_cpres;	/* Preset CRC */
+	uint	sen_cmask;	/* Constant mask for CRC */
+	uint	sen_crcec;	/* CRC Error counter */
+	uint	sen_alec;	/* alignment error counter */
+	uint	sen_disfc;	/* discard frame counter */
+	ushort	sen_pads;	/* Tx short frame pad character */
+	ushort	sen_retlim;	/* Retry limit threshold */
+	ushort	sen_retcnt;	/* Retry limit counter */
+	ushort	sen_maxflr;	/* maximum frame length register */
+	ushort	sen_minflr;	/* minimum frame length register */
+	ushort	sen_maxd1;	/* maximum DMA1 length */
+	ushort	sen_maxd2;	/* maximum DMA2 length */
+	ushort	sen_maxd;	/* Rx max DMA */
+	ushort	sen_dmacnt;	/* Rx DMA counter */
+	ushort	sen_maxb;	/* Max BD byte count */
+	ushort	sen_gaddr1;	/* Group address filter */
+	ushort	sen_gaddr2;
+	ushort	sen_gaddr3;
+	ushort	sen_gaddr4;
+	uint	sen_tbuf0data0;	/* Save area 0 - current frame */
+	uint	sen_tbuf0data1;	/* Save area 1 - current frame */
+	uint	sen_tbuf0rba;	/* Internal */
+	uint	sen_tbuf0crc;	/* Internal */
+	ushort	sen_tbuf0bcnt;	/* Internal */
+	ushort	sen_paddrh;	/* physical address (MSB) */
+	ushort	sen_paddrm;
+	ushort	sen_paddrl;	/* physical address (LSB) */
+	ushort	sen_pper;	/* persistence */
+	ushort	sen_rfbdptr;	/* Rx first BD pointer */
+	ushort	sen_tfbdptr;	/* Tx first BD pointer */
+	ushort	sen_tlbdptr;	/* Tx last BD pointer */
+	uint	sen_tbuf1data0;	/* Save area 0 - current frame */
+	uint	sen_tbuf1data1;	/* Save area 1 - current frame */
+	uint	sen_tbuf1rba;	/* Internal */
+	uint	sen_tbuf1crc;	/* Internal */
+	ushort	sen_tbuf1bcnt;	/* Internal */
+	ushort	sen_txlen;	/* Tx Frame length counter */
+	ushort	sen_iaddr1;	/* Individual address filter */
+	ushort	sen_iaddr2;
+	ushort	sen_iaddr3;
+	ushort	sen_iaddr4;
+	ushort	sen_boffcnt;	/* Backoff counter */
+
+	/* NOTE: Some versions of the manual have the following items
+	 * incorrectly documented.  Below is the proper order.
+	 */
+	ushort	sen_taddrh;	/* temp address (MSB) */
+	ushort	sen_taddrm;
+	ushort	sen_taddrl;	/* temp address (LSB) */
+} scc_enet_t;
+
+/***  MBX  ************************************************************/
+
+#ifdef CONFIG_MBX
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.  The TCLK and RCLK seem unique
+ * to the MBX860 board.  Any two of the four available clocks could be
+ * used, and the MPC860 cookbook manual has an example using different
+ * clock pins.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PC_ENET_TENA	((ushort)0x0001)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000003d)
+#endif	/* CONFIG_MBX */
+
+/***  RPXLITE  ********************************************************/
+
+#ifdef CONFIG_RPXLITE
+/* This ENET stuff is for the MPC850 with ethernet on SCC2.  Some of
+ * this may be unique to the RPX-Lite configuration.
+ * Note TENA is on Port B.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00003d00)
+#endif	/* CONFIG_RPXLITE */
+
+/***  BSEIP  **********************************************************/
+
+#ifdef CONFIG_BSEIP
+/* This ENET stuff is for the MPC823 with ethernet on SCC2.
+ * This is unique to the BSE ip-Engine board.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0100)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+/* BSE uses port B and C bits for PHY control also.
+*/
+#define PB_BSE_POWERUP	((uint)0x00000004)
+#define PB_BSE_FDXDIS	((uint)0x00008000)
+#define PC_BSE_LOOPBACK	((ushort)0x0800)
+
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002c00)
+#endif	/* CONFIG_BSEIP */
+
+/***  RPXCLASSIC  *****************************************************/
+
+#ifdef CONFIG_RPXCLASSIC
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0200)
+#define PA_ENET_RCLK	((ushort)0x0800)
+#define PB_ENET_TENA	((uint)0x00001000)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000003d)
+#endif	/* CONFIG_RPXCLASSIC */
+
+/***  TQM823L, TQM850L  ***********************************************/
+
+#if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L)
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)	/* PA 13 */
+#define PA_ENET_TXD	((ushort)0x0008)	/* PA 12 */
+#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
+#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
+
+#define PB_ENET_TENA	((uint)0x00002000)	/* PB 18 */
+
+#define PC_ENET_CLSN	((ushort)0x0040)	/* PC  9 */
+#define PC_ENET_RENA	((ushort)0x0080)	/* PC  8 */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+ * SCC2.  Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002600)
+#endif	/* CONFIG_TQM823L, CONFIG_TQM850L */
+
+/***  FPS850L  *********************************************************/
+
+#ifdef CONFIG_FPS850L
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)	/* PA 13 */
+#define PA_ENET_TXD	((ushort)0x0008)	/* PA 12 */
+#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
+#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
+
+#define PC_ENET_TENA	((ushort)0x0002)	/* PC 14 */
+#define PC_ENET_CLSN	((ushort)0x0040)	/* PC  9 */
+#define PC_ENET_RENA	((ushort)0x0080)	/* PC  8 */
+
+/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
+ * SCC2.  Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002600)
+#endif	/* CONFIG_FPS850L */
+
+/***  TQM860L  ********************************************************/
+
+#ifdef CONFIG_TQM860L
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)	/* PA 15 */
+#define PA_ENET_TXD	((ushort)0x0002)	/* PA 14 */
+#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
+#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
+
+#define PC_ENET_TENA	((ushort)0x0001)	/* PC 15 */
+#define PC_ENET_CLSN	((ushort)0x0010)	/* PC 11 */
+#define PC_ENET_RENA	((ushort)0x0020)	/* PC 10 */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x00000026)
+#endif	/* CONFIG_TQM860L */
+
+/***  SPD823TS  *******************************************************/
+
+#ifdef CONFIG_SPD823TS
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC2 use.
+ */
+#define PA_ENET_MDC	((ushort)0x0001)	/* PA 15 !!! */
+#define PA_ENET_MDIO	((ushort)0x0002)	/* PA 14 !!! */
+#define PA_ENET_RXD	((ushort)0x0004)	/* PA 13 */
+#define PA_ENET_TXD	((ushort)0x0008)	/* PA 12 */
+#define PA_ENET_RCLK	((ushort)0x0200)	/* PA  6 */
+#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
+
+#define PB_ENET_TENA	((uint)0x00002000)	/* PB 18 */
+
+#define PC_ENET_CLSN	((ushort)0x0040)	/* PC  9 */
+#define PC_ENET_RENA	((ushort)0x0080)	/* PC  8 */
+#define	PC_ENET_RESET	((ushort)0x0100)	/* PC  7 !!! */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK2) to
+ * SCC2.  Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002E00)
+#endif	/* CONFIG_SPD823TS */
+
+
+/***  SM850  *********************************************************/
+
+/* The SM850 Service Module uses SCC2 for IrDA and SCC3 for Ethernet */
+
+#ifdef CONFIG_SM850
+#define PB_ENET_RXD	((uint)0x00000004)	/* PB 29 */
+#define PB_ENET_TXD	((uint)0x00000002)	/* PB 30 */
+#define PA_ENET_RCLK	((ushort)0x0100)	/* PA  7 */
+#define PA_ENET_TCLK	((ushort)0x0400)	/* PA  5 */
+
+#define PC_ENET_LBK	((ushort)0x0008)	/* PC 12 */
+#define PC_ENET_TENA	((ushort)0x0004)	/* PC 13 */
+
+#define PC_ENET_RENA	((ushort)0x0800)	/* PC  4 */
+#define PC_ENET_CLSN	((ushort)0x0400)	/* PC  5 */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+ * SCC3.  Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x00FF0000)
+#define SICR_ENET_CLKRT	((uint)0x00260000)
+#endif	/* CONFIG_SM850 */
+
+/*********************************************************************/
+
+/* SCC Event register as used by Ethernet.
+*/
+#define SCCE_ENET_GRA	((ushort)0x0080)	/* Graceful stop complete */
+#define SCCE_ENET_TXE	((ushort)0x0010)	/* Transmit Error */
+#define SCCE_ENET_RXF	((ushort)0x0008)	/* Full frame received */
+#define SCCE_ENET_BSY	((ushort)0x0004)	/* All incoming buffers full */
+#define SCCE_ENET_TXB	((ushort)0x0002)	/* A buffer was transmitted */
+#define SCCE_ENET_RXB	((ushort)0x0001)	/* A buffer was received */
+
+/* SCC Mode Register (PMSR) as used by Ethernet.
+*/
+#define SCC_PMSR_HBC	((ushort)0x8000)	/* Enable heartbeat */
+#define SCC_PMSR_FC	((ushort)0x4000)	/* Force collision */
+#define SCC_PMSR_RSH	((ushort)0x2000)	/* Receive short frames */
+#define SCC_PMSR_IAM	((ushort)0x1000)	/* Check individual hash */
+#define SCC_PMSR_ENCRC	((ushort)0x0800)	/* Ethernet CRC mode */
+#define SCC_PMSR_PRO	((ushort)0x0200)	/* Promiscuous mode */
+#define SCC_PMSR_BRO	((ushort)0x0100)	/* Catch broadcast pkts */
+#define SCC_PMSR_SBT	((ushort)0x0080)	/* Special backoff timer */
+#define SCC_PMSR_LPB	((ushort)0x0040)	/* Set Loopback mode */
+#define SCC_PMSR_SIP	((ushort)0x0020)	/* Sample Input Pins */
+#define SCC_PMSR_LCW	((ushort)0x0010)	/* Late collision window */
+#define SCC_PMSR_NIB22	((ushort)0x000a)	/* Start frame search */
+#define SCC_PMSR_FDE	((ushort)0x0001)	/* Full duplex enable */
+
+/* Buffer descriptor control/status used by Ethernet receive.
+*/
+#define BD_ENET_RX_EMPTY	((ushort)0x8000)
+#define BD_ENET_RX_WRAP		((ushort)0x2000)
+#define BD_ENET_RX_INTR		((ushort)0x1000)
+#define BD_ENET_RX_LAST		((ushort)0x0800)
+#define BD_ENET_RX_FIRST	((ushort)0x0400)
+#define BD_ENET_RX_MISS		((ushort)0x0100)
+#define BD_ENET_RX_LG		((ushort)0x0020)
+#define BD_ENET_RX_NO		((ushort)0x0010)
+#define BD_ENET_RX_SH		((ushort)0x0008)
+#define BD_ENET_RX_CR		((ushort)0x0004)
+#define BD_ENET_RX_OV		((ushort)0x0002)
+#define BD_ENET_RX_CL		((ushort)0x0001)
+#define BD_ENET_RX_STATS	((ushort)0x013f)	/* All status bits */
+
+/* Buffer descriptor control/status used by Ethernet transmit.
+*/
+#define BD_ENET_TX_READY	((ushort)0x8000)
+#define BD_ENET_TX_PAD		((ushort)0x4000)
+#define BD_ENET_TX_WRAP		((ushort)0x2000)
+#define BD_ENET_TX_INTR		((ushort)0x1000)
+#define BD_ENET_TX_LAST		((ushort)0x0800)
+#define BD_ENET_TX_TC		((ushort)0x0400)
+#define BD_ENET_TX_DEF		((ushort)0x0200)
+#define BD_ENET_TX_HB		((ushort)0x0100)
+#define BD_ENET_TX_LC		((ushort)0x0080)
+#define BD_ENET_TX_RL		((ushort)0x0040)
+#define BD_ENET_TX_RCMASK	((ushort)0x003c)
+#define BD_ENET_TX_UN		((ushort)0x0002)
+#define BD_ENET_TX_CSL		((ushort)0x0001)
+#define BD_ENET_TX_STATS	((ushort)0x03ff)	/* All status bits */
+
+/* SCC as UART
+*/
+typedef struct scc_uart {
+	sccp_t	scc_genscc;
+	uint	scc_res1;	/* Reserved */
+	uint	scc_res2;	/* Reserved */
+	ushort	scc_maxidl;	/* Maximum idle chars */
+	ushort	scc_idlc;	/* temp idle counter */
+	ushort	scc_brkcr;	/* Break count register */
+	ushort	scc_parec;	/* receive parity error counter */
+	ushort	scc_frmec;	/* receive framing error counter */
+	ushort	scc_nosec;	/* receive noise counter */
+	ushort	scc_brkec;	/* receive break condition counter */
+	ushort	scc_brkln;	/* last received break length */
+	ushort	scc_uaddr1;	/* UART address character 1 */
+	ushort	scc_uaddr2;	/* UART address character 2 */
+	ushort	scc_rtemp;	/* Temp storage */
+	ushort	scc_toseq;	/* Transmit out of sequence char */
+	ushort	scc_char1;	/* control character 1 */
+	ushort	scc_char2;	/* control character 2 */
+	ushort	scc_char3;	/* control character 3 */
+	ushort	scc_char4;	/* control character 4 */
+	ushort	scc_char5;	/* control character 5 */
+	ushort	scc_char6;	/* control character 6 */
+	ushort	scc_char7;	/* control character 7 */
+	ushort	scc_char8;	/* control character 8 */
+	ushort	scc_rccm;	/* receive control character mask */
+	ushort	scc_rccr;	/* receive control character register */
+	ushort	scc_rlbc;	/* receive last break character */
+} scc_uart_t;
+
+/* SCC Event and Mask registers when it is used as a UART.
+*/
+#define UART_SCCM_GLR		((ushort)0x1000)
+#define UART_SCCM_GLT		((ushort)0x0800)
+#define UART_SCCM_AB		((ushort)0x0200)
+#define UART_SCCM_IDL		((ushort)0x0100)
+#define UART_SCCM_GRA		((ushort)0x0080)
+#define UART_SCCM_BRKE		((ushort)0x0040)
+#define UART_SCCM_BRKS		((ushort)0x0020)
+#define UART_SCCM_CCR		((ushort)0x0008)
+#define UART_SCCM_BSY		((ushort)0x0004)
+#define UART_SCCM_TX		((ushort)0x0002)
+#define UART_SCCM_RX		((ushort)0x0001)
+
+/* The SCC PMSR when used as a UART.
+*/
+#define SCU_PMSR_FLC		((ushort)0x8000)
+#define SCU_PMSR_SL		((ushort)0x4000)
+#define SCU_PMSR_CL		((ushort)0x3000)
+#define SCU_PMSR_UM		((ushort)0x0c00)
+#define SCU_PMSR_FRZ		((ushort)0x0200)
+#define SCU_PMSR_RZS		((ushort)0x0100)
+#define SCU_PMSR_SYN		((ushort)0x0080)
+#define SCU_PMSR_DRT		((ushort)0x0040)
+#define SCU_PMSR_PEN		((ushort)0x0010)
+#define SCU_PMSR_RPM		((ushort)0x000c)
+#define SCU_PMSR_REVP		((ushort)0x0008)
+#define SCU_PMSR_TPM		((ushort)0x0003)
+#define SCU_PMSR_TEVP		((ushort)0x0002)
+
+/* CPM Transparent mode SCC.
+ */
+typedef struct scc_trans {
+	sccp_t	st_genscc;
+	uint	st_cpres;	/* Preset CRC */
+	uint	st_cmask;	/* Constant mask for CRC */
+} scc_trans_t;
+
+#define BD_SCC_TX_LAST		((ushort)0x0800)
+
+/* IIC parameter RAM.
+*/
+typedef struct iic {
+	ushort	iic_rbase;	/* Rx Buffer descriptor base address */
+	ushort	iic_tbase;	/* Tx Buffer descriptor base address */
+	u_char	iic_rfcr;	/* Rx function code */
+	u_char	iic_tfcr;	/* Tx function code */
+	ushort	iic_mrblr;	/* Max receive buffer length */
+	uint	iic_rstate;	/* Internal */
+	uint	iic_rdp;	/* Internal */
+	ushort	iic_rbptr;	/* Internal */
+	ushort	iic_rbc;	/* Internal */
+	uint	iic_rxtmp;	/* Internal */
+	uint	iic_tstate;	/* Internal */
+	uint	iic_tdp;	/* Internal */
+	ushort	iic_tbptr;	/* Internal */
+	ushort	iic_tbc;	/* Internal */
+	uint	iic_txtmp;	/* Internal */
+} iic_t;
+
+#define BD_IIC_START		((ushort)0x0400)
+
+/* CPM interrupts.  There are nearly 32 interrupts generated by CPM
+ * channels or devices.  All of these are presented to the PPC core
+ * as a single interrupt.  The CPM interrupt handler dispatches its
+ * own handlers, in a similar fashion to the PPC core handler.  We
+ * use the table as defined in the manuals (i.e. no special high
+ * priority and SCC1 == SCCa, etc...).
+ */
+#define CPMVEC_NR		32
+#define	CPMVEC_PIO_PC15		((ushort)0x1f)
+#define	CPMVEC_SCC1		((ushort)0x1e)
+#define	CPMVEC_SCC2		((ushort)0x1d)
+#define	CPMVEC_SCC3		((ushort)0x1c)
+#define	CPMVEC_SCC4		((ushort)0x1b)
+#define	CPMVEC_PIO_PC14		((ushort)0x1a)
+#define	CPMVEC_TIMER1		((ushort)0x19)
+#define	CPMVEC_PIO_PC13		((ushort)0x18)
+#define	CPMVEC_PIO_PC12		((ushort)0x17)
+#define	CPMVEC_SDMA_CB_ERR	((ushort)0x16)
+#define CPMVEC_IDMA1		((ushort)0x15)
+#define CPMVEC_IDMA2		((ushort)0x14)
+#define CPMVEC_TIMER2		((ushort)0x12)
+#define CPMVEC_RISCTIMER	((ushort)0x11)
+#define CPMVEC_I2C		((ushort)0x10)
+#define	CPMVEC_PIO_PC11		((ushort)0x0f)
+#define	CPMVEC_PIO_PC10		((ushort)0x0e)
+#define CPMVEC_TIMER3		((ushort)0x0c)
+#define	CPMVEC_PIO_PC9		((ushort)0x0b)
+#define	CPMVEC_PIO_PC8		((ushort)0x0a)
+#define	CPMVEC_PIO_PC7		((ushort)0x09)
+#define CPMVEC_TIMER4		((ushort)0x07)
+#define	CPMVEC_PIO_PC6		((ushort)0x06)
+#define	CPMVEC_SPI		((ushort)0x05)
+#define	CPMVEC_SMC1		((ushort)0x04)
+#define	CPMVEC_SMC2		((ushort)0x03)
+#define	CPMVEC_PIO_PC5		((ushort)0x02)
+#define	CPMVEC_PIO_PC4		((ushort)0x01)
+#define	CPMVEC_ERROR		((ushort)0x00)
+
+/* CPM interrupt configuration vector.
+*/
+#define	CICR_SCD_SCC4		((uint)0x00c00000)	/* SCC4 @ SCCd */
+#define	CICR_SCC_SCC3		((uint)0x00200000)	/* SCC3 @ SCCc */
+#define	CICR_SCB_SCC2		((uint)0x00040000)	/* SCC2 @ SCCb */
+#define	CICR_SCA_SCC1		((uint)0x00000000)	/* SCC1 @ SCCa */
+#define CICR_IRL_MASK		((uint)0x0000e000)	/* Core interrrupt */
+#define CICR_HP_MASK		((uint)0x00001f00)	/* Hi-pri int. */
+#define CICR_IEN		((uint)0x00000080)	/* Int. enable */
+#define CICR_SPS		((uint)0x00000001)	/* SCC Spread */
+
+extern void cpm_install_handler(int vec, 
+		void (*handler)(void *, struct pt_regs *regs), void *dev_id);
+extern void cpm_free_handler(int vec);
+
+#endif /* __CPM_8XX__ */
diff -u --recursive --new-file v2.4.10/linux/include/asm-ppc/ide.h linux/include/asm-ppc/ide.h
--- v2.4.10/linux/include/asm-ppc/ide.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-ppc/ide.h	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.ide.h 1.13 08/20/01 15:25:16 paulus
+ * BK Id: SCCS/s.ide.h 1.16 09/28/01 07:54:24 trini
  */
 /*
  *  linux/include/asm-ppc/ide.h
@@ -17,6 +17,7 @@
 
 #include <linux/sched.h>
 #include <asm/processor.h>
+#include <asm/mpc8xx.h>
 
 #ifndef MAX_HWIFS
 #define MAX_HWIFS	8
@@ -138,8 +139,9 @@
 
 /*
  * The following are not needed for the non-m68k ports
+ * unless direct IDE on 8xx
  */
-#ifdef CONFIG_APUS
+#if (defined CONFIG_APUS || defined CONFIG_BLK_DEV_MPC8xx_IDE )
 #define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
 #else
 #define ide_ack_intr(hwif)		(1)
diff -u --recursive --new-file v2.4.10/linux/include/asm-ppc/mmu_context.h linux/include/asm-ppc/mmu_context.h
--- v2.4.10/linux/include/asm-ppc/mmu_context.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-ppc/mmu_context.h	Tue Oct  2 09:12:44 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.mmu_context.h 1.15 08/16/01 23:00:17 paulus
+ * BK Id: SCCS/s.mmu_context.h 1.18 09/26/01 16:02:49 paulus
  */
 #ifdef __KERNEL__
 #ifndef __PPC_MMU_CONTEXT_H
@@ -29,7 +29,7 @@
  * of the 32-bit virtual address (the "effective segment ID") in order
  * to spread out the entries in the MMU hash table.  Note, if this
  * function is changed then arch/ppc/mm/hashtable.S will have to be
- * changed correspondly.
+ * changed to correspond.
  */
 #define CTX_TO_VSID(ctx, va)	(((ctx) * (897 * 16) + ((va) >> 28) * 0x111) \
 				 & 0xffffff)
@@ -89,7 +89,7 @@
  * Bitmap of contexts in use.
  * The size of this bitmap is LAST_CONTEXT + 1 bits.
  */
-extern unsigned long context_map[(LAST_CONTEXT+1) / (8*sizeof(unsigned long))];
+extern unsigned long context_map[];
 
 /*
  * This caches the next context number that we expect to be free.
diff -u --recursive --new-file v2.4.10/linux/include/asm-ppc/oak.h linux/include/asm-ppc/oak.h
--- v2.4.10/linux/include/asm-ppc/oak.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/oak.h	Mon Oct  8 11:43:01 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.oak.h 1.7 05/17/01 18:14:25 cort
+ * BK Id: SCCS/s.oak.h 1.10 09/14/01 17:37:56 trini
  */
 /*
  *
@@ -20,11 +20,6 @@
 
 #include <asm/irq.h>
 
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #define _IO_BASE	0
 #define _ISA_MEM_BASE	0
 #define PCI_DRAM_OFFSET	0
@@ -48,6 +43,7 @@
 #define	OAKNET_INT		AIC_INT27
 #define	OAKSERIAL_INT		AIC_INT28
 
+#ifndef __ASSEMBLY__
 /*
  * Data structure defining board information maintained by the boot
  * ROM on IBM's "Oak" evaluation board. An effort has been made to
@@ -64,15 +60,6 @@
 	unsigned int	 bi_busfreq;		/* Bus speed, in Hz */
 } bd_t;
 
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Generic 4xx type
-*/
-#define _MACH_4xx (_MACH_oak)
-
-
+#endif /* !__ASSEMBLY__ */
 #endif /* __OAK_H__ */
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.10/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- v2.4.10/linux/include/asm-ppc/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-ppc/processor.h	Fri Oct  5 12:11:05 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.processor.h 1.28 08/17/01 15:23:17 paulus
+ * BK Id: SCCS/s.processor.h 1.31 10/05/01 16:26:22 paulus
  */
 #ifdef __KERNEL__
 #ifndef __ASM_PPC_PROCESSOR_H
@@ -654,6 +654,27 @@
 
 /* In misc.c */
 void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+
+#define cpu_relax()	do { } while (0)
+
+/*
+ * Prefetch macros.
+ */
+#define ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCHW
+#define ARCH_HAS_SPINLOCK_PREFETCH
+
+extern inline void prefetch(const void *x)
+{
+	 __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x));
+}
+
+extern inline void prefetchw(const void *x)
+{
+	 __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x));
+}
+
+#define spin_lock_prefetch(x)	prefetchw(x)
 
 #endif /* !__ASSEMBLY__ */
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-ppc/spd8xx.h linux/include/asm-ppc/spd8xx.h
--- v2.4.10/linux/include/asm-ppc/spd8xx.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/spd8xx.h	Mon Oct  8 11:40:13 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.spd8xx.h 1.5 05/17/01 18:14:25 cort
+ * BK Id: SCCS/s.spd8xx.h 1.6 09/14/01 17:37:56 trini
  */
 /*
  * A collection of structures, addresses, and values associated with
@@ -100,9 +100,5 @@
 /* We don't use the 8259.
 */
 #define NR_8259_INTS	0
-
-/* Generic 8xx type
-*/
-#define _MACH_8xx (_MACH_spd8xx)
 
 #endif	/* __MACH_SPD8xx_DEFS */
diff -u --recursive --new-file v2.4.10/linux/include/asm-ppc/walnut.h linux/include/asm-ppc/walnut.h
--- v2.4.10/linux/include/asm-ppc/walnut.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/walnut.h	Mon Oct  8 11:43:01 2001
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.walnut.h 1.7 05/17/01 18:14:26 cort
+ * BK Id: SCCS/s.walnut.h 1.10 09/14/01 17:37:56 trini
  */
 /*
  *
@@ -27,10 +27,7 @@
 #ifndef	__WALNUT_H__
 #define	__WALNUT_H__
 
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef __ASSEMBLY__
 /*
  * Data structure defining board information maintained by the boot
  * ROM on IBM's "Walnut" evaluation board. An effort has been made to
@@ -49,19 +46,13 @@
 	unsigned int	 bi_pci_busfreq;	/* PCI Bus speed, in Hz */
 } bd_t;
 
+#endif /* !__ASSEMBLY__ */
+
 /* Memory map for the IBM "Walnut" 405GP evaluation board.
  * Generic 4xx plus RTC.
  */
 #define WALNUT_RTC_ADDR		((uint)0xf0001000)
 #define WALNUT_RTC_SIZE		((uint)4*1024)
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Generic 4xx type
-*/
-#define _MACH_4xx (_MACH_walnut)
 
 #endif /* __WALNUT_H__ */
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.10/linux/include/asm-s390/processor.h linux/include/asm-s390/processor.h
--- v2.4.10/linux/include/asm-s390/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-s390/processor.h	Fri Oct  5 12:11:05 2001
@@ -149,6 +149,8 @@
 #define init_task       (init_task_union.task)
 #define init_stack      (init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 /*
  * Set of msr bits that gdb can change on behalf of a process.
  */
diff -u --recursive --new-file v2.4.10/linux/include/asm-s390x/processor.h linux/include/asm-s390x/processor.h
--- v2.4.10/linux/include/asm-s390x/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-s390x/processor.h	Fri Oct  5 12:11:05 2001
@@ -159,6 +159,8 @@
 #define init_task       (init_task_union.task)
 #define init_stack      (init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 /*
  * Set of msr bits that gdb can change on behalf of a process.
  */
diff -u --recursive --new-file v2.4.10/linux/include/asm-sh/processor.h linux/include/asm-sh/processor.h
--- v2.4.10/linux/include/asm-sh/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-sh/processor.h	Fri Oct  5 12:11:05 2001
@@ -218,4 +218,6 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 #endif /* __ASM_SH_PROCESSOR_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h
--- v2.4.10/linux/include/asm-sparc/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-sparc/processor.h	Fri Oct  5 12:11:05 2001
@@ -201,6 +201,8 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 #endif
 
 #endif /* __ASM_SPARC_PROCESSOR_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc/uaccess.h linux/include/asm-sparc/uaccess.h
--- v2.4.10/linux/include/asm-sparc/uaccess.h	Tue Aug 29 14:09:16 2000
+++ linux/include/asm-sparc/uaccess.h	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: uaccess.h,v 1.22 2000/08/29 07:01:58 davem Exp $
+/* $Id: uaccess.h,v 1.23 2001/09/24 03:51:39 davem Exp $
  * uaccess.h: User space memore access functions.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -116,6 +116,7 @@
 case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
 case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
 case 4: __put_user_asm(x,,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
 default: __pu_ret = __put_user_bad(); break; \
 } } else { __pu_ret = -EFAULT; } __pu_ret; })
 
@@ -126,6 +127,7 @@
 case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \
 case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \
 case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \
+case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \
 default: if (__put_user_bad()) return retval; break; \
 } } else return retval; })
 
@@ -135,6 +137,7 @@
 case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
 case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
 case 4: __put_user_asm(x,,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
 default: __pu_ret = __put_user_bad(); break; \
 } __pu_ret; })
 
@@ -144,6 +147,7 @@
 case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \
 case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \
 case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \
+case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \
 default: if (__put_user_bad()) return retval; break; \
 } })
 
@@ -202,6 +206,7 @@
 case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
 case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
 case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
 default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
 } } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; })
 
@@ -212,6 +217,7 @@
 case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
 case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
 case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
 default: if (__get_user_bad()) return retval; \
 } x = (type) __gu_val; } else return retval; })
 
@@ -222,6 +228,7 @@
 case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
 case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
 case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
 default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
 } x = (type) __gu_val; __gu_ret; })
 
@@ -231,6 +238,7 @@
 case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
 case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
 case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
 default: if (__get_user_bad()) return retval; \
 } x = (type) __gu_val; })
 
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc64/ide.h linux/include/asm-sparc64/ide.h
--- v2.4.10/linux/include/asm-sparc64/ide.h	Mon Jun 19 17:59:39 2000
+++ linux/include/asm-sparc64/ide.h	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: ide.h,v 1.19 2000/05/27 00:49:37 davem Exp $
+/* $Id: ide.h,v 1.21 2001/09/25 20:21:48 kanoj Exp $
  * ide.h: Ultra/PCI specific IDE glue.
  *
  * Copyright (C) 1997  David S. Miller (davem@caip.rutgers.edu)
@@ -14,6 +14,8 @@
 #include <asm/pgalloc.h>
 #include <asm/io.h>
 #include <asm/hdreg.h>
+#include <asm/page.h>
+#include <asm/spitfire.h>
 
 #undef  MAX_HWIFS
 #define MAX_HWIFS	2
@@ -151,7 +153,9 @@
 				void *dst,
 				unsigned long count)
 {
+#if (L1DCACHE_SIZE > PAGE_SIZE)		/* is there D$ aliasing problem */
 	unsigned long end = (unsigned long)dst + (count << 1);
+#endif
 	u16 *ps = dst;
 	u32 *pi;
 
@@ -172,7 +176,9 @@
 	if(count)
 		*ps++ = inw_be(port);
 
+#if (L1DCACHE_SIZE > PAGE_SIZE)		/* is there D$ aliasing problem */
 	__flush_dcache_range((unsigned long)dst, end);
+#endif
 }
 
 static __inline__ void outw_be(unsigned short w, unsigned long addr)
@@ -186,7 +192,9 @@
 				 const void *src,
 				 unsigned long count)
 {
+#if (L1DCACHE_SIZE > PAGE_SIZE)		/* is there D$ aliasing problem */
 	unsigned long end = (unsigned long)src + (count << 1);
+#endif
 	const u16 *ps = src;
 	const u32 *pi;
 
@@ -207,7 +215,9 @@
 	if(count)
 		outw_be(*ps, port);
 
+#if (L1DCACHE_SIZE > PAGE_SIZE)		/* is there D$ aliasing problem */
 	__flush_dcache_range((unsigned long)src, end);
+#endif
 }
 
 #define T_CHAR          (0x0000)        /* char:  don't touch  */
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc64/pgalloc.h linux/include/asm-sparc64/pgalloc.h
--- v2.4.10/linux/include/asm-sparc64/pgalloc.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-sparc64/pgalloc.h	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: pgalloc.h,v 1.21 2001/08/22 22:16:56 kanoj Exp $ */
+/* $Id: pgalloc.h,v 1.23 2001/09/25 20:21:48 kanoj Exp $ */
 #ifndef _SPARC64_PGALLOC_H
 #define _SPARC64_PGALLOC_H
 
@@ -7,6 +7,8 @@
 #include <linux/sched.h>
 
 #include <asm/page.h>
+#include <asm/spitfire.h>
+#include <asm/pgtable.h>
 
 /* Cache and TLB flush operations. */
 
@@ -29,6 +31,8 @@
 extern void flush_icache_range(unsigned long start, unsigned long end);
 
 extern void __flush_dcache_page(void *addr, int flush_icache);
+extern void __flush_icache_page(unsigned long);
+#if (L1DCACHE_SIZE > PAGE_SIZE)		/* is there D$ aliasing problem */
 #define flush_dcache_page(page) \
 do {	if ((page)->mapping && \
 	    !((page)->mapping->i_mmap) && \
@@ -39,6 +43,18 @@
 				    ((tlb_type == spitfire) && \
 				     (page)->mapping != NULL)); \
 } while(0)
+#else /* L1DCACHE_SIZE > PAGE_SIZE */
+#define flush_dcache_page(page) \
+do {	if ((page)->mapping && \
+	    !((page)->mapping->i_mmap) && \
+	    !((page)->mapping->i_mmap_shared)) \
+		set_bit(PG_dcache_dirty, &(page)->flags); \
+	else \
+		if ((tlb_type == spitfire) && \
+		    (page)->mapping != NULL) \
+			__flush_icache_page(__get_phys((unsigned long)((page)->virtual))); \
+} while(0)
+#endif /* L1DCACHE_SIZE > PAGE_SIZE */
 
 extern void __flush_dcache_range(unsigned long start, unsigned long end);
 
@@ -227,6 +243,14 @@
 
 #endif /* CONFIG_SMP */
 
+#if (L1DCACHE_SIZE > PAGE_SIZE)			/* is there D$ aliasing problem */
+#define VPTE_COLOR(address)		(((address) >> (PAGE_SHIFT + 10)) & 1UL)
+#define DCACHE_COLOR(address)		(((address) >> PAGE_SHIFT) & 1UL)
+#else
+#define VPTE_COLOR(address)		0
+#define DCACHE_COLOR(address)		0
+#endif
+
 #define pgd_populate(MM, PGD, PMD)	pgd_set(PGD, PMD)
 
 extern __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
@@ -254,9 +278,7 @@
 
 extern __inline__ void free_pmd_fast(pmd_t *pmd)
 {
-	unsigned long color;
-
-	color = (((unsigned long)pmd >> PAGE_SHIFT) & 0x1UL);
+	unsigned long color = DCACHE_COLOR((unsigned long)pmd);
 	*(unsigned long *)pmd = (unsigned long) pte_quicklist[color];
 	pte_quicklist[color] = (unsigned long *) pmd;
 	pgtable_cache_size++;
@@ -273,7 +295,7 @@
 
 extern __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
-	unsigned long color = (address >> (PAGE_SHIFT + 10)) & 0x1UL;
+	unsigned long color = VPTE_COLOR(address);
 	unsigned long *ret;
 
 	if((ret = (unsigned long *)pte_quicklist[color]) != NULL) {
@@ -286,7 +308,7 @@
 
 extern __inline__ void free_pte_fast(pte_t *pte)
 {
-	unsigned long color = (((unsigned long)pte >> PAGE_SHIFT) & 0x1);
+	unsigned long color = DCACHE_COLOR((unsigned long)pte);
 	*(unsigned long *)pte = (unsigned long) pte_quicklist[color];
 	pte_quicklist[color] = (unsigned long *) pte;
 	pgtable_cache_size++;
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h
--- v2.4.10/linux/include/asm-sparc64/processor.h	Sun Sep 23 11:41:01 2001
+++ linux/include/asm-sparc64/processor.h	Fri Oct  5 12:11:05 2001
@@ -276,6 +276,8 @@
 #define init_task	(init_task_union.task)
 #define init_stack	(init_task_union.stack)
 
+#define cpu_relax()	do { } while (0)
+
 #endif /* __KERNEL__ */
 
 #endif /* !(__ASSEMBLY__) */
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc64/shmparam.h linux/include/asm-sparc64/shmparam.h
--- v2.4.10/linux/include/asm-sparc64/shmparam.h	Mon Dec 20 22:05:52 1999
+++ linux/include/asm-sparc64/shmparam.h	Mon Oct  1 09:19:56 2001
@@ -1,7 +1,10 @@
-/* $Id: shmparam.h,v 1.4 1999/12/09 10:32:44 davem Exp $ */
+/* $Id: shmparam.h,v 1.5 2001/09/24 21:17:57 kanoj Exp $ */
 #ifndef _ASMSPARC64_SHMPARAM_H
 #define _ASMSPARC64_SHMPARAM_H
 
-#define	SHMLBA (PAGE_SIZE<<1)		/* attach addr a multiple of this */
+#include <asm/spitfire.h>
+
+/* attach addr a multiple of this */
+#define	SHMLBA	((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE)
 
 #endif /* _ASMSPARC64_SHMPARAM_H */
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc64/spitfire.h linux/include/asm-sparc64/spitfire.h
--- v2.4.10/linux/include/asm-sparc64/spitfire.h	Thu Apr 12 12:10:25 2001
+++ linux/include/asm-sparc64/spitfire.h	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: spitfire.h,v 1.15 2001/03/27 00:10:15 davem Exp $
+/* $Id: spitfire.h,v 1.16 2001/09/24 21:17:57 kanoj Exp $
  * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -45,6 +45,8 @@
 
 #define SPITFIRE_HIGHEST_LOCKED_TLBENT	(64 - 1)
 #define CHEETAH_HIGHEST_LOCKED_TLBENT	(16 - 1)
+
+#define L1DCACHE_SIZE		0x4000
 
 #define sparc64_highest_locked_tlbent()	\
 	(tlb_type == spitfire ? \
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc64/string.h linux/include/asm-sparc64/string.h
--- v2.4.10/linux/include/asm-sparc64/string.h	Tue Jul  3 17:08:21 2001
+++ linux/include/asm-sparc64/string.h	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: string.h,v 1.19 2001/06/05 20:56:33 davem Exp $
+/* $Id: string.h,v 1.20 2001/09/27 04:36:24 kanoj Exp $
  * string.h: External definitions for optimized assembly string
  *           routines for the Linux Kernel.
  *
@@ -17,10 +17,6 @@
 
 extern void __memmove(void *,const void *,__kernel_size_t);
 extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t);
-extern __kernel_size_t __memcpy_short(void *,const void *,__kernel_size_t,long,long);
-extern __kernel_size_t __memcpy_entry(void *,const void *,__kernel_size_t,long,long);
-extern __kernel_size_t __memcpy_16plus(void *,const void *,__kernel_size_t,long,long);
-extern __kernel_size_t __memcpy_384plus(void *,const void *,__kernel_size_t,long,long);
 extern void *__memset(void *,int,__kernel_size_t);
 extern void *__builtin_memcpy(void *,const void *,__kernel_size_t);
 extern void *__builtin_memset(void *,int,__kernel_size_t);
diff -u --recursive --new-file v2.4.10/linux/include/asm-sparc64/uaccess.h linux/include/asm-sparc64/uaccess.h
--- v2.4.10/linux/include/asm-sparc64/uaccess.h	Tue Aug 29 14:09:16 2000
+++ linux/include/asm-sparc64/uaccess.h	Mon Oct  1 09:19:56 2001
@@ -1,4 +1,4 @@
-/* $Id: uaccess.h,v 1.33 2000/08/29 07:01:58 davem Exp $ */
+/* $Id: uaccess.h,v 1.34 2001/09/27 04:36:24 kanoj Exp $ */
 #ifndef _ASM_UACCESS_H
 #define _ASM_UACCESS_H
 
@@ -248,22 +248,6 @@
        : "=r" (x) : "r" (__m(addr)), "i" (retval))
 
 extern int __get_user_bad(void);
-
-extern __kernel_size_t __memcpy_short(void *to, const void *from,
-				      __kernel_size_t size,
-				      long asi_src, long asi_dst);
-
-extern __kernel_size_t __memcpy_entry(void *to, const void *from,
-				      __kernel_size_t size,
-				      long asi_src, long asi_dst);
-
-extern __kernel_size_t __memcpy_16plus(void *to, const void *from,
-				       __kernel_size_t size,
-				       long asi_src, long asi_dst);
-
-extern __kernel_size_t __memcpy_386plus(void *to, const void *from,
-					__kernel_size_t size,
-					long asi_src, long asi_dst);
 
 extern __kernel_size_t __copy_from_user(void *to, const void *from,
 					__kernel_size_t size);
diff -u --recursive --new-file v2.4.10/linux/include/linux/agp_backend.h linux/include/linux/agp_backend.h
--- v2.4.10/linux/include/linux/agp_backend.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/agp_backend.h	Fri Oct  5 12:13:50 2001
@@ -46,6 +46,7 @@
 	INTEL_GX,
 	INTEL_I810,
 	INTEL_I815,
+	INTEL_I830_M,
 	INTEL_I840,
 	INTEL_I850,
 	VIA_GENERIC,
diff -u --recursive --new-file v2.4.10/linux/include/linux/blkdev.h linux/include/linux/blkdev.h
--- v2.4.10/linux/include/linux/blkdev.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/blkdev.h	Tue Oct  9 15:24:13 2001
@@ -203,15 +203,4 @@
 #define blk_finished_io(nsects)	do { } while (0)
 #define blk_started_io(nsects)	do { } while (0)
 
-static inline int buffered_blk_size(kdev_t dev)
-{
-	int ret = INT_MAX;
-	int major = MAJOR(dev);
-
-	if (blk_size[major])
-		ret = blk_size[major][MINOR(dev)] + ((BUFFERED_BLOCKSIZE-1) >> BLOCK_SIZE_BITS);
-
-	return ret;
-}
-
 #endif
diff -u --recursive --new-file v2.4.10/linux/include/linux/capi.h linux/include/linux/capi.h
--- v2.4.10/linux/include/linux/capi.h	Mon Dec 11 13:21:24 2000
+++ linux/include/linux/capi.h	Sun Sep 30 12:26:42 2001
@@ -1,10 +1,12 @@
-/*
- * $Id: capi.h,v 1.4 2000/06/12 09:20:20 kai Exp $
+/* $Id: capi.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $
  * 
  * CAPI 2.0 Interface for Linux
  * 
  * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
  */
 
 #ifndef __LINUX_CAPI_H__
diff -u --recursive --new-file v2.4.10/linux/include/linux/concap.h linux/include/linux/concap.h
--- v2.4.10/linux/include/linux/concap.h	Mon Dec 11 13:21:27 2000
+++ linux/include/linux/concap.h	Sun Sep 30 12:26:42 2001
@@ -1,5 +1,11 @@
-/* $Id: concap.h,v 1.2 1999/08/23 15:54:21 keil Exp $
-*/
+/* $Id: concap.h,v 1.2.8.1 2001/09/23 22:25:05 kai Exp $
+ *
+ * Copyright 1997 by Henner Eisen <eis@baty.hanse.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
 #ifndef _LINUX_CONCAP_H
 #define _LINUX_CONCAP_H
 #ifdef __KERNEL__
@@ -9,15 +15,12 @@
 /* Stuff to support encapsulation protocols genericly. The encapsulation
    protocol is processed at the uppermost layer of the network interface.
 
-   (c) 1997 by Henner Eisen <eis@baty.hanse.de>
-   This software is subject to the GNU General Public License.
-
    Based on a ideas developed in a 'synchronous device' thread in the
    linux-x25 mailing list contributed by Alan Cox, Thomasz Motylewski
    and Jonathan Naylor.
 
    For more documetation on this refer to Documentation/isdn/README.concap
-   */
+*/
 
 struct concap_proto_ops;
 struct concap_device_ops;
diff -u --recursive --new-file v2.4.10/linux/include/linux/dcache.h linux/include/linux/dcache.h
--- v2.4.10/linux/include/linux/dcache.h	Sun Aug 12 13:28:01 2001
+++ linux/include/linux/dcache.h	Tue Oct  9 15:22:13 2001
@@ -178,6 +178,9 @@
 extern int shrink_icache_memory(int, int);
 extern void prune_icache(int);
 
+/* quota cache memory management (defined in linux/fs/dquot.c) */
+extern int shrink_dqcache_memory(int, unsigned int);
+
 /* only used at mount-time */
 extern struct dentry * d_alloc_root(struct inode *);
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.4.10/linux/include/linux/ext2_fs.h	Tue Aug  7 12:49:18 2001
+++ linux/include/linux/ext2_fs.h	Tue Oct  9 15:22:46 2001
@@ -551,9 +551,9 @@
 /* balloc.c */
 extern int ext2_bg_has_super(struct super_block *sb, int group);
 extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
-extern int ext2_new_block (const struct inode *, unsigned long,
+extern int ext2_new_block (struct inode *, unsigned long,
 			   __u32 *, __u32 *, int *);
-extern void ext2_free_blocks (const struct inode *, unsigned long,
+extern void ext2_free_blocks (struct inode *, unsigned long,
 			      unsigned long);
 extern unsigned long ext2_count_free_blocks (struct super_block *);
 extern void ext2_check_blocks_bitmap (struct super_block *);
diff -u --recursive --new-file v2.4.10/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.4.10/linux/include/linux/fs.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/fs.h	Tue Oct  9 15:22:14 2001
@@ -46,10 +46,6 @@
 #define BLOCK_SIZE_BITS 10
 #define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
 
-/* buffer header fixed size for the blkdev I/O through pagecache */
-#define BUFFERED_BLOCKSIZE_BITS 10
-#define BUFFERED_BLOCKSIZE (1 << BUFFERED_BLOCKSIZE_BITS)
-
 /* And dynamically-tunable limits and defaults: */
 struct files_stat_struct {
 	int nr_files;		/* read only */
@@ -112,6 +108,7 @@
 #define MS_NOATIME	1024	/* Do not update access times. */
 #define MS_NODIRATIME	2048	/* Do not update directory access times */
 #define MS_BIND		4096
+#define MS_REC		16384
 #define MS_NOUSER	(1<<31)
 
 /*
@@ -282,7 +279,7 @@
 
 extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset);
 
-#define touch_buffer(bh)	SetPageReferenced(bh->b_page)
+#define touch_buffer(bh)	mark_page_accessed(bh->b_page)
 
 
 #include <linux/pipe_fs_i.h>
@@ -437,6 +434,7 @@
 	time_t			i_atime;
 	time_t			i_mtime;
 	time_t			i_ctime;
+	unsigned int		i_blkbits;
 	unsigned long		i_blksize;
 	unsigned long		i_blocks;
 	unsigned long		i_version;
@@ -653,6 +651,7 @@
  */
 
 #define MNT_FORCE	0x00000001	/* Attempt to forcibily umount */
+#define MNT_DETACH	0x00000002	/* Just detach from the tree */
 
 #include <linux/minix_fs_sb.h>
 #include <linux/ext2_fs_sb.h>
@@ -921,11 +920,11 @@
 struct dquot_operations {
 	void (*initialize) (struct inode *, short);
 	void (*drop) (struct inode *);
-	int (*alloc_block) (const struct inode *, unsigned long, char);
+	int (*alloc_block) (struct inode *, unsigned long, char);
 	int (*alloc_inode) (const struct inode *, unsigned long);
-	void (*free_block) (const struct inode *, unsigned long);
+	void (*free_block) (struct inode *, unsigned long);
 	void (*free_inode) (const struct inode *, unsigned long);
-	int (*transfer) (struct dentry *, struct iattr *);
+	int (*transfer) (struct inode *, struct iattr *);
 };
 
 struct file_system_type {
@@ -1174,14 +1173,10 @@
 extern void invalidate_inode_pages(struct inode *);
 extern void invalidate_inode_pages2(struct address_space *);
 extern void invalidate_inode_buffers(struct inode *);
-#define invalidate_buffers(dev)	__invalidate_buffers((dev), 0, 0)
-#define destroy_buffers(dev)	__invalidate_buffers((dev), 1, 0)
-#define update_buffers(dev)			\
-do {						\
-	__invalidate_buffers((dev), 0, 1);	\
-	__invalidate_buffers((dev), 0, 2);	\
-} while (0)
-extern void __invalidate_buffers(kdev_t dev, int, int);
+#define invalidate_buffers(dev)	__invalidate_buffers((dev), 0)
+#define destroy_buffers(dev)	__invalidate_buffers((dev), 1)
+extern void invalidate_bdev(struct block_device *, int);
+extern void __invalidate_buffers(kdev_t dev, int);
 extern void sync_inodes(kdev_t);
 extern void sync_unlocked_inodes(void);
 extern void write_inode_now(struct inode *, int);
@@ -1287,9 +1282,10 @@
 /* needed for stackable file system support */
 extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
 
-extern int __user_walk(const char *, unsigned, struct nameidata *);
-extern int path_init(const char *, unsigned, struct nameidata *);
-extern int path_walk(const char *, struct nameidata *);
+extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
+extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
+extern int FASTCALL(path_walk(const char *, struct nameidata *));
+extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
 extern void path_release(struct nameidata *);
 extern int follow_down(struct vfsmount **, struct dentry **);
 extern int follow_up(struct vfsmount **, struct dentry **);
@@ -1312,12 +1308,14 @@
 
 extern void clear_inode(struct inode *);
 extern struct inode * get_empty_inode(void);
+
 static inline struct inode * new_inode(struct super_block *sb)
 {
 	struct inode *inode = get_empty_inode();
 	if (inode) {
 		inode->i_sb = sb;
 		inode->i_dev = sb->s_dev;
+		inode->i_blkbits = sb->s_blocksize_bits;
 	}
 	return inode;
 }
@@ -1344,7 +1342,7 @@
 	if (buf)
 		__bforget(buf);
 }
-extern void set_blocksize(kdev_t, int);
+extern int set_blocksize(kdev_t, int);
 extern struct buffer_head * bread(kdev_t, int, int);
 extern void wakeup_bdflush(void);
 
@@ -1362,12 +1360,12 @@
 extern int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
 extern int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
 				unsigned long *);
+extern int block_commit_write(struct page *page, unsigned from, unsigned to);
 extern int block_sync_page(struct page *);
 
 int generic_block_bmap(struct address_space *, long, get_block_t *);
 int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
 int block_truncate_page(struct address_space *, loff_t, get_block_t *);
-extern int generic_direct_IO(int, struct inode *, struct kiobuf *, unsigned long, int, get_block_t *);
 extern void create_empty_buffers(struct page *, kdev_t, unsigned long);
 
 extern int waitfor_one_page(struct page*);
diff -u --recursive --new-file v2.4.10/linux/include/linux/gameport.h linux/include/linux/gameport.h
--- v2.4.10/linux/include/linux/gameport.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/gameport.h	Tue Oct  9 15:25:20 2001
@@ -74,8 +74,8 @@
 void gameport_register_port(struct gameport *gameport);
 void gameport_unregister_port(struct gameport *gameport);
 #else
-void __inline__ gameport_register_port(struct gameport *gameport) { return; }
-void __inline__ gameport_unregister_port(struct gameport *gameport) { return; }
+static void __inline__ gameport_register_port(struct gameport *gameport) { return; }
+static void __inline__ gameport_unregister_port(struct gameport *gameport) { return; }
 #endif
 
 void gameport_register_device(struct gameport_dev *dev);
diff -u --recursive --new-file v2.4.10/linux/include/linux/genhd.h linux/include/linux/genhd.h
--- v2.4.10/linux/include/linux/genhd.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/genhd.h	Tue Oct  9 15:24:01 2001
@@ -13,23 +13,33 @@
 #include <linux/types.h>
 #include <linux/major.h>
 
+enum {
 /* These three have identical behaviour; use the second one if DOS fdisk gets
    confused about extended/logical partitions starting past cylinder 1023. */
-#define DOS_EXTENDED_PARTITION 5
-#define LINUX_EXTENDED_PARTITION 0x85
-#define WIN98_EXTENDED_PARTITION 0x0f
-
-#define LINUX_SWAP_PARTITION	0x82
-#define LINUX_RAID_PARTITION	0xfd	/* autodetect RAID partition */
-
-#ifdef CONFIG_SOLARIS_X86_PARTITION
-#define SOLARIS_X86_PARTITION	LINUX_SWAP_PARTITION
-#endif
-
-#define DM6_PARTITION		0x54	/* has DDO: use xlated geom & offset */
-#define EZD_PARTITION		0x55	/* EZ-DRIVE */
-#define DM6_AUX1PARTITION	0x51	/* no DDO:  use xlated geom */
-#define DM6_AUX3PARTITION	0x53	/* no DDO:  use xlated geom */
+	DOS_EXTENDED_PARTITION = 5,
+	LINUX_EXTENDED_PARTITION = 0x85,
+	WIN98_EXTENDED_PARTITION = 0x0f,
+
+	LINUX_SWAP_PARTITION = 0x82,
+	LINUX_RAID_PARTITION = 0xfd,	/* autodetect RAID partition */
+
+	SOLARIS_X86_PARTITION =	LINUX_SWAP_PARTITION,
+
+	DM6_PARTITION =	0x54,	/* has DDO: use xlated geom & offset */
+	EZD_PARTITION =	0x55,	/* EZ-DRIVE */
+	DM6_AUX1PARTITION = 0x51,	/* no DDO:  use xlated geom */
+	DM6_AUX3PARTITION = 0x53,	/* no DDO:  use xlated geom */
+
+	FREEBSD_PARTITION = 0xa5,    /* FreeBSD Partition ID */
+	OPENBSD_PARTITION = 0xa6,    /* OpenBSD Partition ID */
+	NETBSD_PARTITION = 0xa9,   /* NetBSD Partition ID */
+	BSDI_PARTITION = 0xb7,    /* BSDI Partition ID */
+/* Ours is not to wonder why.. */
+	BSD_PARTITION =	FREEBSD_PARTITION,
+	MINIX_PARTITION = 0x81,  /* Minix Partition ID */
+	UNIXWARE_PARTITION = 0x63,		/* Partition ID, same as */
+						/* GNU_HURD and SCO Unix */
+};
 
 struct partition {
 	unsigned char boot_ind;		/* 0x80 - active */
@@ -117,13 +127,6 @@
  * BSD disklabel support by Yossi Gottlieb <yogo@math.tau.ac.il>
  * updated by Marc Espie <Marc.Espie@openbsd.org>
  */
-#define FREEBSD_PARTITION	0xa5    /* FreeBSD Partition ID */
-#define OPENBSD_PARTITION	0xa6    /* OpenBSD Partition ID */
-#define NETBSD_PARTITION	0xa9    /* NetBSD Partition ID */
-#define BSDI_PARTITION		0xb7    /* BSDI Partition ID */
-
-/* Ours is not to wonder why.. */
-#define BSD_PARTITION		FREEBSD_PARTITION
 
 /* check against BSD src/sys/sys/disklabel.h for consistency */
 
@@ -182,8 +185,6 @@
  * and Krzysztof G. Baranowski <kgb@knm.org.pl>
  */
 
-#define UNIXWARE_PARTITION     0x63		/* Partition ID, same as */
-						/* GNU_HURD and SCO Unix */
 #define UNIXWARE_DISKMAGIC     (0xCA5E600DUL)	/* The disk magic number */
 #define UNIXWARE_DISKMAGIC2    (0x600DDEEEUL)	/* The slice table magic nr */
 #define UNIXWARE_NUMSLICE      16
@@ -233,7 +234,6 @@
 #endif /* CONFIG_UNIXWARE_DISKLABEL */
 
 #ifdef CONFIG_MINIX_SUBPARTITION
-#   define MINIX_PARTITION         0x81  /* Minix Partition ID */
 #   define MINIX_NR_SUBPARTITIONS  4
 #endif /* CONFIG_MINIX_SUBPARTITION */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/hysdn_if.h linux/include/linux/hysdn_if.h
--- v2.4.10/linux/include/linux/hysdn_if.h	Sat May 19 17:54:14 2001
+++ linux/include/linux/hysdn_if.h	Sun Sep 30 12:26:42 2001
@@ -1,23 +1,13 @@
-/* $Id: hysdn_if.h,v 1.1.8.2 2001/05/17 20:41:52 kai Exp $
-
- * Linux driver for HYSDN cards, ioctl definitions shared by hynetmgr and driver.
- * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+/* $Id: hysdn_if.h,v 1.1.8.3 2001/09/23 22:25:05 kai Exp $
  *
- * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ * Linux driver for HYSDN cards
+ * ioctl definitions shared by hynetmgr and 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, or (at your option)
- * any later version.
+ * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ * Copyright 1999 by Werner Cornelius (werner@titro.de)
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/isdn.h linux/include/linux/isdn.h
--- v2.4.10/linux/include/linux/isdn.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/isdn.h	Sun Sep 30 12:26:42 2001
@@ -1,24 +1,13 @@
-/* $Id: isdn.h,v 1.111.6.8 2001/08/17 12:34:28 kai Exp $
-
+/* $Id: isdn.h,v 1.111.6.9 2001/09/23 22:25:05 kai Exp $
+ *
  * Main header for the Linux ISDN subsystem (linklevel).
  *
  * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
  * Copyright 1995,96    by Michael Hipp (Michael.Hipp@student.uni-tuebingen.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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/isdn_divertif.h linux/include/linux/isdn_divertif.h
--- v2.4.10/linux/include/linux/isdn_divertif.h	Mon Aug 21 07:49:03 2000
+++ linux/include/linux/isdn_divertif.h	Sun Sep 30 12:26:42 2001
@@ -1,22 +1,12 @@
-/* $Id: isdn_divertif.h,v 1.4 2000/05/11 22:29:22 kai Exp $
-
- * Header for the diversion supplementary interface for i4l.
+/* $Id: isdn_divertif.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $
  *
- * Copyright 1998       by Werner Cornelius (werner@isdn4linux.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, or (at your option)
- * any later version.
+ * Header for the diversion supplementary interface for i4l.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Author    Werner Cornelius (werner@titro.de)
+ * Copyright by Werner Cornelius (werner@titro.de)
  *
- * You should have received a copy of the 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 software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/isdn_lzscomp.h linux/include/linux/isdn_lzscomp.h
--- v2.4.10/linux/include/linux/isdn_lzscomp.h	Sun May 23 10:03:42 1999
+++ linux/include/linux/isdn_lzscomp.h	Sun Sep 30 12:26:42 2001
@@ -1,9 +1,11 @@
-/*
- * $Id: isdn_lzscomp.h,v 1.1 1998/07/08 16:52:33 hipp Exp $
+/* $Id: isdn_lzscomp.h,v 1.1.10.1 2001/09/23 22:25:05 kai Exp $
  *
  * Header for isdn_lzscomp.c
  * Concentrated here to not mess up half a dozen kernel headers with code
  * snippets
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/isdn_ppp.h linux/include/linux/isdn_ppp.h
--- v2.4.10/linux/include/linux/isdn_ppp.h	Sat May 19 17:54:14 2001
+++ linux/include/linux/isdn_ppp.h	Sun Sep 30 12:26:42 2001
@@ -1,4 +1,9 @@
-/* -*- mode: c; c-basic-offset: 2 -*- */
+/*
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
 
 #ifndef _LINUX_ISDN_PPP_H
 #define _LINUX_ISDN_PPP_H
diff -u --recursive --new-file v2.4.10/linux/include/linux/isdnif.h linux/include/linux/isdnif.h
--- v2.4.10/linux/include/linux/isdnif.h	Wed Jul 25 17:10:26 2001
+++ linux/include/linux/isdnif.h	Sun Sep 30 12:26:42 2001
@@ -1,25 +1,13 @@
-/* $Id: isdnif.h,v 1.37.6.5 2001/06/11 22:08:38 kai Exp $
-
- * Linux ISDN subsystem
+/* $Id: isdnif.h,v 1.37.6.6 2001/09/23 22:25:05 kai Exp $
  *
+ * Linux ISDN subsystem
  * Definition of the interface between the subsystem and its low-level drivers.
  *
  * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
  * Copyright 1995,96    Thinking Objects Software GmbH Wuerzburg
  * 
- * This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/jffs.h linux/include/linux/jffs.h
--- v2.4.10/linux/include/linux/jffs.h	Mon Aug 27 12:41:48 2001
+++ linux/include/linux/jffs.h	Thu Oct  4 15:13:18 2001
@@ -10,7 +10,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * $Id: jffs.h,v 1.11 2000/08/04 12:46:34 dwmw2 Exp $
+ * $Id: jffs.h,v 1.20 2001/09/18 21:33:37 dwmw2 Exp $
  *
  * Ported to Linux 2.3.x and MTD:
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
@@ -20,10 +20,11 @@
 #ifndef __LINUX_JFFS_H__
 #define __LINUX_JFFS_H__
 
-#define JFFS_VERSION_STRING "1.0"
-
+#include <linux/types.h>
 #include <linux/completion.h>
 
+#define JFFS_VERSION_STRING "1.0"
+
 /* This is a magic number that is used as an identification number for
    this file system.  It is written to the super_block structure.  */
 #define JFFS_MAGIC_SB_BITMASK 0x07c0  /* 1984 */
@@ -206,9 +207,9 @@
 /* This stuff could be used for finding memory leaks.  */
 #define JFFS_MEMORY_DEBUG 0
 
-#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
-extern long no_jffs_file;
 extern long no_jffs_node;
+extern long no_jffs_file;
+#if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
 extern long no_jffs_control;
 extern long no_jffs_raw_inode;
 extern long no_jffs_node_ref;
diff -u --recursive --new-file v2.4.10/linux/include/linux/jffs2_fs_sb.h linux/include/linux/jffs2_fs_sb.h
--- v2.4.10/linux/include/linux/jffs2_fs_sb.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/jffs2_fs_sb.h	Tue Oct  9 15:22:14 2001
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_sb.h,v 1.15 2001/04/18 13:05:28 dwmw2 Exp $ */
+/* $Id: jffs2_fs_sb.h,v 1.16 2001/09/18 20:15:18 dwmw2 Exp $ */
 
 #ifndef _JFFS2_FS_SB
 #define _JFFS2_FS_SB
@@ -26,9 +26,8 @@
 
 	//	pid_t thread_pid;		/* GC thread's PID */
 	struct task_struct *gc_task;	/* GC task struct */
-	struct semaphore gc_thread_sem; /* GC thread startup mutex */
-	struct completion gc_thread_exit; /* GC thread exit completion */
-
+	struct semaphore gc_thread_start; /* GC thread start mutex */
+	struct completion gc_thread_exit; /* GC thread exit completion port */
 	//	__u32 gc_minfree_threshold;	/* GC trigger thresholds */
 	//	__u32 gc_maxdirty_threshold;
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/kernel.h linux/include/linux/kernel.h
--- v2.4.10/linux/include/linux/kernel.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/kernel.h	Tue Oct  9 15:22:14 2001
@@ -96,6 +96,9 @@
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
 
+extern int tainted;
+extern const char *print_tainted(void);
+
 #if DEBUG
 #define pr_debug(fmt,arg...) \
 	printk(KERN_DEBUG fmt,##arg)
diff -u --recursive --new-file v2.4.10/linux/include/linux/list.h linux/include/linux/list.h
--- v2.4.10/linux/include/linux/list.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/list.h	Tue Oct  9 15:22:14 2001
@@ -92,7 +92,6 @@
 static __inline__ void list_del(struct list_head *entry)
 {
 	__list_del(entry->prev, entry->next);
-	entry->next = entry->prev = 0;
 }
 
 /**
diff -u --recursive --new-file v2.4.10/linux/include/linux/lockd/lockd.h linux/include/linux/lockd/lockd.h
--- v2.4.10/linux/include/linux/lockd/lockd.h	Sun Aug 12 13:28:01 2001
+++ linux/include/linux/lockd/lockd.h	Tue Oct  9 15:23:11 2001
@@ -47,6 +47,7 @@
 	unsigned short		h_authflavor;	/* RPC authentication type */
 	unsigned short		h_reclaiming : 1,
 				h_inuse      : 1,
+				h_killed     : 1,
 				h_monitored  : 1;
 	wait_queue_head_t	h_gracewait;	/* wait while reclaiming */
 	u32			h_state;	/* pseudo-state counter */
@@ -120,7 +121,7 @@
 #ifdef CONFIG_LOCKD_V4
 extern struct svc_procedure	nlmsvc_procedures4[];
 #endif
-extern unsigned long		nlmsvc_grace_period;
+extern int			nlmsvc_grace_period;
 extern unsigned long		nlmsvc_timeout;
 
 /*
diff -u --recursive --new-file v2.4.10/linux/include/linux/lockd/nlm.h linux/include/linux/lockd/nlm.h
--- v2.4.10/linux/include/linux/lockd/nlm.h	Mon Dec 11 13:25:38 2000
+++ linux/include/linux/lockd/nlm.h	Mon Oct  1 13:45:48 2001
@@ -49,10 +49,10 @@
 #define NLMPROC_CANCEL_RES	13
 #define NLMPROC_UNLOCK_RES	14
 #define NLMPROC_GRANTED_RES	15
+#define NLMPROC_NSM_NOTIFY	16		/* statd callback */
 #define NLMPROC_SHARE		20
 #define NLMPROC_UNSHARE		21
 #define NLMPROC_NM_LOCK		22
 #define NLMPROC_FREE_ALL	23
-#define NLMPROC_NSM_NOTIFY	24		/* statd callback */
 
 #endif /* LINUX_LOCKD_NLM_H */
diff -u --recursive --new-file v2.4.10/linux/include/linux/miscdevice.h linux/include/linux/miscdevice.h
--- v2.4.10/linux/include/linux/miscdevice.h	Tue Aug  7 12:51:23 2001
+++ linux/include/linux/miscdevice.h	Tue Oct  9 15:23:57 2001
@@ -21,6 +21,7 @@
 #define NVRAM_MINOR 144
 #define I2O_MINOR 166
 #define MICROCODE_MINOR		184
+#define MWAVE_MINOR	219		/* ACP/Mwave Modem */
 #define MPT_MINOR	220
 #define MISC_DYNAMIC_MINOR 255
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.4.10/linux/include/linux/mm.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/mm.h	Tue Oct  9 15:22:18 2001
@@ -550,16 +550,17 @@
 #define __GFP_IO	0x40	/* Can start low memory physical IO? */
 #define __GFP_HIGHIO	0x80	/* Can start high mem physical IO? */
 #define __GFP_FS	0x100	/* Can call down to low-level FS? */
+#define __GFP_WAITBUF	0x200	/* Can we wait for buffers to complete? */
 
 #define GFP_NOHIGHIO	(__GFP_HIGH | __GFP_WAIT | __GFP_IO)
 #define GFP_NOIO	(__GFP_HIGH | __GFP_WAIT)
-#define GFP_NOFS	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO)
+#define GFP_NOFS	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF)
 #define GFP_ATOMIC	(__GFP_HIGH)
-#define GFP_USER	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
-#define GFP_HIGHUSER	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS | __GFP_HIGHMEM)
-#define GFP_KERNEL	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
-#define GFP_NFS		(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
-#define GFP_KSWAPD	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+#define GFP_USER	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
+#define GFP_HIGHUSER	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS | __GFP_HIGHMEM)
+#define GFP_KERNEL	(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
+#define GFP_NFS		(__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
+#define GFP_KSWAPD	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_WAITBUF | __GFP_FS)
 
 /* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
    platforms, used as appropriate on others */
diff -u --recursive --new-file v2.4.10/linux/include/linux/module.h linux/include/linux/module.h
--- v2.4.10/linux/include/linux/module.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/module.h	Tue Oct  9 15:22:14 2001
@@ -346,12 +346,21 @@
 #define __EXPORT_SYMBOL(sym,str)   error config_must_be_included_before_module
 #define EXPORT_SYMBOL(var)	   error config_must_be_included_before_module
 #define EXPORT_SYMBOL_NOVERS(var)  error config_must_be_included_before_module
+#define EXPORT_SYMBOL_GPL(var)  error config_must_be_included_before_module
 
 #elif !defined(CONFIG_MODULES)
 
 #define __EXPORT_SYMBOL(sym,str)
 #define EXPORT_SYMBOL(var)
 #define EXPORT_SYMBOL_NOVERS(var)
+#define EXPORT_SYMBOL_GPL(var)
+
+#elif !defined(EXPORT_SYMTAB)
+
+#define __EXPORT_SYMBOL(sym,str)   error this_object_must_be_defined_as_export_objs_in_the_Makefile
+#define EXPORT_SYMBOL(var)	   error this_object_must_be_defined_as_export_objs_in_the_Makefile
+#define EXPORT_SYMBOL_NOVERS(var)  error this_object_must_be_defined_as_export_objs_in_the_Makefile
+#define EXPORT_SYMBOL_GPL(var)  error this_object_must_be_defined_as_export_objs_in_the_Makefile
 
 #else
 
@@ -362,10 +371,19 @@
 __attribute__((section("__ksymtab"))) =			\
 { (unsigned long)&sym, __kstrtab_##sym }
 
+#define __EXPORT_SYMBOL_GPL(sym, str)			\
+const char __kstrtab_##sym[]				\
+__attribute__((section(".kstrtab"))) = "GPLONLY_" str;	\
+const struct module_symbol __ksymtab_##sym		\
+__attribute__((section("__ksymtab"))) =			\
+{ (unsigned long)&sym, __kstrtab_##sym }
+
 #if defined(MODVERSIONS) || !defined(CONFIG_MODVERSIONS)
 #define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
+#define EXPORT_SYMBOL_GPL(var)  __EXPORT_SYMBOL_GPL(var, __MODULE_STRING(var))
 #else
 #define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
+#define EXPORT_SYMBOL_GPL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
 #endif
 
 #define EXPORT_SYMBOL_NOVERS(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
diff -u --recursive --new-file v2.4.10/linux/include/linux/mount.h linux/include/linux/mount.h
--- v2.4.10/linux/include/linux/mount.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/mount.h	Fri Oct  5 13:05:55 2001
@@ -29,7 +29,6 @@
 	int mnt_flags;
 	char *mnt_devname;		/* Name of device e.g. /dev/dsk/hda1 */
 	struct list_head mnt_list;
-	uid_t mnt_owner;
 };
 
 static inline struct vfsmount *mntget(struct vfsmount *mnt)
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/cfi.h linux/include/linux/mtd/cfi.h
--- v2.4.10/linux/include/linux/mtd/cfi.h	Mon Aug 27 12:41:48 2001
+++ linux/include/linux/mtd/cfi.h	Thu Oct  4 15:13:18 2001
@@ -1,7 +1,7 @@
 
 /* Common Flash Interface structures 
  * See http://support.intel.com/design/flash/technote/index.htm
- * $Id: cfi.h,v 1.22 2001/07/06 09:29:07 dwmw2 Exp $
+ * $Id: cfi.h,v 1.25 2001/09/04 07:06:21 dwmw2 Exp $
  */
 
 #ifndef __MTD_CFI_H__
@@ -244,7 +244,7 @@
 	struct mtd_info *(*cmdset_setup)(struct map_info *);
 	struct cfi_ident *cfiq; /* For now only one. We insist that all devs
 				  must be of the same type. */
-	__u8 mfr, id;
+	int mfr, id;
 	int numchips;
 	unsigned long chipshift; /* Because they're of the same type */
 	const char *im_name;	 /* inter_module name for cmdset_setup */
@@ -368,8 +368,13 @@
 static inline void cfi_udelay(int us)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-	if (current->need_resched)
-		schedule();
+	if (current->need_resched) {
+		unsigned long t = us * HZ / 1000000;
+		if (t < 1)
+			t = 1;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(t);
+	}
 	else
 #endif
 		udelay(us);
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/cfi_endian.h linux/include/linux/mtd/cfi_endian.h
--- v2.4.10/linux/include/linux/mtd/cfi_endian.h	Tue Jul  3 17:08:22 2001
+++ linux/include/linux/mtd/cfi_endian.h	Thu Oct  4 15:13:18 2001
@@ -1,16 +1,5 @@
 /*
- * $Id: cfi_endian.h,v 1.9 2001/04/23 21:19:11 nico Exp $
- *
- * It seems that some helpful people decided to make life easier
- * for software engineers who aren't capable of dealing with the 
- * concept of byteswapping, and advise engineers to swap the bytes
- * by wiring the data lines up to flash chips from BE hosts backwards.
- *
- * So we have ugly stuff here to disable the byteswapping where necessary.
- * I'm not going to try to do this dynamically.
- *
- * At first I thought these guys were on crack, but then I discovered the
- * LART. 
+ * $Id: cfi_endian.h,v 1.10 2001/06/18 11:00:46 abz Exp $
  *
  */
 
@@ -34,10 +23,6 @@
 #define CFI_BIG_ENDIAN
 #endif
 
-#ifdef CONFIG_MTD_CFI_LART_BIT_SWAP
-#define CFI_LART_ENDIAN
-#endif
-
 #endif
 
 #if defined(CFI_LITTLE_ENDIAN)
@@ -61,81 +46,6 @@
 #define cpu_to_cfi32(x) (x)
 #define cfi16_to_cpu(x) (x)
 #define cfi32_to_cpu(x) (x)
-#elif defined (CFI_LART_ENDIAN)
-/* 
-   Fuck me backwards. The data line mapping on LART is as follows:
-
-	U2	CPU	|	U3	CPU
-	 0	20	|	0	12
-	 1	22	|	1	14
-	 2	19	|	2	11
-	 3	17	|	3	9
-	 4	24	|	4	0
-	 5	26	|	5	2
-	 6	31	|	6	7
-	 7	29	|	7	5
-	 8	21	|	8	13
-	 9	23	|	9	15
-	 10	18	|	10	10
-	 11	16	|	11	8
-	 12	25	|	12	1
-	 13	27	|	13	3
-	 14	30	|	14	6
-	 15	28	|	15	4
-
-   For historical reference: the reason why the LART has this strange
-   mapping is that the designer of the board wanted address lines to
-   be as short as possible. Why? Because in that way you don't need
-   drivers in the address lines so the memory access time can be held
-   short. -- Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
-*/
-/* cpu_to_cfi16() and cfi16_to_cpu() are not needed because the LART
- * only has 32 bit wide Flash memory. -- Erik
- */
-#define cpu_to_cfi16(x) (x)
-#define cfi16_to_cpu(x) (x)
-static inline __u32 cfi32_to_cpu(__u32 x)
-{
-	__u32 ret;
-
-	ret =  (x & 0x08009000) >> 11;
-	ret |= (x & 0x00002000) >> 10;
-	ret |= (x & 0x04004000) >> 8;
-	ret |= (x & 0x00000010) >> 4;
-	ret |= (x & 0x91000820) >> 3;
-	ret |= (x & 0x22080080) >> 2;
-	ret |= (x & 0x40000400);
-	ret |= (x & 0x00040040) << 1;
-	ret |= (x & 0x00110000) << 4;
-	ret |= (x & 0x00220100) << 5;
-	ret |= (x & 0x00800208) << 6;
-	ret |= (x & 0x00400004) << 9;
-	ret |= (x & 0x00000001) << 12;
-	ret |= (x & 0x00000002) << 13;
-
-	return ret;
-}
-static inline __u32 cpu_to_cfi32(__u32 x)
-{
-	__u32 ret;
-
-	ret =  (x & 0x00010012) << 11;
-	ret |= (x & 0x00000008) << 10;
-	ret |= (x & 0x00040040) << 8;
-	ret |= (x & 0x00000001) << 4;
-	ret |= (x & 0x12200104) << 3;
-	ret |= (x & 0x08820020) << 2;
-	ret |= (x & 0x40000400);
-	ret |= (x & 0x00080080) >> 1;
-	ret |= (x & 0x01100000) >> 4;
-	ret |= (x & 0x04402000) >> 5;
-	ret |= (x & 0x20008200) >> 6;
-	ret |= (x & 0x80000800) >> 9;
-	ret |= (x & 0x00001000) >> 12;
-	ret |= (x & 0x00004000) >> 13;
-
-	return ret;
-}
 #else
 #error No CFI endianness defined
 #endif
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/doc2000.h linux/include/linux/mtd/doc2000.h
--- v2.4.10/linux/include/linux/mtd/doc2000.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/mtd/doc2000.h	Thu Oct  4 15:13:18 2001
@@ -2,7 +2,7 @@
 /* Linux driver for Disk-On-Chip 2000       */
 /* (c) 1999 Machine Vision Holdings, Inc.   */
 /* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2000.h,v 1.13 2001/05/29 12:03:45 dwmw2 Exp $ */
+/* $Id: doc2000.h,v 1.15 2001/09/19 00:22:15 dwmw2 Exp $ */
 
 #ifndef __MTD_DOC2000_H__
 #define __MTD_DOC2000_H__
@@ -134,6 +134,7 @@
 	int numchips;
 	struct Nand *chips;
 	struct mtd_info *nextdoc;
+	struct semaphore lock;
 };
 
 int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]);
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/ftl.h linux/include/linux/mtd/ftl.h
--- v2.4.10/linux/include/linux/mtd/ftl.h	Sun Feb  4 10:05:30 2001
+++ linux/include/linux/mtd/ftl.h	Thu Oct  4 15:13:18 2001
@@ -1,4 +1,7 @@
 /*
+ * $Id: ftl.h,v 1.5 2001/06/02 20:35:51 dwmw2 Exp $
+ * 
+ * Derived from (and probably identical to):
  * ftl.h 1.7 1999/10/25 20:23:17
  *
  * The contents of this file are subject to the Mozilla Public License
@@ -16,8 +19,8 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in which
- * case the provisions of the GPL are applicable instead of the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
  * above.  If you wish to allow the use of your version of this file
  * only under the terms of the GPL and not to allow others to use
  * your version of this file under the MPL, indicate your decision by
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/gen_probe.h linux/include/linux/mtd/gen_probe.h
--- v2.4.10/linux/include/linux/mtd/gen_probe.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/mtd/gen_probe.h	Thu Oct  4 15:13:18 2001
@@ -0,0 +1,23 @@
+/*
+ * (C) 2001, 2001 Red Hat, Inc.
+ * GPL'd
+ * $Id: gen_probe.h,v 1.1 2001/09/02 18:50:13 dwmw2 Exp $
+ */
+
+#ifndef __LINUX_MTD_GEN_PROBE_H__
+#define __LINUX_MTD_GEN_PROBE_H__
+
+#include <linux/mtd/flashchip.h>
+#include <linux/mtd/map.h> 
+#include <linux/mtd/cfi.h>
+
+struct chip_probe {
+	char *name;
+	int (*probe_chip)(struct map_info *map, __u32 base,
+			  struct flchip *chips, struct cfi_private *cfi);
+
+};
+
+struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp);
+
+#endif /* __LINUX_MTD_GEN_PROBE_H__ */
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/iflash.h linux/include/linux/mtd/iflash.h
--- v2.4.10/linux/include/linux/mtd/iflash.h	Tue Jul  4 10:10:52 2000
+++ linux/include/linux/mtd/iflash.h	Thu Oct  4 15:13:18 2001
@@ -1,4 +1,4 @@
-/* iflash.h $revision$ $date$ (David Hinds) */
+/* $Id: iflash.h,v 1.2 2000/11/13 18:01:54 dwmw2 Exp $ */
 
 #ifndef __MTD_IFLASH_H__
 #define __MTD_IFLASH_H__
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/map.h linux/include/linux/mtd/map.h
--- v2.4.10/linux/include/linux/mtd/map.h	Tue Jul  3 17:08:22 2001
+++ linux/include/linux/mtd/map.h	Thu Oct  4 15:13:18 2001
@@ -1,6 +1,6 @@
 
 /* Overhauled routines for dealing with different mmap regions of flash */
-/* $Id: map.h,v 1.24 2001/06/09 19:53:16 dwmw2 Exp $ */
+/* $Id: map.h,v 1.25 2001/09/09 15:04:17 dwmw2 Exp $ */
 
 #ifndef __LINUX_MTD_MAP_H__
 #define __LINUX_MTD_MAP_H__
@@ -79,7 +79,8 @@
 {
 	struct map_info *map = mtd->priv;
 
-	map->fldrv->destroy(mtd);
+	if (map->fldrv->destroy)
+		map->fldrv->destroy(mtd);
 #ifdef CONFIG_MODULES
 	if (map->fldrv->module)
 		__MOD_DEC_USE_COUNT(map->fldrv->module);
diff -u --recursive --new-file v2.4.10/linux/include/linux/mtd/pmc551.h linux/include/linux/mtd/pmc551.h
--- v2.4.10/linux/include/linux/mtd/pmc551.h	Mon Dec 11 13:16:45 2000
+++ linux/include/linux/mtd/pmc551.h	Thu Oct  4 15:13:18 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: pmc551.h,v 1.3 2000/10/30 20:03:23 major Exp $
+ * $Id: pmc551.h,v 1.4 2001/06/12 16:19:38 major Exp $
  *
  * PMC551 PCI Mezzanine Ram Device
  *
@@ -17,7 +17,7 @@
 
 #include <linux/mtd/mtd.h>
 
-#define PMC551_VERSION "$Id: pmc551.h,v 1.3 2000/10/30 20:03:23 major Exp $\n"\
+#define PMC551_VERSION "$Id: pmc551.h,v 1.4 2001/06/12 16:19:38 major Exp $\n"\
        "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
 
 /*
@@ -26,9 +26,9 @@
 struct mypriv {
         struct pci_dev *dev;
         u_char *start;
-        u32    mem_map0_base_val;
-        u32    curr_mem_map0_val;
-        u32    aperture_size;
+        u32    base_map0;
+        u32    curr_map0;
+        u32    asize;
 	struct mtd_info *nextpmc551;
 };                       
 
@@ -37,9 +37,10 @@
  */
 static int pmc551_erase(struct mtd_info *, struct erase_info *);
 static void pmc551_unpoint(struct mtd_info *, u_char *);
+static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
 static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char
-*);        
+static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);        
+
 
 /*
  * Define the PCI ID's if the kernel doesn't define them for us
@@ -73,9 +74,6 @@
 #define PMC551_DRAM_BLK_SET_COL_MUX(x,v) (((x) & ~0x00007000) | (((v) & 0x7) << 12))
 #define PMC551_DRAM_BLK_SET_ROW_MUX(x,v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8))
 
-
-#define PMC551_ADDR_HIGH_MASK	0x3ff00000
-#define PMC551_ADDR_LOW_MASK	0x000fffff
 
 #endif /* __MTD_PMC551_H__ */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/nfs_fs_i.h linux/include/linux/nfs_fs_i.h
--- v2.4.10/linux/include/linux/nfs_fs_i.h	Mon Aug 27 12:41:48 2001
+++ linux/include/linux/nfs_fs_i.h	Tue Oct  9 15:22:14 2001
@@ -99,5 +99,6 @@
  * Lock flag values
  */
 #define NFS_LCK_GRANTED		0x0001		/* lock has been granted */
+#define NFS_LCK_RECLAIM		0x0002		/* lock marked for reclaiming */
 
 #endif
diff -u --recursive --new-file v2.4.10/linux/include/linux/pagemap.h linux/include/linux/pagemap.h
--- v2.4.10/linux/include/linux/pagemap.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/pagemap.h	Tue Oct  9 15:22:22 2001
@@ -76,14 +76,16 @@
 	__find_get_page(mapping, index, page_hash(mapping, index))
 extern struct page * __find_lock_page (struct address_space * mapping,
 				unsigned long index, struct page **hash);
+extern struct page * find_or_create_page(struct address_space *mapping,
+				unsigned long index, unsigned int gfp_mask);
+
 extern void lock_page(struct page *page);
 #define find_lock_page(mapping, index) \
 	__find_lock_page(mapping, index, page_hash(mapping, index))
 
-extern void __add_page_to_hash_queue(struct page * page, struct page **p);
-
 extern void add_to_page_cache(struct page * page, struct address_space *mapping, unsigned long index);
 extern void add_to_page_cache_locked(struct page * page, struct address_space *mapping, unsigned long index);
+extern int add_to_page_cache_unique(struct page * page, struct address_space *mapping, unsigned long index, struct page **hash);
 
 extern void ___wait_on_page(struct page *);
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.4.10/linux/include/linux/pci_ids.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/pci_ids.h	Mon Oct  8 11:43:01 2001
@@ -345,6 +345,7 @@
 #define PCI_DEVICE_ID_IBM_3780IDSP	0x007d
 #define PCI_DEVICE_ID_IBM_CHUKAR	0x0096
 #define	PCI_DEVICE_ID_IBM_405GP		0x0156
+#define PCI_DEVICE_ID_IBM_SERVERAIDI960	0x01bd
 #define PCI_DEVICE_ID_IBM_MPIC_2	0xffff
 
 #define PCI_VENDOR_ID_COMPEX2		0x101a // pci.ids says "AT&T GIS (NCR)"
@@ -634,6 +635,7 @@
 #define PCI_DEVICE_ID_APPLE_KL_USB	0x0019
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP	0x0020
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC	0x0021
+#define PCI_DEVICE_ID_APPLE_UNI_N_FW2	0x0030
 
 #define PCI_VENDOR_ID_YAMAHA		0x1073
 #define PCI_DEVICE_ID_YAMAHA_724	0x0004
diff -u --recursive --new-file v2.4.10/linux/include/linux/quota.h linux/include/linux/quota.h
--- v2.4.10/linux/include/linux/quota.h	Fri Feb  9 14:46:13 2001
+++ linux/include/linux/quota.h	Fri Oct  5 12:23:53 2001
@@ -81,13 +81,6 @@
 #define QUOTAFILENAME "quota"
 #define QUOTAGROUP "staff"
 
-extern int nr_dquots, nr_free_dquots;
-extern int max_dquots;
-extern int dquot_root_squash;
-
-#define NR_DQHASH 43            /* Just an arbitrary number */
-#define NR_DQUOTS 1024          /* Maximum number of quotas active at one time (Configurable from /proc/sys/fs) */
-
 /*
  * Command definitions for the 'quotactl' system call.
  * The commands are broken into a main command defined below
@@ -151,26 +144,23 @@
 
 #ifdef __KERNEL__
 
-/*
- * Maximum length of a message generated in the quota system,
- * that needs to be kicked onto the tty.
- */
-#define MAX_QUOTA_MESSAGE 75
+extern int nr_dquots, nr_free_dquots;
+extern int dquot_root_squash;
+
+#define NR_DQHASH 43            /* Just an arbitrary number */
 
-#define DQ_LOCKED     0x01	/* locked for update */
-#define DQ_WANT       0x02	/* wanted for update */
-#define DQ_MOD        0x04	/* dquot modified since read */
+#define DQ_LOCKED     0x01	/* dquot under IO */
+#define DQ_MOD        0x02	/* dquot modified since read */
 #define DQ_BLKS       0x10	/* uid/gid has been warned about blk limit */
 #define DQ_INODES     0x20	/* uid/gid has been warned about inode limit */
 #define DQ_FAKE       0x40	/* no limits only usage */
 
 struct dquot {
-	struct dquot *dq_next;		/* Pointer to next dquot */
-	struct dquot **dq_pprev;
-	struct list_head dq_free;	/* free list element */
-	struct dquot *dq_hash_next;	/* Pointer to next in dquot_hash */
-	struct dquot **dq_hash_pprev;	/* Pointer to previous in dquot_hash */
-	wait_queue_head_t dq_wait;	/* Pointer to waitqueue */
+	struct list_head dq_hash;	/* Hash list in memory */
+	struct list_head dq_inuse;	/* List of all quotas */
+	struct list_head dq_free;	/* Free list element */
+	wait_queue_head_t dq_wait_lock;	/* Pointer to waitqueue on dquot lock */
+	wait_queue_head_t dq_wait_free;	/* Pointer to waitqueue for quota to be unused */
 	int dq_count;			/* Reference count */
 
 	/* fields after this point are cleared when invalidating */
@@ -189,7 +179,6 @@
 /*
  * Flags used for set_dqblk.
  */
-#define QUOTA_SYSCALL     0x01
 #define SET_QUOTA         0x02
 #define SET_USE           0x04
 #define SET_QLIMIT        0x08
diff -u --recursive --new-file v2.4.10/linux/include/linux/quotaops.h linux/include/linux/quotaops.h
--- v2.4.10/linux/include/linux/quotaops.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/quotaops.h	Tue Oct  9 15:22:46 2001
@@ -11,10 +11,11 @@
 #define _LINUX_QUOTAOPS_
 
 #include <linux/config.h>
+#include <linux/smp_lock.h>
 
 #if defined(CONFIG_QUOTA)
 
-#include <linux/smp_lock.h>
+#include <linux/fs.h>
 
 /*
  * declaration of quota_function calls in kernel.
@@ -24,85 +25,138 @@
 extern int  quota_off(struct super_block *sb, short type);
 extern int  sync_dquots(kdev_t dev, short type);
 
-extern int  dquot_alloc_block(const struct inode *inode, unsigned long number, char prealloc);
+extern int  dquot_alloc_block(struct inode *inode, unsigned long number, char prealloc);
 extern int  dquot_alloc_inode(const struct inode *inode, unsigned long number);
 
-extern void dquot_free_block(const struct inode *inode, unsigned long number);
+extern void dquot_free_block(struct inode *inode, unsigned long number);
 extern void dquot_free_inode(const struct inode *inode, unsigned long number);
 
-extern int  dquot_transfer(struct dentry *dentry, struct iattr *iattr);
+extern int  dquot_transfer(struct inode *inode, struct iattr *iattr);
 
 /*
  * Operations supported for diskquotas.
  */
+#define sb_any_quota_enabled(sb) ((sb)->s_dquot.flags & (DQUOT_USR_ENABLED | DQUOT_GRP_ENABLED))
+
 static __inline__ void DQUOT_INIT(struct inode *inode)
 {
-	if (!IS_NOQUOTA(inode)) {
-		if (inode->i_sb && inode->i_sb->dq_op)
-			inode->i_sb->dq_op->initialize(inode, -1);
-	}
+	if (!inode->i_sb)
+		BUG();
+	lock_kernel();
+	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
+		inode->i_sb->dq_op->initialize(inode, -1);
+	unlock_kernel();
 }
 
 static __inline__ void DQUOT_DROP(struct inode *inode)
 {
+	lock_kernel();
 	if (IS_QUOTAINIT(inode)) {
-		if (inode->i_sb && inode->i_sb->dq_op)
-			inode->i_sb->dq_op->drop(inode);
+		if (!inode->i_sb)
+			BUG();
+		inode->i_sb->dq_op->drop(inode);	/* Ops must be set when there's any quota... */
 	}
+	unlock_kernel();
 }
 
-static __inline__ int DQUOT_PREALLOC_BLOCK(struct super_block *sb, const struct inode *inode, int nr)
+static __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
 {
-	if (sb->dq_op) {
-		if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), 1) == NO_QUOTA)
+	lock_kernel();
+	if (sb_any_quota_enabled(inode->i_sb)) {
+		/* Number of used blocks is updated in alloc_block() */
+		if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 1) == NO_QUOTA) {
+			unlock_kernel();
 			return 1;
+		}
 	}
+	else
+		inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+	unlock_kernel();
 	return 0;
 }
 
-static __inline__ int DQUOT_ALLOC_BLOCK(struct super_block *sb, const struct inode *inode, int nr)
+static __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
 {
-	if (sb->dq_op) {
-		if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), 0) == NO_QUOTA)
+	int ret;
+        if (!(ret =  DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr)))
+		mark_inode_dirty(inode);
+	return ret;
+}
+
+static __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+{
+	lock_kernel();
+	if (sb_any_quota_enabled(inode->i_sb)) {
+		/* Number of used blocks is updated in alloc_block() */
+		if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 0) == NO_QUOTA) {
+			unlock_kernel();
 			return 1;
+		}
 	}
+	else
+		inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+	unlock_kernel();
 	return 0;
 }
 
-static __inline__ int DQUOT_ALLOC_INODE(struct super_block *sb, struct inode *inode)
+static __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
+{
+	int ret;
+	if (!(ret = DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr)))
+		mark_inode_dirty(inode);
+	return ret;
+}
+
+static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode)
 {
-	if (sb->dq_op) {
+	lock_kernel();
+	if (sb_any_quota_enabled(inode->i_sb)) {
 		DQUOT_INIT(inode);
-		if (sb->dq_op->alloc_inode (inode, 1))
+		if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) {
+			unlock_kernel();
 			return 1;
+		}
 	}
-	inode->i_flags |= S_QUOTA;
+	unlock_kernel();
 	return 0;
 }
 
-static __inline__ void DQUOT_FREE_BLOCK(struct super_block *sb, const struct inode *inode, int nr)
+static __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
 {
-	if (sb->dq_op)
-		sb->dq_op->free_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize));
+	lock_kernel();
+	if (sb_any_quota_enabled(inode->i_sb))
+		inode->i_sb->dq_op->free_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize));
+	else
+		inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
+	unlock_kernel();
 }
 
-static __inline__ void DQUOT_FREE_INODE(struct super_block *sb, struct inode *inode)
+static __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
 {
-	if (sb->dq_op)
-		sb->dq_op->free_inode(inode, 1);
+	DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
+	mark_inode_dirty(inode);
 }
 
-static __inline__ int DQUOT_TRANSFER(struct dentry *dentry, struct iattr *iattr)
+static __inline__ void DQUOT_FREE_INODE(struct inode *inode)
 {
-	int error = -EDQUOT;
+	lock_kernel();
+	if (sb_any_quota_enabled(inode->i_sb))
+		inode->i_sb->dq_op->free_inode(inode, 1);
+	unlock_kernel();
+}
 
-	if (dentry->d_inode->i_sb->dq_op && !IS_NOQUOTA(dentry->d_inode)) {
-		DQUOT_INIT(dentry->d_inode);
-		error = dentry->d_inode->i_sb->dq_op->transfer(dentry, iattr);
-	} else {
-		error = notify_change(dentry, iattr);
+static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
+{
+	lock_kernel();
+	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) {
+		DQUOT_INIT(inode);
+		if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) {
+			unlock_kernel();
+			return 1;
+		}
 	}
-	return error;
+	unlock_kernel();
+	return 0;
 }
 
 #define DQUOT_SYNC(dev)	sync_dquots(dev, -1)
@@ -115,18 +169,53 @@
  */
 #define DQUOT_INIT(inode)			do { } while(0)
 #define DQUOT_DROP(inode)			do { } while(0)
-#define DQUOT_PREALLOC_BLOCK(sb, inode, nr)	(0)
-#define DQUOT_ALLOC_BLOCK(sb, inode, nr)	(0)
-#define DQUOT_ALLOC_INODE(sb, inode)		(0)
-#define DQUOT_FREE_BLOCK(sb, inode, nr)		do { } while(0)
-#define DQUOT_FREE_INODE(sb, inode)		do { } while(0)
+#define DQUOT_ALLOC_INODE(inode)		(0)
+#define DQUOT_FREE_INODE(inode)			do { } while(0)
 #define DQUOT_SYNC(dev)				do { } while(0)
 #define DQUOT_OFF(sb)				do { } while(0)
+#define DQUOT_TRANSFER(inode, iattr)		(0)
+extern __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+{
+	lock_kernel();
+	inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+	unlock_kernel();
+	return 0;
+}
 
-/*
- * Special case expands to a simple notify_change.
- */
-#define DQUOT_TRANSFER(dentry, iattr) notify_change(dentry, iattr)
+extern __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
+{
+	DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr);
+	mark_inode_dirty(inode);
+	return 0;
+}
+
+extern __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+{
+	lock_kernel();
+	inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+	unlock_kernel();
+	return 0;
+}
+
+extern __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
+{
+	DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr);
+	mark_inode_dirty(inode);
+	return 0;
+}
+
+extern __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
+{
+	lock_kernel();
+	inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
+	unlock_kernel();
+}
+
+extern __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
+{
+	DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
+	mark_inode_dirty(inode);
+}	
 
 #endif /* CONFIG_QUOTA */
 #endif /* _LINUX_QUOTAOPS_ */
diff -u --recursive --new-file v2.4.10/linux/include/linux/reiserfs_fs.h linux/include/linux/reiserfs_fs.h
--- v2.4.10/linux/include/linux/reiserfs_fs.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/reiserfs_fs.h	Mon Oct  8 11:52:58 2001
@@ -17,6 +17,7 @@
 #ifdef __KERNEL__
 #include <linux/slab.h>
 #include <linux/tqueue.h>
+#include <asm/hardirq.h>
 #endif
 
 /*
@@ -97,6 +98,21 @@
 ** messages.
 */
 #define REISERFS_DEBUG_CODE 5 /* extra messages to help find/debug errors */ 
+
+/* assertions handling */
+
+/** always check a condition and panic if it's false. */
+#define RASSERT( cond, format, args... )					\
+if( !( cond ) ) 								\
+  reiserfs_panic( 0, "reiserfs[%i]: assertion " #cond " failed at "		\
+		  __FILE__ ":%i:" __FUNCTION__ ": " format "\n",		\
+		  in_interrupt() ? -1 : current -> pid, __LINE__ , ##args )
+
+#if defined( CONFIG_REISERFS_CHECK )
+#define RFALSE( cond, format, args... ) RASSERT( !( cond ), format, ##args )
+#else
+#define RFALSE( cond, format, args... ) do {;} while( 0 )
+#endif
 
 /*
  * Disk Data Structures
diff -u --recursive --new-file v2.4.10/linux/include/linux/sem.h linux/include/linux/sem.h
--- v2.4.10/linux/include/linux/sem.h	Tue Aug  7 12:48:42 2001
+++ linux/include/linux/sem.h	Tue Oct  9 15:22:14 2001
@@ -68,11 +68,11 @@
 #define SEMMNS  (SEMMNI*SEMMSL) /* <= INT_MAX max # of semaphores in system */
 #define SEMOPM  32	        /* <= 1 000 max num of ops per semop call */
 #define SEMVMX  32767           /* <= 32767 semaphore maximum value */
+#define SEMAEM  SEMVMX          /* adjust on exit max value */
 
 /* unused */
 #define SEMUME  SEMOPM          /* max num of undo entries per process */
 #define SEMMNU  SEMMNS          /* num of undo structures system wide */
-#define SEMAEM  (SEMVMX >> 1)   /* adjust on exit max value */
 #define SEMMAP  SEMMNS          /* # of entries in semaphore map */
 #define SEMUSZ  20		/* sizeof struct sem_undo */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/slab.h linux/include/linux/slab.h
--- v2.4.10/linux/include/linux/slab.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/slab.h	Tue Oct  9 15:22:18 2001
@@ -24,7 +24,7 @@
 #define	SLAB_NFS		GFP_NFS
 #define	SLAB_DMA		GFP_DMA
 
-#define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS)
+#define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_WAITBUF|__GFP_FS)
 #define	SLAB_NO_GROW		0x00001000UL	/* don't grow a cache */
 
 /* flags to pass to kmem_cache_create().
diff -u --recursive --new-file v2.4.10/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h
--- v2.4.10/linux/include/linux/smb_fs.h	Tue Jul  3 17:08:22 2001
+++ linux/include/linux/smb_fs.h	Tue Oct  2 17:03:34 2001
@@ -161,84 +161,6 @@
 }
 
 
-/* FIXME! the prototype list is probably not correct. Automate? */
-
-/* linux/fs/smbfs/file.c */
-extern struct inode_operations smb_file_inode_operations;
-extern struct file_operations smb_file_operations;
-extern struct address_space_operations smb_file_aops;
-
-/* linux/fs/smbfs/dir.c */
-extern struct inode_operations smb_dir_inode_operations;
-extern struct file_operations smb_dir_operations;
-void smb_new_dentry(struct dentry *dentry);
-void smb_renew_times(struct dentry *);
-
-/* linux/fs/smbfs/ioctl.c */
-int smb_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
-
-/* linux/fs/smbfs/inode.c */
-struct super_block *smb_read_super(struct super_block *, void *, int);
-void smb_get_inode_attr(struct inode *, struct smb_fattr *);
-void smb_set_inode_attr(struct inode *, struct smb_fattr *);
-void smb_invalidate_inodes(struct smb_sb_info *);
-int  smb_revalidate_inode(struct dentry *);
-int  smb_notify_change(struct dentry *, struct iattr *);
-struct inode *smb_iget(struct super_block *, struct smb_fattr *);
-
-/* linux/fs/smbfs/proc.c */
-int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp);
-__u32 smb_len(unsigned char *);
-__u8 *smb_setup_header(struct smb_sb_info *, __u8, __u16, __u16);
-int smb_get_rsize(struct smb_sb_info *);
-int smb_get_wsize(struct smb_sb_info *);
-int smb_newconn(struct smb_sb_info *, struct smb_conn_opt *);
-int smb_errno(struct smb_sb_info *);
-int smb_close(struct inode *);
-int smb_close_fileid(struct dentry *, __u16);
-int smb_open(struct dentry *, int);
-int smb_proc_read(struct inode *, off_t, int, char *);
-int smb_proc_write(struct inode *, off_t, int, const char *);
-int smb_proc_create(struct dentry *, __u16, time_t, __u16 *);
-int smb_proc_mv(struct dentry *, struct dentry *);
-int smb_proc_mkdir(struct dentry *);
-int smb_proc_rmdir(struct dentry *);
-int smb_proc_unlink(struct dentry *);
-int smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir,
-		     struct smb_cache_control *ctl);
-int smb_proc_getattr(struct dentry *, struct smb_fattr *);
-int smb_proc_setattr(struct dentry *, struct smb_fattr *);
-int smb_proc_settime(struct dentry *, struct smb_fattr *);
-int smb_proc_dskattr(struct super_block *, struct statfs *);
-int smb_proc_disconnect(struct smb_sb_info *);
-int smb_proc_trunc(struct smb_sb_info *, __u16, __u32);
-int smb_proc_flush(struct smb_sb_info *, __u16);
-void smb_init_root_dirent(struct smb_sb_info *, struct smb_fattr *);
-
-/* linux/fs/smbfs/sock.c */
-int smb_round_length(int);
-int smb_valid_socket(struct inode *);
-void smb_close_socket(struct smb_sb_info *);
-int smb_request(struct smb_sb_info *server);
-int smb_catch_keepalive(struct smb_sb_info *server);
-int smb_dont_catch_keepalive(struct smb_sb_info *server);
-int smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
-		       int ldata, unsigned char *data,
-		       int lparam, unsigned char *param,
-		       int *lrdata, unsigned char **rdata,
-		       int *lrparam, unsigned char **rparam);
-
-/* fs/smbfs/cache.c */
-
-void smb_invalid_dir_cache(struct inode * dir);
-void smb_invalidate_dircache_entries(struct dentry *parent);
-struct dentry * smb_dget_fpos(struct dentry *dentry, struct dentry *parent, 
-			      unsigned long fpos);
-int smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
-		   struct smb_cache_control *ctrl, struct qstr *qname,
-		   struct smb_fattr *entry);
-
-
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SMB_FS_H */
diff -u --recursive --new-file v2.4.10/linux/include/linux/smbno.h linux/include/linux/smbno.h
--- v2.4.10/linux/include/linux/smbno.h	Mon Nov 24 10:30:40 1997
+++ linux/include/linux/smbno.h	Sun Oct  7 16:47:43 2001
@@ -39,14 +39,20 @@
 #define ERRbadshare 32          /* Share mode on file conflict with open mode */
 #define ERRlock 33              /* Lock request conflicts with existing lock */
 #define ERRfilexists 80         /* File in operation already exists */
-#define ERRundocumented1 123    /* Invalid name?? e.g. .tmp* */
 #define ERRbadpipe 230          /* Named pipe invalid */
 #define ERRpipebusy 231         /* All instances of pipe are busy */
 #define ERRpipeclosing 232      /* named pipe close in progress */
 #define ERRnotconnected 233     /* No process on other end of named pipe */
 #define ERRmoredata 234         /* More data to be returned */
-#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */
-#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */
+
+#define ERROR_INVALID_PARAMETER	 87
+#define ERROR_DISK_FULL		112
+#define ERROR_INVALID_NAME	123
+#define ERROR_DIR_NOT_EMPTY	145
+#define ERROR_NOT_LOCKED	158
+#define ERROR_ALREADY_EXISTS	183  /* see also 80 ? */
+#define ERROR_EAS_DIDNT_FIT	275 /* Extended attributes didn't fit */
+#define ERROR_EAS_NOT_SUPPORTED	282 /* Extended attributes not supported */
 
 /* Error codes for the ERRSRV class */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/spinlock.h linux/include/linux/spinlock.h
--- v2.4.10/linux/include/linux/spinlock.h	Tue Aug  7 12:48:42 2001
+++ linux/include/linux/spinlock.h	Tue Oct  9 15:22:14 2001
@@ -42,6 +42,7 @@
 #if (DEBUG_SPINLOCKS < 1)
 
 #define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
+#define ATOMIC_DEC_AND_LOCK
 
 /*
  * Your basic spinlocks, allowing only a single CPU anywhere
@@ -128,7 +129,7 @@
 #endif /* !SMP */
 
 /* "lock on reference count zero" */
-#ifndef atomic_dec_and_lock
+#ifndef ATOMIC_DEC_AND_LOCK
 #include <asm/atomic.h>
 extern int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 #endif
diff -u --recursive --new-file v2.4.10/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.4.10/linux/include/linux/swap.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/swap.h	Tue Oct  9 15:22:14 2001
@@ -119,8 +119,11 @@
 /* linux/mm/page_alloc.c */
 
 /* linux/mm/swap_state.c */
+#define SWAP_CACHE_INFO
+#ifdef SWAP_CACHE_INFO
 extern void show_swap_cache_info(void);
-extern void add_to_swap_cache(struct page *, swp_entry_t);
+#endif
+extern int add_to_swap_cache(struct page *, swp_entry_t);
 extern void __delete_from_swap_cache(struct page *page);
 extern void delete_from_swap_cache(struct page *page);
 extern void free_page_and_swap_cache(struct page *page);
@@ -128,9 +131,11 @@
 extern struct page * read_swap_cache_async(swp_entry_t);
 
 /* linux/mm/oom_kill.c */
+extern int out_of_memory(void);
 extern void oom_kill(void);
 
 /* linux/mm/swapfile.c */
+extern int total_swap_pages;
 extern unsigned int nr_swapfiles;
 extern struct swap_info_struct swap_info[];
 extern int is_swap_partition(kdev_t);
@@ -149,15 +154,6 @@
 extern struct swap_list_t swap_list;
 asmlinkage long sys_swapoff(const char *);
 asmlinkage long sys_swapon(const char *, int);
-
-#define SWAP_CACHE_INFO
-
-#ifdef SWAP_CACHE_INFO
-extern unsigned long swap_cache_add_total;
-extern unsigned long swap_cache_del_total;
-extern unsigned long swap_cache_find_total;
-extern unsigned long swap_cache_find_success;
-#endif
 
 extern spinlock_t pagemap_lru_lock;
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.4.10/linux/include/linux/sysctl.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/sysctl.h	Tue Oct  9 15:22:14 2001
@@ -121,6 +121,7 @@
 	KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
 	KERN_S390_USER_DEBUG_LOGGING=51,  /* int: dumps of user faults */
 	KERN_CORE_USES_PID=52,		/* int: use core or core.%pid */
+	KERN_TAINTED=53,	/* int: various kernel tainted flags */
 	KERN_CADPID=54,		/* int: PID of the process to notify on CAD */
 };
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/sysrq.h linux/include/linux/sysrq.h
--- v2.4.10/linux/include/linux/sysrq.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/sysrq.h	Sun Sep 30 12:26:42 2001
@@ -24,6 +24,8 @@
 	char *action_msg;
 };
 
+#ifdef CONFIG_MAGIC_SYSRQ
+
 /* Generic SysRq interface -- you may call it from any device driver, supplying
  * ASCII code of the key, pointer to registers and kbd/tty structs (if they
  * are available -- else NULL's).
@@ -42,7 +44,6 @@
                 struct kbd_struct *, struct tty_struct *);
 
 
-#ifdef CONFIG_MAGIC_SYSRQ
 
 /*
  * Sysrq registration manipulation functions
@@ -55,7 +56,8 @@
 
 extern __inline__ int
 __sysrq_swap_key_ops_nolock(int key, struct sysrq_key_op *insert_op_p,
-				struct sysrq_key_op *remove_op_p) {
+				struct sysrq_key_op *remove_op_p)
+{
 	int retval;
 	if (__sysrq_get_key_op(key) == remove_op_p) {
 		__sysrq_put_key_op(key, insert_op_p);
@@ -87,9 +89,17 @@
 }
 
 #else
-#define register_sysrq_key(a,b)		do {} while(0)
-#define unregister_sysrq_key(a,b)	do {} while(0)
+
+static inline int __reterr(void)
+{
+	return -EINVAL;
+}
+
+#define register_sysrq_key(ig,nore) __reterr()
+#define unregister_sysrq_key(ig,nore) __reterr()
+
 #endif
+
 
 /* Deferred actions */
 
diff -u --recursive --new-file v2.4.10/linux/include/linux/timer.h linux/include/linux/timer.h
--- v2.4.10/linux/include/linux/timer.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/timer.h	Tue Oct  9 15:22:14 2001
@@ -19,7 +19,6 @@
 	unsigned long data;
 	void (*function)(unsigned long);
 };
-typedef struct timer_list timer_t;
 
 extern void add_timer(struct timer_list * timer);
 extern int del_timer(struct timer_list * timer);
diff -u --recursive --new-file v2.4.10/linux/include/linux/usb.h linux/include/linux/usb.h
--- v2.4.10/linux/include/linux/usb.h	Sun Sep 23 11:41:01 2001
+++ linux/include/linux/usb.h	Tue Oct  9 15:25:19 2001
@@ -539,13 +539,12 @@
  *                         SYNCHRONOUS CALL SUPPORT                  *
  *-------------------------------------------------------------------*/
 
-typedef struct
+struct usb_api_data
 {
-  wait_queue_head_t *wakeup;
-
-  void* stuff;
-  /* more to follow */
-} api_wrapper_data;
+	wait_queue_head_t wqh;
+	int done;
+	/* void* stuff;	*/	/* Possible extension later. */
+};
 
 /* -------------------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.10/linux/include/net/irda/irda-usb.h linux/include/net/irda/irda-usb.h
--- v2.4.10/linux/include/net/irda/irda-usb.h	Sun Sep 23 11:41:01 2001
+++ linux/include/net/irda/irda-usb.h	Thu Oct  4 18:41:09 2001
@@ -1,7 +1,7 @@
 /*****************************************************************************
  *
  * Filename:      irda-usb.h
- * Version:       0.9a
+ * Version:       0.9b
  * Description:   IrDA-USB Driver
  * Status:        Experimental 
  * Author:        Dag Brattli <dag@brattli.net>
@@ -63,17 +63,19 @@
 #define IU_MAX_RX_URBS	(IU_MAX_ACTIVE_RX_URBS + 1)
 
 /* Various ugly stuff to try to workaround generic problems */
-/* The USB layer should send empty frames at the end of packets multiple
- * of the frame size. As it doesn't do it by default, we need to do it
- * ourselves... See also following option. */
-#undef IU_BUG_KICK_TX
-/* Use the USB_ZERO_PACKET flag instead of sending empty frame (above)
- * Work only with usb-uhci.o so far. Please fix uhic.c and usb-ohci.c */
-#define IU_USE_USB_ZERO_FLAG
 /* Send speed command in case of timeout, just for trying to get things sane */
 #define IU_BUG_KICK_TIMEOUT
 /* Show the USB class descriptor */
 #undef IU_DUMP_CLASS_DESC 
+/* Assume a minimum round trip latency for USB transfer (in us)...
+ * USB transfer are done in the next USB slot if there is no traffic
+ * (1/19 msec) and is done at 12 Mb/s :
+ * Waiting for slot + tx = (53us + 16us) * 2 = 137us minimum.
+ * Rx notification will only be done at the end of the USB frame period :
+ * OHCI : frame period = 1ms
+ * UHCI : frame period = 1ms, but notification can take 2 or 3 ms :-(
+ * EHCI : frame period = 125us */
+#define IU_USB_MIN_RTT		500	/* This should be safe in most cases */
 
 /* Inbound header */
 #define MEDIA_BUSY    0x80
@@ -136,9 +138,6 @@
 	struct urb *idle_rx_urb;	/* Pointer to idle URB in Rx path */
 	struct urb tx_urb;		/* URB used to send data frames */
 	struct urb speed_urb;		/* URB used to send speed commands */
-#ifdef IU_BUG_KICK_TX
-	struct urb empty_urb;		/* URB used to send empty commands */
-#endif IU_BUG_KICK_TX
 	
 	struct net_device *netdev;	/* Yes! we are some kind of netdev. */
 	struct net_device_stats stats;
diff -u --recursive --new-file v2.4.10/linux/include/net/irda/irlmp.h linux/include/net/irda/irlmp.h
--- v2.4.10/linux/include/net/irda/irlmp.h	Sun Sep 23 11:41:01 2001
+++ linux/include/net/irda/irlmp.h	Thu Oct  4 18:41:09 2001
@@ -216,7 +216,7 @@
 
 void irlmp_discovery_confirm(hashbin_t *discovery_log);
 void irlmp_discovery_request(int nslots);
-struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask);
+struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots);
 void irlmp_do_expiry(void);
 void irlmp_do_discovery(int nslots);
 discovery_t *irlmp_get_discovery_response(void);
diff -u --recursive --new-file v2.4.10/linux/include/net/irda/vlsi_ir.h linux/include/net/irda/vlsi_ir.h
--- v2.4.10/linux/include/net/irda/vlsi_ir.h	Mon Aug 27 12:41:49 2001
+++ linux/include/net/irda/vlsi_ir.h	Thu Oct  4 18:41:09 2001
@@ -3,7 +3,7 @@
  *
  *	vlsi_ir.h:	VLSI82C147 PCI IrDA controller driver for Linux
  *
- *	Version:	0.1, Aug 6, 2001
+ *	Version:	0.3, Sep 30, 2001
  *
  *	Copyright (c) 2001 Martin Diehl
  *
@@ -49,7 +49,7 @@
  *
  * On my HP OB-800 the BIOS sets external 40MHz clock as source
  * when IrDA enabled and I've never detected any PLL lock success.
- * Apparently the 14.31818MHz OSC input required for the PLL to work
+ * Apparently the 14.3...MHz OSC input required for the PLL to work
  * is not connected and the 40MHz EXTCLK is provided externally.
  * At least this is what makes the driver working for me.
  */
@@ -59,7 +59,7 @@
 	/* PLL control */
 
 	CLKCTL_NO_PD		= 0x04,		/* PD# (inverted power down) signal,
-						 * i.e. PLL is powered, if PD_INV is set */
+						 * i.e. PLL is powered, if NO_PD set */
 	CLKCTL_LOCK		= 0x40,		/* (ro) set, if PLL is locked */
 
 	/* clock source selection */
@@ -71,7 +71,7 @@
 
 	CLKCTL_CLKSTP		= 0x80,		/* set to disconnect from selected clock source */
 	CLKCTL_WAKE		= 0x08		/* set to enable wakeup feature: whenever IR activity
-						 * is detected, PD_INV gets set and CLKSTP cleared */
+						 * is detected, NO_PD gets set and CLKSTP cleared */
 };
 
 /* ------------------------------------------ */
@@ -105,8 +105,8 @@
 	 * restriction to the first 16MB of physical address range.
 	 * Hence the approach here is to enable PCI busmaster support using
 	 * the correct 32bit dma-mask used by the chip. Afterwards the device's
-	 * dma-mask gets restricted to 24bit, which must be honoured by all
-	 * allocations for memory areas to be exposed to the chip.
+	 * dma-mask gets restricted to 24bit, which must be honoured somehow by
+	 * all allocations for memory areas to be exposed to the chip ...
 	 *
 	 * Note:
 	 * Don't be surprised to get "Setting latency timer..." messages every
@@ -119,7 +119,7 @@
 
 /* VLSI_PCIIRMISC: IR Miscellaneous Register (u8, rw) */
 
-/* leagcy UART emulation - not used by this driver - would require:
+/* legacy UART emulation - not used by this driver - would require:
  * (see below for some register-value definitions)
  *
  *	- IRMISC_UARTEN must be set to enable UART address decoding
@@ -135,7 +135,7 @@
 
 	IRMISC_IRRAIL		= 0x40,		/* (ro?) IR rail power indication (and control?)
 						 * 0=3.3V / 1=5V. Probably set during power-on?
-						 * Not touched by driver */
+						 * unclear - not touched by driver */
 	IRMISC_IRPD		= 0x08,		/* transceiver power down, if set */
 
 	/* legacy UART control */
@@ -168,7 +168,7 @@
 	VLSI_PIO_RINGBASE	= 0x04,		/* [23:10] of ring address (u16, rw) */
 	VLSI_PIO_RINGSIZE	= 0x06,		/* rx/tx ring size (u16, rw) */
 	VLSI_PIO_PROMPT		= 0x08, 	/* triggers ring processing (u16, wo) */
-						/* 0x0a-0x0f: reserved, duplicated UART regs */
+	/* 0x0a-0x0f: reserved / duplicated UART regs */
 	VLSI_PIO_IRCFG		= 0x10,		/* configuration select (u16, rw) */
 	VLSI_PIO_SIRFLAG	= 0x12,		/* BOF/EOF for filtered SIR (u16, ro) */
 	VLSI_PIO_IRENABLE	= 0x14,		/* enable and status register (u16, rw/ro) */
@@ -176,7 +176,7 @@
 	VLSI_PIO_NPHYCTL	= 0x18,		/* next physical layer select (u16, rw) */
 	VLSI_PIO_MAXPKT		= 0x1a,		/* [11:0] max len for packet receive (u16, rw) */
 	VLSI_PIO_RCVBCNT	= 0x1c		/* current receive-FIFO byte count (u16, ro) */
-						/* 0x1e-0x1f: reserved, duplicated UART regs */
+	/* 0x1e-0x1f: reserved / duplicated UART regs */
 };
 
 /* ------------------------------------------ */
@@ -188,7 +188,7 @@
  * interrupt condition bits:
  * 		set according to corresponding interrupt source
  *		(regardless of the state of the enable bits)
- *		enable bit status indicated whether interrupt gets raised
+ *		enable bit status indicates whether interrupt gets raised
  *		write-to-clear
  * note: RPKTINT and TPKTINT behave different in legacy UART mode (which we don't use :-)
  */
@@ -212,16 +212,16 @@
 
 /* VLSI_PIO_RINGPTR: Ring Pointer Read-Back Register (u16, ro) */
 
-#define MAX_RING_DESCR		64	/* tx, rx rings may contain up to 64 descr each */
-
 /* _both_ ring pointers are indices relative to the _entire_ rx,tx-ring!
  * i.e. the referenced descriptor is located
  * at RINGBASE + PTR * sizeof(descr) for rx and tx
- * therefore, the tx-pointer has offset by MAX_RING_DESCR
+ * therefore, the tx-pointer has offset MAX_RING_DESCR
  */
 
+#define MAX_RING_DESCR		64	/* tx, rx rings may contain up to 64 descr each */
+
 #define RINGPTR_RX_MASK		(MAX_RING_DESCR-1)
-#define RINGPTR_TX_MASK		((MAX_RING_DESCR|(MAX_RING_DESCR-1))<<8)
+#define RINGPTR_TX_MASK		((MAX_RING_DESCR-1)<<8)
 
 #define RINGPTR_GET_RX(p)	((p)&RINGPTR_RX_MASK)
 #define RINGPTR_GET_TX(p)	(((p)&RINGPTR_TX_MASK)>>8)
@@ -233,14 +233,14 @@
 /* Contains [23:10] part of the ring base (bus-) address
  * which must be 1k-alinged. [31:24] is taken from
  * VLSI_PCI_MSTRPAGE above.
- * The controler initiates non-burst PCI BM cycles to
+ * The controller initiates non-burst PCI BM cycles to
  * fetch and update the descriptors in the ring.
  * Once fetched, the descriptor remains cached onchip
  * until it gets closed and updated due to the ring
  * processing state machine.
  * The entire ring area is split in rx and tx areas with each
  * area consisting of 64 descriptors of 8 bytes each.
- * The rx(tx) ring is located at ringbase+0 (ringbase+8*64).
+ * The rx(tx) ring is located at ringbase+0 (ringbase+64*8).
  */
 
 #define BUS_TO_RINGBASE(p)	(((p)>>10)&0x3fff)
@@ -273,9 +273,7 @@
 /* VLSI_PIO_PROMPT: Ring Prompting Register (u16, write-to-start) */
 
 /* writing any value kicks the ring processing state machines
- * for both tx, rx rings.
- * currently enabled rings (according to IRENABLE_ENTXST, IRENABLE_ENRXST
- * status reporting - see below) are considered as follows:
+ * for both tx, rx rings as follows:
  * 	- active rings (currently owning an active descriptor)
  *	  ignore the prompt and continue
  *	- idle rings fetch the next descr from the ring and start
@@ -289,7 +287,7 @@
 /* notes:
  *	- not more than one SIR/MIR/FIR bit must be set at any time
  *	- SIR, MIR, FIR and CRC16 select the configuration which will
- *	  be applied now/next time if/when IRENABLE_IREN is _cleared_ (see below)
+ *	  be applied on next 0->1 transition of IRENABLE_IREN (see below).
  *	- besides allowing the PCI interface to execute busmaster cycles
  *	  and therefore the ring SM to operate, the MSTR bit has side-effects:
  *	  when MSTR is cleared, the RINGPTR's get reset and the legacy UART mode
@@ -340,7 +338,7 @@
  */
 
 enum vlsi_pio_irenable {
-	IRENABLE_IREN		= 0x8000,  /* enable IR phy and gate mode config (rw) */
+	IRENABLE_IREN		= 0x8000,  /* enable IR phy and gate the mode config (rw) */
 	IRENABLE_CFGER		= 0x4000,  /* mode configuration error (ro) */
 	IRENABLE_FIR_ON		= 0x2000,  /* FIR on status (ro) */
 	IRENABLE_MIR_ON		= 0x1000,  /* MIR on status (ro) */
@@ -389,7 +387,7 @@
  *		specification, which provides 1.5 usec pulse width for all speeds (except
  *		for 2.4kbaud getting 6usec). This is well inside IrPHY v1.3 specs and
  *		reduces the transceiver power which drains the battery. At 9.6kbaud for
- *		example this makes more than 90% battery power saving!
+ *		example this amounts to more than 90% battery power saving!
  *
  * MIR-mode:	BAUD = 0
  *		PLSWID = 9(10) for 40(48) MHz input clock
@@ -402,7 +400,7 @@
  */
 
 #define BWP_TO_PHYCTL(B,W,P)	((((B)&0x3f)<<10) | (((W)&0x1f)<<5) | (((P)&0x1f)<<0))
-#define BAUD_BITS(br)		((115200/br)-1)
+#define BAUD_BITS(br)		((115200/(br))-1)
 
 static inline unsigned
 calc_width_bits(unsigned baudrate, unsigned widthselect, unsigned clockselect)
@@ -447,15 +445,25 @@
 
 /* VLSI_PIO_MAXPKT: Maximum Packet Length register (u16, rw) */
 
-/* specifies the maximum legth (up to 4096 bytes), which a
+/* specifies the maximum legth (up to 4k - or (4k-1)? - bytes), which a
  * received frame may have - i.e. the size of the corresponding
  * receive buffers. For simplicity we use the same length for
- * receive and submit buffers. Therefore we use 3k to have
- * enough space for a lot of XBOF's and escapes we may need at
- * some point when wrapping MTU=2048 sized packets for transmission.
- */
+ * receive and submit buffers and increase transfer buffer size
+ * byond IrDA-MTU = 2048 so we have sufficient space left when
+ * packet size increases during wrapping due to XBOFs and CE's.
+ * Even for receiving unwrapped frames we need >MAX_PACKET_LEN
+ * space since the controller appends FCS/CRC (2 or 4 bytes)
+ * so we use 2*IrDA-MTU for both directions and cover even the
+ * worst case, where all data bytes have to be escaped when wrapping.
+ * well, this wastes some memory - anyway, later we will
+ * either map skb's directly or use pci_pool allocator...
+ */
+ 
+#define IRDA_MTU	2048		/* seems to be undefined elsewhere */
+ 
+#define XFER_BUF_SIZE		(2*IRDA_MTU)
 
-#define MAX_PACKET_LENGTH	3172
+#define MAX_PACKET_LENGTH	(XFER_BUF_SIZE-1) /* register uses only [11:0] */
 
 
 /* ------------------------------------------ */
@@ -466,7 +474,7 @@
 /* recive packet counter gets incremented on every non-filtered
  * byte which was put in the receive fifo and reset for each
  * new packet. Used to decide whether we are just in the middle
- * of receiving receiving
+ * of receiving
  */
 
 #define RCVBCNT_MASK	0x0fff
@@ -538,12 +546,21 @@
 
 struct ring_entry {
 	struct sk_buff	*skb;
-	void		*head;
+	void		*data;
+};
+
+
+struct vlsi_ring {
+	unsigned		size;
+	unsigned		mask;
+	unsigned		head, tail;
+	struct ring_descr	*hw;
+	struct ring_entry	buf[MAX_RING_DESCR];
 };
 
 /* ------------------------------------------ */
 
-/* our compound VLSI-PCI-IRDA device information */
+/* our private compound VLSI-PCI-IRDA device information */
 
 typedef struct vlsi_irda_dev {
 	struct pci_dev		*pdev;
@@ -557,14 +574,10 @@
 	int			baud, new_baud;
 
 	dma_addr_t		busaddr;
+	void			*virtaddr;
+	struct vlsi_ring	tx_ring, rx_ring;
 
-	struct ring_descr	*ring_hw;
-
-	struct ring_entry	*ring_buf;
-
-	unsigned		tx_mask, rx_mask;
-
-	unsigned		tx_put, tx_get, rx_put, rx_get;
+	struct timeval		last_rx;
 
 	spinlock_t		lock;
 	
diff -u --recursive --new-file v2.4.10/linux/include/net/route.h linux/include/net/route.h
--- v2.4.10/linux/include/net/route.h	Tue Aug  7 12:49:04 2001
+++ linux/include/net/route.h	Tue Oct  9 15:23:01 2001
@@ -30,6 +30,7 @@
 #include <linux/in_route.h>
 #include <linux/rtnetlink.h>
 #include <linux/route.h>
+#include <linux/cache.h>
 
 #ifndef __KERNEL__
 #warning This file is not supposed to be used outside of kernel.
@@ -105,7 +106,7 @@
         unsigned int out_hit;
         unsigned int out_slow_tot;
         unsigned int out_slow_mc;
-};
+} ____cacheline_aligned_in_smp;
 
 extern struct ip_rt_acct *ip_rt_acct;
 
diff -u --recursive --new-file v2.4.10/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.4.10/linux/include/net/tcp.h	Sun Sep 23 11:41:01 2001
+++ linux/include/net/tcp.h	Tue Oct  9 15:23:53 2001
@@ -266,13 +266,13 @@
  * Never offer a window over 32767 without using window scaling. Some
  * poor stacks do signed 16bit maths! 
  */
-#define MAX_TCP_WINDOW		32767
+#define MAX_TCP_WINDOW		32767U
 
 /* Minimal accepted MSS. It is (60+60+8) - (20+20). */
-#define TCP_MIN_MSS		88
+#define TCP_MIN_MSS		88U
 
 /* Minimal RCV_MSS. */
-#define TCP_MIN_RCVMSS		536
+#define TCP_MIN_RCVMSS		536U
 
 /* After receiving this amount of duplicate ACKs fast retransmit starts. */
 #define TCP_FASTRETRANS_THRESH 3
@@ -281,7 +281,7 @@
 #define TCP_MAX_REORDERING	127
 
 /* Maximal number of ACKs sent quickly to accelerate slow-start. */
-#define TCP_MAX_QUICKACKS	16
+#define TCP_MAX_QUICKACKS	16U
 
 /* urg_data states */
 #define TCP_URG_VALID	0x0100
@@ -323,21 +323,21 @@
 				  * TIME-WAIT timer.
 				  */
 
-#define TCP_DELACK_MAX	(HZ/5)	/* maximal time to delay before sending an ACK */
+#define TCP_DELACK_MAX	((unsigned)(HZ/5))	/* maximal time to delay before sending an ACK */
 #if HZ >= 100
-#define TCP_DELACK_MIN	(HZ/25)	/* minimal time to delay before sending an ACK */
-#define TCP_ATO_MIN	(HZ/25)
+#define TCP_DELACK_MIN	((unsigned)(HZ/25))	/* minimal time to delay before sending an ACK */
+#define TCP_ATO_MIN	((unsigned)(HZ/25))
 #else
-#define TCP_DELACK_MIN	4
-#define TCP_ATO_MIN	4
+#define TCP_DELACK_MIN	4U
+#define TCP_ATO_MIN	4U
 #endif
-#define TCP_RTO_MAX	(120*HZ)
-#define TCP_RTO_MIN	(HZ/5)
-#define TCP_TIMEOUT_INIT (3*HZ)	/* RFC 1122 initial RTO value	*/
-
-#define TCP_RESOURCE_PROBE_INTERVAL (HZ/2) /* Maximal interval between probes
-					    * for local resources.
-					    */
+#define TCP_RTO_MAX	((unsigned)(120*HZ))
+#define TCP_RTO_MIN	((unsigned)(HZ/5))
+#define TCP_TIMEOUT_INIT ((unsigned)(3*HZ))	/* RFC 1122 initial RTO value	*/
+
+#define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes
+					                 * for local resources.
+					                 */
 
 #define TCP_KEEPALIVE_TIME	(120*60*HZ)	/* two hours */
 #define TCP_KEEPALIVE_PROBES	9		/* Max of 9 keepalive probes	*/
@@ -919,14 +919,13 @@
 static inline void tcp_initialize_rcv_mss(struct sock *sk)
 {
 	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
+	unsigned int hint = min(tp->advmss, tp->mss_cache);
 
-	hint = min_t(unsigned int, hint, tp->rcv_wnd/2);
-		
-	tp->ack.rcv_mss = max_t(unsigned int,
-			      min_t(unsigned int,
-				  hint, TCP_MIN_RCVMSS),
-			      TCP_MIN_MSS);
+	hint = min(hint, tp->rcv_wnd/2);
+	hint = min(hint, TCP_MIN_RCVMSS);
+	hint = max(hint, TCP_MIN_MSS);
+
+	tp->ack.rcv_mss = hint;
 }
 
 static __inline__ void __tcp_fast_path_on(struct tcp_opt *tp, u32 snd_wnd)
@@ -1065,7 +1064,7 @@
  *	"Packets left network, but not honestly ACKed yet" PLUS
  *	"Packets fast retransmitted"
  */
-static __inline__ int tcp_packets_in_flight(struct tcp_opt *tp)
+static __inline__ unsigned int tcp_packets_in_flight(struct tcp_opt *tp)
 {
 	return tp->packets_out - tp->left_out + tp->retrans_out;
 }
@@ -1077,7 +1076,7 @@
  */
 static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp)
 {
-	return max_t(u32, tp->snd_cwnd >> 1, 2);
+	return max(tp->snd_cwnd >> 1U, 2U);
 }
 
 /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
@@ -1089,7 +1088,7 @@
 	if ((1<<tp->ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery))
 		return tp->snd_ssthresh;
 	else
-		return max_t(u32, tp->snd_ssthresh,
+		return max(tp->snd_ssthresh,
 			   ((tp->snd_cwnd >> 1) +
 			    (tp->snd_cwnd >> 2)));
 }
@@ -1126,8 +1125,8 @@
 {
 	tp->undo_marker = 0;
 	tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
-	tp->snd_cwnd = min_t(u32, tp->snd_cwnd,
-			   tcp_packets_in_flight(tp) + 1);
+	tp->snd_cwnd = min(tp->snd_cwnd,
+			   tcp_packets_in_flight(tp) + 1U);
 	tp->snd_cwnd_cnt = 0;
 	tp->high_seq = tp->snd_nxt;
 	tp->snd_cwnd_stamp = tcp_time_stamp;
@@ -1484,16 +1483,18 @@
  * be a multiple of mss if possible. We assume here that mss >= 1.
  * This MUST be enforced by all callers.
  */
-static inline void tcp_select_initial_window(int space, __u32 mss,
+static inline void tcp_select_initial_window(int __space, __u32 mss,
 	__u32 *rcv_wnd,
 	__u32 *window_clamp,
 	int wscale_ok,
 	__u8 *rcv_wscale)
 {
+	unsigned int space = (__space < 0 ? 0 : __space);
+
 	/* If no clamp set the clamp to the max possible scaled window */
 	if (*window_clamp == 0)
 		(*window_clamp) = (65535 << 14);
-	space = min_t(u32, *window_clamp, space);
+	space = min(*window_clamp, space);
 
 	/* Quantize space offering to a multiple of mss if possible. */
 	if (space > mss)
@@ -1505,7 +1506,7 @@
 	 * our initial window offering to 32k. There should also
 	 * be a sysctl option to stop being nice.
 	 */
-	(*rcv_wnd) = min_t(int, space, MAX_TCP_WINDOW);
+	(*rcv_wnd) = min(space, MAX_TCP_WINDOW);
 	(*rcv_wscale) = 0;
 	if (wscale_ok) {
 		/* See RFC1323 for an explanation of the limit to 14 */
@@ -1514,7 +1515,7 @@
 			(*rcv_wscale)++;
 		}
 		if (*rcv_wscale && sysctl_tcp_app_win && space>=mss &&
-		    space - max_t(unsigned int, (space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2)
+		    space - max((space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2)
 			(*rcv_wscale)--;
 	}
 
@@ -1532,7 +1533,7 @@
 			*rcv_wnd = init_cwnd*mss;
 	}
 	/* Set the clamp no higher than max representable value */
-	(*window_clamp) = min_t(u32, 65535 << (*rcv_wscale), *window_clamp);
+	(*window_clamp) = min(65535U << (*rcv_wscale), *window_clamp);
 }
 
 static inline int tcp_win_from_space(int space)
@@ -1698,8 +1699,8 @@
 static inline void tcp_moderate_sndbuf(struct sock *sk)
 {
 	if (!(sk->userlocks&SOCK_SNDBUF_LOCK)) {
-		sk->sndbuf = min_t(int, sk->sndbuf, sk->wmem_queued/2);
-		sk->sndbuf = max_t(int, sk->sndbuf, SOCK_MIN_SNDBUF);
+		sk->sndbuf = min(sk->sndbuf, sk->wmem_queued/2);
+		sk->sndbuf = max(sk->sndbuf, SOCK_MIN_SNDBUF);
 	}
 }
 
diff -u --recursive --new-file v2.4.10/linux/init/main.c linux/init/main.c
--- v2.4.10/linux/init/main.c	Sun Sep 23 11:41:01 2001
+++ linux/init/main.c	Sat Oct  6 08:49:16 2001
@@ -65,7 +65,7 @@
 extern int irda_device_init(void);
 #endif
 
-#ifdef CONFIG_X86_IO_APIC
+#ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/smp.h>
 #endif
 
@@ -94,7 +94,6 @@
 extern void sysctl_init(void);
 extern void signals_init(void);
 extern int init_pcmcia_ds(void);
-extern void net_notifier_init(void);
 
 extern void free_initmem(void);
 
@@ -258,9 +257,15 @@
 	{ "cciss/c0d14p",0x68E0 },
 	{ "cciss/c0d15p",0x68F0 },
 #endif
-#ifdef CONFIG_NFTL
 	{ "nftla", 0x5d00 },
-#endif
+	{ "nftlb", 0x5d10 },
+	{ "nftlc", 0x5d20 },
+	{ "nftld", 0x5d30 },
+	{ "ftla", 0x2c00 },
+	{ "ftlb", 0x2c08 },
+	{ "ftlc", 0x2c10 },
+	{ "ftld", 0x2c18 },
+	{ "mtdblock", 0x1f00 },
 	{ NULL, 0 }
 };
 
@@ -477,9 +482,11 @@
 extern void setup_arch(char **);
 extern void cpu_idle(void);
 
+unsigned long wait_init_idle;
+
 #ifndef CONFIG_SMP
 
-#ifdef CONFIG_X86_IO_APIC
+#ifdef CONFIG_X86_LOCAL_APIC
 static void __init smp_init(void)
 {
 	APIC_init_uniprocessor();
@@ -490,14 +497,26 @@
 
 #else
 
+
 /* Called by boot processor to activate the rest. */
 static void __init smp_init(void)
 {
 	/* Get other processors into their bootup holding patterns. */
 	smp_boot_cpus();
+	wait_init_idle = cpu_online_map;
+	clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */
+
 	smp_threads_ready=1;
 	smp_commence();
-}		
+
+	/* Wait for the other cpus to set up their idle processes */
+	printk("Waiting on wait_init_idle (map = 0x%lx)\n", wait_init_idle);
+	while (wait_init_idle) {
+		cpu_relax();
+		barrier();
+	}
+	printk("All processors have done init_idle\n");
+}
 
 #endif
 
@@ -519,7 +538,7 @@
 /*
  *	Activate the first processor.
  */
- 
+
 asmlinkage void __init start_kernel(void)
 {
 	char * command_line;
diff -u --recursive --new-file v2.4.10/linux/ipc/sem.c linux/ipc/sem.c
--- v2.4.10/linux/ipc/sem.c	Mon Feb 19 10:18:18 2001
+++ linux/ipc/sem.c	Sun Sep 30 12:26:42 2001
@@ -53,6 +53,8 @@
  *
  * SMP-threaded, sysctl's added
  * (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
+ * Enforced range limit on SEM_UNDO
+ * (c) 2001 Red Hat Inc <alan@redhat.com>
  */
 
 #include <linux/config.h>
@@ -256,8 +258,19 @@
 		curr->sempid = (curr->sempid << 16) | pid;
 		curr->semval += sem_op;
 		if (sop->sem_flg & SEM_UNDO)
-			un->semadj[sop->sem_num] -= sem_op;
-
+		{
+			int undo = un->semadj[sop->sem_num] - sem_op;
+			/*
+	 		 *	Exceeding the undo range is an error.
+			 */
+			if (undo < (-SEMAEM - 1) || undo > SEMAEM)
+			{
+				/* Don't undo the undo */
+				sop->sem_flg &= ~SEM_UNDO;
+				goto out_of_range;
+			}
+			un->semadj[sop->sem_num] = undo;
+		}
 		if (curr->semval < 0)
 			goto would_block;
 		if (curr->semval > SEMVMX)
diff -u --recursive --new-file v2.4.10/linux/kernel/exec_domain.c linux/kernel/exec_domain.c
--- v2.4.10/linux/kernel/exec_domain.c	Sun Sep 23 11:41:01 2001
+++ linux/kernel/exec_domain.c	Thu Oct  4 16:41:54 2001
@@ -219,13 +219,15 @@
 asmlinkage long
 sys_personality(u_long personality)
 {
-	if (personality == 0xffffffff)
-		goto ret;
-	set_personality(personality);
-	if (current->personality != personality)
-		return -EINVAL;
-ret:
-	return (current->personality);
+	u_long old = current->personality;;
+
+	if (personality != 0xffffffff) {
+		set_personality(personality);
+		if (current->personality != personality)
+			return -EINVAL;
+	}
+
+	return (long)old;
 }
 
 
diff -u --recursive --new-file v2.4.10/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.4.10/linux/kernel/ksyms.c	Sun Sep 23 11:41:01 2001
+++ linux/kernel/ksyms.c	Wed Oct  3 22:57:36 2001
@@ -172,6 +172,7 @@
 EXPORT_SYMBOL(files_lock);
 EXPORT_SYMBOL(check_disk_change);
 EXPORT_SYMBOL(__invalidate_buffers);
+EXPORT_SYMBOL(invalidate_bdev);
 EXPORT_SYMBOL(invalidate_inodes);
 EXPORT_SYMBOL(invalidate_device);
 EXPORT_SYMBOL(invalidate_inode_pages);
@@ -210,7 +211,6 @@
 EXPORT_SYMBOL(generic_file_read);
 EXPORT_SYMBOL(do_generic_file_read);
 EXPORT_SYMBOL(generic_file_write);
-EXPORT_SYMBOL(generic_direct_IO);
 EXPORT_SYMBOL(generic_file_mmap);
 EXPORT_SYMBOL(generic_ro_fops);
 EXPORT_SYMBOL(generic_buffer_fdatasync);
diff -u --recursive --new-file v2.4.10/linux/kernel/panic.c linux/kernel/panic.c
--- v2.4.10/linux/kernel/panic.c	Sun Sep 23 11:41:01 2001
+++ linux/kernel/panic.c	Sun Sep 30 12:26:08 2001
@@ -99,3 +99,24 @@
 		CHECK_EMERGENCY_SYNC
 	}
 }
+
+/**
+ *	print_tainted - return a string to represent the kernel taint state.
+ *
+ *	The string is overwritten by the next call to print_taint().
+ */
+ 
+const char *print_tainted()
+{
+	static char buf[20];
+	if (tainted) {
+		snprintf(buf, sizeof(buf), "Tainted: %c%c",
+			tainted & 1 ? 'P' : 'G',
+			tainted & 2 ? 'F' : ' ');
+	}
+	else
+		snprintf(buf, sizeof(buf), "Not tainted");
+	return(buf);
+}
+
+int tainted = 0;
diff -u --recursive --new-file v2.4.10/linux/kernel/sched.c linux/kernel/sched.c
--- v2.4.10/linux/kernel/sched.c	Sun Sep 23 11:41:01 2001
+++ linux/kernel/sched.c	Fri Oct  5 12:11:05 2001
@@ -1309,6 +1309,8 @@
 	atomic_inc(&current->files->count);
 }
 
+extern unsigned long wait_init_idle;
+
 void __init init_idle(void)
 {
 	struct schedule_data * sched_data;
@@ -1321,6 +1323,7 @@
 	}
 	sched_data->curr = current;
 	sched_data->last_schedule = get_cycles();
+	clear_bit(current->processor, &wait_init_idle);
 }
 
 extern void init_timervecs (void);
diff -u --recursive --new-file v2.4.10/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.4.10/linux/kernel/sysctl.c	Sun Sep 23 11:41:01 2001
+++ linux/kernel/sysctl.c	Fri Oct  5 12:23:53 2001
@@ -170,6 +170,8 @@
 	 0644, NULL, &proc_dointvec},
 	{KERN_CORE_USES_PID, "core_uses_pid", &core_uses_pid, sizeof(int),
 	 0644, NULL, &proc_dointvec},
+	{KERN_TAINTED, "tainted", &tainted, sizeof(int),
+	 0644, NULL, &proc_dointvec},
 	{KERN_CAP_BSET, "cap-bound", &cap_bset, sizeof(kernel_cap_t),
 	 0600, NULL, &proc_dointvec_bset},
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -286,8 +288,6 @@
 	 0644, NULL, &proc_dointvec},
 	{FS_NRDQUOT, "dquot-nr", &nr_dquots, 2*sizeof(int),
 	 0444, NULL, &proc_dointvec},
-	{FS_MAXDQUOT, "dquot-max", &max_dquots, sizeof(int),
-	 0644, NULL, &proc_dointvec},
 	{FS_DENTRY, "dentry-state", &dentry_stat, 6*sizeof(int),
 	 0444, NULL, &proc_dointvec},
 	{FS_OVERFLOWUID, "overflowuid", &fs_overflowuid, sizeof(int), 0644, NULL,
diff -u --recursive --new-file v2.4.10/linux/kernel/timer.c linux/kernel/timer.c
--- v2.4.10/linux/kernel/timer.c	Tue Jul  3 17:08:22 2001
+++ linux/kernel/timer.c	Mon Oct  8 10:41:41 2001
@@ -794,6 +794,12 @@
 
 #endif
 
+/* Thread ID - the internal kernel "pid" */
+asmlinkage long sys_gettid(void)
+{
+	return current->pid;
+}
+
 asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
 {
 	struct timespec t;
diff -u --recursive --new-file v2.4.10/linux/lib/dec_and_lock.c linux/lib/dec_and_lock.c
--- v2.4.10/linux/lib/dec_and_lock.c	Sun Sep 23 11:41:01 2001
+++ linux/lib/dec_and_lock.c	Wed Oct  3 09:11:26 2001
@@ -26,7 +26,7 @@
  * store-conditional approach, for example.
  */
 
-#ifndef atomic_dec_and_lock
+#ifndef ATOMIC_DEC_AND_LOCK
 int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
 {
 	spin_lock(lock);
diff -u --recursive --new-file v2.4.10/linux/mm/filemap.c linux/mm/filemap.c
--- v2.4.10/linux/mm/filemap.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/filemap.c	Thu Oct  4 16:46:30 2001
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/iobuf.h>
+#include <linux/compiler.h>
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -56,6 +57,7 @@
 #define CLUSTER_PAGES		(1 << page_cluster)
 #define CLUSTER_OFFSET(x)	(((x) >> page_cluster) << page_cluster)
 
+static void FASTCALL(add_page_to_hash_queue(struct page * page, struct page **p));
 static void add_page_to_hash_queue(struct page * page, struct page **p)
 {
 	struct page *next = *p;
@@ -170,11 +172,7 @@
 		page = list_entry(curr, struct page, list);
 		curr = curr->next;
 
-		/* We cannot invalidate something in use.. */
-		if (page_count(page) != 1)
-			continue;
-
-		/* ..or dirty.. */
+		/* We cannot invalidate something in dirty.. */
 		if (PageDirty(page))
 			continue;
 
@@ -182,10 +180,20 @@
 		if (TryLockPage(page))
 			continue;
 
+		if (page->buffers && !try_to_free_buffers(page, 0))
+			goto unlock;
+
+		if (page_count(page) != 1)
+			goto unlock;
+
 		__lru_cache_del(page);
 		__remove_inode_page(page);
 		UnlockPage(page);
 		page_cache_release(page);
+		continue;
+unlock:
+		UnlockPage(page);
+		continue;
 	}
 
 	spin_unlock(&pagemap_lru_lock);
@@ -616,9 +624,6 @@
 {
 	unsigned long flags;
 
-	if (PageLocked(page))
-		BUG();
-
 	flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_dirty | 1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_checked);
 	page->flags = flags | (1 << PG_locked);
 	page_cache_get(page);
@@ -635,7 +640,7 @@
 	spin_unlock(&pagecache_lock);
 }
 
-static int add_to_page_cache_unique(struct page * page,
+int add_to_page_cache_unique(struct page * page,
 	struct address_space *mapping, unsigned long offset,
 	struct page **hash)
 {
@@ -792,11 +797,13 @@
 }
 
 /*
- * Same as the above, but lock the page too, verifying that
- * it's still valid once we own it.
- */
-struct page * __find_lock_page (struct address_space *mapping,
-				unsigned long offset, struct page **hash)
+ * Must be called with the pagecache lock held,
+ * will return with it held (but it may be dropped
+ * during blocking operations..
+ */
+static struct page * FASTCALL(__find_lock_page_helper(struct address_space *, unsigned long, struct page *));
+static struct page * __find_lock_page_helper(struct address_space *mapping,
+					unsigned long offset, struct page *hash)
 {
 	struct page *page;
 
@@ -805,27 +812,79 @@
 	 * the hash-list needs a held write-lock.
 	 */
 repeat:
-	spin_lock(&pagecache_lock);
-	page = __find_page_nolock(mapping, offset, *hash);
+	page = __find_page_nolock(mapping, offset, hash);
 	if (page) {
 		page_cache_get(page);
-		spin_unlock(&pagecache_lock);
+		if (TryLockPage(page)) {
+			spin_unlock(&pagecache_lock);
+			lock_page(page);
+			spin_lock(&pagecache_lock);
 
-		lock_page(page);
+			/* Has the page been re-allocated while we slept? */
+			if (page->mapping != mapping || page->index != offset) {
+				UnlockPage(page);
+				page_cache_release(page);
+				goto repeat;
+			}
+		}
+	}
+	return page;
+}
+
+/*
+ * Same as the above, but lock the page too, verifying that
+ * it's still valid once we own it.
+ */
+struct page * __find_lock_page (struct address_space *mapping,
+				unsigned long offset, struct page **hash)
+{
+	struct page *page;
 
-		/* Is the page still hashed? Ok, good.. */
-		if (page->mapping == mapping && page->index == offset)
-			return page;
+	spin_lock(&pagecache_lock);
+	page = __find_lock_page_helper(mapping, offset, *hash);
+	spin_unlock(&pagecache_lock);
+	return page;
+}
 
-		/* Nope: we raced. Release and try again.. */
-		UnlockPage(page);
-		page_cache_release(page);
-		goto repeat;
-	}
+/*
+ * Same as above, but create the page if required..
+ */
+struct page * find_or_create_page(struct address_space *mapping, unsigned long index, unsigned int gfp_mask)
+{
+	struct page *page;
+	struct page **hash = page_hash(mapping, index);
+
+	spin_lock(&pagecache_lock);
+	page = __find_lock_page_helper(mapping, index, *hash);
 	spin_unlock(&pagecache_lock);
-	return NULL;
+	if (!page) {
+		struct page *newpage = alloc_page(gfp_mask);
+		page = ERR_PTR(-ENOMEM);
+		if (newpage) {
+			spin_lock(&pagecache_lock);
+			page = __find_lock_page_helper(mapping, index, *hash);
+			if (likely(!page)) {
+				page = newpage;
+				__add_to_page_cache(page, mapping, index, hash);
+				newpage = NULL;
+			}
+			spin_unlock(&pagecache_lock);
+			if (unlikely(newpage != NULL))
+				page_cache_release(newpage);
+		}
+	}
+	return page;	
 }
 
+/*
+ * Returns locked page at given index in given cache, creating it if needed.
+ */
+struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
+{
+	return find_or_create_page(mapping, index, mapping->gfp_mask);
+}
+
+
 #if 0
 #define PROFILE_READAHEAD
 #define DEBUG_READAHEAD
@@ -956,30 +1015,6 @@
 	return max_readahead[MAJOR(inode->i_dev)][MINOR(inode->i_dev)];
 }
 
-static inline unsigned long calc_end_index(struct inode * inode)
-{
-	unsigned long end_index;
-
-	if (!S_ISBLK(inode->i_mode))
-		end_index = inode->i_size >> PAGE_CACHE_SHIFT;
-	else
-		end_index = buffered_blk_size(inode->i_rdev) >> (PAGE_CACHE_SHIFT - BLOCK_SIZE_BITS);
-
-	return end_index;
-}
-
-static inline loff_t calc_rsize(struct inode * inode)
-{
-	loff_t rsize;
-
-	if (!S_ISBLK(inode->i_mode))
-		rsize = inode->i_size;
-	else
-		rsize = (loff_t) buffered_blk_size(inode->i_rdev) << BLOCK_SIZE_BITS;
-
-	return rsize;
-}
-
 static void generic_file_readahead(int reada_ok,
 	struct file * filp, struct inode * inode,
 	struct page * page)
@@ -990,7 +1025,7 @@
 	unsigned long raend;
 	int max_readahead = get_max_readahead(inode);
 
-	end_index = calc_end_index(inode);
+	end_index = inode->i_size >> PAGE_CACHE_SHIFT;
 
 	raend = filp->f_raend;
 	max_ahead = 0;
@@ -1114,8 +1149,8 @@
  */
 void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc, read_actor_t actor)
 {
-	struct inode *inode = filp->f_dentry->d_inode;
-	struct address_space *mapping = inode->i_mapping;
+	struct address_space *mapping = filp->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
 	unsigned long index, offset;
 	struct page *cached_page;
 	int reada_ok;
@@ -1169,13 +1204,13 @@
 		struct page *page, **hash;
 		unsigned long end_index, nr, ret;
 
-		end_index = calc_end_index(inode);
+		end_index = inode->i_size >> PAGE_CACHE_SHIFT;
 			
 		if (index > end_index)
 			break;
 		nr = PAGE_CACHE_SIZE;
 		if (index == end_index) {
-			nr = calc_rsize(inode) & ~PAGE_CACHE_MASK;
+			nr = inode->i_size & ~PAGE_CACHE_MASK;
 			if (nr <= offset)
 				break;
 		}
@@ -1207,6 +1242,13 @@
 			flush_dcache_page(page);
 
 		/*
+		 * Mark the page accessed if we read the
+		 * beginning or we just did an lseek.
+		 */
+		if (!offset || !filp->f_reada)
+			mark_page_accessed(page);
+
+		/*
 		 * Ok, we have the page, and it's up-to-date, so
 		 * now we can copy it to user space...
 		 *
@@ -1221,7 +1263,6 @@
 		index += offset >> PAGE_CACHE_SHIFT;
 		offset &= ~PAGE_CACHE_MASK;
 
-		mark_page_accessed(page);
 		page_cache_release(page);
 		if (ret == nr && desc->count)
 			continue;
@@ -1316,92 +1357,6 @@
 	UPDATE_ATIME(inode);
 }
 
-static ssize_t generic_file_direct_IO(int rw, struct file * filp, char * buf, size_t count, loff_t offset)
-{
-	ssize_t retval;
-	int new_iobuf, chunk_size, blocksize_mask, blocksize, blocksize_bits, iosize, progress;
-	struct kiobuf * iobuf;
-	struct inode * inode = filp->f_dentry->d_inode;
-	struct address_space * mapping = inode->i_mapping;
-
-	new_iobuf = 0;
-	iobuf = filp->f_iobuf;
-	if (test_and_set_bit(0, &filp->f_iobuf_lock)) {
-		/*
-		 * A parallel read/write is using the preallocated iobuf
-		 * so just run slow and allocate a new one.
-		 */
-		retval = alloc_kiovec(1, &iobuf);
-		if (retval)
-			goto out;
-		new_iobuf = 1;
-	}
-
-	if (!S_ISBLK(inode->i_mode)) {
-		blocksize = inode->i_sb->s_blocksize;
-		blocksize_bits = inode->i_sb->s_blocksize_bits;
-	} else {
-		blocksize = BUFFERED_BLOCKSIZE;
-		blocksize_bits = BUFFERED_BLOCKSIZE_BITS;
-	}
-	blocksize_mask = blocksize - 1;
-	chunk_size = KIO_MAX_ATOMIC_IO << 10;
-
-	retval = -EINVAL;
-	if ((offset & blocksize_mask) || (count & blocksize_mask))
-		goto out_free;
-	if (!mapping->a_ops->direct_IO)
-		goto out_free;
-
-	/*
-	 * Flush to disk exlusively the _data_, metadata must remains
-	 * completly asynchronous or performance will go to /dev/null.
-	 */
-	filemap_fdatasync(mapping);
-	retval = fsync_inode_data_buffers(inode);
-	filemap_fdatawait(mapping);
-	if (retval < 0)
-		goto out_free;
-
-	progress = retval = 0;
-	while (count > 0) {
-		iosize = count;
-		if (iosize > chunk_size)
-			iosize = chunk_size;
-
-		retval = map_user_kiobuf(rw, iobuf, (unsigned long) buf, iosize);
-		if (retval)
-			break;
-
-		retval = mapping->a_ops->direct_IO(rw, inode, iobuf, (offset+progress) >> blocksize_bits, blocksize);
-
-		if (rw == READ && retval > 0)
-			mark_dirty_kiobuf(iobuf, retval);
-		
-		if (retval >= 0) {
-			count -= retval;
-			buf += retval;
-			progress += retval;
-		}
-
-		unmap_kiobuf(iobuf);
-
-		if (retval != iosize)
-			break;
-	}
-
-	if (progress)
-		retval = progress;
-
- out_free:
-	if (!new_iobuf)
-		clear_bit(0, &filp->f_iobuf_lock);
-	else
-		free_kiovec(1, &iobuf);
- out:	
-	return retval;
-}
-
 int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
 {
 	char *kaddr;
@@ -1435,9 +1390,6 @@
 	if ((ssize_t) count < 0)
 		return -EINVAL;
 
-	if (filp->f_flags & O_DIRECT)
-		goto o_direct;
-
 	retval = -EFAULT;
 	if (access_ok(VERIFY_WRITE, buf, count)) {
 		retval = 0;
@@ -1456,28 +1408,7 @@
 				retval = desc.error;
 		}
 	}
- out:
 	return retval;
-
- o_direct:
-	{
-		loff_t pos = *ppos, size;
-		struct inode * inode = filp->f_dentry->d_inode;
-
-		retval = 0;
-		if (!count)
-			goto out; /* skip atime */
-		size = calc_rsize(inode);
-		if (pos < size) {
-			if (pos + count > size)
-				count = size - pos;
-			retval = generic_file_direct_IO(READ, filp, buf, count, pos);
-			if (retval > 0)
-				*ppos = pos + retval;
-		}
-		UPDATE_ATIME(filp->f_dentry->d_inode);
-		goto out;
-	}
 }
 
 static int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset , unsigned long size)
@@ -1662,7 +1593,6 @@
 	struct address_space *mapping = inode->i_mapping;
 	struct page *page, **hash, *old_page;
 	unsigned long size, pgoff;
-	loff_t rsize;
 
 	pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
 
@@ -1671,8 +1601,7 @@
 	 * An external ptracer can access pages that normally aren't
 	 * accessible..
 	 */
-	rsize = calc_rsize(inode);
-	size = (rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	if ((pgoff >= size) && (area->vm_mm == current->mm))
 		return NULL;
 
@@ -2171,14 +2100,13 @@
 	long error = -EBADF;
 	struct file * file;
 	unsigned long size, rlim_rss;
-	loff_t rsize;
 
 	/* Doesn't work if there's no mapped file. */
 	if (!vma->vm_file)
 		return error;
 	file = vma->vm_file;
-	rsize = calc_rsize(file->f_dentry->d_inode);
-	size = (rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	size = (file->f_dentry->d_inode->i_size + PAGE_CACHE_SIZE - 1) >>
+							PAGE_CACHE_SHIFT;
 
 	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 	if (end > vma->vm_end)
@@ -2616,19 +2544,6 @@
 	return page;
 }
 
-/*
- * Returns locked page at given index in given cache, creating it if needed.
- */
-
-struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
-{
-	struct page *cached_page = NULL;
-	struct page *page = __grab_cache_page(mapping,index,&cached_page);
-	if (cached_page)
-		page_cache_release(cached_page);
-	return page;
-}
-
 inline void remove_suid(struct inode *inode)
 {
 	unsigned int mode;
@@ -2662,8 +2577,8 @@
 ssize_t
 generic_file_write(struct file *file,const char *buf,size_t count, loff_t *ppos)
 {
-	struct inode	*inode = file->f_dentry->d_inode; 
-	struct address_space *mapping = inode->i_mapping;
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode	*inode = mapping->host;
 	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
 	loff_t		pos;
 	struct page	*page, *cached_page;
@@ -2695,8 +2610,7 @@
 
 	written = 0;
 
-	/* FIXME: this is for backwards compatibility with 2.4 */
-	if (!S_ISBLK(inode->i_mode) && file->f_flags & O_APPEND)
+	if (file->f_flags & O_APPEND)
 		pos = inode->i_size;
 
 	/*
@@ -2757,17 +2671,15 @@
 			err = -EPERM;
 			goto out;
 		}
-		if (pos >= calc_rsize(inode)) {
-			if (count || pos > calc_rsize(inode)) {
-				/* FIXME: this is for backwards compatibility with 2.4 */
+		if (pos >= inode->i_size) {
+			if (count || pos > inode->i_size) {
 				err = -ENOSPC;
 				goto out;
 			}
-			/* zero-length writes at blkdev end are OK */
 		}
 
-		if (pos + count > calc_rsize(inode))
-			count = calc_rsize(inode) - pos;
+		if (pos + count > inode->i_size)
+			count = inode->i_size - pos;
 	}
 
 	err = 0;
@@ -2778,9 +2690,6 @@
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 	mark_inode_dirty_sync(inode);
 
-	if (file->f_flags & O_DIRECT)
-		goto o_direct;
-
 	do {
 		unsigned long index, offset;
 		long page_fault;
@@ -2855,7 +2764,6 @@
 	if ((status >= 0) && (file->f_flags & O_SYNC))
 		status = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
 	
-out_status:	
 	err = written ? written : status;
 out:
 
@@ -2864,25 +2772,6 @@
 fail_write:
 	status = -EFAULT;
 	goto unlock;
-
-o_direct:
-	written = generic_file_direct_IO(WRITE, file, (char *) buf, count, pos);
-	if (written > 0) {
-		loff_t end = pos + written;
-		if (end > inode->i_size && !S_ISBLK(inode->i_mode)) {
-			inode->i_size = end;
-			mark_inode_dirty(inode);
-		}
-		*ppos = end;
-		invalidate_inode_pages2(mapping);
-	}
-	/*
-	 * Sync the fs metadata but not the minor inode changes and
-	 * of course not the data as we did direct DMA for the IO.
-	 */
-	if (written >= 0 && file->f_flags & O_SYNC)
-		status = generic_osync_inode(inode, OSYNC_METADATA);
-	goto out_status;
 }
 
 void __init page_cache_init(unsigned long mempages)
diff -u --recursive --new-file v2.4.10/linux/mm/memory.c linux/mm/memory.c
--- v2.4.10/linux/mm/memory.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/memory.c	Thu Sep 27 08:41:16 2001
@@ -319,7 +319,9 @@
 		if (pte_none(pte))
 			continue;
 		if (pte_present(pte)) {
-			freed ++;
+			struct page *page = pte_page(pte);
+			if (VALID_PAGE(page) && !PageReserved(page))
+				freed ++;
 			/* This will eventually call __free_pte on the pte. */
 			tlb_remove_page(tlb, ptep, address + offset);
 		} else {
@@ -1101,6 +1103,10 @@
 	return;
 }
 
+/* Swap 80% full? Release the pages as they are paged in.. */
+#define vm_swap_full() \
+	(swapper_space.nrpages*5 > total_swap_pages*4)
+
 /*
  * We hold the mm semaphore and the page_table_lock on entry and exit.
  */
@@ -1158,10 +1164,12 @@
 	swap_free(entry);
 	mark_page_accessed(page);
 	if (exclusive_swap_page(page)) {
-		if (vma->vm_flags & VM_WRITE)
-			pte = pte_mkwrite(pte);
-		pte = pte_mkdirty(pte);
-		delete_from_swap_cache(page);
+		if (write_access || vm_swap_full()) {
+			pte = pte_mkdirty(pte);
+			if (vma->vm_flags & VM_WRITE)
+				pte = pte_mkwrite(pte);
+			delete_from_swap_cache(page);
+		}
 	}
 	UnlockPage(page);
 
diff -u --recursive --new-file v2.4.10/linux/mm/mmap.c linux/mm/mmap.c
--- v2.4.10/linux/mm/mmap.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/mmap.c	Sun Sep 30 11:05:40 2001
@@ -67,8 +67,8 @@
 	if (sysctl_overcommit_memory)
 	    return 1;
 
-	free = atomic_read(&buffermem_pages);
-	free += atomic_read(&page_cache_size);
+	/* The page cache contains buffer pages these days.. */
+	free = atomic_read(&page_cache_size);
 	free += nr_free_pages();
 	free += nr_swap_pages;
 
diff -u --recursive --new-file v2.4.10/linux/mm/oom_kill.c linux/mm/oom_kill.c
--- v2.4.10/linux/mm/oom_kill.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/oom_kill.c	Fri Oct  5 13:13:43 2001
@@ -192,3 +192,67 @@
 	schedule();
 	return;
 }
+
+static inline int node_zones_low(pg_data_t *pgdat)
+{
+	zone_t * zone;
+	int i;
+
+	for (i = pgdat->nr_zones-1; i >= 0; i--) {
+		zone = pgdat->node_zones + i;
+
+		if (zone->free_pages > (zone->pages_low))
+			return 0;
+
+	}
+	return 1;
+}
+
+static int all_zones_low(void)
+{
+	pg_data_t * pgdat = pgdat_list;
+
+	pgdat = pgdat_list;
+	do {
+		if (node_zones_low(pgdat))
+			continue;
+		return 0;
+	} while ((pgdat = pgdat->node_next));
+
+	return 1;
+}
+
+/**
+ * out_of_memory - is the system out of memory?
+ *
+ * Returns 0 if there is still enough memory left,
+ * 1 when we are out of memory (otherwise).
+ */
+int out_of_memory(void)
+{
+	long cache_mem, limit;
+
+	/* Enough free memory?  Not OOM. */
+	if (!all_zones_low())
+		return 0;
+
+	/* Enough swap space left?  Not OOM. */
+	if (nr_swap_pages > 0)
+		return 0;
+
+	/*
+	 * If the buffer and page cache (including swap cache) are over
+	 * their (/proc tunable) minimum, we're still not OOM.  We test
+	 * this to make sure we don't return OOM when the system simply
+	 * has a hard time with the cache.
+	 */
+	cache_mem = atomic_read(&page_cache_size);
+	limit = 2;
+	limit *= num_physpages / 100;
+
+	if (cache_mem > limit)
+		return 0;
+
+	/* Else... */
+	return 1;
+}
diff -u --recursive --new-file v2.4.10/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.4.10/linux/mm/page_alloc.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/page_alloc.c	Mon Oct  8 12:23:51 2001
@@ -357,6 +357,7 @@
 
 	/* here we're in the low on memory slow path */
 
+rebalance:
 	if (current->flags & PF_MEMALLOC) {
 		zone = zonelist->zones;
 		for (;;) {
@@ -371,46 +372,36 @@
 		return NULL;
 	}
 
- rebalance:
+	/* Atomic allocations - we can't balance anything */
+	if (!(gfp_mask & __GFP_WAIT))
+		return NULL;
+
 	page = balance_classzone(classzone, gfp_mask, order, &freed);
 	if (page)
 		return page;
 
 	zone = zonelist->zones;
-	if (likely(freed)) {
-		for (;;) {
-			zone_t *z = *(zone++);
-			if (!z)
-				break;
+	for (;;) {
+		zone_t *z = *(zone++);
+		if (!z)
+			break;
 
-			if (zone_free_pages(z, order) > z->pages_min) {
-				page = rmqueue(z, order);
-				if (page)
-					return page;
-			}
-		}
-		goto rebalance;
-	} else {
-		/* 
-		 * Check that no other task is been killed meanwhile,
-		 * in such a case we can succeed the allocation.
-		 */
-		for (;;) {
-			zone_t *z = *(zone++);
-			if (!z)
-				break;
-
-			if (zone_free_pages(z, order) > z->pages_high) {
-				page = rmqueue(z, order);
-				if (page)
-					return page;
-			}
+		if (zone_free_pages(z, order) > z->pages_min) {
+			page = rmqueue(z, order);
+			if (page)
+				return page;
 		}
 	}
 
-	printk(KERN_NOTICE "__alloc_pages: %u-order allocation failed (gfp=0x%x/%i) from %p\n",
-	       order, gfp_mask, !!(current->flags & PF_MEMALLOC), __builtin_return_address(0));
-	return NULL;
+	/* Don't let big-order allocations loop */
+	if (order)
+		return NULL;
+
+	/* Yield for kswapd, and try again */
+	current->policy |= SCHED_YIELD;
+	__set_current_state(TASK_RUNNING);
+	schedule();
+	goto rebalance;
 }
 
 /*
@@ -480,7 +471,7 @@
 	zone_t **zonep, *zone;
 
 	do {
-		zonelist = pgdat->node_zonelists + __GFP_HIGHMEM;
+		zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK);
 		zonep = zonelist->zones;
 
 		for (zone = *zonep++; zone; zone = *zonep++)
@@ -515,6 +506,30 @@
 {
  	unsigned int order;
 	unsigned type;
+	pg_data_t *tmpdat = pgdat;
+
+	printk("Free pages:      %6dkB (%6dkB HighMem)\n",
+		nr_free_pages() << (PAGE_SHIFT-10),
+		nr_free_highpages() << (PAGE_SHIFT-10));
+
+	while (tmpdat) {
+		zone_t *zone;
+		for (zone = tmpdat->node_zones;
+			       	zone < tmpdat->node_zones + MAX_NR_ZONES; zone++)
+			printk("Zone:%s freepages:%6lukB min:%6luKB low:%6lukB " 
+				       "high:%6lukB\n", 
+					zone->name,
+					(zone->free_pages)
+					<< ((PAGE_SHIFT-10)),
+					zone->pages_min
+					<< ((PAGE_SHIFT-10)),
+					zone->pages_low
+					<< ((PAGE_SHIFT-10)),
+					zone->pages_high
+					<< ((PAGE_SHIFT-10)));
+			
+		tmpdat = tmpdat->node_next;
+	}
 
 	printk("Free pages:      %6dkB (%6dkB HighMem)\n",
 		nr_free_pages() << (PAGE_SHIFT-10),
diff -u --recursive --new-file v2.4.10/linux/mm/shmem.c linux/mm/shmem.c
--- v2.4.10/linux/mm/shmem.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/shmem.c	Thu Oct  4 16:46:30 2001
@@ -245,6 +245,14 @@
 	index = page->index;
 	inode = mapping->host;
 	info = &inode->u.shmem_i;
+getswap:
+	swap = get_swap_page();
+	if (!swap.val) {
+		activate_page(page);
+		SetPageDirty(page);
+		error = -ENOMEM;
+		goto out;
+	}
 
 	spin_lock(&info->lock);
 	entry = shmem_swp_entry(info, index);
@@ -257,32 +265,27 @@
 	/* Remove it from the page cache */
 	lru_cache_del(page);
 	remove_inode_page(page);
+	page_cache_release(page);
 
-	swap_list_lock();
-	swap = get_swap_page();
-
-	if (!swap.val) {
-		swap_list_unlock();
-		/* Add it back to the page cache */
+	/* Add it to the swap cache */
+	if (add_to_swap_cache(page, swap) != 0) {
+		/*
+		 * Raced with "speculative" read_swap_cache_async.
+		 * Add page back to page cache, unref swap, try again.
+		 */
 		add_to_page_cache_locked(page, mapping, index);
-		activate_page(page);
-		SetPageDirty(page);
-		error = -ENOMEM;
-		goto out;
+		spin_unlock(&info->lock);
+		swap_free(swap);
+		goto getswap;
 	}
 
-	/* Add it to the swap cache */
-	add_to_swap_cache(page, swap);
-	swap_list_unlock();
-
-	set_page_dirty(page);
-	info->swapped++;
 	*entry = swap;
+	info->swapped++;
+	spin_unlock(&info->lock);
+	set_page_dirty(page);
 	error = 0;
 out:
-	spin_unlock(&info->lock);
 	UnlockPage(page);
-	page_cache_release(page);
 	return error;
 }
 
diff -u --recursive --new-file v2.4.10/linux/mm/swap_state.c linux/mm/swap_state.c
--- v2.4.10/linux/mm/swap_state.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/swap_state.c	Mon Oct  8 10:42:10 2001
@@ -46,36 +46,49 @@
 };
 
 #ifdef SWAP_CACHE_INFO
-unsigned long swap_cache_add_total;
-unsigned long swap_cache_del_total;
-unsigned long swap_cache_find_total;
-unsigned long swap_cache_find_success;
+#define INC_CACHE_INFO(x)	(swap_cache_info.x++)
+
+static struct {
+	unsigned long add_total;
+	unsigned long del_total;
+	unsigned long find_success;
+	unsigned long find_total;
+	unsigned long noent_race;
+	unsigned long exist_race;
+} swap_cache_info;
 
 void show_swap_cache_info(void)
 {
-	printk("Swap cache: add %ld, delete %ld, find %ld/%ld\n",
-		swap_cache_add_total, 
-		swap_cache_del_total,
-		swap_cache_find_success, swap_cache_find_total);
+	printk("Swap cache: add %lu, delete %lu, find %lu/%lu, race %lu+%lu\n",
+		swap_cache_info.add_total, swap_cache_info.del_total,
+		swap_cache_info.find_success, swap_cache_info.find_total,
+		swap_cache_info.noent_race, swap_cache_info.exist_race);
 }
+#else
+#define INC_CACHE_INFO(x)	do { } while (0)
 #endif
 
-void add_to_swap_cache(struct page *page, swp_entry_t entry)
+int add_to_swap_cache(struct page *page, swp_entry_t entry)
 {
-	unsigned long flags;
-
-#ifdef SWAP_CACHE_INFO
-	swap_cache_add_total++;
-#endif
+	if (page->mapping)
+		BUG();
+	if (!swap_duplicate(entry)) {
+		INC_CACHE_INFO(noent_race);
+		return -ENOENT;
+	}
+	if (add_to_page_cache_unique(page, &swapper_space, entry.val,
+			page_hash(&swapper_space, entry.val)) != 0) {
+		swap_free(entry);
+		INC_CACHE_INFO(exist_race);
+		return -EEXIST;
+	}
+	SetPageUptodate(page);
 	if (!PageLocked(page))
 		BUG();
-	if (page->mapping)
+	if (!PageSwapCache(page))
 		BUG();
-
-	/* clear PG_dirty so a subsequent set_page_dirty takes effect */
-	flags = page->flags & ~(1 << PG_error | 1 << PG_dirty | 1 << PG_arch_1 | 1 << PG_referenced);
-	page->flags = flags | (1 << PG_uptodate);
-	add_to_page_cache_locked(page, &swapper_space, entry.val);
+	INC_CACHE_INFO(add_total);
+	return 0;
 }
 
 /*
@@ -84,16 +97,13 @@
  */
 void __delete_from_swap_cache(struct page *page)
 {
-#ifdef SWAP_CACHE_INFO
-	swap_cache_del_total++;
-#endif
 	if (!PageLocked(page))
 		BUG();
 	if (!PageSwapCache(page))
 		BUG();
-
 	ClearPageDirty(page);
 	__remove_inode_page(page);
+	INC_CACHE_INFO(del_total);
 }
 
 /*
@@ -155,9 +165,6 @@
 {
 	struct page *found;
 
-#ifdef SWAP_CACHE_INFO
-	swap_cache_find_total++;
-#endif
 	found = find_get_page(&swapper_space, entry.val);
 	/*
 	 * Unsafe to assert PageSwapCache and mapping on page found:
@@ -165,10 +172,9 @@
 	 * the swap cache at this moment.  find_lock_page would prevent
 	 * that, but no need to change: we _have_ got the right page.
 	 */
-#ifdef SWAP_CACHE_INFO
+	INC_CACHE_INFO(find_total);
 	if (found)
-		swap_cache_find_success++;
-#endif
+		INC_CACHE_INFO(find_success);
 	return found;
 }
 
@@ -180,58 +186,49 @@
  */
 struct page * read_swap_cache_async(swp_entry_t entry)
 {
-	struct page *found_page, *new_page;
-	struct page **hash;
-	
-	/*
-	 * Look for the page in the swap cache.  Since we normally call
-	 * this only after lookup_swap_cache() failed, re-calling that
-	 * would confuse the statistics: use __find_get_page() directly.
-	 */
-	hash = page_hash(&swapper_space, entry.val);
-	found_page = __find_get_page(&swapper_space, entry.val, hash);
-	if (found_page)
-		goto out;
-
-	new_page = alloc_page(GFP_HIGHUSER);
-	if (!new_page)
-		goto out;		/* Out of memory */
-	if (TryLockPage(new_page))
-		BUG();
-
-	/*
-	 * Check the swap cache again, in case we stalled above.
-	 * swap_list_lock is guarding against races between this check
-	 * and where the new page is added to the swap cache below.
-	 * It is also guarding against race where try_to_swap_out
-	 * allocates entry with get_swap_page then adds to cache.
-	 */
-	swap_list_lock();
-	found_page = __find_get_page(&swapper_space, entry.val, hash);
-	if (found_page)
-		goto out_free_page;
-
-	/*
-	 * Make sure the swap entry is still in use.  It could have gone
-	 * since caller dropped page_table_lock, while allocating page above,
-	 * or while allocating page in prior call via swapin_readahead.
-	 */
-	if (!swap_duplicate(entry))	/* Account for the swap cache */
-		goto out_free_page;
-
-	/* 
-	 * Add it to the swap cache and read its contents.
-	 */
-	add_to_swap_cache(new_page, entry);
-	swap_list_unlock();
+	struct page *found_page, *new_page = NULL;
+	int err;
 
-	rw_swap_page(READ, new_page);
-	return new_page;
+	do {
+		/*
+		 * First check the swap cache.  Since this is normally
+		 * called after lookup_swap_cache() failed, re-calling
+		 * that would confuse statistics: use find_get_page()
+		 * directly.
+		 */
+		found_page = find_get_page(&swapper_space, entry.val);
+		if (found_page)
+			break;
+
+		/*
+		 * Get a new page to read into from swap.
+		 */
+		if (!new_page) {
+			new_page = alloc_page(GFP_HIGHUSER);
+			if (!new_page)
+				break;		/* Out of memory */
+		}
+
+		/*
+		 * Associate the page with swap entry in the swap cache.
+		 * May fail (-ENOENT) if swap entry has been freed since
+		 * our caller observed it.  May fail (-EEXIST) if there
+		 * is already a page associated with this entry in the
+		 * swap cache: added by a racing read_swap_cache_async,
+		 * or by try_to_swap_out (or shmem_writepage) re-using
+		 * the just freed swap entry for an existing page.
+		 */
+		err = add_to_swap_cache(new_page, entry);
+		if (!err) {
+			/*
+			 * Initiate read into locked page and return.
+			 */
+			rw_swap_page(READ, new_page);
+			return new_page;
+		}
+	} while (err != -ENOENT);
 
-out_free_page:
-	swap_list_unlock();
-	UnlockPage(new_page);
-	page_cache_release(new_page);
-out:
+	if (new_page)
+		page_cache_release(new_page);
 	return found_page;
 }
diff -u --recursive --new-file v2.4.10/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.4.10/linux/mm/swapfile.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/swapfile.c	Thu Oct  4 16:46:30 2001
@@ -87,8 +87,7 @@
 			si->lowest_bit = si->max;
 			si->highest_bit = 0;
 		}
-		/* Initial count 1 for user reference + 1 for swap cache */
-		si->swap_map[offset] = 2;
+		si->swap_map[offset] = 1;
 		nr_swap_pages--;
 		si->cluster_next = offset+1;
 		return offset;
@@ -98,11 +97,6 @@
 	return 0;
 }
 
-/*
- * Callers of get_swap_page must hold swap_list_lock across the call,
- * and across the following add_to_swap_cache, to guard against races
- * with read_swap_cache_async.
- */
 swp_entry_t get_swap_page(void)
 {
 	struct swap_info_struct * p;
@@ -111,6 +105,7 @@
 	int type, wrapped = 0;
 
 	entry.val = 0;	/* Out of memory */
+	swap_list_lock();
 	type = swap_list.next;
 	if (type < 0)
 		goto out;
@@ -146,6 +141,7 @@
 				goto out;	/* out of swap space */
 	}
 out:
+	swap_list_unlock();
 	return entry;
 }
 
diff -u --recursive --new-file v2.4.10/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.4.10/linux/mm/vmscan.c	Sun Sep 23 11:41:01 2001
+++ linux/mm/vmscan.c	Sun Oct  7 17:18:31 2001
@@ -125,18 +125,20 @@
 	 * we have the swap cache set up to associate the
 	 * page with that swap entry.
 	 */
-	swap_list_lock();
-	entry = get_swap_page();
-	if (entry.val) {
+	for (;;) {
+		entry = get_swap_page();
+		if (!entry.val)
+			break;
 		/* Add it to the swap cache and mark it dirty */
-		add_to_swap_cache(page, entry);
-		swap_list_unlock();
-		set_page_dirty(page);
-		goto set_swap_pte;
+		if (add_to_swap_cache(page, entry) == 0) {
+			set_page_dirty(page);
+			goto set_swap_pte;
+		}
+		/* Raced with "speculative" read_swap_cache_async */
+		swap_free(entry);
 	}
 
 	/* No swap space left */
-	swap_list_unlock();
 	set_pte(page_table, pte);
 	UnlockPage(page);
 	return 0;
@@ -332,7 +334,6 @@
 	spin_lock(&pagemap_lru_lock);
 	while (max_scan && (entry = inactive_list.prev) != &inactive_list) {
 		struct page * page;
-		swp_entry_t swap;
 
 		if (unlikely(current->need_resched)) {
 			spin_unlock(&pagemap_lru_lock);
@@ -407,12 +408,6 @@
 			if (try_to_free_buffers(page, gfp_mask)) {
 				if (!page->mapping) {
 					/*
-					 * Account we successfully freed a page
-					 * of buffer cache.
-					 */
-					atomic_dec(&buffermem_pages);
-
-					/*
 					 * We must not allow an anon page
 					 * with no buffers to be visible on
 					 * the LRU, so we unlock the page after
@@ -472,23 +467,17 @@
 
 		/* point of no return */
 		if (likely(!PageSwapCache(page))) {
-			swap.val = 0;
 			__remove_inode_page(page);
+			spin_unlock(&pagecache_lock);
 		} else {
+			swp_entry_t swap;
 			swap.val = page->index;
 			__delete_from_swap_cache(page);
-		}
-		spin_unlock(&pagecache_lock);
-
-		__lru_cache_del(page);
-
-		if (unlikely(swap.val != 0)) {
-			/* must drop lru lock if getting swap_list lock */
-			spin_unlock(&pagemap_lru_lock);
+			spin_unlock(&pagecache_lock);
 			swap_free(swap);
-			spin_lock(&pagemap_lru_lock);
 		}
 
+		__lru_cache_del(page);
 		UnlockPage(page);
 
 		/* effectively free the page here */
@@ -536,33 +525,40 @@
 static int FASTCALL(shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages));
 static int shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages)
 {
-	int max_scan = nr_inactive_pages / priority;
+	int max_scan;
+	int chunk_size = nr_pages;
+	unsigned long ratio;
 
 	nr_pages -= kmem_cache_reap(gfp_mask);
 	if (nr_pages <= 0)
 		return 0;
 
-	/* Do we want to age the active list? */
-	if (nr_inactive_pages < nr_active_pages*2)
-		refill_inactive(nr_pages);
-
+	nr_pages = chunk_size;
+	/* try to keep the active list 2/3 of the size of the cache */
+	ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2);
+	refill_inactive(ratio);
+  
+	max_scan = nr_inactive_pages / priority;
 	nr_pages = shrink_cache(nr_pages, max_scan, classzone, gfp_mask);
 	if (nr_pages <= 0)
 		return 0;
 
 	shrink_dcache_memory(priority, gfp_mask);
 	shrink_icache_memory(priority, gfp_mask);
+#ifdef CONFIG_QUOTA
+	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+#endif
 
 	return nr_pages;
 }
 
 int try_to_free_pages(zone_t * classzone, unsigned int gfp_mask, unsigned int order)
 {
-	int priority = DEF_PRIORITY;
 	int ret = 0;
+	int priority = DEF_PRIORITY;
+	int nr_pages = SWAP_CLUSTER_MAX;
 
 	do {
-		int nr_pages = SWAP_CLUSTER_MAX;
 		nr_pages = shrink_caches(priority, classzone, gfp_mask, nr_pages);
 		if (nr_pages <= 0)
 			return 1;
@@ -602,7 +598,7 @@
 		if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) {
 			zone->need_balance = 0;
 			__set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(HZ*5);
+			schedule_timeout(HZ);
 			continue;
 		}
 		if (check_classzone_need_balance(zone))
@@ -625,6 +621,9 @@
 		do
 			need_more_balance |= kswapd_balance_pgdat(pgdat);
 		while ((pgdat = pgdat->node_next));
+		if (need_more_balance && out_of_memory()) {
+			oom_kill();	
+		}
 	} while (need_more_balance);
 }
 
diff -u --recursive --new-file v2.4.10/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c
--- v2.4.10/linux/net/appletalk/aarp.c	Tue Jul  3 17:08:22 2001
+++ linux/net/appletalk/aarp.c	Sun Sep 30 12:26:08 2001
@@ -58,6 +58,7 @@
 #include <linux/atalk.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/module.h>
 
 int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;
 int sysctl_aarp_tick_time = AARP_TICK_TIME;
@@ -982,3 +983,4 @@
 }
 #endif
 #endif  /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/atm/common.c linux/net/atm/common.c
--- v2.4.10/linux/net/atm/common.c	Mon Aug 27 12:41:49 2001
+++ linux/net/atm/common.c	Sun Sep 30 12:26:08 2001
@@ -930,6 +930,8 @@
 	if (size)
 		ret_val =  put_user(size,&((struct atmif_sioc *) arg)->length) ?
 			-EFAULT : 0;
+	else
+		ret_val = 0;
 
  done:
 	spin_unlock (&atm_dev_lock); 
diff -u --recursive --new-file v2.4.10/linux/net/atm/lec.c linux/net/atm/lec.c
--- v2.4.10/linux/net/atm/lec.c	Tue Jul  3 17:08:22 2001
+++ linux/net/atm/lec.c	Sun Sep 30 12:26:08 2001
@@ -2193,3 +2193,4 @@
         lec_arp_put(priv->lec_arp_tables,entry);
         lec_arp_unlock(priv);  
 }
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/atm/mpc.c linux/net/atm/mpc.c
--- v2.4.10/linux/net/atm/mpc.c	Tue Jul  3 17:08:22 2001
+++ linux/net/atm/mpc.c	Sun Sep 30 12:26:08 2001
@@ -1479,3 +1479,4 @@
 	return;
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/bluetooth/hci_core.c linux/net/bluetooth/hci_core.c
--- v2.4.10/linux/net/bluetooth/hci_core.c	Sun Sep 23 11:41:01 2001
+++ linux/net/bluetooth/hci_core.c	Sun Sep 30 12:26:08 2001
@@ -2028,3 +2028,5 @@
 {
 	return 0;
 }
+
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/bluetooth/l2cap_core.c linux/net/bluetooth/l2cap_core.c
--- v2.4.10/linux/net/bluetooth/l2cap_core.c	Sun Sep 23 11:41:01 2001
+++ linux/net/bluetooth/l2cap_core.c	Sun Sep 30 12:26:08 2001
@@ -2312,3 +2312,5 @@
 
 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
 MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
+MODULE_LICENSE("GPL");
+
diff -u --recursive --new-file v2.4.10/linux/net/bridge/br.c linux/net/bridge/br.c
--- v2.4.10/linux/net/bridge/br.c	Mon Oct 23 21:59:03 2000
+++ linux/net/bridge/br.c	Sun Sep 30 12:26:08 2001
@@ -82,3 +82,4 @@
 
 module_init(br_init)
 module_exit(br_deinit)
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/core/dev.c linux/net/core/dev.c
--- v2.4.10/linux/net/core/dev.c	Sun Sep 23 11:41:01 2001
+++ linux/net/core/dev.c	Sat Oct  6 15:21:58 2001
@@ -552,12 +552,22 @@
 {
 	int i;
 	char buf[32];
+	char *p;
 
 	/*
-	 *	If you need over 100 please also fix the algorithm...
+	 * Verify the string as this thing may have come from
+	 * the user.  There must be one "%d" and no other "%"
+	 * characters.
+	 */
+	p = strchr(name, '%');
+	if (!p || p[1] != 'd' || strchr(p+2, '%'))
+		return -EINVAL;
+
+	/*
+	 * If you need over 100 please also fix the algorithm...
 	 */
 	for (i = 0; i < 100; i++) {
-		sprintf(buf,name,i);
+		snprintf(buf,sizeof(buf),name,i);
 		if (__dev_get_by_name(buf) == NULL) {
 			strcpy(dev->name, buf);
 			return i;
diff -u --recursive --new-file v2.4.10/linux/net/core/neighbour.c linux/net/core/neighbour.c
--- v2.4.10/linux/net/core/neighbour.c	Tue Jul  3 17:08:22 2001
+++ linux/net/core/neighbour.c	Mon Oct  1 09:19:56 2001
@@ -725,11 +725,11 @@
 			if (skb) {
 				if (skb_queue_len(&neigh->arp_queue) >= neigh->parms->queue_len) {
 					struct sk_buff *buff;
-					buff = neigh->arp_queue.prev;
+					buff = neigh->arp_queue.next;
 					__skb_unlink(buff, &neigh->arp_queue);
 					kfree_skb(buff);
 				}
-				__skb_queue_head(&neigh->arp_queue, skb);
+				__skb_queue_tail(&neigh->arp_queue, skb);
 			}
 			write_unlock_bh(&neigh->lock);
 			return 1;
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/devinet.c linux/net/ipv4/devinet.c
--- v2.4.10/linux/net/ipv4/devinet.c	Wed May 16 10:21:45 2001
+++ linux/net/ipv4/devinet.c	Mon Oct  1 09:19:57 2001
@@ -1,7 +1,7 @@
 /*
  *	NET3	IP device support routines.
  *
- *	Version: $Id: devinet.c,v 1.42 2001/05/16 16:45:35 davem Exp $
+ *	Version: $Id: devinet.c,v 1.43 2001/09/26 22:52:58 davem Exp $
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -20,6 +20,10 @@
  *	Changes:
  *	        Alexey Kuznetsov:	pa_* fields are replaced with ifaddr lists.
  *		Cyrus Durgin:		updated for kmod
+ *		Matthias Andree:	in devinet_ioctl, compare label and 
+ *					address (4.4BSD alias style support),
+ *					fall back to comparing just the label
+ *					if no match found.
  */
 
 #include <linux/config.h>
@@ -463,6 +467,7 @@
 int devinet_ioctl(unsigned int cmd, void *arg)
 {
 	struct ifreq ifr;
+	struct sockaddr_in sin_orig;
 	struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
 	struct in_device *in_dev;
 	struct in_ifaddr **ifap = NULL;
@@ -470,6 +475,7 @@
 	struct net_device *dev;
 	char *colon;
 	int ret = 0;
+	int tryaddrmatch = 0;
 
 	/*
 	 *	Fetch the caller's info block into kernel space
@@ -479,6 +485,9 @@
 		return -EFAULT;
 	ifr.ifr_name[IFNAMSIZ-1] = 0;
 
+	/* save original address for comparison */
+	memcpy(&sin_orig, sin, sizeof(*sin));
+
 	colon = strchr(ifr.ifr_name, ':');
 	if (colon)
 		*colon = 0;
@@ -492,10 +501,11 @@
 	case SIOCGIFBRDADDR:	/* Get the broadcast address */
 	case SIOCGIFDSTADDR:	/* Get the destination address */
 	case SIOCGIFNETMASK:	/* Get the netmask for the interface */
-		/* Note that this ioctls will not sleep,
+		/* Note that these ioctls will not sleep,
 		   so that we do not impose a lock.
 		   One day we will be forced to put shlock here (I mean SMP)
 		 */
+		tryaddrmatch = (sin_orig.sin_family == AF_INET);
 		memset(sin, 0, sizeof(*sin));
 		sin->sin_family = AF_INET;
 		break;
@@ -529,9 +539,27 @@
 		*colon = ':';
 
 	if ((in_dev=__in_dev_get(dev)) != NULL) {
-		for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
-			if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
-				break;
+		if (tryaddrmatch) {
+			/* Matthias Andree */
+			/* compare label and address (4.4BSD style) */
+			/* note: we only do this for a limited set of ioctls
+			   and only if the original address family was AF_INET.
+			   This is checked above. */
+			for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) {
+				if ((strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
+				    && (sin_orig.sin_addr.s_addr == ifa->ifa_address)) {
+					break; /* found */
+				}
+			}
+		}
+		/* we didn't get a match, maybe the application is
+		   4.3BSD-style and passed in junk so we fall back to 
+		   comparing just the label */
+		if (ifa == NULL) {
+			for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
+				if (strcmp(ifr.ifr_name, ifa->ifa_label) == 0)
+					break;
+		}
 	}
 
 	if (ifa == NULL && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) {
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/inetpeer.c linux/net/ipv4/inetpeer.c
--- v2.4.10/linux/net/ipv4/inetpeer.c	Tue Jul  3 17:08:22 2001
+++ linux/net/ipv4/inetpeer.c	Mon Oct  1 09:19:56 2001
@@ -3,7 +3,7 @@
  *
  *  This source is covered by the GNU GPL, the same as all kernel sources.
  *
- *  Version:	$Id: inetpeer.c,v 1.6 2001/06/21 20:30:14 davem Exp $
+ *  Version:	$Id: inetpeer.c,v 1.7 2001/09/20 21:22:50 davem Exp $
  *
  *  Authors:	Andrey V. Savochkin <saw@msu.ru>
  */
@@ -67,6 +67,7 @@
  *		ip_id_count: idlock
  */
 
+/* Exported for inet_getid inline function.  */
 spinlock_t inet_peer_idlock = SPIN_LOCK_UNLOCKED;
 
 static kmem_cache_t *peer_cachep;
@@ -83,10 +84,13 @@
 #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
 
 static volatile int peer_total;
+/* Exported for sysctl_net_ipv4.  */
 int inet_peer_threshold = 65536 + 128;	/* start to throw entries more
 					 * aggressively at this stage */
 int inet_peer_minttl = 120 * HZ;	/* TTL under high load: 120 sec */
 int inet_peer_maxttl = 10 * 60 * HZ;	/* usual time to live: 10 min */
+
+/* Exported for inet_putpeer inline function.  */
 struct inet_peer *inet_peer_unused_head,
 		**inet_peer_unused_tailp = &inet_peer_unused_head;
 spinlock_t inet_peer_unused_lock = SPIN_LOCK_UNLOCKED;
@@ -95,10 +99,12 @@
 static void peer_check_expire(unsigned long dummy);
 static struct timer_list peer_periodic_timer =
 	{ { NULL, NULL }, 0, 0, &peer_check_expire };
+
+/* Exported for sysctl_net_ipv4.  */
 int inet_peer_gc_mintime = 10 * HZ,
     inet_peer_gc_maxtime = 120 * HZ;
 
-
+/* Called from ip_output.c:ip_init  */
 void __init inet_initpeers(void)
 {
 	struct sysinfo si;
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/ip_gre.c linux/net/ipv4/ip_gre.c
--- v2.4.10/linux/net/ipv4/ip_gre.c	Tue May 15 01:29:35 2001
+++ linux/net/ipv4/ip_gre.c	Mon Oct  1 09:19:56 2001
@@ -284,7 +284,7 @@
 		}
 		if (i==100)
 			goto failed;
-		memcpy(parms->name, dev->name, IFNAMSIZ);
+		memcpy(nt->parms.name, dev->name, IFNAMSIZ);
 	}
 	if (register_netdevice(dev) < 0)
 		goto failed;
@@ -1011,6 +1011,7 @@
 			err = -EPERM;
 			if (t == &ipgre_fb_tunnel)
 				goto done;
+			dev = t->dev;
 		}
 		err = unregister_netdevice(dev);
 		break;
@@ -1296,3 +1297,4 @@
 }
 
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/ipconfig.c linux/net/ipv4/ipconfig.c
--- v2.4.10/linux/net/ipv4/ipconfig.c	Tue May  1 20:59:24 2001
+++ linux/net/ipv4/ipconfig.c	Mon Oct  1 09:19:56 2001
@@ -1,5 +1,5 @@
 /*
- *  $Id: ipconfig.c,v 1.37 2001/04/30 18:54:12 davem Exp $
+ *  $Id: ipconfig.c,v 1.38 2001/09/25 23:23:07 davem Exp $
  *
  *  Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
  *  user-supplied information to configure own IP address and routes.
@@ -816,62 +816,67 @@
 		u8 *ext;
 
 #ifdef IPCONFIG_DHCP
-
-		u32 server_id = INADDR_NONE;
-		int mt = 0;
-
-		ext = &b->exten[4];
-		while (ext < end && *ext != 0xff) {
-			u8 *opt = ext++;
-			if (*opt == 0)	/* Padding */
-				continue;
-			ext += *ext + 1;
-			if (ext >= end)
-				break;
-			switch (*opt) {
-			case 53:	/* Message type */
-				if (opt[1])
-					mt = opt[2];
-				break;
-			case 54:	/* Server ID (IP address) */
-				if (opt[1] >= 4)
-					memcpy(&server_id, opt + 2, 4);
-				break;
+		if (ic_proto_enabled & IC_USE_DHCP) {
+			u32 server_id = INADDR_NONE;
+			int mt = 0;
+
+			ext = &b->exten[4];
+			while (ext < end && *ext != 0xff) {
+				u8 *opt = ext++;
+				if (*opt == 0)	/* Padding */
+					continue;
+				ext += *ext + 1;
+				if (ext >= end)
+					break;
+				switch (*opt) {
+				case 53:	/* Message type */
+					if (opt[1])
+						mt = opt[2];
+					break;
+				case 54:	/* Server ID (IP address) */
+					if (opt[1] >= 4)
+						memcpy(&server_id, opt + 2, 4);
+					break;
+				};
 			}
-		}
 
 #ifdef IPCONFIG_DEBUG
-		printk("DHCP: Got message type %d\n", mt);
+			printk("DHCP: Got message type %d\n", mt);
 #endif
 
-		switch (mt) {
-		    case DHCPOFFER:
-			/* While in the process of accepting one offer,
-			   ignore all others. */
-			if (ic_myaddr != INADDR_NONE)
-				goto drop;
-			/* Let's accept that offer. */
-			ic_myaddr = b->your_ip;
-			ic_servaddr = server_id;
+			switch (mt) {
+			case DHCPOFFER:
+				/* While in the process of accepting one offer,
+				 * ignore all others.
+				 */
+				if (ic_myaddr != INADDR_NONE)
+					goto drop;
+
+				/* Let's accept that offer. */
+				ic_myaddr = b->your_ip;
+				ic_servaddr = server_id;
 #ifdef IPCONFIG_DEBUG
-			printk("DHCP: Offered address %u.%u.%u.%u", NIPQUAD(ic_myaddr));
-			printk(" by server %u.%u.%u.%u\n", NIPQUAD(ic_servaddr));
+				printk("DHCP: Offered address %u.%u.%u.%u",
+				       NIPQUAD(ic_myaddr));
+				printk(" by server %u.%u.%u.%u\n",
+				       NIPQUAD(ic_servaddr));
 #endif
-			break;
+				break;
 
-		    case DHCPACK:
-			/* Yeah! */
-			break;
+			case DHCPACK:
+				/* Yeah! */
+				break;
 
-		    default:
-			/* Urque.  Forget it*/
-			ic_myaddr = INADDR_NONE;
-			ic_servaddr = INADDR_NONE;
-			goto drop;
-		}
+			default:
+				/* Urque.  Forget it*/
+				ic_myaddr = INADDR_NONE;
+				ic_servaddr = INADDR_NONE;
+				goto drop;
+			};
 
-		ic_dhcp_msgtype = mt;
+			ic_dhcp_msgtype = mt;
 
+		}
 #endif /* IPCONFIG_DHCP */
 
 		ext = &b->exten[4];
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/ipip.c linux/net/ipv4/ipip.c
--- v2.4.10/linux/net/ipv4/ipip.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/ipip.c	Mon Oct  1 09:19:56 2001
@@ -1,7 +1,7 @@
 /*
  *	Linux NET3:	IP/IP protocol decoder. 
  *
- *	Version: $Id: ipip.c,v 1.47 2001/09/18 00:36:07 davem Exp $
+ *	Version: $Id: ipip.c,v 1.49 2001/09/25 22:35:47 davem Exp $
  *
  *	Authors:
  *		Sam Lantinga (slouken@cs.ucdavis.edu)  02/01/95
@@ -255,7 +255,7 @@
 		}
 		if (i==100)
 			goto failed;
-		memcpy(parms->name, dev->name, IFNAMSIZ);
+		memcpy(nt->parms.name, dev->name, IFNAMSIZ);
 	}
 	if (register_netdevice(dev) < 0)
 		goto failed;
@@ -758,6 +758,7 @@
 			err = -EPERM;
 			if (t == &ipip_fb_tunnel)
 				goto done;
+			dev = t->dev;
 		}
 		err = unregister_netdevice(dev);
 		break;
@@ -903,3 +904,4 @@
 module_init(ipip_init);
 #endif
 module_exit(ipip_fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ip_conntrack_ftp.c linux/net/ipv4/netfilter/ip_conntrack_ftp.c
--- v2.4.10/linux/net/ipv4/netfilter/ip_conntrack_ftp.c	Wed Apr 25 15:02:09 2001
+++ linux/net/ipv4/netfilter/ip_conntrack_ftp.c	Sun Sep 30 12:26:08 2001
@@ -417,6 +417,7 @@
 
 EXPORT_SYMBOL(ip_ftp_lock);
 EXPORT_SYMBOL(ip_conntrack_ftp);
+MODULE_LICENSE("GPL");
 
 module_init(init);
 module_exit(fini);
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ip_conntrack_standalone.c linux/net/ipv4/netfilter/ip_conntrack_standalone.c
--- v2.4.10/linux/net/ipv4/netfilter/ip_conntrack_standalone.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/netfilter/ip_conntrack_standalone.c	Sun Sep 30 12:26:08 2001
@@ -33,6 +33,8 @@
 #endif
 
 struct module *ip_conntrack_module = THIS_MODULE;
+MODULE_LICENSE("GPL");
+
 
 static unsigned int
 print_tuple(char *buffer, const struct ip_conntrack_tuple *tuple,
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ip_nat_ftp.c linux/net/ipv4/netfilter/ip_nat_ftp.c
--- v2.4.10/linux/net/ipv4/netfilter/ip_nat_ftp.c	Wed Apr 25 15:02:35 2001
+++ linux/net/ipv4/netfilter/ip_nat_ftp.c	Sun Sep 30 12:26:08 2001
@@ -369,3 +369,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ip_nat_standalone.c linux/net/ipv4/netfilter/ip_nat_standalone.c
--- v2.4.10/linux/net/ipv4/netfilter/ip_nat_standalone.c	Fri Apr 27 14:15:01 2001
+++ linux/net/ipv4/netfilter/ip_nat_standalone.c	Sun Sep 30 12:26:08 2001
@@ -343,3 +343,4 @@
 EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
 EXPORT_SYMBOL(ip_nat_seq_adjust);
 EXPORT_SYMBOL(ip_nat_delete_sack);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ip_queue.c linux/net/ipv4/netfilter/ip_queue.c
--- v2.4.10/linux/net/ipv4/netfilter/ip_queue.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/netfilter/ip_queue.c	Sun Sep 30 12:26:08 2001
@@ -685,5 +685,7 @@
 }
 
 MODULE_DESCRIPTION("IPv4 packet queue handler");
+MODULE_LICENSE("GPL");
+
 module_init(init);
 module_exit(fini);
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ip_tables.c linux/net/ipv4/netfilter/ip_tables.c
--- v2.4.10/linux/net/ipv4/netfilter/ip_tables.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/netfilter/ip_tables.c	Sun Sep 30 12:26:08 2001
@@ -1764,3 +1764,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipchains_core.c linux/net/ipv4/netfilter/ipchains_core.c
--- v2.4.10/linux/net/ipv4/netfilter/ipchains_core.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/netfilter/ipchains_core.c	Sun Sep 30 12:26:08 2001
@@ -1765,3 +1765,4 @@
 #endif
 	return ret;
 }
+MODULE_LICENSE("BSD without advertisement clause");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_LOG.c linux/net/ipv4/netfilter/ipt_LOG.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_LOG.c	Mon Jan  1 09:54:07 2001
+++ linux/net/ipv4/netfilter/ipt_LOG.c	Sun Sep 30 12:26:08 2001
@@ -353,3 +353,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_MARK.c linux/net/ipv4/netfilter/ipt_MARK.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_MARK.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_MARK.c	Sun Sep 30 12:26:08 2001
@@ -64,3 +64,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_MASQUERADE.c linux/net/ipv4/netfilter/ipt_MASQUERADE.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_MASQUERADE.c	Fri Apr 27 14:15:01 2001
+++ linux/net/ipv4/netfilter/ipt_MASQUERADE.c	Sun Sep 30 12:26:08 2001
@@ -204,3 +204,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_MIRROR.c linux/net/ipv4/netfilter/ipt_MIRROR.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_MIRROR.c	Mon Dec 11 12:37:04 2000
+++ linux/net/ipv4/netfilter/ipt_MIRROR.c	Sun Sep 30 12:26:08 2001
@@ -151,3 +151,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_REDIRECT.c linux/net/ipv4/netfilter/ipt_REDIRECT.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_REDIRECT.c	Tue Jun 20 14:32:27 2000
+++ linux/net/ipv4/netfilter/ipt_REDIRECT.c	Sun Sep 30 12:26:08 2001
@@ -105,3 +105,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_REJECT.c linux/net/ipv4/netfilter/ipt_REJECT.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_REJECT.c	Tue Jul  3 17:08:22 2001
+++ linux/net/ipv4/netfilter/ipt_REJECT.c	Sat Oct  6 08:50:28 2001
@@ -325,7 +325,7 @@
 {
  	const struct ipt_reject_info *rejinfo = targinfo;
 
- 	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_icmp))) {
+ 	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) {
   		DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize);
   		return 0;
   	}
@@ -374,3 +374,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_TCPMSS.c linux/net/ipv4/netfilter/ipt_TCPMSS.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_TCPMSS.c	Tue Mar  6 22:44:16 2001
+++ linux/net/ipv4/netfilter/ipt_TCPMSS.c	Sun Sep 30 12:26:08 2001
@@ -243,3 +243,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_TOS.c linux/net/ipv4/netfilter/ipt_TOS.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_TOS.c	Fri Feb  9 11:34:13 2001
+++ linux/net/ipv4/netfilter/ipt_TOS.c	Sun Sep 30 12:26:08 2001
@@ -83,3 +83,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_limit.c linux/net/ipv4/netfilter/ipt_limit.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_limit.c	Thu Aug 10 12:35:15 2000
+++ linux/net/ipv4/netfilter/ipt_limit.c	Sun Sep 30 12:26:08 2001
@@ -133,3 +133,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_mac.c linux/net/ipv4/netfilter/ipt_mac.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_mac.c	Thu Jul  6 21:20:00 2000
+++ linux/net/ipv4/netfilter/ipt_mac.c	Sat Oct  6 08:50:28 2001
@@ -20,7 +20,7 @@
 
     /* Is mac pointer valid? */
     return (skb->mac.raw >= skb->head
-	    && skb->mac.raw < skb->head + skb->len - ETH_HLEN
+	    && (skb->mac.raw + ETH_HLEN) <= skb->data
 	    /* If so, compare... */
 	    && ((memcmp(skb->mac.ethernet->h_source, info->srcaddr, ETH_ALEN)
 		== 0) ^ info->invert));
@@ -62,3 +62,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_mark.c linux/net/ipv4/netfilter/ipt_mark.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_mark.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_mark.c	Sun Sep 30 12:26:08 2001
@@ -48,3 +48,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_multiport.c linux/net/ipv4/netfilter/ipt_multiport.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_multiport.c	Tue Jun 20 14:32:27 2000
+++ linux/net/ipv4/netfilter/ipt_multiport.c	Sun Sep 30 12:26:08 2001
@@ -101,3 +101,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_owner.c linux/net/ipv4/netfilter/ipt_owner.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_owner.c	Sun Aug 13 12:53:19 2000
+++ linux/net/ipv4/netfilter/ipt_owner.c	Sun Sep 30 12:26:08 2001
@@ -152,3 +152,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_state.c linux/net/ipv4/netfilter/ipt_state.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_state.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_state.c	Sun Sep 30 12:26:08 2001
@@ -61,3 +61,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_tcpmss.c linux/net/ipv4/netfilter/ipt_tcpmss.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_tcpmss.c	Tue Mar  6 22:44:16 2001
+++ linux/net/ipv4/netfilter/ipt_tcpmss.c	Sun Sep 30 12:26:08 2001
@@ -106,3 +106,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_tos.c linux/net/ipv4/netfilter/ipt_tos.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_tos.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_tos.c	Sun Sep 30 12:26:08 2001
@@ -49,3 +49,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/ipt_unclean.c linux/net/ipv4/netfilter/ipt_unclean.c
--- v2.4.10/linux/net/ipv4/netfilter/ipt_unclean.c	Wed Jul 25 17:10:26 2001
+++ linux/net/ipv4/netfilter/ipt_unclean.c	Sun Sep 30 12:26:08 2001
@@ -583,3 +583,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/iptable_filter.c linux/net/ipv4/netfilter/iptable_filter.c
--- v2.4.10/linux/net/ipv4/netfilter/iptable_filter.c	Fri May 12 11:45:26 2000
+++ linux/net/ipv4/netfilter/iptable_filter.c	Sun Sep 30 12:26:08 2001
@@ -179,3 +179,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/netfilter/iptable_mangle.c linux/net/ipv4/netfilter/iptable_mangle.c
--- v2.4.10/linux/net/ipv4/netfilter/iptable_mangle.c	Wed Jul 25 17:10:26 2001
+++ linux/net/ipv4/netfilter/iptable_mangle.c	Sun Sep 30 12:26:08 2001
@@ -204,3 +204,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.4.10/linux/net/ipv4/tcp.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/tcp.c	Mon Oct  1 09:19:57 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp.c,v 1.211 2001/09/20 00:35:35 davem Exp $
+ * Version:	$Id: tcp.c,v 1.212 2001/09/21 21:27:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -852,7 +852,7 @@
 
 		page = pages[poffset/PAGE_SIZE];
 		offset = poffset % PAGE_SIZE;
-		size = min_t(unsigned int, psize, PAGE_SIZE-offset);
+		size = min(psize, PAGE_SIZE-offset);
 
 		if (tp->send_head==NULL || (copy = mss_now - skb->len) <= 0) {
 new_segment:
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.4.10/linux/net/ipv4/tcp_input.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/tcp_input.c	Mon Oct  1 09:19:57 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_input.c,v 1.236 2001/09/18 22:29:09 davem Exp $
+ * Version:	$Id: tcp_input.c,v 1.237 2001/09/21 21:27:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -168,7 +168,7 @@
 	if (quickacks==0)
 		quickacks=2;
 	if (quickacks > tp->ack.quick)
-		tp->ack.quick = min_t(unsigned int, quickacks, TCP_MAX_QUICKACKS);
+		tp->ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
 }
 
 void tcp_enter_quickack_mode(struct tcp_opt *tp)
@@ -198,7 +198,7 @@
 	int sndmem = tp->mss_clamp+MAX_TCP_HEADER+16+sizeof(struct sk_buff);
 
 	if (sk->sndbuf < 3*sndmem)
-		sk->sndbuf = min_t(int, 3*sndmem, sysctl_tcp_wmem[2]);
+		sk->sndbuf = min(3*sndmem, sysctl_tcp_wmem[2]);
 }
 
 /* 2. Tuning advertised window (window_clamp, rcv_ssthresh)
@@ -262,7 +262,7 @@
 			incr = __tcp_grow_window(sk, tp, skb);
 
 		if (incr) {
-			tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh + incr, tp->window_clamp);
+			tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp);
 			tp->ack.quick |= 1;
 		}
 	}
@@ -282,7 +282,7 @@
 	while (tcp_win_from_space(rcvmem) < tp->advmss)
 		rcvmem += 128;
 	if (sk->rcvbuf < 4*rcvmem)
-		sk->rcvbuf = min_t(int, 4*rcvmem, sysctl_tcp_rmem[2]);
+		sk->rcvbuf = min(4*rcvmem, sysctl_tcp_rmem[2]);
 }
 
 /* 4. Try to fixup all. It is made iimediately after connection enters
@@ -304,16 +304,16 @@
 		tp->window_clamp = maxwin;
 
 		if (sysctl_tcp_app_win && maxwin>4*tp->advmss)
-			tp->window_clamp = max_t(u32, maxwin-(maxwin>>sysctl_tcp_app_win), 4*tp->advmss);
+			tp->window_clamp = max(maxwin-(maxwin>>sysctl_tcp_app_win), 4*tp->advmss);
 	}
 
 	/* Force reservation of one segment. */
 	if (sysctl_tcp_app_win &&
 	    tp->window_clamp > 2*tp->advmss &&
 	    tp->window_clamp + tp->advmss > maxwin)
-		tp->window_clamp = max_t(u32, 2*tp->advmss, maxwin-tp->advmss);
+		tp->window_clamp = max(2*tp->advmss, maxwin-tp->advmss);
 
-	tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh, tp->window_clamp);
+	tp->rcv_ssthresh = min(tp->rcv_ssthresh, tp->window_clamp);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
@@ -321,7 +321,7 @@
 static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp)
 {
 	struct sk_buff *skb;
-	int app_win = tp->rcv_nxt - tp->copied_seq;
+	unsigned int app_win = tp->rcv_nxt - tp->copied_seq;
 	int ofo_win = 0;
 
 	tp->ack.quick = 0;
@@ -338,7 +338,7 @@
 		    !(sk->userlocks&SOCK_RCVBUF_LOCK) &&
 		    !tcp_memory_pressure &&
 		    atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0])
-			sk->rcvbuf = min_t(int, atomic_read(&sk->rmem_alloc), sysctl_tcp_rmem[2]);
+			sk->rcvbuf = min(atomic_read(&sk->rmem_alloc), sysctl_tcp_rmem[2]);
 	}
 	if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) {
 		app_win += ofo_win;
@@ -346,11 +346,11 @@
 			app_win >>= 1;
 		if (app_win > tp->ack.rcv_mss)
 			app_win -= tp->ack.rcv_mss;
-		app_win = max_t(unsigned int, app_win, 2*tp->advmss);
+		app_win = max(app_win, 2U*tp->advmss);
 
 		if (!ofo_win)
-			tp->window_clamp = min_t(u32, tp->window_clamp, app_win);
-		tp->rcv_ssthresh = min_t(u32, tp->window_clamp, 2*tp->advmss);
+			tp->window_clamp = min(tp->window_clamp, app_win);
+		tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
 	}
 }
 
@@ -472,7 +472,7 @@
 		/* no previous measure. */
 		tp->srtt = m<<3;	/* take the measured time to be rtt */
 		tp->mdev = m<<2;	/* make sure rto = 3*rtt */
-		tp->mdev_max = tp->rttvar = max_t(u32, tp->mdev, TCP_RTO_MIN);
+		tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
 		tp->rtt_seq = tp->snd_nxt;
 	}
 }
@@ -575,7 +575,7 @@
 			   tp->ca_state == TCP_CA_Open) {
 			/* Cong. avoidance phase, cwnd is reliable. */
 			if (!(dst->mxlock&(1<<RTAX_SSTHRESH)))
-				dst->ssthresh = max_t(u32, tp->snd_cwnd>>1, tp->snd_ssthresh);
+				dst->ssthresh = max(tp->snd_cwnd>>1, tp->snd_ssthresh);
 			if (!(dst->mxlock&(1<<RTAX_CWND)))
 				dst->cwnd = (dst->cwnd + tp->snd_cwnd)>>1;
 		} else {
@@ -617,7 +617,7 @@
 	else if (cwnd > tp->snd_ssthresh)
 		cwnd = tp->snd_ssthresh;
 
-	return min_t(u32, cwnd, tp->snd_cwnd_clamp);
+	return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
 }
 
 /* Initialize metrics on socket. */
@@ -668,7 +668,7 @@
 		tp->srtt = dst->rtt;
 	if (dst->rttvar > tp->mdev) {
 		tp->mdev = dst->rttvar;
-		tp->mdev_max = tp->rttvar = max_t(u32, tp->mdev, TCP_RTO_MIN);
+		tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
 	}
 	tcp_set_rto(tp);
 	tcp_bound_rto(tp);
@@ -693,7 +693,7 @@
 static void tcp_update_reordering(struct tcp_opt *tp, int metric, int ts)
 {
 	if (metric > tp->reordering) {
-		tp->reordering = min_t(unsigned int, TCP_MAX_REORDERING, metric);
+		tp->reordering = min(TCP_MAX_REORDERING, metric);
 
 		/* This exciting event is worth to be remembered. 8) */
 		if (ts)
@@ -848,12 +848,12 @@
 				if (sacked&TCPCB_RETRANS) {
 					if ((dup_sack && in_sack) &&
 					    (sacked&TCPCB_SACKED_ACKED))
-						reord = min_t(int, fack_count, reord);
+						reord = min(fack_count, reord);
 				} else {
 					/* If it was in a hole, we detected reordering. */
 					if (fack_count < prior_fackets &&
 					    !(sacked&TCPCB_SACKED_ACKED))
-						reord = min_t(int, fack_count, reord);
+						reord = min(fack_count, reord);
 				}
 
 				/* Nothing to do; acked frame is about to be dropped. */
@@ -885,7 +885,7 @@
 					 */
 					if (!(sacked & TCPCB_RETRANS) &&
 					    fack_count < prior_fackets)
-						reord = min_t(int, fack_count, reord);
+						reord = min(fack_count, reord);
 
 					if (sacked & TCPCB_LOST) {
 						TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
@@ -901,7 +901,7 @@
 					tp->fackets_out = fack_count;
 			} else {
 				if (dup_sack && (sacked&TCPCB_RETRANS))
-					reord = min_t(int, fack_count, reord);
+					reord = min(fack_count, reord);
 			}
 
 			/* D-SACK. We can detect redundant retransmission
@@ -1177,7 +1177,7 @@
 	 * recovery more?
 	 */
 	if (tp->packets_out <= tp->reordering &&
-	    tp->sacked_out >= max_t(u32, tp->packets_out/2, sysctl_tcp_reordering) &&
+	    tp->sacked_out >= max_t(__u32, tp->packets_out/2, sysctl_tcp_reordering) &&
 	    !tcp_may_send_now(sk, tp)) {
 		/* We have nothing to send. This connection is limited
 		 * either by receiver window or by application.
@@ -1194,9 +1194,10 @@
  */
 static void tcp_check_reno_reordering(struct tcp_opt *tp, int addend)
 {
-	u32 holes = min_t(unsigned int,
-			max_t(unsigned int, tp->lost_out, 1),
-			tp->packets_out);
+	u32 holes;
+
+	holes = max(tp->lost_out, 1U);
+	holes = min(holes, tp->packets_out);
 
 	if (tp->sacked_out + holes > tp->packets_out) {
 		tp->sacked_out = tp->packets_out - holes;
@@ -1291,7 +1292,7 @@
  */
 static __inline__ void tcp_moderate_cwnd(struct tcp_opt *tp)
 {
-	tp->snd_cwnd = min_t(u32, tp->snd_cwnd,
+	tp->snd_cwnd = min(tp->snd_cwnd,
 			   tcp_packets_in_flight(tp)+tcp_max_burst(tp));
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
@@ -1308,7 +1309,7 @@
 	if (decr && tp->snd_cwnd > tp->snd_ssthresh/2)
 		tp->snd_cwnd -= decr;
 
-	tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tcp_packets_in_flight(tp)+1);
+	tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
@@ -1340,15 +1341,14 @@
 static void tcp_undo_cwr(struct tcp_opt *tp, int undo)
 {
 	if (tp->prior_ssthresh) {
-		tp->snd_cwnd = max_t(unsigned int,
-				   tp->snd_cwnd, tp->snd_ssthresh<<1);
+		tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
 
 		if (undo && tp->prior_ssthresh > tp->snd_ssthresh) {
 			tp->snd_ssthresh = tp->prior_ssthresh;
 			TCP_ECN_withdraw_cwr(tp);
 		}
 	} else {
-		tp->snd_cwnd = max_t(unsigned int, tp->snd_cwnd, tp->snd_ssthresh);
+		tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh);
 	}
 	tcp_moderate_cwnd(tp);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
@@ -1450,7 +1450,7 @@
 
 static __inline__ void tcp_complete_cwr(struct tcp_opt *tp)
 {
-	tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_ssthresh);
+	tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
@@ -1836,7 +1836,7 @@
 		 */
 	} else {
 		tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0,
-				     min_t(u32, tp->rto << tp->backoff, TCP_RTO_MAX));
+				     min(tp->rto << tp->backoff, TCP_RTO_MAX));
 	}
 }
 
@@ -2323,7 +2323,7 @@
 		tp->dsack = 1;
 		tp->duplicate_sack[0].start_seq = seq;
 		tp->duplicate_sack[0].end_seq = end_seq;
-		tp->eff_sacks = min_t(unsigned int, tp->num_sacks+1, 4-tp->tstamp_ok);
+		tp->eff_sacks = min(tp->num_sacks+1, 4-tp->tstamp_ok);
 	}
 }
 
@@ -2376,7 +2376,7 @@
 			 * Decrease num_sacks.
 			 */
 			tp->num_sacks--;
-			tp->eff_sacks = min_t(unsigned int, tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
+			tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
 			for(i=this_sack; i < tp->num_sacks; i++)
 				sp[i] = sp[i+1];
 			continue;
@@ -2438,7 +2438,7 @@
 	sp->start_seq = seq;
 	sp->end_seq = end_seq;
 	tp->num_sacks++;
-	tp->eff_sacks = min_t(unsigned int, tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
+	tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
 }
 
 /* RCV.NXT advances, some SACKs should be eaten. */
@@ -2475,7 +2475,7 @@
 	}
 	if (num_sacks != tp->num_sacks) {
 		tp->num_sacks = num_sacks;
-		tp->eff_sacks = min_t(unsigned int, tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
+		tp->eff_sacks = min(tp->num_sacks+tp->dsack, 4-tp->tstamp_ok);
 	}
 }
 
@@ -2807,7 +2807,7 @@
 
 			if (offset < 0) BUG();
 			if (size > 0) {
-				size = min_t(int, copy, size);
+				size = min(copy, size);
 				if (skb_copy_bits(skb, offset, skb_put(nskb, size), size))
 					BUG();
 				TCP_SKB_CB(nskb)->end_seq += size;
@@ -2886,7 +2886,7 @@
 	if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
 		tcp_clamp_window(sk, tp);
 	else if (tcp_memory_pressure)
-		tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh, 4*tp->advmss);
+		tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss);
 
 	tcp_collapse_ofo_queue(sk);
 	tcp_collapse(sk, sk->receive_queue.next,
@@ -2941,7 +2941,7 @@
 	if (tp->ca_state == TCP_CA_Open &&
 	    sk->socket && !test_bit(SOCK_NOSPACE, &sk->socket->flags)) {
 		/* Limited by application or receiver window. */
-		u32 win_used = max_t(u32, tp->snd_cwnd_used, 2);
+		u32 win_used = max(tp->snd_cwnd_used, 2U);
 		if (win_used < tp->snd_cwnd) {
 			tp->snd_ssthresh = tcp_current_ssthresh(tp);
 			tp->snd_cwnd = (tp->snd_cwnd+win_used)>>1;
@@ -2970,7 +2970,7 @@
 		demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering+1);
 		sndmem *= 2*demanded;
 		if (sndmem > sk->sndbuf)
-			sk->sndbuf = min_t(int, sndmem, sysctl_tcp_wmem[2]);
+			sk->sndbuf = min(sndmem, sysctl_tcp_wmem[2]);
 		tp->snd_cwnd_stamp = tcp_time_stamp;
 	}
 
@@ -3520,7 +3520,7 @@
 
 		if (tp->wscale_ok == 0) {
 			tp->snd_wscale = tp->rcv_wscale = 0;
-			tp->window_clamp = min_t(u32, tp->window_clamp, 65535);
+			tp->window_clamp = min(tp->window_clamp, 65535U);
 		}
 
 		if (tp->saw_tstamp) {
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.4.10/linux/net/ipv4/tcp_ipv4.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/tcp_ipv4.c	Mon Oct  1 09:19:56 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_ipv4.c,v 1.230 2001/09/01 00:31:50 davem Exp $
+ * Version:	$Id: tcp_ipv4.c,v 1.231 2001/09/26 23:38:47 davem Exp $
  *
  *		IPv4 specific functions
  *
@@ -1486,7 +1486,7 @@
 			bh_lock_sock(nsk);
 			return nsk;
 		}
-		tcp_tw_put((struct tcp_tw_bucket*)sk);
+		tcp_tw_put((struct tcp_tw_bucket*)nsk);
 		return NULL;
 	}
 
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/tcp_minisocks.c linux/net/ipv4/tcp_minisocks.c
--- v2.4.10/linux/net/ipv4/tcp_minisocks.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/tcp_minisocks.c	Mon Oct  1 09:19:57 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_minisocks.c,v 1.13 2001/09/18 22:29:10 davem Exp $
+ * Version:	$Id: tcp_minisocks.c,v 1.14 2001/09/21 21:27:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -766,7 +766,7 @@
 			newtp->rcv_wscale = req->rcv_wscale;
 		} else {
 			newtp->snd_wscale = newtp->rcv_wscale = 0;
-			newtp->window_clamp = min_t(u32, newtp->window_clamp, 65535);
+			newtp->window_clamp = min(newtp->window_clamp, 65535U);
 		}
 		newtp->snd_wnd = ntohs(skb->h.th->window) << newtp->snd_wscale;
 		newtp->max_window = newtp->snd_wnd;
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.4.10/linux/net/ipv4/tcp_output.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/tcp_output.c	Mon Oct  1 09:19:57 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_output.c,v 1.141 2001/09/18 22:29:10 davem Exp $
+ * Version:	$Id: tcp_output.c,v 1.142 2001/09/21 21:27:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -105,11 +105,11 @@
 	u32 cwnd = tp->snd_cwnd;
 
 	tp->snd_ssthresh = tcp_current_ssthresh(tp);
-	restart_cwnd = min_t(u32, restart_cwnd, cwnd);
+	restart_cwnd = min(restart_cwnd, cwnd);
 
 	while ((delta -= tp->rto) > 0 && cwnd > restart_cwnd)
 		cwnd >>= 1;
-	tp->snd_cwnd = max_t(u32, cwnd, restart_cwnd);
+	tp->snd_cwnd = max(cwnd, restart_cwnd);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 	tp->snd_cwnd_used = 0;
 }
@@ -526,7 +526,7 @@
 
 	/* Bound mss with half of window */
 	if (tp->max_window && mss_now > (tp->max_window>>1))
-		mss_now = max_t(u32, (tp->max_window>>1), 68 - tp->tcp_header_len);
+		mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len);
 
 	/* And store cached results */
 	tp->pmtu_cookie = pmtu;
@@ -651,7 +651,7 @@
 	 */
 	int mss = tp->ack.rcv_mss;
 	int free_space = tcp_space(sk);
-	int full_space = min_t(unsigned int, tp->window_clamp, tcp_full_space(sk));
+	int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk));
 	int window;
 
 	if (mss > full_space)
@@ -661,7 +661,7 @@
 		tp->ack.quick = 0;
 
 		if (tcp_memory_pressure)
-			tp->rcv_ssthresh = min_t(u32, tp->rcv_ssthresh, 4*tp->advmss);
+			tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss);
 
 		if (free_space < mss)
 			return 0;
@@ -817,7 +817,7 @@
 	/* Do not sent more than we queued. 1/4 is reserved for possible
 	 * copying overhead: frgagmentation, tunneling, mangling etc.
 	 */
-	if (atomic_read(&sk->wmem_alloc) > min_t(int, sk->wmem_queued+(sk->wmem_queued>>2),sk->sndbuf))
+	if (atomic_read(&sk->wmem_alloc) > min(sk->wmem_queued+(sk->wmem_queued>>2),sk->sndbuf))
 		return -EAGAIN;
 
 	/* If receiver has shrunk his window, and skb is out of
@@ -1264,13 +1264,13 @@
 		 * directly.
 		 */
 		if (tp->srtt) {
-			int rtt = max_t(unsigned int, tp->srtt>>3, TCP_DELACK_MIN);
+			int rtt = max(tp->srtt>>3, TCP_DELACK_MIN);
 
 			if (rtt < max_ato)
 				max_ato = rtt;
 		}
 
-		ato = min_t(int, ato, max_ato);
+		ato = min(ato, max_ato);
 	}
 
 	/* Stay within the limit we were given */
@@ -1386,7 +1386,7 @@
 			 */
 			if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq ||
 			    skb->len > mss) {
-				seg_size = min_t(int, seg_size, mss);
+				seg_size = min(seg_size, mss);
 				TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 				if (tcp_fragment(sk, skb, seg_size))
 					return -1;
@@ -1429,7 +1429,7 @@
 		tp->backoff++;
 		tp->probes_out++;
 		tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, 
-				      min_t(u32, tp->rto << tp->backoff, TCP_RTO_MAX));
+				      min(tp->rto << tp->backoff, TCP_RTO_MAX));
 	} else {
 		/* If packet was not sent due to local congestion,
 		 * do not backoff and do not remember probes_out.
@@ -1440,6 +1440,6 @@
 		if (!tp->probes_out)
 			tp->probes_out=1;
 		tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, 
-				      min_t(unsigned int, tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL));
+				      min(tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL));
 	}
 }
diff -u --recursive --new-file v2.4.10/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.4.10/linux/net/ipv4/tcp_timer.c	Sun Sep 23 11:41:01 2001
+++ linux/net/ipv4/tcp_timer.c	Mon Oct  1 09:19:57 2001
@@ -5,7 +5,7 @@
  *
  *		Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:	$Id: tcp_timer.c,v 1.86 2001/09/18 22:29:10 davem Exp $
+ * Version:	$Id: tcp_timer.c,v 1.87 2001/09/21 21:27:34 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -248,7 +248,7 @@
 	if (tcp_ack_scheduled(tp)) {
 		if (!tp->ack.pingpong) {
 			/* Delayed ACK missed: inflate ATO. */
-			tp->ack.ato = min_t(u32, tp->ack.ato << 1, tp->rto);
+			tp->ack.ato = min(tp->ack.ato << 1, tp->rto);
 		} else {
 			/* Delayed ACK missed: leave pingpong mode and
 			 * deflate ATO.
@@ -381,7 +381,7 @@
 		if (!tp->retransmits)
 			tp->retransmits=1;
 		tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS,
-				     min_t(u32, tp->rto, TCP_RESOURCE_PROBE_INTERVAL));
+				     min(tp->rto, TCP_RESOURCE_PROBE_INTERVAL));
 		goto out;
 	}
 
@@ -404,7 +404,7 @@
 	tp->retransmits++;
 
 out_reset_timer:
-	tp->rto = min_t(u32, tp->rto << 1, TCP_RTO_MAX);
+	tp->rto = min(tp->rto << 1, TCP_RTO_MAX);
 	tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
 	if (tp->retransmits > sysctl_tcp_retries1)
 		__sk_dst_reset(sk);
@@ -517,8 +517,7 @@
 
 					if (req->retrans++ == 0)
 						lopt->qlen_young--;
-					timeo = min_t(unsigned long,
-						    (TCP_TIMEOUT_INIT << req->retrans),
+					timeo = min((TCP_TIMEOUT_INIT << req->retrans),
 						    TCP_RTO_MAX);
 					req->expires = now + timeo;
 					reqp = &req->dl_next;
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.4.10/linux/net/ipv6/af_inet6.c	Tue Jul  3 17:08:22 2001
+++ linux/net/ipv6/af_inet6.c	Sun Sep 30 12:26:08 2001
@@ -718,3 +718,4 @@
 }
 module_exit(inet6_exit);
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/netfilter/ip6_tables.c linux/net/ipv6/netfilter/ip6_tables.c
--- v2.4.10/linux/net/ipv6/netfilter/ip6_tables.c	Sun Aug 12 13:28:01 2001
+++ linux/net/ipv6/netfilter/ip6_tables.c	Sun Sep 30 12:26:08 2001
@@ -1801,3 +1801,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/netfilter/ip6t_MARK.c linux/net/ipv6/netfilter/ip6t_MARK.c
--- v2.4.10/linux/net/ipv6/netfilter/ip6t_MARK.c	Mon Jan 22 13:30:21 2001
+++ linux/net/ipv6/netfilter/ip6t_MARK.c	Sun Sep 30 12:26:08 2001
@@ -65,3 +65,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/netfilter/ip6t_limit.c linux/net/ipv6/netfilter/ip6t_limit.c
--- v2.4.10/linux/net/ipv6/netfilter/ip6t_limit.c	Mon May 22 09:50:55 2000
+++ linux/net/ipv6/netfilter/ip6t_limit.c	Sun Sep 30 12:26:08 2001
@@ -133,3 +133,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/netfilter/ip6t_mark.c linux/net/ipv6/netfilter/ip6t_mark.c
--- v2.4.10/linux/net/ipv6/netfilter/ip6t_mark.c	Mon Jan 22 13:30:21 2001
+++ linux/net/ipv6/netfilter/ip6t_mark.c	Sun Sep 30 12:26:08 2001
@@ -48,3 +48,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/netfilter/ip6table_filter.c linux/net/ipv6/netfilter/ip6table_filter.c
--- v2.4.10/linux/net/ipv6/netfilter/ip6table_filter.c	Fri Jul 28 12:35:30 2000
+++ linux/net/ipv6/netfilter/ip6table_filter.c	Sun Sep 30 12:26:08 2001
@@ -181,3 +181,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/netfilter/ip6table_mangle.c linux/net/ipv6/netfilter/ip6table_mangle.c
--- v2.4.10/linux/net/ipv6/netfilter/ip6table_mangle.c	Mon Jan 22 13:30:21 2001
+++ linux/net/ipv6/netfilter/ip6table_mangle.c	Sun Sep 30 12:26:09 2001
@@ -187,3 +187,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/sit.c linux/net/ipv6/sit.c
--- v2.4.10/linux/net/ipv6/sit.c	Sun Sep 23 11:41:02 2001
+++ linux/net/ipv6/sit.c	Mon Oct  1 09:19:56 2001
@@ -6,7 +6,7 @@
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *	Alexey Kuznetsov	<kuznet@ms2.inr.ac.ru>
  *
- *	$Id: sit.c,v 1.52 2001/09/01 00:31:50 davem Exp $
+ *	$Id: sit.c,v 1.53 2001/09/25 05:09:53 davem Exp $
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -712,6 +712,7 @@
 			err = -EPERM;
 			if (t == &ipip6_fb_tunnel)
 				goto done;
+			dev = t->dev;
 		}
 		err = unregister_netdevice(dev);
 		break;
diff -u --recursive --new-file v2.4.10/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.4.10/linux/net/ipv6/tcp_ipv6.c	Sun Sep 23 11:41:02 2001
+++ linux/net/ipv6/tcp_ipv6.c	Mon Oct  1 09:19:56 2001
@@ -5,7 +5,7 @@
  *	Authors:
  *	Pedro Roque		<roque@di.fc.ul.pt>	
  *
- *	$Id: tcp_ipv6.c,v 1.138 2001/09/01 00:31:50 davem Exp $
+ *	$Id: tcp_ipv6.c,v 1.139 2001/09/26 23:38:47 davem Exp $
  *
  *	Based on: 
  *	linux/net/ipv4/tcp.c
@@ -1098,7 +1098,7 @@
 			bh_lock_sock(nsk);
 			return nsk;
 		}
-		tcp_tw_put((struct tcp_tw_bucket*)sk);
+		tcp_tw_put((struct tcp_tw_bucket*)nsk);
 		return NULL;
 	}
 
diff -u --recursive --new-file v2.4.10/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v2.4.10/linux/net/ipx/af_ipx.c	Sun Sep 23 11:41:02 2001
+++ linux/net/ipx/af_ipx.c	Sun Sep 30 12:26:13 2001
@@ -2637,3 +2637,4 @@
 }
 
 module_exit(ipx_proto_finito);
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/irda/af_irda.c linux/net/irda/af_irda.c
--- v2.4.10/linux/net/irda/af_irda.c	Sun Sep 23 11:41:02 2001
+++ linux/net/irda/af_irda.c	Thu Oct  4 18:41:09 2001
@@ -637,7 +637,7 @@
 	 * Note : we have to use irlmp_get_discoveries(), as opposed
 	 * to play with the cachelog directly, because while we are
 	 * making our ias query, le log might change... */
-	discoveries = irlmp_get_discoveries(&number, self->mask);
+	discoveries = irlmp_get_discoveries(&number, self->mask, self->nslots);
 	/* Check if the we got some results */
 	if (discoveries == NULL)
 		return -ENETUNREACH;	/* No nodes discovered */
@@ -2091,7 +2091,8 @@
 	switch (optname) {
 	case IRLMP_ENUMDEVICES:
 		/* Ask lmp for the current discovery log */
-		discoveries = irlmp_get_discoveries(&list.len, self->mask);
+		discoveries = irlmp_get_discoveries(&list.len, self->mask,
+						    self->nslots);
 		/* Check if the we got some results */
 		if (discoveries == NULL)
 			return -EAGAIN;		/* Didn't find any devices */
@@ -2571,6 +2572,7 @@
  
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem"); 
+MODULE_LICENSE("GPL");
 #ifdef CONFIG_IRDA_DEBUG
 MODULE_PARM(irda_debug, "1l");
 #endif
diff -u --recursive --new-file v2.4.10/linux/net/irda/ircomm/ircomm_core.c linux/net/irda/ircomm/ircomm_core.c
--- v2.4.10/linux/net/irda/ircomm/ircomm_core.c	Fri Mar  2 11:12:12 2001
+++ linux/net/irda/ircomm/ircomm_core.c	Sun Sep 30 12:26:09 2001
@@ -514,6 +514,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dag@brattli.net>");
 MODULE_DESCRIPTION("IrCOMM protocol");
+MODULE_LICENSE("GPL");
 
 int init_module(void) 
 {
diff -u --recursive --new-file v2.4.10/linux/net/irda/ircomm/ircomm_tty.c linux/net/irda/ircomm/ircomm_tty.c
--- v2.4.10/linux/net/irda/ircomm/ircomm_tty.c	Sun Aug 12 13:28:01 2001
+++ linux/net/irda/ircomm/ircomm_tty.c	Sun Sep 30 12:26:09 2001
@@ -1363,6 +1363,7 @@
 #ifdef MODULE
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("IrCOMM serial TTY driver");
+MODULE_LICENSE("GPL");
 
 int init_module(void) 
 {
diff -u --recursive --new-file v2.4.10/linux/net/irda/irias_object.c linux/net/irda/irias_object.c
--- v2.4.10/linux/net/irda/irias_object.c	Sun Sep 23 11:41:02 2001
+++ linux/net/irda/irias_object.c	Thu Oct  4 18:41:09 2001
@@ -435,8 +435,6 @@
 struct ias_value *irias_new_string_value(char *string)
 {
 	struct ias_value *value;
-	int len;
-	char *new_str;
 
 	value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
 	if (value == NULL) {
diff -u --recursive --new-file v2.4.10/linux/net/irda/irlan/irlan_common.c linux/net/irda/irlan/irlan_common.c
--- v2.4.10/linux/net/irda/irlan/irlan_common.c	Wed Jul 25 17:10:27 2001
+++ linux/net/irda/irlan/irlan_common.c	Sun Sep 30 12:26:09 2001
@@ -1184,6 +1184,7 @@
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); 
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(eth, "i");
 MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");
diff -u --recursive --new-file v2.4.10/linux/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- v2.4.10/linux/net/irda/irlap_event.c	Sun Sep 23 11:41:02 2001
+++ linux/net/irda/irlap_event.c	Thu Oct  4 18:41:09 2001
@@ -701,7 +701,21 @@
 		 * We are allowed to send two frames, but this may increase
 		 * the connect latency, so lets not do it for now.
 		 */
-		/* What the hell is this ? - Jean II */
+		/* This is full of good intentions, but doesn't work in
+		 * practice.
+		 * After sending the first UA response, we switch the
+		 * dongle to the negociated speed, which is usually
+		 * different than 9600 kb/s.
+		 * From there, there is two solutions :
+		 * 1) The other end has received the first UA response :
+		 * it will set up the connection, move to state LAP_NRM_P,
+		 * and will ignore and drop the second UA response.
+		 * Actually, it's even worse : the other side will almost
+		 * immediately send a RR that will likely collide with the
+		 * UA response (depending on negociated turnaround).
+		 * 2) The other end has not received the first UA response,
+		 * will stay at 9600 and will never see the second UA response.
+		 * Jean II */
 		irlap_send_ua_response_frame(self, &self->qos_rx);
 #endif
 
diff -u --recursive --new-file v2.4.10/linux/net/irda/irlmp.c linux/net/irda/irlmp.c
--- v2.4.10/linux/net/irda/irlmp.c	Sun Sep 23 11:41:02 2001
+++ linux/net/irda/irlmp.c	Thu Oct  4 18:41:09 2001
@@ -781,10 +781,6 @@
  */
 void irlmp_discovery_request(int nslots)
 {
-	/* Check if user wants to override the default */
-	if (nslots == DISCOVERY_DEFAULT_SLOTS)
-		nslots = sysctl_discovery_slots;
-
 	/* Return current cached discovery log */
 	irlmp_discovery_confirm(irlmp->cachelog);
 
@@ -792,21 +788,43 @@
 	 * Start a single discovery operation if discovery is not already
          * running 
 	 */
-	if (!sysctl_discovery)
+	if (!sysctl_discovery) {
+		/* Check if user wants to override the default */
+		if (nslots == DISCOVERY_DEFAULT_SLOTS)
+			nslots = sysctl_discovery_slots;
+
 		irlmp_do_discovery(nslots);
-	/* Note : we never do expiry here. Expiry will run on the
-	 * discovery timer regardless of the state of sysctl_discovery
-	 * Jean II */
+		/* Note : we never do expiry here. Expiry will run on the
+		 * discovery timer regardless of the state of sysctl_discovery
+		 * Jean II */
+	}
 }
 
 /*
- * Function irlmp_get_discoveries (pn, mask)
+ * Function irlmp_get_discoveries (pn, mask, slots)
  *
  *    Return the current discovery log
  *
  */
-struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask)
+struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots)
 {
+	/* If discovery is not enabled, it's likely that the discovery log
+	 * will be empty. So, we trigger a single discovery, so that next
+	 * time the user call us there might be some results in the log.
+	 * Jean II
+	 */
+	if (!sysctl_discovery) {
+		/* Check if user wants to override the default */
+		if (nslots == DISCOVERY_DEFAULT_SLOTS)
+			nslots = sysctl_discovery_slots;
+
+		/* Start discovery - will complete sometime later */
+		irlmp_do_discovery(nslots);
+		/* Note : we never do expiry here. Expiry will run on the
+		 * discovery timer regardless of the state of sysctl_discovery
+		 * Jean II */
+	}
+
 	/* Return current cached discovery log */
 	return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask));
 }
diff -u --recursive --new-file v2.4.10/linux/net/irda/irnet/irnet_irda.c linux/net/irda/irnet/irnet_irda.c
--- v2.4.10/linux/net/irda/irnet/irnet_irda.c	Sun Sep 23 11:41:02 2001
+++ linux/net/irda/irnet/irnet_irda.c	Thu Oct  4 18:41:09 2001
@@ -370,7 +370,8 @@
   DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
 
   /* Ask lmp for the current discovery log */
-  self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask);
+  self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
+					    DISCOVERY_DEFAULT_SLOTS);
 
   /* Check if the we got some results */
   if(self->discoveries == NULL)
@@ -426,7 +427,8 @@
   DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
 
   /* Ask lmp for the current discovery log */
-  discoveries = irlmp_get_discoveries(&number, 0xffff);
+  discoveries = irlmp_get_discoveries(&number, 0xffff,
+				      DISCOVERY_DEFAULT_SLOTS);
   /* Check if the we got some results */
   if(discoveries == NULL)
     DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
@@ -664,7 +666,8 @@
   DENTER(IRDA_SERV_TRACE, "(self=0x%X)\n", (unsigned int) self);
 
   /* Ask lmp for the current discovery log */
-  discoveries = irlmp_get_discoveries(&number, 0xffff);
+  discoveries = irlmp_get_discoveries(&number, 0xffff,
+				      DISCOVERY_DEFAULT_SLOTS);
   /* Check if the we got some results */
   if (discoveries == NULL)
     DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n");
diff -u --recursive --new-file v2.4.10/linux/net/irda/irnet/irnet_ppp.c linux/net/irda/irnet/irnet_ppp.c
--- v2.4.10/linux/net/irda/irnet/irnet_ppp.c	Sun Sep 23 11:41:02 2001
+++ linux/net/irda/irnet/irnet_ppp.c	Thu Oct  4 18:41:09 2001
@@ -14,6 +14,7 @@
  */
 
 #include "irnet_ppp.h"		/* Private header */
+/* Please put other headers in irnet.h - Thanks */
 
 /************************* CONTROL CHANNEL *************************/
 /*
@@ -199,7 +200,8 @@
       __u16		mask = irlmp_service_to_hint(S_LAN);
 
       /* Ask IrLMP for the current discovery log */
-      ap->discoveries = irlmp_get_discoveries(&ap->disco_number, mask);
+      ap->discoveries = irlmp_get_discoveries(&ap->disco_number, mask,
+					      DISCOVERY_DEFAULT_SLOTS);
       /* Check if the we got some results */
       if(ap->discoveries == NULL)
 	ap->disco_number = -1;
@@ -1095,3 +1097,4 @@
   return ppp_irnet_cleanup();
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/cls_fw.c linux/net/sched/cls_fw.c
--- v2.4.10/linux/net/sched/cls_fw.c	Fri Mar 17 10:56:20 2000
+++ linux/net/sched/cls_fw.c	Sun Sep 30 12:26:09 2001
@@ -383,3 +383,4 @@
 	unregister_tcf_proto_ops(&cls_fw_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/cls_route.c linux/net/sched/cls_route.c
--- v2.4.10/linux/net/sched/cls_route.c	Sun Aug 12 13:28:01 2001
+++ linux/net/sched/cls_route.c	Sun Sep 30 12:26:09 2001
@@ -638,3 +638,4 @@
 	unregister_tcf_proto_ops(&cls_route4_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/cls_rsvp.c linux/net/sched/cls_rsvp.c
--- v2.4.10/linux/net/sched/cls_rsvp.c	Wed Apr 29 22:46:59 1998
+++ linux/net/sched/cls_rsvp.c	Sun Sep 30 12:26:09 2001
@@ -39,3 +39,4 @@
 #define RSVP_OPS	cls_rsvp_ops
 
 #include "cls_rsvp.h"
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/cls_rsvp6.c linux/net/sched/cls_rsvp6.c
--- v2.4.10/linux/net/sched/cls_rsvp6.c	Wed Apr 29 22:46:59 1998
+++ linux/net/sched/cls_rsvp6.c	Sun Sep 30 12:26:09 2001
@@ -40,3 +40,4 @@
 #define RSVP_OPS	cls_rsvp6_ops
 
 #include "cls_rsvp.h"
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/cls_tcindex.c linux/net/sched/cls_tcindex.c
--- v2.4.10/linux/net/sched/cls_tcindex.c	Sun Mar 25 18:14:25 2001
+++ linux/net/sched/cls_tcindex.c	Sun Sep 30 12:26:09 2001
@@ -515,3 +515,4 @@
 	unregister_tcf_proto_ops(&cls_tcindex_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/cls_u32.c linux/net/sched/cls_u32.c
--- v2.4.10/linux/net/sched/cls_u32.c	Sun Aug 12 13:28:01 2001
+++ linux/net/sched/cls_u32.c	Sun Sep 30 12:26:09 2001
@@ -726,3 +726,4 @@
 	unregister_tcf_proto_ops(&cls_u32_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_cbq.c linux/net/sched/sch_cbq.c
--- v2.4.10/linux/net/sched/sch_cbq.c	Sun Aug 12 13:28:01 2001
+++ linux/net/sched/sch_cbq.c	Sun Sep 30 12:26:09 2001
@@ -2120,3 +2120,4 @@
 	unregister_qdisc(&cbq_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_csz.c linux/net/sched/sch_csz.c
--- v2.4.10/linux/net/sched/sch_csz.c	Mon Aug 23 10:01:02 1999
+++ linux/net/sched/sch_csz.c	Sun Sep 30 12:26:09 2001
@@ -1069,3 +1069,4 @@
 	unregister_qdisc(&csz_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_dsmark.c linux/net/sched/sch_dsmark.c
--- v2.4.10/linux/net/sched/sch_dsmark.c	Sun Mar 25 18:14:25 2001
+++ linux/net/sched/sch_dsmark.c	Sun Sep 30 12:26:09 2001
@@ -490,3 +490,4 @@
 	unregister_qdisc(&dsmark_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_gred.c linux/net/sched/sch_gred.c
--- v2.4.10/linux/net/sched/sch_gred.c	Tue Jul  3 17:08:22 2001
+++ linux/net/sched/sch_gred.c	Sun Sep 30 12:26:09 2001
@@ -632,3 +632,4 @@
 	unregister_qdisc(&gred_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_ingress.c linux/net/sched/sch_ingress.c
--- v2.4.10/linux/net/sched/sch_ingress.c	Fri Aug 18 10:26:25 2000
+++ linux/net/sched/sch_ingress.c	Sun Sep 30 12:26:09 2001
@@ -392,3 +392,4 @@
 	unregister_qdisc(&ingress_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_prio.c linux/net/sched/sch_prio.c
--- v2.4.10/linux/net/sched/sch_prio.c	Fri Jan  7 16:57:13 2000
+++ linux/net/sched/sch_prio.c	Sun Sep 30 12:26:09 2001
@@ -421,3 +421,4 @@
 }
 
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_red.c linux/net/sched/sch_red.c
--- v2.4.10/linux/net/sched/sch_red.c	Tue Jul  3 17:08:22 2001
+++ linux/net/sched/sch_red.c	Sun Sep 30 12:26:09 2001
@@ -497,3 +497,4 @@
 	unregister_qdisc(&red_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_sfq.c linux/net/sched/sch_sfq.c
--- v2.4.10/linux/net/sched/sch_sfq.c	Mon Aug 23 10:01:02 1999
+++ linux/net/sched/sch_sfq.c	Sun Sep 30 12:26:09 2001
@@ -496,3 +496,4 @@
 	unregister_qdisc(&sfq_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_tbf.c linux/net/sched/sch_tbf.c
--- v2.4.10/linux/net/sched/sch_tbf.c	Sun Sep 23 11:41:02 2001
+++ linux/net/sched/sch_tbf.c	Sun Sep 30 12:26:09 2001
@@ -427,3 +427,4 @@
 	unregister_qdisc(&tbf_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/sched/sch_teql.c linux/net/sched/sch_teql.c
--- v2.4.10/linux/net/sched/sch_teql.c	Sun Jul  9 22:30:41 2000
+++ linux/net/sched/sch_teql.c	Sun Sep 30 12:26:09 2001
@@ -493,3 +493,4 @@
 	rtnl_unlock();
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/net/socket.c linux/net/socket.c
--- v2.4.10/linux/net/socket.c	Sun Sep 23 11:41:02 2001
+++ linux/net/socket.c	Fri Sep 28 18:03:48 2001
@@ -440,11 +440,10 @@
 	struct inode * inode;
 	struct socket * sock;
 
-	inode = get_empty_inode();
+	inode = new_inode(sock_mnt->mnt_sb);
 	if (!inode)
 		return NULL;
 
-	inode->i_sb = sock_mnt->mnt_sb;
 	sock = socki_lookup(inode);
 
 	inode->i_mode = S_IFSOCK|S_IRWXUGO;
diff -u --recursive --new-file v2.4.10/linux/net/sunrpc/sched.c linux/net/sunrpc/sched.c
--- v2.4.10/linux/net/sunrpc/sched.c	Sun Sep 23 11:41:02 2001
+++ linux/net/sunrpc/sched.c	Mon Oct  1 13:45:47 2001
@@ -772,8 +772,8 @@
 		}
 		if (flags & RPC_TASK_ASYNC)
 			return NULL;
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ>>4);
+		current->policy |= SCHED_YIELD;
+		schedule();
 	} while (!signalled());
 
 	return NULL;
@@ -1116,8 +1116,8 @@
 		__rpc_schedule();
 		if (all_tasks) {
 			dprintk("rpciod_killall: waiting for tasks to exit\n");
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			current->policy |= SCHED_YIELD;
+			schedule();
 		}
 	}
 
@@ -1187,8 +1187,8 @@
 	 * wait briefly before checking the process id.
 	 */
 	current->sigpending = 0;
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(1);
+	current->policy |= SCHED_YIELD;
+	schedule();
 	/*
 	 * Display a message if we're going to wait longer.
 	 */
diff -u --recursive --new-file v2.4.10/linux/net/sunrpc/xdr.c linux/net/sunrpc/xdr.c
--- v2.4.10/linux/net/sunrpc/xdr.c	Sun Sep 23 11:41:02 2001
+++ linux/net/sunrpc/xdr.c	Mon Oct  1 09:19:56 2001
@@ -95,7 +95,7 @@
 	if ((len = ntohl(*p++)) > maxlen)
 		return NULL;
 	*lenp = len;
-	*sp = p;
+	*sp = (char *) p;
 	return p + XDR_QUADLEN(len);
 }
 
diff -u --recursive --new-file v2.4.10/linux/net/sunrpc/xprt.c linux/net/sunrpc/xprt.c
--- v2.4.10/linux/net/sunrpc/xprt.c	Sun Sep 23 11:41:02 2001
+++ linux/net/sunrpc/xprt.c	Mon Oct  8 12:36:07 2001
@@ -1401,12 +1401,6 @@
 
 	dprintk("RPC: %4d release request %p\n", task->tk_pid, req);
 
-	/* remove slot from queue of pending */
-	if (task->tk_rpcwait) {
-		printk("RPC: task of released request still queued!\n");
-		rpc_remove_wait_queue(task);
-	}
-
 	spin_lock_bh(&xprt->xprt_lock);
 	req->rq_next = xprt->free;
 	xprt->free   = req;
diff -u --recursive --new-file v2.4.10/linux/net/wanrouter/af_wanpipe.c linux/net/wanrouter/af_wanpipe.c
--- v2.4.10/linux/net/wanrouter/af_wanpipe.c	Tue Jul  3 17:08:22 2001
+++ linux/net/wanrouter/af_wanpipe.c	Sun Sep 30 12:26:42 2001
@@ -2763,3 +2763,4 @@
 	return 0;
 }
 #endif
+MODULE_LICENSE("GPL");
diff -u --recursive --new-file v2.4.10/linux/scripts/kernel-doc linux/scripts/kernel-doc
--- v2.4.10/linux/scripts/kernel-doc	Tue Jul  3 17:08:22 2001
+++ linux/scripts/kernel-doc	Fri Oct  5 12:06:51 2001
@@ -31,6 +31,12 @@
 #		Return error code.
 # 		Keith Owens <kaos@ocs.com.au>
 
+# 23/09/2001 - Added support for typedefs, structs, enums and unions
+#              Support for Context section; can be terminated using empty line
+#              Small fixes (like spaces vs. \s in regex)
+# -- Tim Jansen <tim@tjansen.de>
+
+
 #
 # This will read a 'c' file and scan for embedded comments in the
 # style of gnome comments (+minor extensions - see below).
@@ -95,7 +101,48 @@
 #  */
 # etc.
 #
-# All descriptions can be multiline, apart from the short function description.
+# Beside functions you can also write documentation for structs, unions, 
+# enums and typedefs. Instead of the function name you must write the name 
+# of the declaration;  the struct/union/enum/typedef must always precede 
+# the name. Nesting of declarations is not supported. 
+# Use the argument mechanism to document members or constants. In 
+# structs and unions you must declare one member per declaration 
+# (comma-separated members are not allowed -  the parser does not support 
+# this).
+# e.g.
+# /**
+#  * struct my_struct - short description
+#  * @a: first member
+#  * @b: second member
+#  * 
+#  * Longer description
+#  */
+# struct my_struct {
+#     int a;
+#     int b;
+# };
+#
+# All descriptions can be multiline, except the short function description.
+# 
+# You can also add additional sections. When documenting kernel functions you 
+# should document the "Context:" of the function, e.g. whether the functions 
+# can be called form interrupts. Unlike other sections you can end it with an
+# empty line. 
+# Example-sections should contain the string EXAMPLE so that they are marked 
+# appropriately in DocBook.
+#
+# Example:
+# /**
+#  * user_function - function that can only be called in user context
+#  * @a: some argument
+#  * Context: !in_interrupt()
+#  * 
+#  * Some description
+#  * Example:
+#  *    user_function(22);
+#  */
+# ...
+#
 #
 # All descriptive text is further processed, scanning for the following special
 # patterns, which are highlighted appropriately.
@@ -115,7 +162,6 @@
 my $type_struct = '\&((struct\s*)?[_\w]+)';
 my $type_env = '(\$\w+)';
 
-
 # Output conversion substitutions.
 #  One for each output format
 
@@ -177,14 +223,18 @@
 my $blankline = $blankline_man;
 my $modulename = "Kernel API";
 my $function_only = 0;
+my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 
+		'July', 'August', 'September', 'October', 
+		'November', 'December')[(localtime)[4]] . 
+  " " . ((localtime)[5]+1900);
 
 # Essentially these are globals
 # They probably want to be tidied up made more localised or summat.
 # CAVEAT EMPTOR!  Some of the others I localised may not want to be which
 # could cause "use of undefined value" or other bugs.
-my ($function, %function_table,%parametertypes,$function_purpose);
-my ($type,$file,$function_name,$return_type);
-my ($newsection,$newcontents,$prototype,$filelist);
+my ($function, %function_table,%parametertypes,$declaration_purpose);
+my ($type,$file,$declaration_name,$return_type);
+my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
 
 my $lineprefix="";
 
@@ -193,28 +243,38 @@
 # 1 - looking for function name
 # 2 - scanning field start.
 # 3 - scanning prototype.
-my $state = 0;
+# 4 - documentation block
+my $state;
+
+#declaration types: can be
+# 'function', 'struct', 'union', 'enum', 'typedef'
+my $decl_type;
+
 my $doc_special = "\@\%\$\&";
 
-my $doc_start = "^/\\*\\*\$";
-my $doc_end = "\\*/";
-my $doc_com = "\\s*\\*\\s*";
-my $doc_func = $doc_com."(\\w+):?";
-my $doc_sect = $doc_com."([".$doc_special."]?[\\w ]+):(.*)";
-my $doc_content = $doc_com."(.*)";
-my $doc_block = $doc_com."DOC:\\s*(.*)?";
-
-my %constants = ();
-my %parameters = ();
-my @parameterlist = ();
-my %sections = ();
-my @sectionlist = ();
-my %source_map = ();
+my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
+my $doc_end = '\*/';
+my $doc_com = '\s*\*\s*';
+my $doc_decl = $doc_com.'(\w+)';
+my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)';
+my $doc_content = $doc_com.'(.*)';
+my $doc_block = $doc_com.'DOC:\s*(.*)?';
+
+my %constants;
+my %parameterdescs;
+my @parameterlist;
+my %sections;
+my @sectionlist;
 
 my $contents = "";
 my $section_default = "Description";	# default section
 my $section_intro = "Introduction";
 my $section = $section_default;
+my $section_context = "Context";
+
+my $undescribed = "-- undescribed --";
+
+reset_state();
 
 while ($ARGV[0] =~ m/^-(.*)/) {
     my $cmd = shift @ARGV;
@@ -280,7 +340,7 @@
     } elsif ($name =~ m/$type_param/) {
 #	print STDERR "parameter def '$1' = '$contents'\n";
 	$name = $1;
-	$parameters{$name} = $contents;
+	$parameterdescs{$name} = $contents;
     } else {
 #	print STDERR "other section '$name' = '$contents'\n";
 	$sections{$name} = $contents;
@@ -291,28 +351,28 @@
 ##
 # output function
 #
-# parameters, a hash.
+# parameterdescs, a hash.
 #  function => "function name"
 #  parameterlist => @list of parameters
-#  parameters => %parameter descriptions
+#  parameterdescs => %parameter descriptions
 #  sectionlist => @list of sections
 #  sections => %descriont descriptions
 #  
 
-sub output_highlight(@) {
+sub output_highlight {
     my $contents = join "\n",@_;
     my $line;
 
-#	DEBUG
-#	if (!defined $contents) {
-#	    use Carp;
-#	    confess "output_highlight got called with no args?\n";
-#    }
+#   DEBUG
+#   if (!defined $contents) {
+#	use Carp;
+#	confess "output_highlight got called with no args?\n";
+#   }
 
     eval $dohighlight;
     die $@ if $@;
     foreach $line (split "\n", $contents) {
-	if ($line eq ""){
+      if ($line eq ""){
 	    print $lineprefix, $blankline;
 	} else {
             $line =~ s/\\\\\\/\&/g;
@@ -322,9 +382,98 @@
     }
 }
 
+#output sections in html
+sub output_section_html(%) {
+    my %args = %{$_[0]};
+    my $section;
 
-# output in html
-sub output_html(%) {
+    foreach $section (@{$args{'sectionlist'}}) {
+	print "<h3>$section</h3>\n";
+	print "<blockquote>\n";
+	output_highlight($args{'sections'}{$section});
+	print "</blockquote>\n";
+    }  
+}
+
+# output enum in html
+sub output_enum_html(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+    my $count;
+    print "<h2>enum ".$args{'enum'}."</h2>\n";
+
+    print "<b>enum ".$args{'enum'}."</b> {<br>\n";
+    $count = 0;
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        print " <b>".$parameter."</b>";
+	if ($count != $#{$args{'parameterlist'}}) {
+	    $count++;
+	    print ",\n";
+	}
+	print "<br>";
+    }
+    print "};<br>\n";
+
+    print "<h3>Constants</h3>\n";
+    print "<dl>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	print "<dt><b>".$parameter."</b>\n";
+	print "<dd>";
+	output_highlight($args{'parameterdescs'}{$parameter});
+    }
+    print "</dl>\n";
+    output_section_html(@_);
+    print "<hr>\n";
+}
+
+# output tyepdef in html
+sub output_typedef_html(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+    my $count;
+    print "<h2>typedef ".$args{'typedef'}."</h2>\n";
+
+    print "<b>typedef ".$args{'typedef'}."</b>\n";
+    output_section_html(@_);
+    print "<hr>\n";
+}
+
+# output struct in html
+sub output_struct_html(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+
+    print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n";
+    print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+	$type = $args{'parametertypes'}{$parameter};
+	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+	    # pointer-to-function
+	    print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
+	} elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+	    print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
+	} else {
+	    print " <i>$type</i> <b>$parameter</b>;<br>\n";
+	}
+    }
+    print "};<br>\n";
+
+    print "<h3>Members</h3>\n";
+    print "<dl>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+	print "<dt><b>".$parameter."</b>\n";
+	print "<dd>";
+	output_highlight($args{'parameterdescs'}{$parameter});
+    }
+    print "</dl>\n";
+    output_section_html(@_);
+    print "<hr>\n";
+}
+
+# output function in html
+sub output_function_html(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
@@ -352,22 +501,17 @@
     print "<h3>Arguments</h3>\n";
     print "<dl>\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
 	print "<dt><b>".$parameter."</b>\n";
 	print "<dd>";
-	output_highlight($args{'parameters'}{$parameter});
+	output_highlight($args{'parameterdescs'}{$parameter});
     }
     print "</dl>\n";
-    foreach $section (@{$args{'sectionlist'}}) {
-	print "<h3>$section</h3>\n";
-	print "<blockquote>\n";
-	output_highlight($args{'sections'}{$section});
-	print "</blockquote>\n";
-    }
+    output_section_html(@_);
     print "<hr>\n";
 }
 
-
-# output in html
+# output intro in html
 sub output_intro_html(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
@@ -382,8 +526,26 @@
     print "<hr>\n";
 }
 
-# output in sgml DocBook
-sub output_sgml(%) {
+sub output_section_sgml(%) {
+    my %args = %{$_[0]};
+    my $section;    
+    # print out each section
+    $lineprefix="   ";
+    foreach $section (@{$args{'sectionlist'}}) {
+	print "<refsect1>\n <title>$section</title>\n <para>\n";
+	if ($section =~ m/EXAMPLE/i) {
+	    print "<example><para>\n";
+	}
+	output_highlight($args{'sections'}{$section});
+	if ($section =~ m/EXAMPLE/i) {
+	    print "</para></example>\n";
+	}
+	print " </para>\n</refsect1>\n";
+    }
+}
+
+# output function in sgml DocBook
+sub output_function_sgml(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
@@ -406,10 +568,9 @@
 
     print "<refsynopsisdiv>\n";
     print " <title>Synopsis</title>\n";
-    print "  <funcsynopsis>\n";
+    print "  <funcsynopsis><funcprototype>\n";
     print "   <funcdef>".$args{'functiontype'}." ";
-    print "<function>".$args{'function'}." ";
-    print "</function></funcdef>\n";
+    print "<function>".$args{'function'}." </function></funcdef>\n";
 
     $count = 0;
     if ($#{$args{'parameterlist'}} >= 0) {
@@ -427,7 +588,7 @@
     } else {
 	print "  <void>\n";
     }
-    print "  </funcsynopsis>\n";
+    print "  </funcprototype></funcsynopsis>\n";
     print "</refsynopsisdiv>\n";
 
     # print parameters
@@ -438,7 +599,7 @@
 	    print "  <varlistentry>\n   <term><parameter>$parameter</parameter></term>\n";
 	    print "   <listitem>\n    <para>\n";
 	    $lineprefix="     ";
-	    output_highlight($args{'parameters'}{$parameter});
+	    output_highlight($args{'parameterdescs'}{$parameter});
 	    print "    </para>\n   </listitem>\n  </varlistentry>\n";
 	}
 	print " </variablelist>\n";
@@ -447,19 +608,157 @@
     }
     print "</refsect1>\n";
 
-    # print out each section
-    $lineprefix="   ";
-    foreach $section (@{$args{'sectionlist'}}) {
-	print "<refsect1>\n <title>$section</title>\n <para>\n";
-	if ($section =~ m/EXAMPLE/i) {
-	    print "<example><para>\n";
-	}
-	output_highlight($args{'sections'}{$section});
-	if ($section =~ m/EXAMPLE/i) {
-	    print "</para></example>\n";
+    output_section_sgml(@_);
+    print "</refentry>\n\n";
+}
+
+# output struct in sgml DocBook
+sub output_struct_sgml(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+    my $id;
+
+    $id = "API-struct-".$args{'struct'};
+    $id =~ s/[^A-Za-z0-9]/-/g;
+
+    print "<refentry>\n";
+    print "<refmeta>\n";
+    print "<refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
+    print "</refmeta>\n";
+    print "<refnamediv>\n";
+    print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
+    print " <refpurpose>\n";
+    print "  ";
+    output_highlight ($args{'purpose'});
+    print " </refpurpose>\n";
+    print "</refnamediv>\n";
+
+    print "<refsynopsisdiv>\n";
+    print " <title>Synopsis</title>\n";
+    print "  <programlisting>\n";
+    print $args{'type'}." ".$args{'struct'}." {\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+	$type = $args{'parametertypes'}{$parameter};
+	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+	    # pointer-to-function
+	    print "  $1 $parameter ($2);\n";
+	} elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+	    print "  $1 $parameter$2;\n";
+	} else {
+	    print "  ".$type." ".$parameter.";\n";
 	}
-	print " </para>\n</refsect1>\n";
     }
+    print "};";
+    print "  </programlisting>\n";
+    print "</refsynopsisdiv>\n";
+
+    print " <refsect1>\n";
+    print "  <title>Members</title>\n";
+
+    print "  <variablelist>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+      ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+      print "    <varlistentry>";
+      print "      <term>$parameter</term>\n";
+      print "      <listitem><para>\n";
+      output_highlight($args{'parameterdescs'}{$parameter});
+      print "      </para></listitem>\n";
+      print "    </varlistentry>\n";
+    }
+    print "  </variablelist>\n";
+    print " </refsect1>\n";
+
+    output_section_sgml(@_);
+
+    print "</refentry>\n\n";
+}
+
+# output enum in sgml DocBook
+sub output_enum_sgml(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+    my $count;
+    my $id;
+
+    $id = "API-enum-".$args{'enum'};
+    $id =~ s/[^A-Za-z0-9]/-/g;
+
+    print "<refentry>\n";
+    print "<refmeta>\n";
+    print "<refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n";
+    print "</refmeta>\n";
+    print "<refnamediv>\n";
+    print " <refname>enum ".$args{'enum'}."</refname>\n";
+    print " <refpurpose>\n";
+    print "  ";
+    output_highlight ($args{'purpose'});
+    print " </refpurpose>\n";
+    print "</refnamediv>\n";
+
+    print "<refsynopsisdiv>\n";
+    print " <title>Synopsis</title>\n";
+    print "  <programlisting>\n";
+    print "enum ".$args{'enum'}." {\n";
+    $count = 0;
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        print "  $parameter";
+        if ($count != $#{$args{'parameterlist'}}) {
+	    $count++;
+	    print ",";
+        }
+	print "\n";
+    }
+    print "};";
+    print "  </programlisting>\n";
+    print "</refsynopsisdiv>\n";
+
+    print "<refsect1>\n";
+    print " <title>Constants</title>\n";    
+    print "  <variablelist>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+      print "    <varlistentry>";
+      print "      <term>$parameter</term>\n";
+      print "      <listitem><para>\n";
+      output_highlight($args{'parameterdescs'}{$parameter});
+      print "      </para></listitem>\n";
+      print "    </varlistentry>\n";
+    }
+    print "  </variablelist>\n";
+    print "</refsect1>\n";
+
+    output_section_sgml(@_);
+
+    print "</refentry>\n\n";
+}
+
+# output typedef in sgml DocBook
+sub output_typedef_sgml(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+    my $id;
+
+    $id = "API-typedef-".$args{'typedef'};
+    $id =~ s/[^A-Za-z0-9]/-/g;
+
+    print "<refentry>\n";
+    print "<refmeta>\n";
+    print "<refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n";
+    print "</refmeta>\n";
+    print "<refnamediv>\n";
+    print " <refname>typedef ".$args{'typedef'}."</refname>\n";
+    print " <refpurpose>\n";
+    print "  ";
+    output_highlight ($args{'purpose'});
+    print " </refpurpose>\n";
+    print "</refnamediv>\n";
+
+    print "<refsynopsisdiv>\n";
+    print " <title>Synopsis</title>\n";
+    print "  <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n";
+    print "</refsynopsisdiv>\n";
+
+    output_section_sgml(@_);
 
     print "</refentry>\n\n";
 }
@@ -491,7 +790,7 @@
 }
 
 # output in sgml DocBook
-sub output_gnome {
+sub output_function_gnome {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
@@ -535,7 +834,7 @@
 	    print "  <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
 	    print "   <entry>\n";
 	    $lineprefix="     ";
-	    output_highlight($args{'parameters'}{$parameter});
+	    output_highlight($args{'parameterdescs'}{$parameter});
 	    print "    </entry></row>\n";
 	}
 	print " </tbody></tgroup></informaltable>\n";
@@ -565,13 +864,13 @@
 }
 
 ##
-# output in man
-sub output_man(%) {
+# output function in man
+sub output_function_man(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
 
-    print ".TH \"$args{'module'}\" 9 \"$args{'function'}\" \"April 2001\" \"API Manual\" LINUX\n";
+    print ".TH \"$args{'module'}\" 9 \"$args{'function'}\" \"$man_date\" \"API Manual\" LINUX\n";
 
     print ".SH NAME\n";
     print $args{'function'}." \\- ".$args{'purpose'}."\n";
@@ -600,7 +899,7 @@
     print ".SH Arguments\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
 	print ".IP \"".$parameter."\" 12\n";
-	output_highlight($args{'parameters'}{$parameter});
+	output_highlight($args{'parameterdescs'}{$parameter});
     }
     foreach $section (@{$args{'sectionlist'}}) {
 	print ".SH \"$section\"\n";
@@ -608,12 +907,110 @@
     }
 }
 
+##
+# output enum in man
+sub output_enum_man(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+    my $count;
+
+    print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
+
+    print ".SH NAME\n";
+    print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n";
+
+    print ".SH SYNOPSIS\n";
+    print "enum ".$args{'enum'}." {\n";
+    $count = 0;
+    foreach my $parameter (@{$args{'parameterlist'}}) {
+        print ".br\n.BI \"    $parameter\"\n";
+	if ($count == $#{$args{'parameterlist'}}) {
+	    print "\n};\n";
+	    last;
+	}
+	else {
+	    print ", \n.br\n";
+	}
+	$count++;
+    }
+
+    print ".SH Constants\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	print ".IP \"".$parameter."\" 12\n";
+	output_highlight($args{'parameterdescs'}{$parameter});
+    }
+    foreach $section (@{$args{'sectionlist'}}) {
+	print ".SH \"$section\"\n";
+	output_highlight($args{'sections'}{$section});
+    }
+}
+
+##
+# output struct in man
+sub output_struct_man(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+
+    print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n";
+
+    print ".SH NAME\n";
+    print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n";
+
+    print ".SH SYNOPSIS\n";
+    print $args{'type'}." ".$args{'struct'}." {\n";
+
+    foreach my $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+	print "\n.br\n";
+	$type = $args{'parametertypes'}{$parameter};
+	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+	    # pointer-to-function
+	    print ".BI \"    ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n";
+	} elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+	    print ".BI \"    ".$1."\" ".$parameter.$2." \""."\"\n;\n";
+	} else {
+	    $type =~ s/([^\*])$/$1 /;
+	    print ".BI \"    ".$type."\" ".$parameter." \""."\"\n;\n";
+	}
+	print "\n.br\n";
+    }
+    print "};\n.br\n";
+
+    print ".SH Arguments\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+	print ".IP \"".$parameter."\" 12\n";
+	output_highlight($args{'parameterdescs'}{$parameter});
+    }
+    foreach $section (@{$args{'sectionlist'}}) {
+	print ".SH \"$section\"\n";
+	output_highlight($args{'sections'}{$section});
+    }
+}
+
+##
+# output typedef in man
+sub output_typedef_man(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+
+    print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
+
+    print ".SH NAME\n";
+    print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n";
+
+    foreach $section (@{$args{'sectionlist'}}) {
+	print ".SH \"$section\"\n";
+	output_highlight($args{'sections'}{$section});
+    }
+}
+
 sub output_intro_man(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
     my $count;
 
-    print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"April 2001\" \"API Manual\" LINUX\n";
+    print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
 
     foreach $section (@{$args{'sectionlist'}}) {
 	print ".SH \"$section\"\n";
@@ -623,7 +1020,7 @@
 
 ##
 # output in text
-sub output_text(%) {
+sub output_function_text(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
 
@@ -632,6 +1029,7 @@
     print $start;
     my $count = 0;
     foreach my $parameter (@{$args{'parameterlist'}}) {
+	$type = $args{'parametertypes'}{$parameter};
 	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 	    # pointer-to-function
 	    print $1.$parameter.") (".$2;
@@ -649,15 +1047,94 @@
 
     print "Arguments:\n\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
-	print $parameter."\n\t".$args{'parameters'}{$parameter}."\n";
+	print $parameter."\n\t".$args{'parameterdescs'}{$parameter}."\n";
     }
+    output_section_text(@_);
+}
+
+#output sections in text
+sub output_section_text(%) {
+    my %args = %{$_[0]};
+    my $section;
+
+    print "\n";
     foreach $section (@{$args{'sectionlist'}}) {
 	print "$section:\n\n";
 	output_highlight($args{'sections'}{$section});
-    }
+    }  
     print "\n\n";
 }
 
+# output enum in text
+sub output_enum_text(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+    my $count;
+    print "Enum:\n\n";
+
+    print "enum ".$args{'enum'}." {\n";
+    $count = 0;
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        print "\t$parameter";
+	if ($count != $#{$args{'parameterlist'}}) {
+	    $count++;
+	    print ",";
+	}
+	print "\n";
+    }
+    print "};\n\n";
+
+    print "Constants:\n\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	print "$parameter\n\t";
+	print $args{'parameterdescs'}{$parameter}."\n";
+    }
+
+    output_section_text(@_);
+}
+
+# output typedef in text
+sub output_typedef_text(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+    my $count;
+    print "Typedef:\n\n";
+
+    print "typedef ".$args{'typedef'}."\n";
+    output_section_text(@_);
+}
+
+# output struct as text
+sub output_struct_text(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+
+    print $args{'type'}." ".$args{'struct'}.":\n\n";
+    print $args{'type'}." ".$args{'struct'}." {\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+	$type = $args{'parametertypes'}{$parameter};
+	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+	    # pointer-to-function
+	    print "\t$1 $parameter) ($2);\n";
+	} elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+	    print "\t$1 $parameter$2;\n";
+	} else {
+	    print "\t".$type." ".$parameter.";\n";
+	}
+    }
+    print "};\n\n";
+
+    print "Members:\n\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
+	print "$parameter\n\t";
+	print $args{'parameterdescs'}{$parameter}."\n";
+    }
+    print "\n";
+    output_section_text(@_);
+}
+
 sub output_intro_text(%) {
     my %args = %{$_[0]};
     my ($parameter, $section);
@@ -670,12 +1147,18 @@
 }
 
 ##
-# generic output function - calls the right one based
-# on current output mode.
-sub output_function {
+# generic output function for typedefs
+sub output_declaration {
     no strict 'refs';
-    my $func = "output_".$output_mode;
-    &$func(@_);
+    my $name = shift;
+    my $functype = shift;
+    my $func = "output_${functype}_$output_mode";
+    if (($function_only==0) || 
+	( $function_only == 1 && defined($function_table{$name})) || 
+	( $function_only == 2 && !defined($function_table{$name})))
+    {
+        &$func(@_);
+    }
 }
 
 ##
@@ -687,6 +1170,179 @@
     &$func(@_);
 }
 
+##
+# takes a declaration (struct, union, enum, typedef) and 
+# invokes the right handler. NOT called for functions.
+sub dump_declaration($$) {
+    no strict 'refs';
+    my ($prototype, $file) = @_;
+    my $func = "dump_".$decl_type;
+    &$func(@_);
+}
+
+sub dump_union($$) {
+    dump_struct(@_);
+}
+
+sub dump_struct($$) {
+    my $x = shift;
+    my $file = shift;
+
+    if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
+        $declaration_name = $2;
+        my $members = $3;
+
+	# ignore embedded structs or unions
+	$members =~ s/{.*}//g;
+
+	create_parameterlist($members, ';');
+
+	output_declaration($declaration_name,
+			   'struct',
+			   {'struct' => $declaration_name,
+			    'module' => $modulename,
+			    'parameterlist' => \@parameterlist,
+			    'parameterdescs' => \%parameterdescs,
+			    'parametertypes' => \%parametertypes,
+			    'sectionlist' => \@sectionlist,
+			    'sections' => \%sections,
+			    'purpose' => $declaration_purpose,
+			    'type' => $decl_type
+			   });
+    }
+    else {
+        print STDERR "Cannot parse struct or union!\n";
+    }
+}
+
+sub dump_enum($$) {
+    my $x = shift;
+    my $file = shift;
+
+    if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
+        $declaration_name = $1;
+        my $members = $2;
+
+	foreach my $arg (split ',', $members) {
+	    $arg =~ s/^\s*(\w+).*/$1/;
+	    push @parameterlist, $arg;
+	    if (!$parameterdescs{$arg}) {
+	        $parameterdescs{$arg} = $undescribed;
+	        print STDERR "Warning($file:$.): Enum value '$arg' ".
+		    "described in enum '$declaration_name'\n";
+	    }
+
+	}
+	
+	output_declaration($declaration_name,
+			   'enum',
+			   {'enum' => $declaration_name,
+			    'module' => $modulename,
+			    'parameterlist' => \@parameterlist,
+			    'parameterdescs' => \%parameterdescs,
+			    'sectionlist' => \@sectionlist,
+			    'sections' => \%sections,
+			    'purpose' => $declaration_purpose
+			   });
+    }
+    else {
+        print STDERR "Cannot parse enum!\n";
+    }
+}
+
+sub dump_typedef($$) {
+    my $x = shift;
+    my $file = shift;
+
+    while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
+        $x =~ s/\(*.\)\s*;$/;/;
+	$x =~ s/\[*.\]\s*;$/;/;
+    }
+
+    if ($x =~ /typedef.*\s+(\w+)\s*;/) {
+        $declaration_name = $1;
+
+	output_declaration($declaration_name,
+			   'typedef',
+			   {'typedef' => $declaration_name,
+			    'module' => $modulename,
+			    'sectionlist' => \@sectionlist,
+			    'sections' => \%sections,
+			    'purpose' => $declaration_purpose
+			   });
+    }
+    else {
+        print STDERR "Cannot parse typedef!\n";
+    }
+}
+
+sub create_parameterlist($$) {
+    my $args = shift;
+    my $splitter = shift;
+    my $type;
+    my $param;
+
+    while ($args =~ /(\([^\),]+),/) {
+        $args =~ s/(\([^\),]+),/$1#/g;
+    }
+    
+    foreach my $arg (split($splitter, $args)) {
+        # strip leading/trailing spaces
+        $arg =~ s/^\s*//;
+	$arg =~ s/\s*$//;
+	$arg =~ s/\s+/ /;
+
+	if ($arg =~ m/\(/) {
+	    # pointer-to-function
+	    $arg =~ tr/#/,/;
+	    $arg =~ m/[^\(]+\(\*([^\)]+)\)/;
+	    $param = $1;
+	    $type = $arg;
+	    $type =~ s/([^\(]+\(\*)$param/$1/;
+	} else {
+	    # evil magic to get fixed array parameters to work
+	    $arg =~ s/(.+\s+)(.+)\[.*/$1* $2/;
+	    my @args = split('\s', $arg);
+	
+	    $param = pop @args;
+	    if ($param =~ m/^(\*+)(.*)/) {
+	        $param = $2;
+		push @args, $1;
+	    } 
+	    elsif ($param =~ m/(.*?)\s*:\s*(\d+)/) {
+	        $param = $1;
+	        push @args, ":$2";
+	    }
+	    $type = join " ", @args;
+	}
+
+	if ($type eq "" && $param eq "...")
+	{
+	    $type="...";
+	    $param="...";
+	    $parameterdescs{"..."} = "variable arguments";
+	}
+	elsif ($type eq "" && ($param eq "" or $param eq "void"))
+	{
+	    $type="";
+	    $param="void";
+	    $parameterdescs{void} = "no arguments";
+	}
+	if (defined $type && $type && !defined $parameterdescs{$param}) {
+	    $parameterdescs{$param} = $undescribed;
+
+	    if (($type eq 'function') || ($type eq 'enum')) {
+	        print STDERR "Warning($file:$.): Function parameter ".
+		    "or member '$param' not " .
+		    "described in '$declaration_name'\n";
+	    }
+	    ++$errors;
+        }
+
+	push @parameterlist, $param;
+	$parametertypes{$param} = $type;
+    }
+}
 
 ##
 # takes a function prototype and the name of the current file being
@@ -733,122 +1389,30 @@
 	$prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 	$prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
 	$return_type = $1;
-	$function_name = $2;
+	$declaration_name = $2;
 	my $args = $3;
-	my ($param);
-
-	# allow for up to six args to function pointers
-	$args =~ s/(\([^\),]+),/$1#/g;
-	$args =~ s/(\([^\),]+),/$1#/g;
-	$args =~ s/(\([^\),]+),/$1#/g;
-	$args =~ s/(\([^\),]+),/$1#/g;
-	$args =~ s/(\([^\),]+),/$1#/g;
-#	print STDERR "ARGS = '$args'\n";
-
-	foreach my $arg (split ',', $args) {
-	    # strip leading/trailing spaces
-	    $arg =~ s/^\s*//;
-	    $arg =~ s/\s*$//;
 
-	    if ($arg =~ m/\(/) {
-		# pointer-to-function
-		$arg =~ tr/#/,/;
-		$arg =~ m/[^\(]+\(\*([^\)]+)\)/;
-		$param = $1;
-		$type = $arg;
-		$type =~ s/([^\(]+\(\*)$param/$1/;
-	    } else {
-		# evil magic to get fixed array parameters to work
-		$arg =~ s/(.+\s+)(.+)\[.*/$1* $2/;
-#		print STDERR "SCAN ARG: '$arg'\n";
-		my @args = split('\s', $arg);
-
-#		print STDERR " -> @args\n";
-		$param = pop @args;
-#		print STDERR " -> @args\n";
-		if ($param =~ m/^(\*+)(.*)/) {
-		    $param = $2;
-		    push @args, $1;
-		}
-		$type = join " ", @args;
-	    }
-
-	    if ($type eq "" && $param eq "...")
-	    {
-		$type="...";
-		$param="...";
-		$parameters{"..."} = "variable arguments";
-	    }
-	    elsif ($type eq "" && ($param eq "" or $param eq "void"))
-	    {
-		$type="";
-		$param="void";
-		$parameters{void} = "no arguments";
-	    }
-            if (defined $type && $type && !defined $parameters{$param}) {
-	        $parameters{$param} = "-- undescribed --";
-	        print STDERR "Warning($file:$.): Function parameter '$param' not described in '$function_name'\n";
-		++$errors;
-	    }
-
-	    push @parameterlist, $param;
-	    $parametertypes{$param} = $type;
-#	    print STDERR "param = '$param', type = '$type'\n";
-	}
+	create_parameterlist($args, ',');
     } else {
 	print STDERR "Error($.): cannot understand prototype: '$prototype'\n";
 	++$errors;
 	return;
     }
 
-    if ($function_only==0 || 
-     ( $function_only == 1 && defined($function_table{$function_name})) || 
-     ( $function_only == 2 && !defined($function_table{$function_name})))
-    {
-	output_function({'function' => $function_name,
-			 'module' => $modulename,
-			 'functiontype' => $return_type,
-			 'parameterlist' => \@parameterlist,
-			 'parameters' => \%parameters,
-			 'parametertypes' => \%parametertypes,
-			 'sectionlist' => \@sectionlist,
-			 'sections' => \%sections,
-			 'purpose' => $function_purpose
-			 });
-    }
+    output_declaration($declaration_name, 
+		       'function',
+		       {'function' => $declaration_name,
+			'module' => $modulename,
+			'functiontype' => $return_type,
+			'parameterlist' => \@parameterlist,
+			'parameterdescs' => \%parameterdescs,
+			'parametertypes' => \%parametertypes,
+			'sectionlist' => \@sectionlist,
+			'sections' => \%sections,
+			'purpose' => $declaration_purpose
+		       });
 }
 
-######################################################################
-# main
-# states
-# 0 - normal code
-# 1 - looking for function name
-# 2 - scanning field start.
-# 3 - scanning prototype.
-$state = 0;
-$section = "";
-
-$doc_special = "\@\%\$\&";
-
-$doc_start = "^/\\*\\*\\s*\$"; # Allow whitespace at end of comment start.
-$doc_end = "\\*/";
-$doc_com = "\\s*\\*\\s*";
-$doc_func = $doc_com."(\\w+):?";
-$doc_sect = $doc_com."([".$doc_special."]?[\\w ]+):(.*)";
-$doc_content = $doc_com."(.*)";
-$doc_block = $doc_com."DOC:\\s*(.*)?";
-
-%constants = ();
-%parameters = ();
-@parameterlist = ();
-%sections = ();
-@sectionlist = ();
-
-$contents = "";
-$section_default = "Description";	# default section
-$section_intro = "Introduction";
-$section = $section_default;
-
 sub process_file($);
 
 # Read the file that maps relative names to absolute names for
@@ -879,8 +1443,68 @@
 
 exit($errors);
 
+sub reset_state {
+    $function = "";
+    %constants = ();
+    %parameterdescs = ();
+    %parametertypes = ();
+    @parameterlist = ();
+    %sections = ();
+    @sectionlist = ();
+    $prototype = "";
+    
+    $state = 0;
+}
+
+sub process_state3_function($) { 
+    my $x = shift;
+
+    if ($x =~ m#\s*/\*\s+MACDOC\s*#io) {
+	# do nothing
+    }
+    elsif ($x =~ /([^\{]*)/) {
+        $prototype .= $1;
+    }
+    if (($x =~ /\{/) || ($x =~ /\#/) || ($x =~ /;/)) {
+        $prototype =~ s@/\*.*?\*/@@gos;	# strip comments.
+	$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
+	$prototype =~ s@^\s+@@gos; # strip leading spaces
+	dump_function($prototype,$file);
+	reset_state();
+    }
+}
+
+sub process_state3_type($) { 
+    my $x = shift;
+
+    $x =~ s@/\*.*?\*/@@gos;	# strip comments.
+    $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
+    $x =~ s@^\s+@@gos; # strip leading spaces
+    $x =~ s@\s+$@@gos; # strip trailing spaces
+
+    while (1) {
+        if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
+	    $prototype .= $1 . $2;
+	    ($2 eq '{') && $brcount++;
+	    ($2 eq '}') && $brcount--;
+	    if (($2 eq ';') && ($brcount == 0)) {
+	        dump_declaration($prototype,$file);
+		reset_state();
+	        last;
+	    }
+	    $x = $3;
+        } else {
+	    $prototype .= $x;
+	    last;
+	}
+    }
+}
+
 sub process_file($) {
     my ($file) = @_;
+    my $identifier;
+    my $func;
+
     if (defined($source_map{$file})) {
 	$file = $source_map{$file};
     }
@@ -906,16 +1530,32 @@
 			$section = $1;
 		}
             }
-	    elsif (/$doc_func/o) {
-		$function = $1;
+	    elsif (/$doc_decl/o) {
+		$identifier = $1;
+		if (/\s*([\w\s]+?)\s*-/) {
+		    $identifier = $1;
+		}
+
 		$state = 2;
 		if (/-(.*)/) {
-		    $function_purpose = $1;
+		    $declaration_purpose = $1;
+		} else {
+		    $declaration_purpose = "";
+		}
+		if ($identifier =~ m/^struct/) {
+		    $decl_type = 'struct';
+		} elsif ($identifier =~ m/^union/) {
+		    $decl_type = 'union';
+		} elsif ($identifier =~ m/^enum/) {
+		    $decl_type = 'enum';
+		} elsif ($identifier =~ m/^typedef/) {
+		    $decl_type = 'typedef';
 		} else {
-		    $function_purpose = "";
+		    $decl_type = 'function';
 		}
+
 		if ($verbose) {
-		    print STDERR "Info($.): Scanning doc for $function\n";
+		    print STDERR "Info($.): Scanning doc for $identifier\n";
 		}
 	    } else {
 		print STDERR "WARN($.): Cannot understand $_ on line $.",
@@ -952,13 +1592,15 @@
 		    $contents = "";
 		}
 
-#	    print STDERR "end of doc comment, looking for prototype\n";
 		$prototype = "";
 		$state = 3;
+		$brcount = 0;
+#	    print STDERR "end of doc comment, looking for prototype\n";
 	    } elsif (/$doc_content/) {
 		# miguel-style comment kludge, look for blank lines after
 		# @parameter line to signify start of description
-		if ($1 eq "" && $section =~ m/^@/) {
+		if ($1 eq "" && 
+			($section =~ m/^@/ || $section eq $section_context)) {
 		    $contents =~ s/\&/\\\\\\amp;/g;
 		    $contents =~ s/\</\\\\\\lt;/g;
 		    $contents =~ s/\>/\\\\\\gt;/g;
@@ -974,28 +1616,10 @@
 		++$errors;
 	    }
 	} elsif ($state == 3) {	# scanning for function { (end of prototype)
-	    if (m#\s*/\*\s+MACDOC\s*#io) {
-	      # do nothing
-	    }
-	    elsif (/([^\{]*)/) {
-		$prototype .= $1;
-	    }
-	    if (/\{/ || /\#/ || /;/) { # added for #define AK, ';' added for declarations.
-		$prototype =~ s@/\*.*?\*/@@gos;	# strip comments.
-		$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
-		$prototype =~ s@^ +@@gos; # strip leading spaces
-		dump_function($prototype,$file);
-
-		$function = "";
-		%constants = ();
-		%parameters = ();
-		%parametertypes = ();
-		@parameterlist = ();
-		%sections = ();
-		@sectionlist = ();
-		$prototype = "";
-
-		$state = 0;
+	    if ($decl_type eq 'function') {
+	        process_state3_function($_);
+	    } else {
+	        process_state3_type($_);
 	    }
 	} elsif ($state == 4) {
 		# Documentation block
@@ -1006,7 +1630,7 @@
 			$contents = "";
 			$function = "";
 			%constants = ();
-			%parameters = ();
+			%parameterdescs = ();
 			%parametertypes = ();
 			@parameterlist = ();
 			%sections = ();
@@ -1026,7 +1650,7 @@
 			$contents = "";
 			$function = "";
 			%constants = ();
-			%parameters = ();
+			%parameterdescs = ();
 			%parametertypes = ();
 			@parameterlist = ();
 			%sections = ();
diff -u --recursive --new-file v2.4.10/linux/scripts/split-include.c linux/scripts/split-include.c
--- v2.4.10/linux/scripts/split-include.c	Mon Jan  5 01:41:01 1998
+++ linux/scripts/split-include.c	Mon Oct  8 11:46:09 2001
@@ -188,7 +188,7 @@
      * So by having an initial \n, strstr will find exact matches.
      */
 
-    fp_find = popen("find * -type f -print", "r");
+    fp_find = popen("find * -type f -name \"*.h\" -print", "r");
     if (fp_find == 0)
 	ERROR_EXIT( "find" );
 
