## Automatically generated incremental diff
## From:   linux-2.4.11-pre1
## To:     linux-2.4.11-pre2
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.4.11-pre1/CREDITS linux/CREDITS
--- linux-2.4.11-pre1/CREDITS	Sun Sep  9 10:43:02 2001
+++ linux/CREDITS	Mon Dec  3 23:14:07 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
diff -urN linux-2.4.11-pre1/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.4.11-pre1/Documentation/Configure.help	Sun Sep 23 09:52:38 2001
+++ linux/Documentation/Configure.help	Mon Dec  3 23:14:07 2001
@@ -120,17 +120,30 @@
   
   If you don't know what to do here, say N.
   
-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 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 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 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
diff -urN linux-2.4.11-pre1/Documentation/DocBook/mousedrivers.tmpl linux/Documentation/DocBook/mousedrivers.tmpl
--- linux-2.4.11-pre1/Documentation/DocBook/mousedrivers.tmpl	Thu Jan  4 12:50:12 2001
+++ linux/Documentation/DocBook/mousedrivers.tmpl	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/Documentation/fb/matroxfb.txt linux/Documentation/fb/matroxfb.txt
--- linux-2.4.11-pre1/Documentation/fb/matroxfb.txt	Mon Jul  2 13:56:40 2001
+++ linux/Documentation/fb/matroxfb.txt	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/Documentation/filesystems/fat_cvf.txt linux/Documentation/filesystems/fat_cvf.txt
--- linux-2.4.11-pre1/Documentation/filesystems/fat_cvf.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/filesystems/fat_cvf.txt	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/Documentation/oops-tracing.txt linux/Documentation/oops-tracing.txt
--- linux-2.4.11-pre1/Documentation/oops-tracing.txt	Tue Oct  3 09:24:41 2000
+++ linux/Documentation/oops-tracing.txt	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/Documentation/sysctl/kernel.txt linux/Documentation/sysctl/kernel.txt
--- linux-2.4.11-pre1/Documentation/sysctl/kernel.txt	Mon Jan 10 18:15:58 2000
+++ linux/Documentation/sysctl/kernel.txt	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/MAINTAINERS linux/MAINTAINERS
--- linux-2.4.11-pre1/MAINTAINERS	Sun Sep 23 09:49:00 2001
+++ linux/MAINTAINERS	Mon Dec  3 23:14:07 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
diff -urN linux-2.4.11-pre1/Makefile linux/Makefile
--- linux-2.4.11-pre1/Makefile	Mon Dec  3 23:13:56 2001
+++ linux/Makefile	Mon Dec  3 23:14:07 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 11
-EXTRAVERSION =-pre1
+EXTRAVERSION =-pre2
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.11-pre1/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- linux-2.4.11-pre1/arch/alpha/kernel/process.c	Mon Sep 17 15:29:09 2001
+++ linux/arch/alpha/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- linux-2.4.11-pre1/arch/alpha/kernel/traps.c	Mon Sep 17 13:16:30 2001
+++ linux/arch/alpha/kernel/traps.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- linux-2.4.11-pre1/arch/arm/kernel/process.c	Fri Sep  7 09:28:38 2001
+++ linux/arch/arm/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
--- linux-2.4.11-pre1/arch/cris/kernel/traps.c	Thu Jul 26 15:10:06 2001
+++ linux/arch/cris/kernel/traps.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/i386/config.in linux/arch/i386/config.in
--- linux-2.4.11-pre1/arch/i386/config.in	Mon Sep 17 22:52:35 2001
+++ linux/arch/i386/config.in	Mon Dec  3 23:14:07 2001
@@ -170,10 +170,13 @@
 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
 fi
 
diff -urN linux-2.4.11-pre1/arch/i386/defconfig linux/arch/i386/defconfig
--- linux-2.4.11-pre1/arch/i386/defconfig	Tue Sep 18 11:15:11 2001
+++ linux/arch/i386/defconfig	Mon Dec  3 23:14:07 2001
@@ -311,7 +311,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
@@ -753,6 +752,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 -urN linux-2.4.11-pre1/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- linux-2.4.11-pre1/arch/i386/kernel/apm.c	Mon Sep 17 22:52:35 2001
+++ linux/arch/i386/kernel/apm.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- linux-2.4.11-pre1/arch/i386/kernel/process.c	Mon Sep 17 22:52:35 2001
+++ linux/arch/i386/kernel/process.c	Mon Dec  3 23:14:07 2001
@@ -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 -urN linux-2.4.11-pre1/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- linux-2.4.11-pre1/arch/i386/kernel/traps.c	Tue Sep 18 13:39:51 2001
+++ linux/arch/i386/kernel/traps.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
--- linux-2.4.11-pre1/arch/ia64/kernel/process.c	Tue Jul 31 10:30:08 2001
+++ linux/arch/ia64/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- linux-2.4.11-pre1/arch/m68k/kernel/process.c	Mon Sep 17 15:29:09 2001
+++ linux/arch/m68k/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/mips/mm/mips32.c linux/arch/mips/mm/mips32.c
--- linux-2.4.11-pre1/arch/mips/mm/mips32.c	Sun Sep  9 10:43:02 2001
+++ linux/arch/mips/mm/mips32.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
--- linux-2.4.11-pre1/arch/mips/mm/r2300.c	Sun Sep  9 10:43:02 2001
+++ linux/arch/mips/mm/r2300.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c
--- linux-2.4.11-pre1/arch/mips/mm/r4xx0.c	Sun Sep  9 10:43:02 2001
+++ linux/arch/mips/mm/r4xx0.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/mips/mm/r5432.c linux/arch/mips/mm/r5432.c
--- linux-2.4.11-pre1/arch/mips/mm/r5432.c	Sun Sep  9 10:43:02 2001
+++ linux/arch/mips/mm/r5432.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/mips/mm/rm7k.c linux/arch/mips/mm/rm7k.c
--- linux-2.4.11-pre1/arch/mips/mm/rm7k.c	Wed Jul  4 11:50:39 2001
+++ linux/arch/mips/mm/rm7k.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/mips64/mm/andes.c linux/arch/mips64/mm/andes.c
--- linux-2.4.11-pre1/arch/mips64/mm/andes.c	Sun Sep  9 10:43:02 2001
+++ linux/arch/mips64/mm/andes.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/mips64/mm/r4xx0.c linux/arch/mips64/mm/r4xx0.c
--- linux-2.4.11-pre1/arch/mips64/mm/r4xx0.c	Sun Sep  9 10:43:02 2001
+++ linux/arch/mips64/mm/r4xx0.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/parisc/kernel/traps.c linux/arch/parisc/kernel/traps.c
--- linux-2.4.11-pre1/arch/parisc/kernel/traps.c	Wed Dec  6 11:46:39 2000
+++ linux/arch/parisc/kernel/traps.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/parisc/mm/pa11.c linux/arch/parisc/mm/pa11.c
--- linux-2.4.11-pre1/arch/parisc/mm/pa11.c	Tue Dec  5 12:29:39 2000
+++ linux/arch/parisc/mm/pa11.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/parisc/mm/pa20.c linux/arch/parisc/mm/pa20.c
--- linux-2.4.11-pre1/arch/parisc/mm/pa20.c	Tue Dec  5 12:29:39 2000
+++ linux/arch/parisc/mm/pa20.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- linux-2.4.11-pre1/arch/ppc/kernel/process.c	Mon Sep 17 15:29:09 2001
+++ linux/arch/ppc/kernel/process.c	Mon Dec  3 23:14:07 2001
@@ -243,8 +243,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 -urN linux-2.4.11-pre1/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- linux-2.4.11-pre1/arch/ppc/kernel/traps.c	Tue Aug 28 06:58:33 2001
+++ linux/arch/ppc/kernel/traps.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
--- linux-2.4.11-pre1/arch/s390/kernel/process.c	Sun Aug 12 10:38:47 2001
+++ linux/arch/s390/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/s390x/kernel/process.c linux/arch/s390x/kernel/process.c
--- linux-2.4.11-pre1/arch/s390x/kernel/process.c	Sun Aug 12 10:38:48 2001
+++ linux/arch/s390x/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
--- linux-2.4.11-pre1/arch/sh/kernel/process.c	Sat Sep  8 12:29:09 2001
+++ linux/arch/sh/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- linux-2.4.11-pre1/arch/sparc/kernel/process.c	Sun Feb 18 19:49:44 2001
+++ linux/arch/sparc/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c
--- linux-2.4.11-pre1/arch/sparc/mm/init.c	Thu Sep 20 20:02:03 2001
+++ linux/arch/sparc/mm/init.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- linux-2.4.11-pre1/arch/sparc64/defconfig	Thu Sep 20 14:11:57 2001
+++ linux/arch/sparc64/defconfig	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/dtlb_backend.S linux/arch/sparc64/kernel/dtlb_backend.S
--- linux-2.4.11-pre1/arch/sparc64/kernel/dtlb_backend.S	Thu Sep 20 14:11:57 2001
+++ linux/arch/sparc64/kernel/dtlb_backend.S	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
--- linux-2.4.11-pre1/arch/sparc64/kernel/process.c	Thu Sep 20 14:11:57 2001
+++ linux/arch/sparc64/kernel/process.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
--- linux-2.4.11-pre1/arch/sparc64/kernel/ptrace.c	Tue Sep 18 16:58:03 2001
+++ linux/arch/sparc64/kernel/ptrace.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- linux-2.4.11-pre1/arch/sparc64/kernel/setup.c	Thu Sep 20 14:11:57 2001
+++ linux/arch/sparc64/kernel/setup.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- linux-2.4.11-pre1/arch/sparc64/kernel/sparc64_ksyms.c	Fri Sep  7 11:01:20 2001
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- linux-2.4.11-pre1/arch/sparc64/kernel/sys_sparc32.c	Tue Aug 14 19:57:28 2001
+++ linux/arch/sparc64/kernel/sys_sparc32.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/traps.c linux/arch/sparc64/kernel/traps.c
--- linux-2.4.11-pre1/arch/sparc64/kernel/traps.c	Thu Sep 20 14:11:57 2001
+++ linux/arch/sparc64/kernel/traps.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/kernel/ttable.S linux/arch/sparc64/kernel/ttable.S
--- linux-2.4.11-pre1/arch/sparc64/kernel/ttable.S	Tue Aug 14 19:57:28 2001
+++ linux/arch/sparc64/kernel/ttable.S	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/lib/VIScopy.S linux/arch/sparc64/lib/VIScopy.S
--- linux-2.4.11-pre1/arch/sparc64/lib/VIScopy.S	Thu Nov  9 15:57:41 2000
+++ linux/arch/sparc64/lib/VIScopy.S	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/lib/blockops.S linux/arch/sparc64/lib/blockops.S
--- linux-2.4.11-pre1/arch/sparc64/lib/blockops.S	Thu Sep 20 14:11:57 2001
+++ linux/arch/sparc64/lib/blockops.S	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- linux-2.4.11-pre1/arch/sparc64/mm/init.c	Thu Sep 20 20:02:03 2001
+++ linux/arch/sparc64/mm/init.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/mm/ultra.S linux/arch/sparc64/mm/ultra.S
--- linux-2.4.11-pre1/arch/sparc64/mm/ultra.S	Thu Sep 20 14:11:57 2001
+++ linux/arch/sparc64/mm/ultra.S	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/arch/sparc64/prom/misc.c linux/arch/sparc64/prom/misc.c
--- linux-2.4.11-pre1/arch/sparc64/prom/misc.c	Wed Jul  5 22:15:25 2000
+++ linux/arch/sparc64/prom/misc.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/block/genhd.c linux/drivers/block/genhd.c
--- linux-2.4.11-pre1/drivers/block/genhd.c	Sun Sep  9 12:00:55 2001
+++ linux/drivers/block/genhd.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/3780i.c linux/drivers/char/mwave/3780i.c
--- linux-2.4.11-pre1/drivers/char/mwave/3780i.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/3780i.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/3780i.h linux/drivers/char/mwave/3780i.h
--- linux-2.4.11-pre1/drivers/char/mwave/3780i.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/3780i.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/Makefile linux/drivers/char/mwave/Makefile
--- linux-2.4.11-pre1/drivers/char/mwave/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/Makefile	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/README linux/drivers/char/mwave/README
--- linux-2.4.11-pre1/drivers/char/mwave/README	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/README	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/mwavedd.c linux/drivers/char/mwave/mwavedd.c
--- linux-2.4.11-pre1/drivers/char/mwave/mwavedd.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/mwavedd.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/mwavedd.h linux/drivers/char/mwave/mwavedd.h
--- linux-2.4.11-pre1/drivers/char/mwave/mwavedd.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/mwavedd.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/mwavepub.h linux/drivers/char/mwave/mwavepub.h
--- linux-2.4.11-pre1/drivers/char/mwave/mwavepub.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/mwavepub.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/smapi.c linux/drivers/char/mwave/smapi.c
--- linux-2.4.11-pre1/drivers/char/mwave/smapi.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/smapi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/smapi.h linux/drivers/char/mwave/smapi.h
--- linux-2.4.11-pre1/drivers/char/mwave/smapi.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/smapi.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/tp3780i.c linux/drivers/char/mwave/tp3780i.c
--- linux-2.4.11-pre1/drivers/char/mwave/tp3780i.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/tp3780i.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/mwave/tp3780i.h linux/drivers/char/mwave/tp3780i.h
--- linux-2.4.11-pre1/drivers/char/mwave/tp3780i.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/mwave/tp3780i.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/char/softdog.c linux/drivers/char/softdog.c
--- linux-2.4.11-pre1/drivers/char/softdog.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/char/softdog.c	Mon Dec  3 23:14:07 2001
@@ -46,6 +46,7 @@
 static int soft_margin = TIMER_MARGIN;	/* in seconds */
 
 MODULE_PARM(soft_margin,"i");
+MODULE_LICENSE("GPL");
 
 /*
  *	Our timer
diff -urN linux-2.4.11-pre1/drivers/char/sysrq.c linux/drivers/char/sysrq.c
--- linux-2.4.11-pre1/drivers/char/sysrq.c	Thu Sep 20 14:12:28 2001
+++ linux/drivers/char/sysrq.c	Mon Dec  3 23:14:07 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,18 +225,18 @@
 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,
 		struct kbd_struct *kbd, struct tty_struct *tty) {
 	emergency_sync_scheduled = EMERG_REMOUNT;
-	wakeup_bdflush();
+	wakeup_bdflush(0);
 }
 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/0",
 };
 
 /* 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-adap-ite.c linux/drivers/i2c/i2c-adap-ite.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-adap-ite.c	Sun Sep  9 10:43:02 2001
+++ linux/drivers/i2c/i2c-adap-ite.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-algo-bit.c linux/drivers/i2c/i2c-algo-bit.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-algo-bit.c	Tue Mar  6 19:44:34 2001
+++ linux/drivers/i2c/i2c-algo-bit.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-algo-ite.c linux/drivers/i2c/i2c-algo-ite.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-algo-ite.c	Sun Sep  9 10:43:02 2001
+++ linux/drivers/i2c/i2c-algo-ite.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-algo-pcf.c linux/drivers/i2c/i2c-algo-pcf.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-algo-pcf.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2c/i2c-algo-pcf.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-core.c linux/drivers/i2c/i2c-core.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-core.c	Fri Feb  9 11:40:02 2001
+++ linux/drivers/i2c/i2c-core.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-dev.c linux/drivers/i2c/i2c-dev.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-dev.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/i2c/i2c-dev.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-elektor.c linux/drivers/i2c/i2c-elektor.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-elektor.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2c/i2c-elektor.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-elv.c linux/drivers/i2c/i2c-elv.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-elv.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2c/i2c-elv.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-philips-par.c linux/drivers/i2c/i2c-philips-par.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-philips-par.c	Tue Jul 25 18:10:42 2000
+++ linux/drivers/i2c/i2c-philips-par.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/i2c/i2c-velleman.c linux/drivers/i2c/i2c-velleman.c
--- linux-2.4.11-pre1/drivers/i2c/i2c-velleman.c	Wed Feb  9 18:48:03 2000
+++ linux/drivers/i2c/i2c-velleman.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/ide/ataraid.c linux/drivers/ide/ataraid.c
--- linux-2.4.11-pre1/drivers/ide/ataraid.c	Mon Sep 17 23:23:40 2001
+++ linux/drivers/ide/ataraid.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/ide/ataraid.h linux/drivers/ide/ataraid.h
--- linux-2.4.11-pre1/drivers/ide/ataraid.h	Mon Sep 17 23:23:40 2001
+++ linux/drivers/ide/ataraid.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/ide/hptraid.c linux/drivers/ide/hptraid.c
--- linux-2.4.11-pre1/drivers/ide/hptraid.c	Sun Sep 23 00:14:31 2001
+++ linux/drivers/ide/hptraid.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c
--- linux-2.4.11-pre1/drivers/ide/ide-cs.c	Fri Feb  9 11:40:02 2001
+++ linux/drivers/ide/ide-cs.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.4.11-pre1/drivers/ide/ide-pci.c	Sun Sep  9 10:43:02 2001
+++ linux/drivers/ide/ide-pci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/ide/pdcraid.c linux/drivers/ide/pdcraid.c
--- linux-2.4.11-pre1/drivers/ide/pdcraid.c	Sun Sep 23 00:14:54 2001
+++ linux/drivers/ide/pdcraid.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/ieee1394/ieee1394_syms.c linux/drivers/ieee1394/ieee1394_syms.c
--- linux-2.4.11-pre1/drivers/ieee1394/ieee1394_syms.c	Sun Aug 12 12:39:02 2001
+++ linux/drivers/ieee1394/ieee1394_syms.c	Mon Dec  3 23:14:07 2001
@@ -79,3 +79,4 @@
 EXPORT_SYMBOL(hpsb_nodeid_get_entry);
 EXPORT_SYMBOL(hpsb_get_host_by_ne);
 EXPORT_SYMBOL(hpsb_guid_fill_packet);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/ieee1394/ohci1394.c linux/drivers/ieee1394/ohci1394.c
--- linux-2.4.11-pre1/drivers/ieee1394/ohci1394.c	Thu Aug 16 09:49:49 2001
+++ linux/drivers/ieee1394/ohci1394.c	Mon Dec  3 23:14:07 2001
@@ -2402,6 +2402,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 -urN linux-2.4.11-pre1/drivers/ieee1394/pcilynx.c linux/drivers/ieee1394/pcilynx.c
--- linux-2.4.11-pre1/drivers/ieee1394/pcilynx.c	Sun Aug 12 12:39:02 2001
+++ linux/drivers/ieee1394/pcilynx.c	Mon Dec  3 23:14:07 2001
@@ -1627,6 +1627,7 @@
 
 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);
 
diff -urN linux-2.4.11-pre1/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c
--- linux-2.4.11-pre1/drivers/ieee1394/raw1394.c	Sun Aug 12 12:41:36 2001
+++ linux/drivers/ieee1394/raw1394.c	Mon Dec  3 23:14:07 2001
@@ -1031,3 +1031,4 @@
 
 module_init(init_raw1394);
 module_exit(cleanup_raw1394);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/ieee1394/video1394.c linux/drivers/ieee1394/video1394.c
--- linux-2.4.11-pre1/drivers/ieee1394/video1394.c	Thu Sep 13 15:21:32 2001
+++ linux/drivers/ieee1394/video1394.c	Mon Dec  3 23:14:07 2001
@@ -1639,6 +1639,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 -urN linux-2.4.11-pre1/drivers/input/evdev.c linux/drivers/input/evdev.c
--- linux-2.4.11-pre1/drivers/input/evdev.c	Wed Sep 12 15:34:06 2001
+++ linux/drivers/input/evdev.c	Mon Dec  3 23:14:07 2001
@@ -398,3 +398,5 @@
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Event character device driver");
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/drivers/input/input.c linux/drivers/input/input.c
--- linux-2.4.11-pre1/drivers/input/input.c	Wed Sep 12 15:34:06 2001
+++ linux/drivers/input/input.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/input/joydev.c linux/drivers/input/joydev.c
--- linux-2.4.11-pre1/drivers/input/joydev.c	Wed Apr 11 19:02:30 2001
+++ linux/drivers/input/joydev.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/input/mousedev.c linux/drivers/input/mousedev.c
--- linux-2.4.11-pre1/drivers/input/mousedev.c	Wed Sep 12 15:34:06 2001
+++ linux/drivers/input/mousedev.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/act2000/act2000.h linux/drivers/isdn/act2000/act2000.h
--- linux-2.4.11-pre1/drivers/isdn/act2000/act2000.h	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/act2000/act2000.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/act2000/act2000_isa.c linux/drivers/isdn/act2000/act2000_isa.c
--- linux-2.4.11-pre1/drivers/isdn/act2000/act2000_isa.c	Sun Sep  9 10:43:02 2001
+++ linux/drivers/isdn/act2000/act2000_isa.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/act2000/act2000_isa.h linux/drivers/isdn/act2000/act2000_isa.h
--- linux-2.4.11-pre1/drivers/isdn/act2000/act2000_isa.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/act2000/act2000_isa.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/act2000/capi.c linux/drivers/isdn/act2000/capi.c
--- linux-2.4.11-pre1/drivers/isdn/act2000/capi.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/act2000/capi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/act2000/capi.h linux/drivers/isdn/act2000/capi.h
--- linux-2.4.11-pre1/drivers/isdn/act2000/capi.h	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/act2000/capi.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/act2000/module.c linux/drivers/isdn/act2000/module.c
--- linux-2.4.11-pre1/drivers/isdn/act2000/module.c	Mon Aug 13 16:35:29 2001
+++ linux/drivers/isdn/act2000/module.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/avm_cs.c linux/drivers/isdn/avmb1/avm_cs.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/avm_cs.c	Fri Mar  2 11:12:07 2001
+++ linux/drivers/isdn/avmb1/avm_cs.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/avmcard.h linux/drivers/isdn/avmb1/avmcard.h
--- linux-2.4.11-pre1/drivers/isdn/avmb1/avmcard.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/avmcard.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/b1.c	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/b1.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/b1dma.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/avmb1/b1dma.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/b1isa.c	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/b1isa.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/b1pci.c	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/b1pci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/b1pcmcia.c	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/b1pcmcia.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/c4.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/isdn/avmb1/c4.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capi.c	Mon Aug 13 16:35:28 2001
+++ linux/drivers/isdn/avmb1/capi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capicmd.h linux/drivers/isdn/avmb1/capicmd.h
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capicmd.h	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/capicmd.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capidev.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capidev.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capidrv.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capidrv.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capidrv.h linux/drivers/isdn/avmb1/capidrv.h
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capidrv.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capidrv.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capifs.c linux/drivers/isdn/avmb1/capifs.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capifs.c	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/capifs.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capifs.h linux/drivers/isdn/avmb1/capifs.h
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capifs.h	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/capifs.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capilli.h linux/drivers/isdn/avmb1/capilli.h
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capilli.h	Thu Aug 12 09:42:33 1999
+++ linux/drivers/isdn/avmb1/capilli.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capiutil.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/avmb1/capiutil.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/capiutil.h linux/drivers/isdn/avmb1/capiutil.h
--- linux-2.4.11-pre1/drivers/isdn/avmb1/capiutil.h	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/capiutil.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/kcapi.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/isdn/avmb1/kcapi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/t1isa.c	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/t1isa.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c
--- linux-2.4.11-pre1/drivers/isdn/avmb1/t1pci.c	Tue Jun 12 13:03:18 2001
+++ linux/drivers/isdn/avmb1/t1pci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/divert/divert_init.c linux/drivers/isdn/divert/divert_init.c
--- linux-2.4.11-pre1/drivers/isdn/divert/divert_init.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/divert/divert_init.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c
--- linux-2.4.11-pre1/drivers/isdn/divert/divert_procfs.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/divert/divert_procfs.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/divert/isdn_divert.c linux/drivers/isdn/divert/isdn_divert.c
--- linux-2.4.11-pre1/drivers/isdn/divert/isdn_divert.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/divert/isdn_divert.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/divert/isdn_divert.h linux/drivers/isdn/divert/isdn_divert.h
--- linux-2.4.11-pre1/drivers/isdn/divert/isdn_divert.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/divert/isdn_divert.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/Divas_mod.c linux/drivers/isdn/eicon/Divas_mod.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/Divas_mod.c	Thu Sep 13 12:55:23 2001
+++ linux/drivers/isdn/eicon/Divas_mod.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/adapter.h linux/drivers/isdn/eicon/adapter.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/adapter.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/adapter.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/bri.c linux/drivers/isdn/eicon/bri.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/bri.c	Sat May 19 17:43:06 2001
+++ linux/drivers/isdn/eicon/bri.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/common.c linux/drivers/isdn/eicon/common.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/common.c	Sun Aug 12 17:37:53 2001
+++ linux/drivers/isdn/eicon/common.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/constant.h linux/drivers/isdn/eicon/constant.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/constant.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/constant.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/divalog.h linux/drivers/isdn/eicon/divalog.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/divalog.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/divalog.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/divas.h linux/drivers/isdn/eicon/divas.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/divas.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/divas.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/dsp_defs.h linux/drivers/isdn/eicon/dsp_defs.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/dsp_defs.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/dsp_defs.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/dspdids.h linux/drivers/isdn/eicon/dspdids.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/dspdids.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/dspdids.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon.h linux/drivers/isdn/eicon/eicon.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon.h	Fri Jul  6 17:01:06 2001
+++ linux/drivers/isdn/eicon/eicon.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_dsp.h linux/drivers/isdn/eicon/eicon_dsp.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_dsp.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_dsp.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_idi.c linux/drivers/isdn/eicon/eicon_idi.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_idi.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/eicon/eicon_idi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_idi.h linux/drivers/isdn/eicon/eicon_idi.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_idi.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_idi.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_io.c linux/drivers/isdn/eicon/eicon_io.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_io.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/eicon_io.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_isa.c linux/drivers/isdn/eicon/eicon_isa.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_isa.c	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_isa.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_isa.h linux/drivers/isdn/eicon/eicon_isa.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_isa.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_isa.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_mod.c	Sun Aug 12 11:16:18 2001
+++ linux/drivers/isdn/eicon/eicon_mod.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_pci.c linux/drivers/isdn/eicon/eicon_pci.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_pci.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/eicon_pci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/eicon_pci.h linux/drivers/isdn/eicon/eicon_pci.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/eicon_pci.h	Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_pci.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/fourbri.c linux/drivers/isdn/eicon/fourbri.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/fourbri.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/fourbri.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/fpga.c linux/drivers/isdn/eicon/fpga.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/fpga.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/fpga.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/idi.c linux/drivers/isdn/eicon/idi.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/idi.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/eicon/idi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/idi.h linux/drivers/isdn/eicon/idi.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/idi.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/idi.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/kprintf.c linux/drivers/isdn/eicon/kprintf.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/kprintf.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/eicon/kprintf.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/lincfg.c linux/drivers/isdn/eicon/lincfg.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/lincfg.c	Mon Aug 13 16:35:28 2001
+++ linux/drivers/isdn/eicon/lincfg.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/linchr.c linux/drivers/isdn/eicon/linchr.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/linchr.c	Sun Aug 12 17:37:53 2001
+++ linux/drivers/isdn/eicon/linchr.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/linio.c linux/drivers/isdn/eicon/linio.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/linio.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/eicon/linio.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/linsys.c linux/drivers/isdn/eicon/linsys.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/linsys.c	Sun Aug 12 17:37:53 2001
+++ linux/drivers/isdn/eicon/linsys.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/log.c linux/drivers/isdn/eicon/log.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/log.c	Sun Aug 12 11:16:18 2001
+++ linux/drivers/isdn/eicon/log.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/pc.h linux/drivers/isdn/eicon/pc.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/pc.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/eicon/pc.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/pc_maint.h linux/drivers/isdn/eicon/pc_maint.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/pc_maint.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/pc_maint.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/pr_pc.h linux/drivers/isdn/eicon/pr_pc.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/pr_pc.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/pr_pc.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/pri.c linux/drivers/isdn/eicon/pri.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/pri.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/pri.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/sys.h linux/drivers/isdn/eicon/sys.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/sys.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/eicon/sys.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/uxio.h linux/drivers/isdn/eicon/uxio.h
--- linux-2.4.11-pre1/drivers/isdn/eicon/uxio.h	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/eicon/uxio.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/eicon/xlog.c linux/drivers/isdn/eicon/xlog.c
--- linux-2.4.11-pre1/drivers/isdn/eicon/xlog.c	Sun Aug 12 11:16:18 2001
+++ linux/drivers/isdn/eicon/xlog.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/amd7930.c linux/drivers/isdn/hisax/amd7930.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/amd7930.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/amd7930.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/arcofi.c linux/drivers/isdn/hisax/arcofi.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/arcofi.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/arcofi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/arcofi.h linux/drivers/isdn/hisax/arcofi.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/arcofi.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/arcofi.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/asuscom.c linux/drivers/isdn/hisax/asuscom.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/asuscom.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hisax/asuscom.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/avm_a1.c linux/drivers/isdn/hisax/avm_a1.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/avm_a1.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/avm_a1.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/avm_a1p.c linux/drivers/isdn/hisax/avm_a1p.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/avm_a1p.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/avm_a1p.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/avm_pci.c linux/drivers/isdn/hisax/avm_pci.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/avm_pci.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/avm_pci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/bkm_a4t.c linux/drivers/isdn/hisax/bkm_a4t.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/bkm_a4t.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hisax/bkm_a4t.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/bkm_a8.c linux/drivers/isdn/hisax/bkm_a8.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/bkm_a8.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hisax/bkm_a8.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/bkm_ax.h linux/drivers/isdn/hisax/bkm_ax.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/bkm_ax.h	Fri Mar  2 18:38:37 2001
+++ linux/drivers/isdn/hisax/bkm_ax.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/callc.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/callc.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/cert.c linux/drivers/isdn/hisax/cert.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/cert.c	Sat Jul 28 12:12:37 2001
+++ linux/drivers/isdn/hisax/cert.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/config.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/config.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/diva.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/diva.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/elsa.c linux/drivers/isdn/hisax/elsa.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/elsa.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hisax/elsa.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/elsa_cs.c linux/drivers/isdn/hisax/elsa_cs.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/elsa_cs.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/hisax/elsa_cs.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/elsa_ser.c linux/drivers/isdn/hisax/elsa_ser.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/elsa_ser.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/elsa_ser.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/fsm.c linux/drivers/isdn/hisax/fsm.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/fsm.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/fsm.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/fsm.h linux/drivers/isdn/hisax/fsm.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/fsm.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/fsm.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/gazel.c linux/drivers/isdn/hisax/gazel.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/gazel.c	Tue Jun 12 10:34:48 2001
+++ linux/drivers/isdn/hisax/gazel.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bds0.c linux/drivers/isdn/hisax/hfc_2bds0.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bds0.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/hfc_2bds0.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bds0.h linux/drivers/isdn/hisax/hfc_2bds0.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bds0.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hfc_2bds0.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bs0.c linux/drivers/isdn/hisax/hfc_2bs0.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bs0.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/hfc_2bs0.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bs0.h linux/drivers/isdn/hisax/hfc_2bs0.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_2bs0.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hfc_2bs0.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_pci.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/hisax/hfc_pci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_pci.h linux/drivers/isdn/hisax/hfc_pci.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_pci.h	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hisax/hfc_pci.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_sx.c linux/drivers/isdn/hisax/hfc_sx.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_sx.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/hisax/hfc_sx.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfc_sx.h linux/drivers/isdn/hisax/hfc_sx.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfc_sx.h	Sun Aug  6 12:43:41 2000
+++ linux/drivers/isdn/hisax/hfc_sx.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hfcscard.c linux/drivers/isdn/hisax/hfcscard.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/hfcscard.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hfcscard.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hisax.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/hisax.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hisax_debug.h linux/drivers/isdn/hisax/hisax_debug.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hisax_debug.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/hisax_debug.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hisax_if.h linux/drivers/isdn/hisax/hisax_if.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hisax_if.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/hisax_if.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hscx.c linux/drivers/isdn/hisax/hscx.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/hscx.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/hscx.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hscx.h linux/drivers/isdn/hisax/hscx.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/hscx.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hscx.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/hscx_irq.c linux/drivers/isdn/hisax/hscx_irq.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/hscx_irq.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/hisax/hscx_irq.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/icc.c linux/drivers/isdn/hisax/icc.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/icc.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/icc.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/icc.h linux/drivers/isdn/hisax/icc.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/icc.h	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hisax/icc.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/ipac.h linux/drivers/isdn/hisax/ipac.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/ipac.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/ipac.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isac.c linux/drivers/isdn/hisax/isac.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/isac.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/isac.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isac.h linux/drivers/isdn/hisax/isac.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/isac.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isac.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/isar.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/isdn/hisax/isar.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isar.h linux/drivers/isdn/hisax/isar.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/isar.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isar.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/isdnl1.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/isdnl1.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isdnl1.h linux/drivers/isdn/hisax/isdnl1.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/isdnl1.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/isdnl1.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isdnl2.c linux/drivers/isdn/hisax/isdnl2.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/isdnl2.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/isdnl2.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isdnl2.h linux/drivers/isdn/hisax/isdnl2.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/isdnl2.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl2.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isdnl3.c linux/drivers/isdn/hisax/isdnl3.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/isdnl3.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/isdnl3.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isdnl3.h linux/drivers/isdn/hisax/isdnl3.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/isdnl3.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isdnl3.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/isurf.c linux/drivers/isdn/hisax/isurf.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/isurf.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/isurf.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/ix1_micro.c linux/drivers/isdn/hisax/ix1_micro.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/ix1_micro.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/ix1_micro.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/jade.c linux/drivers/isdn/hisax/jade.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/jade.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/jade.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/jade.h linux/drivers/isdn/hisax/jade.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/jade.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/jade.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/jade_irq.c linux/drivers/isdn/hisax/jade_irq.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/jade_irq.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/jade_irq.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/l3_1tr6.c linux/drivers/isdn/hisax/l3_1tr6.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/l3_1tr6.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3_1tr6.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/l3_1tr6.h linux/drivers/isdn/hisax/l3_1tr6.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/l3_1tr6.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3_1tr6.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/l3dss1.c linux/drivers/isdn/hisax/l3dss1.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/l3dss1.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/hisax/l3dss1.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/l3dss1.h linux/drivers/isdn/hisax/l3dss1.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/l3dss1.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3dss1.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/l3ni1.c linux/drivers/isdn/hisax/l3ni1.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/l3ni1.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/hisax/l3ni1.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/l3ni1.h linux/drivers/isdn/hisax/l3ni1.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/l3ni1.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/l3ni1.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/lmgr.c linux/drivers/isdn/hisax/lmgr.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/lmgr.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/lmgr.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/mic.c linux/drivers/isdn/hisax/mic.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/mic.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/mic.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/netjet.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/netjet.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/netjet.h linux/drivers/isdn/hisax/netjet.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/netjet.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/netjet.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/niccy.c linux/drivers/isdn/hisax/niccy.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/niccy.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/niccy.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/nj_s.c linux/drivers/isdn/hisax/nj_s.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/nj_s.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hisax/nj_s.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/nj_u.c linux/drivers/isdn/hisax/nj_u.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/nj_u.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hisax/nj_u.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/q931.c linux/drivers/isdn/hisax/q931.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/q931.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hisax/q931.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/rawhdlc.c linux/drivers/isdn/hisax/rawhdlc.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/rawhdlc.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/rawhdlc.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/rawhdlc.h linux/drivers/isdn/hisax/rawhdlc.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/rawhdlc.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/rawhdlc.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/s0box.c linux/drivers/isdn/hisax/s0box.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/s0box.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/s0box.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/saphir.c linux/drivers/isdn/hisax/saphir.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/saphir.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/saphir.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/sedlbauer.c linux/drivers/isdn/hisax/sedlbauer.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/sedlbauer.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hisax/sedlbauer.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/sedlbauer_cs.c linux/drivers/isdn/hisax/sedlbauer_cs.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/sedlbauer_cs.c	Mon Aug 13 16:35:28 2001
+++ linux/drivers/isdn/hisax/sedlbauer_cs.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/sportster.c linux/drivers/isdn/hisax/sportster.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/sportster.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/sportster.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/st5481.h linux/drivers/isdn/hisax/st5481.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/st5481.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/st5481.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/st5481_b.c linux/drivers/isdn/hisax/st5481_b.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/st5481_b.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/st5481_b.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/st5481_d.c linux/drivers/isdn/hisax/st5481_d.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/st5481_d.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/st5481_d.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/st5481_init.c linux/drivers/isdn/hisax/st5481_init.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/st5481_init.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/st5481_init.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/st5481_usb.c linux/drivers/isdn/hisax/st5481_usb.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/st5481_usb.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/hisax/st5481_usb.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/tei.c linux/drivers/isdn/hisax/tei.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/tei.c	Tue Jun 12 10:34:48 2001
+++ linux/drivers/isdn/hisax/tei.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/teleint.c linux/drivers/isdn/hisax/teleint.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/teleint.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/teleint.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/teles0.c linux/drivers/isdn/hisax/teles0.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/teles0.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/teles0.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/teles3.c linux/drivers/isdn/hisax/teles3.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/teles3.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/teles3.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/telespci.c linux/drivers/isdn/hisax/telespci.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/telespci.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/telespci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/w6692.c linux/drivers/isdn/hisax/w6692.c
--- linux-2.4.11-pre1/drivers/isdn/hisax/w6692.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/hisax/w6692.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hisax/w6692.h linux/drivers/isdn/hisax/w6692.h
--- linux-2.4.11-pre1/drivers/isdn/hisax/w6692.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/hisax/w6692.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/boardergo.c linux/drivers/isdn/hysdn/boardergo.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/boardergo.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/hysdn/boardergo.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/boardergo.h linux/drivers/isdn/hysdn/boardergo.h
--- linux-2.4.11-pre1/drivers/isdn/hysdn/boardergo.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/hysdn/boardergo.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hycapi.c linux/drivers/isdn/hysdn/hycapi.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hycapi.c	Tue Jun 12 10:34:48 2001
+++ linux/drivers/isdn/hysdn/hycapi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_boot.c linux/drivers/isdn/hysdn/hysdn_boot.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_boot.c	Mon Mar 26 15:38:19 2001
+++ linux/drivers/isdn/hysdn/hysdn_boot.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_defs.h linux/drivers/isdn/hysdn/hysdn_defs.h
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_defs.h	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_defs.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_init.c linux/drivers/isdn/hysdn/hysdn_init.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_init.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/hysdn/hysdn_init.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_net.c linux/drivers/isdn/hysdn/hysdn_net.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_net.c	Tue Jun 12 10:34:48 2001
+++ linux/drivers/isdn/hysdn/hysdn_net.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_pof.h linux/drivers/isdn/hysdn/hysdn_pof.h
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_pof.h	Fri Nov 17 11:16:20 2000
+++ linux/drivers/isdn/hysdn/hysdn_pof.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_procconf.c	Mon Aug 13 16:35:28 2001
+++ linux/drivers/isdn/hysdn/hysdn_procconf.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_proclog.c	Mon Aug 13 16:35:28 2001
+++ linux/drivers/isdn/hysdn/hysdn_proclog.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_sched.c linux/drivers/isdn/hysdn/hysdn_sched.c
--- linux-2.4.11-pre1/drivers/isdn/hysdn/hysdn_sched.c	Sat May 19 17:54:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_sched.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/hysdn/ince1pc.h linux/drivers/isdn/hysdn/ince1pc.h
--- linux-2.4.11-pre1/drivers/isdn/hysdn/ince1pc.h	Mon Aug 21 07:49:03 2000
+++ linux/drivers/isdn/hysdn/ince1pc.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
--- linux-2.4.11-pre1/drivers/isdn/icn/icn.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/icn/icn.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/icn/icn.h linux/drivers/isdn/icn/icn.h
--- linux-2.4.11-pre1/drivers/isdn/icn/icn.h	Fri Sep  7 09:28:38 2001
+++ linux/drivers/isdn/icn/icn.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_audio.c linux/drivers/isdn/isdn_audio.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_audio.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/isdn/isdn_audio.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_audio.h linux/drivers/isdn/isdn_audio.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_audio.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_audio.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_bsdcomp.c linux/drivers/isdn/isdn_bsdcomp.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_bsdcomp.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/isdn/isdn_bsdcomp.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_common.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/isdn_common.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_common.h linux/drivers/isdn/isdn_common.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_common.h	Mon Nov 27 16:53:43 2000
+++ linux/drivers/isdn/isdn_common.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_concap.c linux/drivers/isdn/isdn_concap.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_concap.c	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_concap.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_concap.h linux/drivers/isdn/isdn_concap.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_concap.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_concap.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_net.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/isdn_net.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_net.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/isdn_net.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_ppp.c	Sat Jul 28 12:12:37 2001
+++ linux/drivers/isdn/isdn_ppp.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_ppp.h linux/drivers/isdn/isdn_ppp.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_ppp.h	Mon Dec 11 13:21:44 2000
+++ linux/drivers/isdn/isdn_ppp.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_tty.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/isdn_tty.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_tty.h linux/drivers/isdn/isdn_tty.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_tty.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/isdn_tty.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_ttyfax.c linux/drivers/isdn/isdn_ttyfax.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_ttyfax.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/isdn_ttyfax.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_ttyfax.h linux/drivers/isdn/isdn_ttyfax.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_ttyfax.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_ttyfax.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_v110.c linux/drivers/isdn/isdn_v110.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_v110.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/isdn_v110.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_v110.h linux/drivers/isdn/isdn_v110.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_v110.h	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_v110.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_x25iface.c linux/drivers/isdn/isdn_x25iface.c
--- linux-2.4.11-pre1/drivers/isdn/isdn_x25iface.c	Sun Aug  6 12:43:42 2000
+++ linux/drivers/isdn/isdn_x25iface.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdn_x25iface.h linux/drivers/isdn/isdn_x25iface.h
--- linux-2.4.11-pre1/drivers/isdn/isdn_x25iface.h	Mon Dec 11 13:21:52 2000
+++ linux/drivers/isdn/isdn_x25iface.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdnloop/isdnloop.c linux/drivers/isdn/isdnloop/isdnloop.c
--- linux-2.4.11-pre1/drivers/isdn/isdnloop/isdnloop.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/isdnloop/isdnloop.h linux/drivers/isdn/isdnloop/isdnloop.h
--- linux-2.4.11-pre1/drivers/isdn/isdnloop/isdnloop.h	Sun Sep  9 10:45:43 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/callbacks.c linux/drivers/isdn/pcbit/callbacks.c
--- linux-2.4.11-pre1/drivers/isdn/pcbit/callbacks.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/callbacks.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/callbacks.h linux/drivers/isdn/pcbit/callbacks.h
--- linux-2.4.11-pre1/drivers/isdn/pcbit/callbacks.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/callbacks.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/capi.c linux/drivers/isdn/pcbit/capi.c
--- linux-2.4.11-pre1/drivers/isdn/pcbit/capi.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/capi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/capi.h linux/drivers/isdn/pcbit/capi.h
--- linux-2.4.11-pre1/drivers/isdn/pcbit/capi.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/capi.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/drv.c linux/drivers/isdn/pcbit/drv.c
--- linux-2.4.11-pre1/drivers/isdn/pcbit/drv.c	Wed Apr 11 19:02:36 2001
+++ linux/drivers/isdn/pcbit/drv.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/edss1.c linux/drivers/isdn/pcbit/edss1.c
--- linux-2.4.11-pre1/drivers/isdn/pcbit/edss1.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/edss1.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/edss1.h linux/drivers/isdn/pcbit/edss1.h
--- linux-2.4.11-pre1/drivers/isdn/pcbit/edss1.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/edss1.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/layer2.c linux/drivers/isdn/pcbit/layer2.c
--- linux-2.4.11-pre1/drivers/isdn/pcbit/layer2.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/isdn/pcbit/layer2.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/layer2.h linux/drivers/isdn/pcbit/layer2.h
--- linux-2.4.11-pre1/drivers/isdn/pcbit/layer2.h	Fri Sep  7 09:28:38 2001
+++ linux/drivers/isdn/pcbit/layer2.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/module.c linux/drivers/isdn/pcbit/module.c
--- linux-2.4.11-pre1/drivers/isdn/pcbit/module.c	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/module.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/pcbit/pcbit.h linux/drivers/isdn/pcbit/pcbit.h
--- linux-2.4.11-pre1/drivers/isdn/pcbit/pcbit.h	Fri Mar  2 11:12:09 2001
+++ linux/drivers/isdn/pcbit/pcbit.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/card.h linux/drivers/isdn/sc/card.h
--- linux-2.4.11-pre1/drivers/isdn/sc/card.h	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/card.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/command.c linux/drivers/isdn/sc/command.c
--- linux-2.4.11-pre1/drivers/isdn/sc/command.c	Thu May 29 21:53:06 1997
+++ linux/drivers/isdn/sc/command.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/debug.c linux/drivers/isdn/sc/debug.c
--- linux-2.4.11-pre1/drivers/isdn/sc/debug.c	Fri Sep 14 14:40:00 2001
+++ linux/drivers/isdn/sc/debug.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/debug.h linux/drivers/isdn/sc/debug.h
--- linux-2.4.11-pre1/drivers/isdn/sc/debug.h	Sat Feb 26 20:20:13 2000
+++ linux/drivers/isdn/sc/debug.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/event.c linux/drivers/isdn/sc/event.c
--- linux-2.4.11-pre1/drivers/isdn/sc/event.c	Wed Apr  1 16:21:04 1998
+++ linux/drivers/isdn/sc/event.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/hardware.h linux/drivers/isdn/sc/hardware.h
--- linux-2.4.11-pre1/drivers/isdn/sc/hardware.h	Wed Apr  1 16:21:04 1998
+++ linux/drivers/isdn/sc/hardware.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/includes.h linux/drivers/isdn/sc/includes.h
--- linux-2.4.11-pre1/drivers/isdn/sc/includes.h	Fri Feb  9 11:30:23 2001
+++ linux/drivers/isdn/sc/includes.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/init.c linux/drivers/isdn/sc/init.c
--- linux-2.4.11-pre1/drivers/isdn/sc/init.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/isdn/sc/init.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/interrupt.c linux/drivers/isdn/sc/interrupt.c
--- linux-2.4.11-pre1/drivers/isdn/sc/interrupt.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/sc/interrupt.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/ioctl.c linux/drivers/isdn/sc/ioctl.c
--- linux-2.4.11-pre1/drivers/isdn/sc/ioctl.c	Sun Nov  7 16:34:00 1999
+++ linux/drivers/isdn/sc/ioctl.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/message.c linux/drivers/isdn/sc/message.c
--- linux-2.4.11-pre1/drivers/isdn/sc/message.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/sc/message.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/message.h linux/drivers/isdn/sc/message.h
--- linux-2.4.11-pre1/drivers/isdn/sc/message.h	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/message.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/packet.c linux/drivers/isdn/sc/packet.c
--- linux-2.4.11-pre1/drivers/isdn/sc/packet.c	Sun Nov  7 16:34:00 1999
+++ linux/drivers/isdn/sc/packet.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/scioc.h linux/drivers/isdn/sc/scioc.h
--- linux-2.4.11-pre1/drivers/isdn/sc/scioc.h	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/scioc.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/shmem.c linux/drivers/isdn/sc/shmem.c
--- linux-2.4.11-pre1/drivers/isdn/sc/shmem.c	Thu Feb 27 10:57:30 1997
+++ linux/drivers/isdn/sc/shmem.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/sc/timer.c linux/drivers/isdn/sc/timer.c
--- linux-2.4.11-pre1/drivers/isdn/sc/timer.c	Mon Aug 21 07:49:03 2000
+++ linux/drivers/isdn/sc/timer.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam.h linux/drivers/isdn/tpam/tpam.h
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam.h	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/tpam/tpam.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam_commands.c linux/drivers/isdn/tpam/tpam_commands.c
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam_commands.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/tpam/tpam_commands.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam_crcpc.c linux/drivers/isdn/tpam/tpam_crcpc.c
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam_crcpc.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/tpam/tpam_crcpc.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam_hdlc.c linux/drivers/isdn/tpam/tpam_hdlc.c
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam_hdlc.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/tpam/tpam_hdlc.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam_main.c linux/drivers/isdn/tpam/tpam_main.c
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam_main.c	Wed Jul 18 09:45:40 2001
+++ linux/drivers/isdn/tpam/tpam_main.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam_memory.c linux/drivers/isdn/tpam/tpam_memory.c
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam_memory.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/tpam/tpam_memory.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam_nco.c linux/drivers/isdn/tpam/tpam_nco.c
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam_nco.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/tpam/tpam_nco.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/isdn/tpam/tpam_queues.c linux/drivers/isdn/tpam/tpam_queues.c
--- linux-2.4.11-pre1/drivers/isdn/tpam/tpam_queues.c	Mon Jul  2 14:07:55 2001
+++ linux/drivers/isdn/tpam/tpam_queues.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/md/linear.c linux/drivers/md/linear.c
--- linux-2.4.11-pre1/drivers/md/linear.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/md/linear.c	Mon Dec  3 23:14:07 2001
@@ -203,3 +203,4 @@
 
 module_init(linear_init);
 module_exit(linear_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/md/multipath.c linux/drivers/md/multipath.c
--- linux-2.4.11-pre1/drivers/md/multipath.c	Fri Sep 14 14:22:18 2001
+++ linux/drivers/md/multipath.c	Mon Dec  3 23:14:07 2001
@@ -1258,4 +1258,4 @@
 
 module_init(multipath_init);
 module_exit(multipath_exit);
-
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/md/raid0.c linux/drivers/md/raid0.c
--- linux-2.4.11-pre1/drivers/md/raid0.c	Wed Jun 20 20:55:08 2001
+++ linux/drivers/md/raid0.c	Mon Dec  3 23:14:07 2001
@@ -347,5 +347,4 @@
 
 module_init(raid0_init);
 module_exit(raid0_exit);
-
-
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/md/raid1.c linux/drivers/md/raid1.c
--- linux-2.4.11-pre1/drivers/md/raid1.c	Wed Aug 29 20:47:41 2001
+++ linux/drivers/md/raid1.c	Mon Dec  3 23:14:07 2001
@@ -1826,4 +1826,4 @@
 
 module_init(raid1_init);
 module_exit(raid1_exit);
-
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/md/raid5.c linux/drivers/md/raid5.c
--- linux-2.4.11-pre1/drivers/md/raid5.c	Fri Sep  7 10:48:39 2001
+++ linux/drivers/md/raid5.c	Mon Dec  3 23:14:07 2001
@@ -2026,4 +2026,4 @@
 
 module_init(raid5_init);
 module_exit(raid5_exit);
-
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/md/xor.c linux/drivers/md/xor.c
--- linux-2.4.11-pre1/drivers/md/xor.c	Mon Jan 22 14:49:36 2001
+++ linux/drivers/md/xor.c	Mon Dec  3 23:14:07 2001
@@ -137,5 +137,6 @@
 }
 
 MD_EXPORT_SYMBOL(xor_block);
+MODULE_LICENSE("GPL");
 
 module_init(calibrate_xor_block);
diff -urN linux-2.4.11-pre1/drivers/media/radio/miropcm20-radio.c linux/drivers/media/radio/miropcm20-radio.c
--- linux-2.4.11-pre1/drivers/media/radio/miropcm20-radio.c	Tue Jun 12 10:56:11 2001
+++ linux/drivers/media/radio/miropcm20-radio.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/miropcm20-rds-core.c linux/drivers/media/radio/miropcm20-rds-core.c
--- linux-2.4.11-pre1/drivers/media/radio/miropcm20-rds-core.c	Tue Jun 12 10:56:11 2001
+++ linux/drivers/media/radio/miropcm20-rds-core.c	Mon Dec  3 23:14:07 2001
@@ -208,3 +208,4 @@
 void __exit unload_aci_rds(void)
 {
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/radio/miropcm20-rds.c linux/drivers/media/radio/miropcm20-rds.c
--- linux-2.4.11-pre1/drivers/media/radio/miropcm20-rds.c	Tue Jun 12 10:56:11 2001
+++ linux/drivers/media/radio/miropcm20-rds.c	Mon Dec  3 23:14:07 2001
@@ -138,3 +138,4 @@
 
 module_init(miropcm20_rds_init);
 module_exit(miropcm20_rds_cleanup);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/radio/radio-aimslab.c linux/drivers/media/radio/radio-aimslab.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-aimslab.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-aimslab.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-aztech.c linux/drivers/media/radio/radio-aztech.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-aztech.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-aztech.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-cadet.c linux/drivers/media/radio/radio-cadet.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-cadet.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-cadet.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-gemtek-pci.c linux/drivers/media/radio/radio-gemtek-pci.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-gemtek-pci.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/radio/radio-gemtek-pci.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-gemtek.c linux/drivers/media/radio/radio-gemtek.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-gemtek.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-gemtek.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-maestro.c linux/drivers/media/radio/radio-maestro.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-maestro.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-maestro.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-maxiradio.c linux/drivers/media/radio/radio-maxiradio.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-maxiradio.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-maxiradio.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-rtrack2.c linux/drivers/media/radio/radio-rtrack2.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-rtrack2.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-rtrack2.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-sf16fmi.c linux/drivers/media/radio/radio-sf16fmi.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-sf16fmi.c	Sun Aug 12 11:16:18 2001
+++ linux/drivers/media/radio/radio-sf16fmi.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-terratec.c linux/drivers/media/radio/radio-terratec.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-terratec.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-terratec.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-trust.c linux/drivers/media/radio/radio-trust.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-trust.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-trust.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-typhoon.c linux/drivers/media/radio/radio-typhoon.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-typhoon.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-typhoon.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/radio/radio-zoltrix.c linux/drivers/media/radio/radio-zoltrix.c
--- linux-2.4.11-pre1/drivers/media/radio/radio-zoltrix.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/radio/radio-zoltrix.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/adv7175.c linux/drivers/media/video/adv7175.c
--- linux-2.4.11-pre1/drivers/media/video/adv7175.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/adv7175.c	Mon Dec  3 23:14:07 2001
@@ -476,3 +476,4 @@
 
 module_init(adv7175_init);
 module_exit(adv7175_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/bt819.c linux/drivers/media/video/bt819.c
--- linux-2.4.11-pre1/drivers/media/video/bt819.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/bt819.c	Mon Dec  3 23:14:07 2001
@@ -494,3 +494,4 @@
 
 module_init(bt819_setup);
 module_exit(bt819_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/bt856.c linux/drivers/media/video/bt856.c
--- linux-2.4.11-pre1/drivers/media/video/bt856.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/bt856.c	Mon Dec  3 23:14:07 2001
@@ -301,3 +301,4 @@
 
 module_init(bt856_init);
 module_exit(bt856_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/bttv-cards.c linux/drivers/media/video/bttv-cards.c
--- linux-2.4.11-pre1/drivers/media/video/bttv-cards.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/bttv-cards.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- linux-2.4.11-pre1/drivers/media/video/bttv-driver.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/bttv-driver.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/bttv-if.c linux/drivers/media/video/bttv-if.c
--- linux-2.4.11-pre1/drivers/media/video/bttv-if.c	Mon Feb 19 14:43:36 2001
+++ linux/drivers/media/video/bttv-if.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/bw-qcam.c linux/drivers/media/video/bw-qcam.c
--- linux-2.4.11-pre1/drivers/media/video/bw-qcam.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/bw-qcam.c	Mon Dec  3 23:14:07 2001
@@ -1051,3 +1051,4 @@
 	return 0;
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/c-qcam.c linux/drivers/media/video/c-qcam.c
--- linux-2.4.11-pre1/drivers/media/video/c-qcam.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/c-qcam.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/i2c-old.c linux/drivers/media/video/i2c-old.c
--- linux-2.4.11-pre1/drivers/media/video/i2c-old.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/media/video/i2c-old.c	Mon Dec  3 23:14:07 2001
@@ -448,3 +448,4 @@
 {
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/i2c-parport.c linux/drivers/media/video/i2c-parport.c
--- linux-2.4.11-pre1/drivers/media/video/i2c-parport.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/media/video/i2c-parport.c	Mon Dec  3 23:14:07 2001
@@ -149,3 +149,4 @@
   parport_unregister_driver(&parport_i2c_driver);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/meye.c linux/drivers/media/video/meye.c
--- linux-2.4.11-pre1/drivers/media/video/meye.c	Sat Jul 28 12:35:55 2001
+++ linux/drivers/media/video/meye.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/msp3400.c linux/drivers/media/video/msp3400.c
--- linux-2.4.11-pre1/drivers/media/video/msp3400.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/msp3400.c	Mon Dec  3 23:14:07 2001
@@ -131,6 +131,8 @@
 MODULE_PARM(simple,"i");
 MODULE_PARM(amsound,"i");
 MODULE_PARM(dolby,"i");
+MODULE_LICENSE("GPL");
+
 
 /* ---------------------------------------------------------------------- */
 
diff -urN linux-2.4.11-pre1/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- linux-2.4.11-pre1/drivers/media/video/planb.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/media/video/planb.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/pms.c linux/drivers/media/video/pms.c
--- linux-2.4.11-pre1/drivers/media/video/pms.c	Thu May 24 15:14:08 2001
+++ linux/drivers/media/video/pms.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/saa5249.c linux/drivers/media/video/saa5249.c
--- linux-2.4.11-pre1/drivers/media/video/saa5249.c	Wed Jul  4 14:41:33 2001
+++ linux/drivers/media/video/saa5249.c	Mon Dec  3 23:14:07 2001
@@ -694,3 +694,4 @@
 	ioctl:		saa5249_ioctl,
 };
 
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/saa7110.c linux/drivers/media/video/saa7110.c
--- linux-2.4.11-pre1/drivers/media/video/saa7110.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/saa7110.c	Mon Dec  3 23:14:07 2001
@@ -426,3 +426,4 @@
 
 module_init(saa7110_init);
 module_exit(saa7110_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/saa7111.c linux/drivers/media/video/saa7111.c
--- linux-2.4.11-pre1/drivers/media/video/saa7111.c	Thu Sep 13 15:21:32 2001
+++ linux/drivers/media/video/saa7111.c	Mon Dec  3 23:14:07 2001
@@ -448,3 +448,4 @@
 
 module_init(saa7111_init);
 module_exit(saa7111_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/saa7185.c linux/drivers/media/video/saa7185.c
--- linux-2.4.11-pre1/drivers/media/video/saa7185.c	Thu Sep 13 15:21:32 2001
+++ linux/drivers/media/video/saa7185.c	Mon Dec  3 23:14:07 2001
@@ -406,3 +406,4 @@
 
 module_init(saa7185_init);
 module_exit(saa7185_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c
--- linux-2.4.11-pre1/drivers/media/video/stradis.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/stradis.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/tda7432.c linux/drivers/media/video/tda7432.c
--- linux-2.4.11-pre1/drivers/media/video/tda7432.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/tda7432.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/tda9875.c linux/drivers/media/video/tda9875.c
--- linux-2.4.11-pre1/drivers/media/video/tda9875.c	Sat May 19 17:43:06 2001
+++ linux/drivers/media/video/tda9875.c	Mon Dec  3 23:14:07 2001
@@ -34,6 +34,8 @@
 #include "id.h"
 
 MODULE_PARM(debug,"i");
+MODULE_LICENSE("GPL");
+
 
 static int debug = 0;	/* insmod parameter */
 
diff -urN linux-2.4.11-pre1/drivers/media/video/tuner-3036.c linux/drivers/media/video/tuner-3036.c
--- linux-2.4.11-pre1/drivers/media/video/tuner-3036.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/media/video/tuner-3036.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/tuner.c linux/drivers/media/video/tuner.c
--- linux-2.4.11-pre1/drivers/media/video/tuner.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/tuner.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/tvaudio.c linux/drivers/media/video/tvaudio.c
--- linux-2.4.11-pre1/drivers/media/video/tvaudio.c	Sun Aug  5 13:15:05 2001
+++ linux/drivers/media/video/tvaudio.c	Mon Dec  3 23:14:07 2001
@@ -1168,6 +1168,7 @@
 
 module_init(audiochip_init_module);
 module_exit(audiochip_cleanup_module);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/media/video/tvmixer.c linux/drivers/media/video/tvmixer.c
--- linux-2.4.11-pre1/drivers/media/video/tvmixer.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/media/video/tvmixer.c	Mon Dec  3 23:14:07 2001
@@ -355,3 +355,4 @@
  * c-basic-offset: 8
  * End:
  */
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- linux-2.4.11-pre1/drivers/media/video/videodev.c	Tue Aug 28 07:00:58 2001
+++ linux/drivers/media/video/videodev.c	Mon Dec  3 23:14:07 2001
@@ -592,6 +592,8 @@
 
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/media/video/w9966.c linux/drivers/media/video/w9966.c
--- linux-2.4.11-pre1/drivers/media/video/w9966.c	Thu May 24 15:14:08 2001
+++ linux/drivers/media/video/w9966.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/zr36067.c linux/drivers/media/video/zr36067.c
--- linux-2.4.11-pre1/drivers/media/video/zr36067.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/media/video/zr36067.c	Mon Dec  3 23:14:07 2001
@@ -4901,3 +4901,4 @@
 
 module_init(init_dc10_cards);
 module_exit(unload_dc10_cards);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/media/video/zr36120.c linux/drivers/media/video/zr36120.c
--- linux-2.4.11-pre1/drivers/media/video/zr36120.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/media/video/zr36120.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/media/video/zr36120_mem.c linux/drivers/media/video/zr36120_mem.c
--- linux-2.4.11-pre1/drivers/media/video/zr36120_mem.c	Mon Aug  7 21:01:36 2000
+++ linux/drivers/media/video/zr36120_mem.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/message/fusion/mptbase.c linux/drivers/message/fusion/mptbase.c
--- linux-2.4.11-pre1/drivers/message/fusion/mptbase.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/message/fusion/mptbase.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/message/fusion/mptbase.h linux/drivers/message/fusion/mptbase.h
--- linux-2.4.11-pre1/drivers/message/fusion/mptbase.h	Fri Sep  7 09:28:38 2001
+++ linux/drivers/message/fusion/mptbase.h	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/message/fusion/mptctl.c linux/drivers/message/fusion/mptctl.c
--- linux-2.4.11-pre1/drivers/message/fusion/mptctl.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/message/fusion/mptctl.c	Mon Dec  3 23:14:07 2001
@@ -93,6 +93,8 @@
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
diff -urN linux-2.4.11-pre1/drivers/message/fusion/mptlan.c linux/drivers/message/fusion/mptlan.c
--- linux-2.4.11-pre1/drivers/message/fusion/mptlan.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/message/fusion/mptlan.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/message/fusion/mptscsih.c linux/drivers/message/fusion/mptscsih.c
--- linux-2.4.11-pre1/drivers/message/fusion/mptscsih.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/message/fusion/mptscsih.c	Mon Dec  3 23:14:07 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 -urN linux-2.4.11-pre1/drivers/net/3c501.c linux/drivers/net/3c501.c
--- linux-2.4.11-pre1/drivers/net/3c501.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/3c501.c	Mon Dec  3 23:14:07 2001
@@ -980,6 +980,8 @@
 }
 
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/3c503.c linux/drivers/net/3c503.c
--- linux-2.4.11-pre1/drivers/net/3c503.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/3c503.c	Mon Dec  3 23:14:08 2001
@@ -667,6 +667,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/3c505.c linux/drivers/net/3c505.c
--- linux-2.4.11-pre1/drivers/net/3c505.c	Sun Aug 12 10:51:42 2001
+++ linux/drivers/net/3c505.c	Mon Dec  3 23:14:08 2001
@@ -1673,3 +1673,4 @@
 }
 
 #endif				/* MODULE */
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/3c507.c linux/drivers/net/3c507.c
--- linux-2.4.11-pre1/drivers/net/3c507.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/3c507.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/3c509.c linux/drivers/net/3c509.c
--- linux-2.4.11-pre1/drivers/net/3c509.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/3c509.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/3c515.c linux/drivers/net/3c515.c
--- linux-2.4.11-pre1/drivers/net/3c515.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/3c515.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- linux-2.4.11-pre1/drivers/net/3c59x.c	Mon Sep 17 13:16:30 2001
+++ linux/drivers/net/3c59x.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/8139too.c linux/drivers/net/8139too.c
--- linux-2.4.11-pre1/drivers/net/8139too.c	Sun Sep  2 07:59:04 2001
+++ linux/drivers/net/8139too.c	Mon Dec  3 23:14:08 2001
@@ -592,6 +592,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");
@@ -825,6 +827,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);
diff -urN linux-2.4.11-pre1/drivers/net/82596.c linux/drivers/net/82596.c
--- linux-2.4.11-pre1/drivers/net/82596.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/82596.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/8390.c linux/drivers/net/8390.c
--- linux-2.4.11-pre1/drivers/net/8390.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/8390.c	Mon Dec  3 23:14:08 2001
@@ -1156,6 +1156,8 @@
 }
 
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- linux-2.4.11-pre1/drivers/net/ac3200.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/ac3200.c	Mon Dec  3 23:14:08 2001
@@ -395,6 +395,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/acenic.c linux/drivers/net/acenic.c
--- linux-2.4.11-pre1/drivers/net/acenic.c	Mon Sep 10 08:06:32 2001
+++ linux/drivers/net/acenic.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/aironet4500_card.c linux/drivers/net/aironet4500_card.c
--- linux-2.4.11-pre1/drivers/net/aironet4500_card.c	Mon Sep 17 22:52:35 2001
+++ linux/drivers/net/aironet4500_card.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/aironet4500_core.c linux/drivers/net/aironet4500_core.c
--- linux-2.4.11-pre1/drivers/net/aironet4500_core.c	Mon Sep 17 22:52:35 2001
+++ linux/drivers/net/aironet4500_core.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/aironet4500_proc.c linux/drivers/net/aironet4500_proc.c
--- linux-2.4.11-pre1/drivers/net/aironet4500_proc.c	Mon Sep 17 22:52:35 2001
+++ linux/drivers/net/aironet4500_proc.c	Mon Dec  3 23:14:08 2001
@@ -604,3 +604,4 @@
 module_exit(aironet_proc_exit);
 
 #endif // whole proc system styff
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/arlan-proc.c linux/drivers/net/arlan-proc.c
--- linux-2.4.11-pre1/drivers/net/arlan-proc.c	Thu Apr 12 12:15:25 2001
+++ linux/drivers/net/arlan-proc.c	Mon Dec  3 23:14:08 2001
@@ -1068,3 +1068,4 @@
 };
 
 #endif				// MODULE
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/arlan.c linux/drivers/net/arlan.c
--- linux-2.4.11-pre1/drivers/net/arlan.c	Sun Aug  5 13:12:40 2001
+++ linux/drivers/net/arlan.c	Mon Dec  3 23:14:08 2001
@@ -2079,3 +2079,4 @@
 
 
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/at1700.c linux/drivers/net/at1700.c
--- linux-2.4.11-pre1/drivers/net/at1700.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/at1700.c	Mon Dec  3 23:14:08 2001
@@ -918,6 +918,8 @@
 	release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/atp.c linux/drivers/net/atp.c
--- linux-2.4.11-pre1/drivers/net/atp.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/atp.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/bonding.c linux/drivers/net/bonding.c
--- linux-2.4.11-pre1/drivers/net/bonding.c	Tue Mar  6 22:44:15 2001
+++ linux/drivers/net/bonding.c	Mon Dec  3 23:14:08 2001
@@ -299,6 +299,7 @@
 
 module_init(bonding_init);
 module_exit(bonding_exit);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/bsd_comp.c linux/drivers/net/bsd_comp.c
--- linux-2.4.11-pre1/drivers/net/bsd_comp.c	Sun Jul 15 16:22:23 2001
+++ linux/drivers/net/bsd_comp.c	Mon Dec  3 23:14:08 2001
@@ -1173,3 +1173,4 @@
 
 module_init(bsdcomp_init);
 module_exit(bsdcomp_cleanup);
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- linux-2.4.11-pre1/drivers/net/cs89x0.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/net/cs89x0.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- linux-2.4.11-pre1/drivers/net/de4x5.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/de4x5.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/de600.c linux/drivers/net/de600.c
--- linux-2.4.11-pre1/drivers/net/de600.c	Mon Sep 10 08:06:32 2001
+++ linux/drivers/net/de600.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/de620.c linux/drivers/net/de620.c
--- linux-2.4.11-pre1/drivers/net/de620.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/de620.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/defxx.c linux/drivers/net/defxx.c
--- linux-2.4.11-pre1/drivers/net/defxx.c	Sat Jun 30 10:36:37 2001
+++ linux/drivers/net/defxx.c	Mon Dec  3 23:14:08 2001
@@ -3413,6 +3413,7 @@
 
 module_init(dfx_init);
 module_exit(dfx_cleanup);
+MODULE_LICENSE("GPL");
 
 
 /*
diff -urN linux-2.4.11-pre1/drivers/net/depca.c linux/drivers/net/depca.c
--- linux-2.4.11-pre1/drivers/net/depca.c	Sun Aug 12 12:33:23 2001
+++ linux/drivers/net/depca.c	Mon Dec  3 23:14:08 2001
@@ -2076,6 +2076,7 @@
   release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE);
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
 
 
 /*
diff -urN linux-2.4.11-pre1/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- linux-2.4.11-pre1/drivers/net/dgrs.c	Mon Sep 10 08:06:32 2001
+++ linux/drivers/net/dgrs.c	Mon Dec  3 23:14:08 2001
@@ -126,6 +126,8 @@
 	{ }			/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, dgrs_pci_tbl);
+MODULE_LICENSE("GPL");
+
 
 /*
  *	Firmware.  Compiled separately for local compilation,
diff -urN linux-2.4.11-pre1/drivers/net/dl2k.c linux/drivers/net/dl2k.c
--- linux-2.4.11-pre1/drivers/net/dl2k.c	Thu Sep 20 20:56:31 2001
+++ linux/drivers/net/dl2k.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/dmfe.c linux/drivers/net/dmfe.c
--- linux-2.4.11-pre1/drivers/net/dmfe.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/net/dmfe.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/dummy.c linux/drivers/net/dummy.c
--- linux-2.4.11-pre1/drivers/net/dummy.c	Mon Jul  2 14:02:53 2001
+++ linux/drivers/net/dummy.c	Mon Dec  3 23:14:08 2001
@@ -122,3 +122,4 @@
 
 module_init(dummy_init_module);
 module_exit(dummy_cleanup_module);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/e2100.c linux/drivers/net/e2100.c
--- linux-2.4.11-pre1/drivers/net/e2100.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/e2100.c	Mon Dec  3 23:14:08 2001
@@ -440,6 +440,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/eepro.c linux/drivers/net/eepro.c
--- linux-2.4.11-pre1/drivers/net/eepro.c	Sun Aug 12 10:51:42 2001
+++ linux/drivers/net/eepro.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- linux-2.4.11-pre1/drivers/net/eepro100.c	Mon Sep 17 21:32:48 2001
+++ linux/drivers/net/eepro100.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- linux-2.4.11-pre1/drivers/net/eexpress.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/eexpress.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/epic100.c linux/drivers/net/epic100.c
--- linux-2.4.11-pre1/drivers/net/epic100.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/epic100.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/eql.c linux/drivers/net/eql.c
--- linux-2.4.11-pre1/drivers/net/eql.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/net/eql.c	Mon Dec  3 23:14:08 2001
@@ -1016,6 +1016,7 @@
 
 module_init(eql_init_module);
 module_exit(eql_cleanup_module);
+MODULE_LICENSE("GPL");
 
 /*
  * Local Variables: 
diff -urN linux-2.4.11-pre1/drivers/net/es3210.c linux/drivers/net/es3210.c
--- linux-2.4.11-pre1/drivers/net/es3210.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/es3210.c	Mon Dec  3 23:14:08 2001
@@ -429,3 +429,5 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- linux-2.4.11-pre1/drivers/net/eth16i.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/eth16i.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/ethertap.c linux/drivers/net/ethertap.c
--- linux-2.4.11-pre1/drivers/net/ethertap.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/ethertap.c	Mon Dec  3 23:14:08 2001
@@ -374,3 +374,5 @@
 }
 
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- linux-2.4.11-pre1/drivers/net/ewrk3.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/net/ewrk3.c	Mon Dec  3 23:14:08 2001
@@ -1876,6 +1876,8 @@
 	release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE);
 }
 #endif				/* MODULE */
+MODULE_LICENSE("GPL");
+
 
 
 /*
diff -urN linux-2.4.11-pre1/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c
--- linux-2.4.11-pre1/drivers/net/fc/iph5526.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/net/fc/iph5526.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/fc/tach.h linux/drivers/net/fc/tach.h
--- linux-2.4.11-pre1/drivers/net/fc/tach.h	Mon Aug 23 10:12:38 1999
+++ linux/drivers/net/fc/tach.h	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/hamachi.c linux/drivers/net/hamachi.c
--- linux-2.4.11-pre1/drivers/net/hamachi.c	Sun Aug 12 10:51:42 2001
+++ linux/drivers/net/hamachi.c	Mon Dec  3 23:14:08 2001
@@ -521,6 +521,8 @@
 
 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");
diff -urN linux-2.4.11-pre1/drivers/net/hamradio/yam.c linux/drivers/net/hamradio/yam.c
--- linux-2.4.11-pre1/drivers/net/hamradio/yam.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/net/hamradio/yam.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- linux-2.4.11-pre1/drivers/net/hp-plus.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/hp-plus.c	Mon Dec  3 23:14:08 2001
@@ -457,6 +457,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/hp.c linux/drivers/net/hp.c
--- linux-2.4.11-pre1/drivers/net/hp.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/hp.c	Mon Dec  3 23:14:08 2001
@@ -429,6 +429,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/hp100.c linux/drivers/net/hp100.c
--- linux-2.4.11-pre1/drivers/net/hp100.c	Sat Mar  3 10:55:47 2001
+++ linux/drivers/net/hp100.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/irda/actisys.c linux/drivers/net/irda/actisys.c
--- linux-2.4.11-pre1/drivers/net/irda/actisys.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/actisys.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/ali-ircc.c linux/drivers/net/irda/ali-ircc.c
--- linux-2.4.11-pre1/drivers/net/irda/ali-ircc.c	Thu Sep 13 16:26:52 2001
+++ linux/drivers/net/irda/ali-ircc.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/esi.c linux/drivers/net/irda/esi.c
--- linux-2.4.11-pre1/drivers/net/irda/esi.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/esi.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/girbil.c linux/drivers/net/irda/girbil.c
--- linux-2.4.11-pre1/drivers/net/irda/girbil.c	Wed Jun 21 10:10:02 2000
+++ linux/drivers/net/irda/girbil.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- linux-2.4.11-pre1/drivers/net/irda/irport.c	Thu Sep 13 16:26:52 2001
+++ linux/drivers/net/irda/irport.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- linux-2.4.11-pre1/drivers/net/irda/irtty.c	Thu Sep 13 16:26:52 2001
+++ linux/drivers/net/irda/irtty.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/litelink.c linux/drivers/net/irda/litelink.c
--- linux-2.4.11-pre1/drivers/net/irda/litelink.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/litelink.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/nsc-ircc.c linux/drivers/net/irda/nsc-ircc.c
--- linux-2.4.11-pre1/drivers/net/irda/nsc-ircc.c	Thu Sep 13 16:26:52 2001
+++ linux/drivers/net/irda/nsc-ircc.c	Mon Dec  3 23:14:08 2001
@@ -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 -urN linux-2.4.11-pre1/drivers/net/irda/old_belkin.c linux/drivers/net/irda/old_belkin.c
--- linux-2.4.11-pre1/drivers/net/irda/old_belkin.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/old_belkin.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- linux-2.4.11-pre1/drivers/net/irda/smc-ircc.c	Sun Aug 12 10:51:42 2001
+++ linux/drivers/net/irda/smc-ircc.c	Mon Dec  3 23:14:08 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 },
@@ -132,7 +132,7 @@
 	{ 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 },
@@ -1219,6 +1219,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");
diff -urN linux-2.4.11-pre1/drivers/net/irda/tekram.c linux/drivers/net/irda/tekram.c
--- linux-2.4.11-pre1/drivers/net/irda/tekram.c	Thu Jan  6 14:46:18 2000
+++ linux/drivers/net/irda/tekram.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c
--- linux-2.4.11-pre1/drivers/net/irda/toshoboe.c	Sun Sep 23 09:55:14 2001
+++ linux/drivers/net/irda/toshoboe.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/irda/vlsi_ir.c linux/drivers/net/irda/vlsi_ir.c
--- linux-2.4.11-pre1/drivers/net/irda/vlsi_ir.c	Fri Sep 14 14:39:59 2001
+++ linux/drivers/net/irda/vlsi_ir.c	Mon Dec  3 23:14:08 2001
@@ -46,6 +46,8 @@
 
 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";
diff -urN linux-2.4.11-pre1/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
--- linux-2.4.11-pre1/drivers/net/irda/w83977af_ir.c	Thu Sep 13 16:26:52 2001
+++ linux/drivers/net/irda/w83977af_ir.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/lance.c linux/drivers/net/lance.c
--- linux-2.4.11-pre1/drivers/net/lance.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/lance.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/lne390.c linux/drivers/net/lne390.c
--- linux-2.4.11-pre1/drivers/net/lne390.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/lne390.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/lp486e.c linux/drivers/net/lp486e.c
--- linux-2.4.11-pre1/drivers/net/lp486e.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/net/lp486e.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/mac89x0.c linux/drivers/net/mac89x0.c
--- linux-2.4.11-pre1/drivers/net/mac89x0.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/mac89x0.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/natsemi.c linux/drivers/net/natsemi.c
--- linux-2.4.11-pre1/drivers/net/natsemi.c	Tue Aug 14 10:14:12 2001
+++ linux/drivers/net/natsemi.c	Mon Dec  3 23:14:08 2001
@@ -171,6 +171,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");
diff -urN linux-2.4.11-pre1/drivers/net/ne.c linux/drivers/net/ne.c
--- linux-2.4.11-pre1/drivers/net/ne.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/ne.c	Mon Dec  3 23:14:08 2001
@@ -788,6 +788,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
--- linux-2.4.11-pre1/drivers/net/ne2k-pci.c	Wed Jun 20 11:13:18 2001
+++ linux/drivers/net/ne2k-pci.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/ne3210.c linux/drivers/net/ne3210.c
--- linux-2.4.11-pre1/drivers/net/ne3210.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/ne3210.c	Mon Dec  3 23:14:08 2001
@@ -415,5 +415,7 @@
 		}
 	}
 }
+MODULE_LICENSE("GPL");
+
 #endif /* MODULE */
 
diff -urN linux-2.4.11-pre1/drivers/net/ni5010.c linux/drivers/net/ni5010.c
--- linux-2.4.11-pre1/drivers/net/ni5010.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/net/ni5010.c	Mon Dec  3 23:14:08 2001
@@ -783,6 +783,7 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/ni52.c linux/drivers/net/ni52.c
--- linux-2.4.11-pre1/drivers/net/ni52.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/ni52.c	Mon Dec  3 23:14:08 2001
@@ -1362,6 +1362,7 @@
 	printk("\n");
 }
 #endif
+MODULE_LICENSE("GPL");
 
 /*
  * END: linux/drivers/net/ni52.c
diff -urN linux-2.4.11-pre1/drivers/net/ni65.c linux/drivers/net/ni65.c
--- linux-2.4.11-pre1/drivers/net/ni65.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/ni65.c	Mon Dec  3 23:14:08 2001
@@ -1214,6 +1214,7 @@
 	dev_ni65.priv = NULL;
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
 
 /*
  * END of ni65.c
diff -urN linux-2.4.11-pre1/drivers/net/ns83820.c linux/drivers/net/ns83820.c
--- linux-2.4.11-pre1/drivers/net/ns83820.c	Thu Sep 20 14:20:14 2001
+++ linux/drivers/net/ns83820.c	Mon Dec  3 23:14:08 2001
@@ -1,7 +1,7 @@
-#define VERSION "0.11"
+#define VERSION "0.12"
 /* 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,9 @@
  *	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
  *
  * Driver Overview
  * ===============
@@ -61,7 +63,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,6 +370,7 @@
 
 struct ns83820 {
 	struct net_device	net_dev;
+	struct net_device_stats	stats;
 	u8			*base;
 
 	struct pci_dev		*pci_dev;
@@ -732,39 +737,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 +795,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 +980,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 +1084,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,6 +1208,28 @@
 	return 0;
 }
 
+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 ns83820_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 {
 	struct ns83820 *dev;
@@ -1241,6 +1293,9 @@
 	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();
@@ -1423,6 +1478,9 @@
 
 MODULE_AUTHOR("Benjamin LaHaise <bcrl@redhat.com>");
 MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver");
+MODULE_LICENSE("GPL");
+
 MODULE_DEVICE_TABLE(pci, pci_device_id);
+
 module_init(ns83820_init);
 module_exit(ns83820_exit);
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/3c574_cs.c linux/drivers/net/pcmcia/3c574_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/3c574_cs.c	Sun Aug  5 13:12:40 2001
+++ linux/drivers/net/pcmcia/3c574_cs.c	Mon Dec  3 23:14:08 2001
@@ -1312,6 +1312,7 @@
 
 module_init(init_3c574_cs);
 module_exit(exit_3c574_cs);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/3c589_cs.c linux/drivers/net/pcmcia/3c589_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/3c589_cs.c	Sun Aug  5 13:12:40 2001
+++ linux/drivers/net/pcmcia/3c589_cs.c	Mon Dec  3 23:14:08 2001
@@ -1097,3 +1097,4 @@
 
 module_init(init_3c589_cs);
 module_exit(exit_3c589_cs);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/aironet4500_cs.c linux/drivers/net/pcmcia/aironet4500_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/aironet4500_cs.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/pcmcia/aironet4500_cs.c	Mon Dec  3 23:14:08 2001
@@ -644,4 +644,4 @@
 
 module_init(aironet_cs_init);
 module_exit(aironet_cs_exit);
-
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/fmvj18x_cs.c linux/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/fmvj18x_cs.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/pcmcia/fmvj18x_cs.c	Mon Dec  3 23:14:08 2001
@@ -1257,3 +1257,4 @@
     }
     restore_flags(flags);
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/ibmtr_cs.c linux/drivers/net/pcmcia/ibmtr_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/ibmtr_cs.c	Sun Aug  5 13:12:41 2001
+++ linux/drivers/net/pcmcia/ibmtr_cs.c	Mon Dec  3 23:14:08 2001
@@ -107,6 +107,7 @@
 MODULE_PARM(srambase, "i");
 MODULE_PARM(sramsize, "i");
 MODULE_PARM(ringspeed, "i");
+MODULE_LICENSE("GPL");
 
 /*====================================================================*/
 
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/netwave_cs.c linux/drivers/net/pcmcia/netwave_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/netwave_cs.c	Wed Apr 25 14:36:23 2001
+++ linux/drivers/net/pcmcia/netwave_cs.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/pcmcia/nmclan_cs.c linux/drivers/net/pcmcia/nmclan_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/nmclan_cs.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/pcmcia/nmclan_cs.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/pcmcia/pcnet_cs.c linux/drivers/net/pcmcia/pcnet_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/pcnet_cs.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/pcmcia/pcnet_cs.c	Mon Dec  3 23:14:08 2001
@@ -1522,3 +1522,4 @@
 
 module_init(init_pcnet_cs);
 module_exit(exit_pcnet_cs);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/ray_cs.c	Wed Apr 25 14:36:23 2001
+++ linux/drivers/net/pcmcia/ray_cs.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/pcmcia/smc91c92_cs.c linux/drivers/net/pcmcia/smc91c92_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/smc91c92_cs.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/pcmcia/smc91c92_cs.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/pcmcia/wavelan_cs.c linux/drivers/net/pcmcia/wavelan_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/wavelan_cs.c	Wed Apr 25 14:36:23 2001
+++ linux/drivers/net/pcmcia/wavelan_cs.c	Mon Dec  3 23:14:08 2001
@@ -4832,3 +4832,4 @@
 
 module_init(init_wavelan_cs);
 module_exit(exit_wavelan_cs);
+MODULE_LICENSE("BSD without advertisement clause");
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/xirc2ps_cs.c linux/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/xirc2ps_cs.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/net/pcmcia/xirc2ps_cs.c	Mon Dec  3 23:14:08 2001
@@ -2090,3 +2090,4 @@
 
 __setup("xirc2ps_cs=", setup_xirc2ps_cs);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/xircom_cb.c linux/drivers/net/pcmcia/xircom_cb.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/xircom_cb.c	Mon Sep 17 22:52:35 2001
+++ linux/drivers/net/pcmcia/xircom_cb.c	Mon Dec  3 23:14:08 2001
@@ -37,6 +37,7 @@
 
 MODULE_DESCRIPTION("Xircom Cardbus ethernet driver");
 MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>");
+MODULE_LICENSE("GPL");
 
 
 
diff -urN linux-2.4.11-pre1/drivers/net/pcmcia/xircom_tulip_cb.c linux/drivers/net/pcmcia/xircom_tulip_cb.c
--- linux-2.4.11-pre1/drivers/net/pcmcia/xircom_tulip_cb.c	Fri Sep 14 14:40:00 2001
+++ linux/drivers/net/pcmcia/xircom_tulip_cb.c	Mon Dec  3 23:14:08 2001
@@ -106,6 +106,8 @@
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(debug, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(rx_copybreak, "i");
diff -urN linux-2.4.11-pre1/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- linux-2.4.11-pre1/drivers/net/pcnet32.c	Sun Sep  9 10:50:48 2001
+++ linux/drivers/net/pcnet32.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/plip.c linux/drivers/net/plip.c
--- linux-2.4.11-pre1/drivers/net/plip.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/plip.c	Mon Dec  3 23:14:08 2001
@@ -1432,6 +1432,7 @@
 
 module_init(plip_init);
 module_exit(plip_cleanup_module);
+MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
diff -urN linux-2.4.11-pre1/drivers/net/ppp_async.c linux/drivers/net/ppp_async.c
--- linux-2.4.11-pre1/drivers/net/ppp_async.c	Wed Jul  4 11:50:39 2001
+++ linux/drivers/net/ppp_async.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/ppp_deflate.c linux/drivers/net/ppp_deflate.c
--- linux-2.4.11-pre1/drivers/net/ppp_deflate.c	Wed Jul  4 11:50:39 2001
+++ linux/drivers/net/ppp_deflate.c	Mon Dec  3 23:14:08 2001
@@ -657,3 +657,4 @@
 
 module_init(deflate_init);
 module_exit(deflate_cleanup);
+MODULE_LICENSE("BSD without advertisement clause");
diff -urN linux-2.4.11-pre1/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c
--- linux-2.4.11-pre1/drivers/net/rcpci45.c	Mon Jul  2 14:03:04 2001
+++ linux/drivers/net/rcpci45.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/sb1000.c linux/drivers/net/sb1000.c
--- linux-2.4.11-pre1/drivers/net/sb1000.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/sb1000.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/shaper.c linux/drivers/net/shaper.c
--- linux-2.4.11-pre1/drivers/net/shaper.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/net/shaper.c	Mon Dec  3 23:14:08 2001
@@ -743,4 +743,5 @@
 
 module_init(shaper_init);
 module_exit(shaper_exit);
+MODULE_LICENSE("GPL");
 
diff -urN linux-2.4.11-pre1/drivers/net/sis900.c linux/drivers/net/sis900.c
--- linux-2.4.11-pre1/drivers/net/sis900.c	Sun Sep  9 10:45:43 2001
+++ linux/drivers/net/sis900.c	Mon Dec  3 23:14:08 2001
@@ -161,6 +161,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");
diff -urN linux-2.4.11-pre1/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- linux-2.4.11-pre1/drivers/net/sk98lin/skge.c	Tue Aug  7 08:30:50 2001
+++ linux/drivers/net/sk98lin/skge.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/skfp/skfddi.c linux/drivers/net/skfp/skfddi.c
--- linux-2.4.11-pre1/drivers/net/skfp/skfddi.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/skfp/skfddi.c	Mon Dec  3 23:14:08 2001
@@ -187,6 +187,7 @@
 	{ }			/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, skfddi_pci_tbl);
+MODULE_LICENSE("GPL");
 
 // Define module-wide (static) variables
 
diff -urN linux-2.4.11-pre1/drivers/net/slhc.c linux/drivers/net/slhc.c
--- linux-2.4.11-pre1/drivers/net/slhc.c	Tue Mar  6 22:44:16 2001
+++ linux/drivers/net/slhc.c	Mon Dec  3 23:14:08 2001
@@ -797,3 +797,4 @@
 EXPORT_SYMBOL(slhc_toss);
 
 #endif /* CONFIG_INET */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/drivers/net/slip.c linux/drivers/net/slip.c
--- linux-2.4.11-pre1/drivers/net/slip.c	Wed Jun 20 11:10:53 2001
+++ linux/drivers/net/slip.c	Mon Dec  3 23:14:08 2001
@@ -1516,3 +1516,4 @@
 }
 
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- linux-2.4.11-pre1/drivers/net/smc-ultra.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/smc-ultra.c	Mon Dec  3 23:14:08 2001
@@ -557,6 +557,8 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
 
 
 /*
diff -urN linux-2.4.11-pre1/drivers/net/smc-ultra32.c linux/drivers/net/smc-ultra32.c
--- linux-2.4.11-pre1/drivers/net/smc-ultra32.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/smc-ultra32.c	Mon Dec  3 23:14:08 2001
@@ -415,3 +415,5 @@
 	}
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/drivers/net/starfire.c linux/drivers/net/starfire.c
--- linux-2.4.11-pre1/drivers/net/starfire.c	Wed Sep 19 14:10:41 2001
+++ linux/drivers/net/starfire.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/strip.c linux/drivers/net/strip.c
--- linux-2.4.11-pre1/drivers/net/strip.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/net/strip.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/sundance.c linux/drivers/net/sundance.c
--- linux-2.4.11-pre1/drivers/net/sundance.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/sundance.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/sungem.c linux/drivers/net/sungem.c
--- linux-2.4.11-pre1/drivers/net/sungem.c	Thu Sep 20 14:11:57 2001
+++ linux/drivers/net/sungem.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- linux-2.4.11-pre1/drivers/net/sunhme.c	Tue Aug 14 19:57:28 2001
+++ linux/drivers/net/sunhme.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/tlan.c linux/drivers/net/tlan.c
--- linux-2.4.11-pre1/drivers/net/tlan.c	Mon Jul  2 14:03:04 2001
+++ linux/drivers/net/tlan.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/tokenring/lanstreamer.c linux/drivers/net/tokenring/lanstreamer.c
--- linux-2.4.11-pre1/drivers/net/tokenring/lanstreamer.c	Wed Jun 20 11:13:18 2001
+++ linux/drivers/net/tokenring/lanstreamer.c	Mon Dec  3 23:14:08 2001
@@ -1825,3 +1825,4 @@
 
 module_init(streamer_init_module);
 module_exit(streamer_cleanup_module);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- linux-2.4.11-pre1/drivers/net/tulip/tulip_core.c	Thu Sep 20 20:57:31 2001
+++ linux/drivers/net/tulip/tulip_core.c	Mon Dec  3 23:14:08 2001
@@ -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 -urN linux-2.4.11-pre1/drivers/net/tun.c linux/drivers/net/tun.c
--- linux-2.4.11-pre1/drivers/net/tun.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/net/tun.c	Mon Dec  3 23:14:08 2001
@@ -581,3 +581,4 @@
 
 module_init(tun_init);
 module_exit(tun_cleanup);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- linux-2.4.11-pre1/drivers/net/via-rhine.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/net/via-rhine.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/wan/cycx_drv.c linux/drivers/net/wan/cycx_drv.c
--- linux-2.4.11-pre1/drivers/net/wan/cycx_drv.c	Mon Apr  3 19:32:57 2000
+++ linux/drivers/net/wan/cycx_drv.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/wan/hostess_sv11.c linux/drivers/net/wan/hostess_sv11.c
--- linux-2.4.11-pre1/drivers/net/wan/hostess_sv11.c	Sun Sep  9 10:50:48 2001
+++ linux/drivers/net/wan/hostess_sv11.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/wan/sealevel.c linux/drivers/net/wan/sealevel.c
--- linux-2.4.11-pre1/drivers/net/wan/sealevel.c	Sun Sep  9 10:50:48 2001
+++ linux/drivers/net/wan/sealevel.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- linux-2.4.11-pre1/drivers/net/wavelan.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/wavelan.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/net/wd.c linux/drivers/net/wd.c
--- linux-2.4.11-pre1/drivers/net/wd.c	Tue Jul 17 18:53:55 2001
+++ linux/drivers/net/wd.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- linux-2.4.11-pre1/drivers/net/winbond-840.c	Fri Sep 14 14:40:00 2001
+++ linux/drivers/net/winbond-840.c	Mon Dec  3 23:14:08 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");
diff -urN linux-2.4.11-pre1/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
--- linux-2.4.11-pre1/drivers/net/yellowfin.c	Thu Sep 20 20:56:32 2001
+++ linux/drivers/net/yellowfin.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/parport/parport_cs.c linux/drivers/parport/parport_cs.c
--- linux-2.4.11-pre1/drivers/parport/parport_cs.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/parport/parport_cs.c	Mon Dec  3 23:14:08 2001
@@ -480,3 +480,4 @@
 
 module_init(init_parport_cs);
 module_exit(exit_parport_cs);
+MODULE_LICENSE("Dual MPL/GPL");
diff -urN linux-2.4.11-pre1/drivers/parport/parport_serial.c linux/drivers/parport/parport_serial.c
--- linux-2.4.11-pre1/drivers/parport/parport_serial.c	Fri Sep  7 18:15:17 2001
+++ linux/drivers/parport/parport_serial.c	Mon Dec  3 23:14:08 2001
@@ -357,6 +357,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 -urN linux-2.4.11-pre1/drivers/parport/share.c linux/drivers/parport/share.c
--- linux-2.4.11-pre1/drivers/parport/share.c	Sun Aug 12 12:31:28 2001
+++ linux/drivers/parport/share.c	Mon Dec  3 23:14:08 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>
@@ -1140,3 +1141,4 @@
 	return parport_parse_params (nports, dmastr, dmaval, PARPORT_DMA_AUTO,
 				     PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO);
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/pcmcia/cb_enabler.c linux/drivers/pcmcia/cb_enabler.c
--- linux-2.4.11-pre1/drivers/pcmcia/cb_enabler.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/pcmcia/cb_enabler.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- linux-2.4.11-pre1/drivers/pcmcia/cs.c	Wed Jun 20 11:19:02 2001
+++ linux/drivers/pcmcia/cs.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
--- linux-2.4.11-pre1/drivers/pcmcia/ds.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/pcmcia/ds.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c
--- linux-2.4.11-pre1/drivers/pcmcia/i82365.c	Tue Sep 18 14:10:43 2001
+++ linux/drivers/pcmcia/i82365.c	Mon Dec  3 23:14:08 2001
@@ -1660,5 +1660,5 @@
 
 module_init(init_i82365);
 module_exit(exit_i82365);
-
+MODULE_LICENSE("Dual MPL/GPL");
 /*====================================================================*/
diff -urN linux-2.4.11-pre1/drivers/pcmcia/tcic.c linux/drivers/pcmcia/tcic.c
--- linux-2.4.11-pre1/drivers/pcmcia/tcic.c	Tue Mar  6 19:28:32 2001
+++ linux/drivers/pcmcia/tcic.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- linux-2.4.11-pre1/drivers/pcmcia/yenta.c	Wed Aug 29 06:13:40 2001
+++ linux/drivers/pcmcia/yenta.c	Mon Dec  3 23:14:08 2001
@@ -895,3 +895,4 @@
 	yenta_proc_setup
 };
 EXPORT_SYMBOL(yenta_operations);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
--- linux-2.4.11-pre1/drivers/s390/block/dasd.c	Mon Sep 10 12:42:32 2001
+++ linux/drivers/s390/block/dasd.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/block/dasd_3990_erp.c linux/drivers/s390/block/dasd_3990_erp.c
--- linux-2.4.11-pre1/drivers/s390/block/dasd_3990_erp.c	Sun Aug  5 13:12:41 2001
+++ linux/drivers/s390/block/dasd_3990_erp.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/block/dasd_diag.c linux/drivers/s390/block/dasd_diag.c
--- linux-2.4.11-pre1/drivers/s390/block/dasd_diag.c	Sun Aug  5 13:12:41 2001
+++ linux/drivers/s390/block/dasd_diag.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/block/dasd_eckd.c linux/drivers/s390/block/dasd_eckd.c
--- linux-2.4.11-pre1/drivers/s390/block/dasd_eckd.c	Sun Aug  5 13:12:41 2001
+++ linux/drivers/s390/block/dasd_eckd.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/block/dasd_eckd.h linux/drivers/s390/block/dasd_eckd.h
--- linux-2.4.11-pre1/drivers/s390/block/dasd_eckd.h	Sun Aug  5 13:12:41 2001
+++ linux/drivers/s390/block/dasd_eckd.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/block/dasd_fba.c linux/drivers/s390/block/dasd_fba.c
--- linux-2.4.11-pre1/drivers/s390/block/dasd_fba.c	Sun Aug  5 13:12:41 2001
+++ linux/drivers/s390/block/dasd_fba.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/block/dasd_int.h linux/drivers/s390/block/dasd_int.h
--- linux-2.4.11-pre1/drivers/s390/block/dasd_int.h	Sun Aug  5 13:12:41 2001
+++ linux/drivers/s390/block/dasd_int.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/char/ctrlchar.c linux/drivers/s390/char/ctrlchar.c
--- linux-2.4.11-pre1/drivers/s390/char/ctrlchar.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/s390/char/ctrlchar.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/char/hwc_cpi.c linux/drivers/s390/char/hwc_cpi.c
--- linux-2.4.11-pre1/drivers/s390/char/hwc_cpi.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/s390/char/hwc_cpi.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/char/hwc_rw.c linux/drivers/s390/char/hwc_rw.c
--- linux-2.4.11-pre1/drivers/s390/char/hwc_rw.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/s390/char/hwc_rw.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/misc/chandev.c linux/drivers/s390/misc/chandev.c
--- linux-2.4.11-pre1/drivers/s390/misc/chandev.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/s390/misc/chandev.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/net/ctcmain.c linux/drivers/s390/net/ctcmain.c
--- linux-2.4.11-pre1/drivers/s390/net/ctcmain.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/s390/net/ctcmain.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/net/iucv.c linux/drivers/s390/net/iucv.c
--- linux-2.4.11-pre1/drivers/s390/net/iucv.c	Mon Sep 10 09:04:53 2001
+++ linux/drivers/s390/net/iucv.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/net/iucv.h linux/drivers/s390/net/iucv.h
--- linux-2.4.11-pre1/drivers/s390/net/iucv.h	Wed Jul 25 14:12:02 2001
+++ linux/drivers/s390/net/iucv.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/net/netiucv.c linux/drivers/s390/net/netiucv.c
--- linux-2.4.11-pre1/drivers/s390/net/netiucv.c	Mon Sep 10 09:04:53 2001
+++ linux/drivers/s390/net/netiucv.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/s390/s390io.c linux/drivers/s390/s390io.c
--- linux-2.4.11-pre1/drivers/s390/s390io.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/s390/s390io.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- linux-2.4.11-pre1/drivers/scsi/3w-xxxx.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/scsi/3w-xxxx.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- linux-2.4.11-pre1/drivers/scsi/53c7,8xx.c	Fri Apr 27 14:04:32 2001
+++ linux/drivers/scsi/53c7,8xx.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/53c700.c linux/drivers/scsi/53c700.c
--- linux-2.4.11-pre1/drivers/scsi/53c700.c	Sun Sep  9 10:50:48 2001
+++ linux/drivers/scsi/53c700.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/53c700.h linux/drivers/scsi/53c700.h
--- linux-2.4.11-pre1/drivers/scsi/53c700.h	Sun Sep  9 10:50:48 2001
+++ linux/drivers/scsi/53c700.h	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/53c700.scr linux/drivers/scsi/53c700.scr
--- linux-2.4.11-pre1/drivers/scsi/53c700.scr	Sun Sep  9 10:50:48 2001
+++ linux/drivers/scsi/53c700.scr	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c
--- linux-2.4.11-pre1/drivers/scsi/53c7xx.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/scsi/53c7xx.c	Mon Dec  3 23:14:08 2001
@@ -230,9 +230,7 @@
  *
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <linux/config.h>
 
diff -urN linux-2.4.11-pre1/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c
--- linux-2.4.11-pre1/drivers/scsi/AM53C974.c	Fri Apr 27 13:59:17 2001
+++ linux/drivers/scsi/AM53C974.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- linux-2.4.11-pre1/drivers/scsi/BusLogic.c	Thu Jul  5 11:28:16 2001
+++ linux/drivers/scsi/BusLogic.c	Mon Dec  3 23:14:08 2001
@@ -4993,6 +4993,7 @@
 /*
   Get it all started
 */
+MODULE_LICENSE("GPL");
 
 static SCSI_Host_Template_T driver_template = BUSLOGIC;
 
diff -urN linux-2.4.11-pre1/drivers/scsi/ChangeLog.serverraid linux/drivers/scsi/ChangeLog.serverraid
--- linux-2.4.11-pre1/drivers/scsi/ChangeLog.serverraid	Mon Aug 30 10:43:25 1999
+++ linux/drivers/scsi/ChangeLog.serverraid	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- linux-2.4.11-pre1/drivers/scsi/Config.in	Sun Sep  9 10:52:35 2001
+++ linux/drivers/scsi/Config.in	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- linux-2.4.11-pre1/drivers/scsi/Makefile	Wed Sep 12 15:35:39 2001
+++ linux/drivers/scsi/Makefile	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c
--- linux-2.4.11-pre1/drivers/scsi/NCR53C9x.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/scsi/NCR53C9x.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c
--- linux-2.4.11-pre1/drivers/scsi/NCR53c406a.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/scsi/NCR53c406a.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- linux-2.4.11-pre1/drivers/scsi/advansys.c	Sun Aug 12 17:37:53 2001
+++ linux/drivers/scsi/advansys.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- linux-2.4.11-pre1/drivers/scsi/aha152x.c	Sun Aug  5 13:12:40 2001
+++ linux/drivers/scsi/aha152x.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- linux-2.4.11-pre1/drivers/scsi/aha1542.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/scsi/aha1542.c	Mon Dec  3 23:14:08 2001
@@ -1800,6 +1800,7 @@
 
 	return 0;
 }
+MODULE_LICENSE("GPL");
 
 
 /* Eventually this will go into an include file, but this will be later */
diff -urN linux-2.4.11-pre1/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- linux-2.4.11-pre1/drivers/scsi/aha1740.c	Tue Mar  6 19:44:37 2001
+++ linux/drivers/scsi/aha1740.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/aic7xxx/aic7xxx_linux.c linux/drivers/scsi/aic7xxx/aic7xxx_linux.c
--- linux-2.4.11-pre1/drivers/scsi/aic7xxx/aic7xxx_linux.c	Sun Aug 12 17:37:53 2001
+++ linux/drivers/scsi/aic7xxx/aic7xxx_linux.c	Mon Dec  3 23:14:08 2001
@@ -120,9 +120,7 @@
  * under normal conditions.
  */
 
-#if defined(MODULE)
 #include <linux/module.h>
-#endif
 
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
@@ -2869,6 +2867,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 -urN linux-2.4.11-pre1/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- linux-2.4.11-pre1/drivers/scsi/aic7xxx_old.c	Tue Sep 18 14:10:44 2001
+++ linux/drivers/scsi/aic7xxx_old.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c
--- linux-2.4.11-pre1/drivers/scsi/atp870u.c	Sun Aug 12 10:51:41 2001
+++ linux/drivers/scsi/atp870u.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/cpqfcTSinit.c linux/drivers/scsi/cpqfcTSinit.c
--- linux-2.4.11-pre1/drivers/scsi/cpqfcTSinit.c	Sun Aug 12 10:51:41 2001
+++ linux/drivers/scsi/cpqfcTSinit.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/dmx3191d.c linux/drivers/scsi/dmx3191d.c
--- linux-2.4.11-pre1/drivers/scsi/dmx3191d.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/scsi/dmx3191d.c	Mon Dec  3 23:14:08 2001
@@ -119,6 +119,7 @@
 	return 0;
 }
 
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = DMX3191D;
 #include "scsi_module.c"
diff -urN linux-2.4.11-pre1/drivers/scsi/dpt_i2o.c linux/drivers/scsi/dpt_i2o.c
--- linux-2.4.11-pre1/drivers/scsi/dpt_i2o.c	Sun Sep  9 10:52:35 2001
+++ linux/drivers/scsi/dpt_i2o.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/dtc.c linux/drivers/scsi/dtc.c
--- linux-2.4.11-pre1/drivers/scsi/dtc.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/dtc.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- linux-2.4.11-pre1/drivers/scsi/eata.c	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/eata.c	Mon Dec  3 23:14:08 2001
@@ -2077,3 +2077,4 @@
 #ifndef MODULE
 __setup("eata=", option_setup);
 #endif /* end MODULE */
+MODULE_LICENSE("BSD");
diff -urN linux-2.4.11-pre1/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- linux-2.4.11-pre1/drivers/scsi/eata_dma.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/scsi/eata_dma.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c
--- linux-2.4.11-pre1/drivers/scsi/eata_pio.c	Mon Sep 10 08:06:32 2001
+++ linux/drivers/scsi/eata_pio.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/fd_mcs.c linux/drivers/scsi/fd_mcs.c
--- linux-2.4.11-pre1/drivers/scsi/fd_mcs.c	Mon Sep 18 13:36:25 2000
+++ linux/drivers/scsi/fd_mcs.c	Mon Dec  3 23:14:08 2001
@@ -77,9 +77,7 @@
 
  **************************************************************************/
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <linux/sched.h>
 #include <linux/blk.h>
diff -urN linux-2.4.11-pre1/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- linux-2.4.11-pre1/drivers/scsi/fdomain.c	Sun Jul 15 16:22:23 2001
+++ linux/drivers/scsi/fdomain.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- linux-2.4.11-pre1/drivers/scsi/g_NCR5380.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/scsi/g_NCR5380.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- linux-2.4.11-pre1/drivers/scsi/gdth.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/scsi/gdth.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.4.11-pre1/drivers/scsi/ide-scsi.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/scsi/ide-scsi.c	Mon Dec  3 23:14:08 2001
@@ -849,3 +849,4 @@
 
 module_init(init_idescsi_module);
 module_exit(exit_idescsi_module);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/scsi/imm.c linux/drivers/scsi/imm.c
--- linux-2.4.11-pre1/drivers/scsi/imm.c	Sun Aug 12 12:31:28 2001
+++ linux/drivers/scsi/imm.c	Mon Dec  3 23:14:08 2001
@@ -1270,3 +1270,4 @@
     printk("imm: No devices found, aborting driver load.\n");
     return 1;
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c
--- linux-2.4.11-pre1/drivers/scsi/in2000.c	Sun Aug 12 10:51:41 2001
+++ linux/drivers/scsi/in2000.c	Mon Dec  3 23:14:08 2001
@@ -2360,6 +2360,8 @@
 
 }
 
+MODULE_LICENSE("GPL");
+
 
 static Scsi_Host_Template driver_template = IN2000;
 #include "scsi_module.c"
diff -urN linux-2.4.11-pre1/drivers/scsi/ini9100u.c linux/drivers/scsi/ini9100u.c
--- linux-2.4.11-pre1/drivers/scsi/ini9100u.c	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/ini9100u.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/inia100.c linux/drivers/scsi/inia100.c
--- linux-2.4.11-pre1/drivers/scsi/inia100.c	Fri Mar  2 18:38:38 2001
+++ linux/drivers/scsi/inia100.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/ips.c linux/drivers/scsi/ips.c
--- linux-2.4.11-pre1/drivers/scsi/ips.c	Thu Aug 16 09:49:49 2001
+++ linux/drivers/scsi/ips.c	Mon Dec  3 23:14:08 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);
 
-   mdata.plh.plh_type = 0;
-   mdata.plh.plh_wp = 0;
-   mdata.plh.plh_bdl = 8;
+   memset(&mdata, 0, sizeof(IPS_SCSI_MODE_PAGE_DATA));
+
+   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)
@@ -7519,9 +7566,10 @@
       return (0);
 }
 
+#if defined (MODULE)
 static Scsi_Host_Template driver_template = IPS;
 #include "scsi_module.c"
-
+#endif
 
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
diff -urN linux-2.4.11-pre1/drivers/scsi/ips.h linux/drivers/scsi/ips.h
--- linux-2.4.11-pre1/drivers/scsi/ips.h	Thu Jul 19 21:08:13 2001
+++ linux/drivers/scsi/ips.h	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/lasi700.c linux/drivers/scsi/lasi700.c
--- linux-2.4.11-pre1/drivers/scsi/lasi700.c	Sun Sep  9 11:58:36 2001
+++ linux/drivers/scsi/lasi700.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/lasi700.h linux/drivers/scsi/lasi700.h
--- linux-2.4.11-pre1/drivers/scsi/lasi700.h	Sun Sep  9 11:58:36 2001
+++ linux/drivers/scsi/lasi700.h	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
--- linux-2.4.11-pre1/drivers/scsi/megaraid.c	Mon Sep 17 13:16:30 2001
+++ linux/drivers/scsi/megaraid.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- linux-2.4.11-pre1/drivers/scsi/ncr53c8xx.c	Thu Jul  5 11:28:17 2001
+++ linux/drivers/scsi/ncr53c8xx.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/osst.c linux/drivers/scsi/osst.c
--- linux-2.4.11-pre1/drivers/scsi/osst.c	Thu Jul 19 21:18:15 2001
+++ linux/drivers/scsi/osst.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c
--- linux-2.4.11-pre1/drivers/scsi/pas16.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/pas16.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c
--- linux-2.4.11-pre1/drivers/scsi/pci2000.c	Fri Apr 27 14:06:02 2001
+++ linux/drivers/scsi/pci2000.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/pci2220i.c linux/drivers/scsi/pci2220i.c
--- linux-2.4.11-pre1/drivers/scsi/pci2220i.c	Mon Apr 30 17:13:07 2001
+++ linux/drivers/scsi/pci2220i.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/pcmcia/aha152x_stub.c linux/drivers/scsi/pcmcia/aha152x_stub.c
--- linux-2.4.11-pre1/drivers/scsi/pcmcia/aha152x_stub.c	Fri Mar  2 18:38:39 2001
+++ linux/drivers/scsi/pcmcia/aha152x_stub.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c
--- linux-2.4.11-pre1/drivers/scsi/pcmcia/nsp_cs.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/scsi/pcmcia/nsp_cs.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
--- linux-2.4.11-pre1/drivers/scsi/ppa.c	Sun Aug 12 12:31:28 2001
+++ linux/drivers/scsi/ppa.c	Mon Dec  3 23:14:08 2001
@@ -1145,3 +1145,4 @@
     printk("ppa: No devices found, aborting driver load.\n");
     return 1;
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/scsi/psi240i.c linux/drivers/scsi/psi240i.c
--- linux-2.4.11-pre1/drivers/scsi/psi240i.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/psi240i.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/qla1280.c linux/drivers/scsi/qla1280.c
--- linux-2.4.11-pre1/drivers/scsi/qla1280.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/scsi/qla1280.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c
--- linux-2.4.11-pre1/drivers/scsi/qlogicfas.c	Tue May 22 10:23:16 2001
+++ linux/drivers/scsi/qlogicfas.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- linux-2.4.11-pre1/drivers/scsi/qlogicfc.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/scsi/qlogicfc.c	Mon Dec  3 23:14:08 2001
@@ -2259,6 +2259,7 @@
 
 #endif				/* DEBUG_ISP2x00 */
 
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = QLOGICFC;
 
diff -urN linux-2.4.11-pre1/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- linux-2.4.11-pre1/drivers/scsi/qlogicisp.c	Thu Jul  5 11:28:17 2001
+++ linux/drivers/scsi/qlogicisp.c	Mon Dec  3 23:14:08 2001
@@ -1994,6 +1994,7 @@
 
 #endif /* DEBUG_ISP1020 */
 
+MODULE_LICENSE("GPL");
 
 static Scsi_Host_Template driver_template = QLOGICISP;
 
diff -urN linux-2.4.11-pre1/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- linux-2.4.11-pre1/drivers/scsi/scsi.c	Thu Jul 19 21:07:04 2001
+++ linux/drivers/scsi/scsi.c	Mon Dec  3 23:14:08 2001
@@ -2515,6 +2515,7 @@
 
 MODULE_PARM(scsihosts, "s");
 MODULE_DESCRIPTION("SCSI core");
+MODULE_LICENSE("GPL");
 
 #ifndef MODULE
 int __init scsi_setup(char *str)
diff -urN linux-2.4.11-pre1/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- linux-2.4.11-pre1/drivers/scsi/scsi_debug.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/scsi_debug.c	Mon Dec  3 23:14:08 2001
@@ -805,3 +805,4 @@
  * tab-width: 8
  * End:
  */
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- linux-2.4.11-pre1/drivers/scsi/sd.c	Mon Sep 10 12:42:32 2001
+++ linux/drivers/scsi/sd.c	Mon Dec  3 23:14:08 2001
@@ -1409,3 +1409,4 @@
 
 module_init(init_sd);
 module_exit(exit_sd);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- linux-2.4.11-pre1/drivers/scsi/seagate.c	Fri Sep 14 14:40:00 2001
+++ linux/drivers/scsi/seagate.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- linux-2.4.11-pre1/drivers/scsi/sg.c	Sun Sep 16 11:09:45 2001
+++ linux/drivers/scsi/sg.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/sim710.c linux/drivers/scsi/sim710.c
--- linux-2.4.11-pre1/drivers/scsi/sim710.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/scsi/sim710.c	Mon Dec  3 23:14:08 2001
@@ -187,6 +187,8 @@
 
 MODULE_AUTHOR("Richard Hirst");
 MODULE_DESCRIPTION("Simple NCR53C710 driver");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(sim710, "s");
 
 #endif
diff -urN linux-2.4.11-pre1/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- linux-2.4.11-pre1/drivers/scsi/sr.c	Mon Aug 27 14:20:21 2001
+++ linux/drivers/scsi/sr.c	Mon Dec  3 23:14:08 2001
@@ -940,3 +940,4 @@
 
 module_init(init_sr);
 module_exit(exit_sr);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/scsi/st.c linux/drivers/scsi/st.c
--- linux-2.4.11-pre1/drivers/scsi/st.c	Sun Aug 12 11:21:47 2001
+++ linux/drivers/scsi/st.c	Mon Dec  3 23:14:08 2001
@@ -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");
diff -urN linux-2.4.11-pre1/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c
--- linux-2.4.11-pre1/drivers/scsi/sym53c416.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/scsi/sym53c416.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- linux-2.4.11-pre1/drivers/scsi/sym53c8xx.c	Thu Jul  5 11:28:16 2001
+++ linux/drivers/scsi/sym53c8xx.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/t128.c linux/drivers/scsi/t128.c
--- linux-2.4.11-pre1/drivers/scsi/t128.c	Sat Nov 11 19:01:11 2000
+++ linux/drivers/scsi/t128.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/tmscsim.c linux/drivers/scsi/tmscsim.c
--- linux-2.4.11-pre1/drivers/scsi/tmscsim.c	Fri Apr 27 14:07:19 2001
+++ linux/drivers/scsi/tmscsim.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- linux-2.4.11-pre1/drivers/scsi/u14-34f.c	Sat May 19 17:43:06 2001
+++ linux/drivers/scsi/u14-34f.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- linux-2.4.11-pre1/drivers/scsi/ultrastor.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/scsi/ultrastor.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c
--- linux-2.4.11-pre1/drivers/scsi/wd7000.c	Wed Apr 11 19:02:37 2001
+++ linux/drivers/scsi/wd7000.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/ac97.c linux/drivers/sound/ac97.c
--- linux-2.4.11-pre1/drivers/sound/ac97.c	Sun Jul 15 16:22:23 2001
+++ linux/drivers/sound/ac97.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- linux-2.4.11-pre1/drivers/sound/ac97_codec.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/sound/ac97_codec.c	Mon Dec  3 23:14:08 2001
@@ -1020,3 +1020,4 @@
 }
 
 EXPORT_SYMBOL(ac97_set_adc_rate);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/aci.c linux/drivers/sound/aci.c
--- linux-2.4.11-pre1/drivers/sound/aci.c	Tue Jun 12 10:56:11 2001
+++ linux/drivers/sound/aci.c	Mon Dec  3 23:14:08 2001
@@ -706,3 +706,4 @@
 
 module_init(attach_aci);
 module_exit(unload_aci);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/ad1816.c linux/drivers/sound/ad1816.c
--- linux-2.4.11-pre1/drivers/sound/ad1816.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/ad1816.c	Mon Dec  3 23:14:08 2001
@@ -1471,3 +1471,4 @@
 
 __setup("ad1816=", setup_ad1816);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- linux-2.4.11-pre1/drivers/sound/ad1848.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/sound/ad1848.c	Mon Dec  3 23:14:08 2001
@@ -3064,3 +3064,4 @@
 
 __setup("ad1848=", setup_ad1848);	
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/adlib_card.c linux/drivers/sound/adlib_card.c
--- linux-2.4.11-pre1/drivers/sound/adlib_card.c	Sat May 19 12:50:28 2001
+++ linux/drivers/sound/adlib_card.c	Mon Dec  3 23:14:08 2001
@@ -70,3 +70,4 @@
 }
 __setup("adlib=", setup_adlib);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/aedsp16.c linux/drivers/sound/aedsp16.c
--- linux-2.4.11-pre1/drivers/sound/aedsp16.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/sound/aedsp16.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/awe_wave.c linux/drivers/sound/awe_wave.c
--- linux-2.4.11-pre1/drivers/sound/awe_wave.c	Mon Aug 27 08:11:43 2001
+++ linux/drivers/sound/awe_wave.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- linux-2.4.11-pre1/drivers/sound/cmpci.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/sound/cmpci.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/cs4232.c linux/drivers/sound/cs4232.c
--- linux-2.4.11-pre1/drivers/sound/cs4232.c	Mon Jul  2 13:56:41 2001
+++ linux/drivers/sound/cs4232.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/cs4281/cs4281m.c linux/drivers/sound/cs4281/cs4281m.c
--- linux-2.4.11-pre1/drivers/sound/cs4281/cs4281m.c	Sun Aug 12 10:51:41 2001
+++ linux/drivers/sound/cs4281/cs4281m.c	Mon Dec  3 23:14:08 2001
@@ -4512,6 +4512,7 @@
 
 MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com");
 MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
+MODULE_LICENSE("GPL");
 
 // --------------------------------------------------------------------- 
 
diff -urN linux-2.4.11-pre1/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- linux-2.4.11-pre1/drivers/sound/cs46xx.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/sound/cs46xx.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/emu10k1/main.c linux/drivers/sound/emu10k1/main.c
--- linux-2.4.11-pre1/drivers/sound/emu10k1/main.c	Sun Aug 12 17:53:57 2001
+++ linux/drivers/sound/emu10k1/main.c	Mon Dec  3 23:14:08 2001
@@ -999,6 +999,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",
diff -urN linux-2.4.11-pre1/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- linux-2.4.11-pre1/drivers/sound/es1370.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/sound/es1370.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- linux-2.4.11-pre1/drivers/sound/es1371.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/sound/es1371.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c
--- linux-2.4.11-pre1/drivers/sound/esssolo1.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/sound/esssolo1.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/gus_card.c linux/drivers/sound/gus_card.c
--- linux-2.4.11-pre1/drivers/sound/gus_card.c	Sun Sep 17 09:45:05 2000
+++ linux/drivers/sound/gus_card.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- linux-2.4.11-pre1/drivers/sound/i810_audio.c	Sun Sep  9 10:52:35 2001
+++ linux/drivers/sound/i810_audio.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/mad16.c linux/drivers/sound/mad16.c
--- linux-2.4.11-pre1/drivers/sound/mad16.c	Fri Apr  6 10:51:19 2001
+++ linux/drivers/sound/mad16.c	Mon Dec  3 23:14:08 2001
@@ -1071,3 +1071,4 @@
 
 __setup("mad16=", setup_mad16);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/maestro.c linux/drivers/sound/maestro.c
--- linux-2.4.11-pre1/drivers/sound/maestro.c	Sun Sep 23 09:53:45 2001
+++ linux/drivers/sound/maestro.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/maestro3.c linux/drivers/sound/maestro3.c
--- linux-2.4.11-pre1/drivers/sound/maestro3.c	Sun Aug 12 10:38:48 2001
+++ linux/drivers/sound/maestro3.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/maui.c linux/drivers/sound/maui.c
--- linux-2.4.11-pre1/drivers/sound/maui.c	Sat Nov 11 18:33:13 2000
+++ linux/drivers/sound/maui.c	Mon Dec  3 23:14:08 2001
@@ -474,3 +474,4 @@
 
 __setup("maui=", setup_maui);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/midibuf.c linux/drivers/sound/midibuf.c
--- linux-2.4.11-pre1/drivers/sound/midibuf.c	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/midibuf.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/mpu401.c linux/drivers/sound/mpu401.c
--- linux-2.4.11-pre1/drivers/sound/mpu401.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/mpu401.c	Mon Dec  3 23:14:08 2001
@@ -1794,3 +1794,4 @@
 
 __setup("mpu401=", setup_mpu401);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/msnd.c linux/drivers/sound/msnd.c
--- linux-2.4.11-pre1/drivers/sound/msnd.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/sound/msnd.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- linux-2.4.11-pre1/drivers/sound/msnd_pinnacle.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/sound/msnd_pinnacle.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/nm256_audio.c linux/drivers/sound/nm256_audio.c
--- linux-2.4.11-pre1/drivers/sound/nm256_audio.c	Wed Jul  4 11:50:39 2001
+++ linux/drivers/sound/nm256_audio.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/opl3.c linux/drivers/sound/opl3.c
--- linux-2.4.11-pre1/drivers/sound/opl3.c	Sun Sep 17 09:45:06 2000
+++ linux/drivers/sound/opl3.c	Mon Dec  3 23:14:08 2001
@@ -1250,3 +1250,4 @@
 
 __setup("opl3=", setup_opl3);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/opl3sa.c linux/drivers/sound/opl3sa.c
--- linux-2.4.11-pre1/drivers/sound/opl3sa.c	Wed Sep 27 13:53:56 2000
+++ linux/drivers/sound/opl3sa.c	Mon Dec  3 23:14:08 2001
@@ -334,3 +334,4 @@
 
 __setup("opl3sa=", setup_opl3sa);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- linux-2.4.11-pre1/drivers/sound/opl3sa2.c	Sun Sep  9 10:52:35 2001
+++ linux/drivers/sound/opl3sa2.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/pas2_card.c linux/drivers/sound/pas2_card.c
--- linux-2.4.11-pre1/drivers/sound/pas2_card.c	Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/pas2_card.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/pss.c linux/drivers/sound/pss.c
--- linux-2.4.11-pre1/drivers/sound/pss.c	Tue Jun 12 11:06:54 2001
+++ linux/drivers/sound/pss.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/rme96xx.c linux/drivers/sound/rme96xx.c
--- linux-2.4.11-pre1/drivers/sound/rme96xx.c	Sun Aug 12 10:51:42 2001
+++ linux/drivers/sound/rme96xx.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- linux-2.4.11-pre1/drivers/sound/sb_card.c	Tue Sep 18 14:10:43 2001
+++ linux/drivers/sound/sb_card.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- linux-2.4.11-pre1/drivers/sound/sb_common.c	Wed Jul  4 11:50:39 2001
+++ linux/drivers/sound/sb_common.c	Mon Dec  3 23:14:08 2001
@@ -1292,3 +1292,4 @@
 EXPORT_SYMBOL(probe_sbmpu);
 EXPORT_SYMBOL(unload_sbmpu);
 EXPORT_SYMBOL(smw_free);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c
--- linux-2.4.11-pre1/drivers/sound/sb_mixer.c	Wed Jul 25 14:12:02 2001
+++ linux/drivers/sound/sb_mixer.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/sgalaxy.c linux/drivers/sound/sgalaxy.c
--- linux-2.4.11-pre1/drivers/sound/sgalaxy.c	Sat Nov 11 18:33:14 2000
+++ linux/drivers/sound/sgalaxy.c	Mon Dec  3 23:14:08 2001
@@ -194,3 +194,4 @@
 
 __setup("sgalaxy=", setup_sgalaxy);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- linux-2.4.11-pre1/drivers/sound/sonicvibes.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/sound/sonicvibes.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- linux-2.4.11-pre1/drivers/sound/sound_core.c	Sun Sep  9 10:52:35 2001
+++ linux/drivers/sound/sound_core.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- linux-2.4.11-pre1/drivers/sound/soundcard.c	Sun Aug 12 10:51:42 2001
+++ linux/drivers/sound/soundcard.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/sscape.c linux/drivers/sound/sscape.c
--- linux-2.4.11-pre1/drivers/sound/sscape.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/sound/sscape.c	Mon Dec  3 23:14:08 2001
@@ -1528,3 +1528,4 @@
 
 __setup("sscape=", setup_sscape);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/trident.c linux/drivers/sound/trident.c
--- linux-2.4.11-pre1/drivers/sound/trident.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/sound/trident.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/trix.c linux/drivers/sound/trix.c
--- linux-2.4.11-pre1/drivers/sound/trix.c	Sun Jan 28 13:30:07 2001
+++ linux/drivers/sound/trix.c	Mon Dec  3 23:14:08 2001
@@ -543,3 +543,4 @@
 
 __setup("trix=", setup_trix);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/uart401.c linux/drivers/sound/uart401.c
--- linux-2.4.11-pre1/drivers/sound/uart401.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/uart401.c	Mon Dec  3 23:14:08 2001
@@ -478,3 +478,4 @@
 
 __setup("uart401=", setup_uart401);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/uart6850.c linux/drivers/sound/uart6850.c
--- linux-2.4.11-pre1/drivers/sound/uart6850.c	Sun Sep 17 09:45:07 2000
+++ linux/drivers/sound/uart6850.c	Mon Dec  3 23:14:08 2001
@@ -361,3 +361,4 @@
 }
 __setup("uart6850=", setup_uart6850);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/v_midi.c linux/drivers/sound/v_midi.c
--- linux-2.4.11-pre1/drivers/sound/v_midi.c	Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/v_midi.c	Mon Dec  3 23:14:08 2001
@@ -287,3 +287,4 @@
 
 module_init(init_vmidi);
 module_exit(cleanup_vmidi);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c
--- linux-2.4.11-pre1/drivers/sound/via82cxxx_audio.c	Sun Sep  9 10:52:35 2001
+++ linux/drivers/sound/via82cxxx_audio.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c
--- linux-2.4.11-pre1/drivers/sound/wavfront.c	Thu Sep 13 12:49:44 2001
+++ linux/drivers/sound/wavfront.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- linux-2.4.11-pre1/drivers/sound/ymfpci.c	Mon Sep 17 23:26:09 2001
+++ linux/drivers/sound/ymfpci.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h
--- linux-2.4.11-pre1/drivers/usb/pegasus.h	Wed Jun 27 13:59:32 2001
+++ linux/drivers/usb/pegasus.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/usb/scanner.h linux/drivers/usb/scanner.h
--- linux-2.4.11-pre1/drivers/usb/scanner.h	Mon Sep 17 22:52:35 2001
+++ linux/drivers/usb/scanner.h	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c
--- linux-2.4.11-pre1/drivers/usb/serial/belkin_sa.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/serial/belkin_sa.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/usb/serial/belkin_sa.h linux/drivers/usb/serial/belkin_sa.h
--- linux-2.4.11-pre1/drivers/usb/serial/belkin_sa.h	Fri Apr  6 15:51:52 2001
+++ linux/drivers/usb/serial/belkin_sa.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c
--- linux-2.4.11-pre1/drivers/usb/serial/cyberjack.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/serial/cyberjack.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c
--- linux-2.4.11-pre1/drivers/usb/serial/pl2303.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/serial/pl2303.c	Mon Dec  3 23:14:08 2001
@@ -12,6 +12,9 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * 2001_Sep_19 gkh
+ *	Added break support.
+ *
  * 2001_Aug_30 gkh
  *	fixed oops in write_bulk_callback.
  *
@@ -53,7 +56,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.7"
+#define DRIVER_VERSION "v0.8"
 #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
 
 
@@ -67,6 +70,26 @@
 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 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 +103,7 @@
 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 void pl2303_shutdown (struct usb_serial *serial);
 
 
 /* All of the device info needed for the PL2303 SIO serial converter */
@@ -102,6 +126,7 @@
 	read_bulk_callback:	pl2303_read_bulk_callback,
 	read_int_callback:	pl2303_read_int_callback,
 	write_bulk_callback:	pl2303_write_bulk_callback,
+	shutdown:		pl2303_shutdown,
 };
 
 
@@ -145,54 +170,60 @@
 
 
 
-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};
+	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;
@@ -216,7 +247,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 +255,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 +274,52 @@
 		/* 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);
-
+			     SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
+			     1, 0, NULL, 0, 100);
 	dbg ("0x21:0x22:1:0  %d", i);
-
+#if 0
 	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-			     0x22, 0x21, 3, 0, NULL, 0, 100);
+			     SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
+			     1, 0, NULL, 0, 100);
+	dbg ("0x21:0x22:1:0  %d", i);
 
+	i = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
+			     SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
+			     3, 0, NULL, 0, 100);
 	dbg ("0x21:0x22:3:0  %d", i);
-
+#endif
 	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 +333,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 +350,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 +373,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 +383,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) {
@@ -360,6 +401,7 @@
 static void pl2303_close (struct usb_serial_port *port, struct file *filp)
 {
 	unsigned int c_cflag;
+	int result;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return;
@@ -377,28 +419,30 @@
 		}
 
 		/* 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
-pl2303_ioctl (struct usb_serial_port *port, struct file *file,
-	      unsigned int cmd, unsigned long arg)
+static int pl2303_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg)
 {
-// struct usb_serial *serial = port->serial;
-// __u16 urb_value=0; /* Will hold the new flags */
-// char buf[1];
-// int  ret, mask;
-
-
 	dbg ("pl2303_sio ioctl 0x%04x", cmd);
 
 	/* Based on code from acm.c and others */
@@ -423,23 +467,50 @@
 			return(-ENOIOCTLCMD);
 			break;
 	}
-	dbg ("pl2303_ioctl returning 0");
 
 	return 0;
-}				/* pl2303_ioctl */
+}
+
+
+static void pl2303_break_ctl (struct usb_serial_port *port, int break_state)
+{
+	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_break_ctl(struct usb_serial_port *port,int break_state)
+static void pl2303_shutdown (struct usb_serial *serial)
 {
-//FIXME
+	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);
 }
 
 
-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 +553,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 +586,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 -urN linux-2.4.11-pre1/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- linux-2.4.11-pre1/drivers/usb/serial/usbserial.c	Fri Sep 14 14:16:08 2001
+++ linux/drivers/usb/serial/usbserial.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/usb/serial/xircom_pgs_fw.h linux/drivers/usb/serial/xircom_pgs_fw.h
--- linux-2.4.11-pre1/drivers/usb/serial/xircom_pgs_fw.h	Fri Sep 14 14:41:56 2001
+++ linux/drivers/usb/serial/xircom_pgs_fw.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/usb/usb-skeleton.c linux/drivers/usb/usb-skeleton.c
--- linux-2.4.11-pre1/drivers/usb/usb-skeleton.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/usb-skeleton.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/drivers/usb/usb.c linux/drivers/usb/usb.c
--- linux-2.4.11-pre1/drivers/usb/usb.c	Tue Aug 28 11:22:21 2001
+++ linux/drivers/usb/usb.c	Mon Dec  3 23:14:08 2001
@@ -2397,6 +2397,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);
 
diff -urN linux-2.4.11-pre1/drivers/usb/usbvideo.c linux/drivers/usb/usbvideo.c
--- linux-2.4.11-pre1/drivers/usb/usbvideo.c	Fri Sep  7 09:28:37 2001
+++ linux/drivers/usb/usbvideo.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/video/fbgen.c linux/drivers/video/fbgen.c
--- linux-2.4.11-pre1/drivers/video/fbgen.c	Fri Mar  2 18:38:39 2001
+++ linux/drivers/video/fbgen.c	Mon Dec  3 23:14:08 2001
@@ -440,3 +440,4 @@
     } else
 	fbgen_install_cmap(currcon, info2);
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/video/matrox/i2c-matroxfb.c linux/drivers/video/matrox/i2c-matroxfb.c
--- linux-2.4.11-pre1/drivers/video/matrox/i2c-matroxfb.c	Fri Mar 10 10:48:47 2000
+++ linux/drivers/video/matrox/i2c-matroxfb.c	Mon Dec  3 23:14:08 2001
@@ -349,3 +349,4 @@
 module_init(i2c_matroxfb_init);
 module_exit(i2c_matroxfb_exit);
 /* no __setup required */
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/video/matrox/matroxfb_DAC1064.c linux/drivers/video/matrox/matroxfb_DAC1064.c
--- linux-2.4.11-pre1/drivers/video/matrox/matroxfb_DAC1064.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/video/matrox/matroxfb_DAC1064.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/video/matrox/matroxfb_Ti3026.c linux/drivers/video/matrox/matroxfb_Ti3026.c
--- linux-2.4.11-pre1/drivers/video/matrox/matroxfb_Ti3026.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/video/matrox/matroxfb_Ti3026.c	Mon Dec  3 23:14:08 2001
@@ -863,3 +863,4 @@
 };
 EXPORT_SYMBOL(matrox_millennium);
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/video/matrox/matroxfb_accel.c linux/drivers/video/matrox/matroxfb_accel.c
--- linux-2.4.11-pre1/drivers/video/matrox/matroxfb_accel.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/video/matrox/matroxfb_accel.c	Mon Dec  3 23:14:08 2001
@@ -1237,3 +1237,4 @@
 		ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs;
 	}
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- linux-2.4.11-pre1/drivers/video/matrox/matroxfb_base.c	Wed Jun 27 17:10:55 2001
+++ linux/drivers/video/matrox/matroxfb_base.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/video/matrox/matroxfb_base.h linux/drivers/video/matrox/matroxfb_base.h
--- linux-2.4.11-pre1/drivers/video/matrox/matroxfb_base.h	Fri Sep 14 14:40:00 2001
+++ linux/drivers/video/matrox/matroxfb_base.h	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/video/matrox/matroxfb_misc.c linux/drivers/video/matrox/matroxfb_misc.c
--- linux-2.4.11-pre1/drivers/video/matrox/matroxfb_misc.c	Thu Aug 10 12:34:31 2000
+++ linux/drivers/video/matrox/matroxfb_misc.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/video/riva/fbdev.c linux/drivers/video/riva/fbdev.c
--- linux-2.4.11-pre1/drivers/video/riva/fbdev.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/video/riva/fbdev.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/video/sun3fb.c linux/drivers/video/sun3fb.c
--- linux-2.4.11-pre1/drivers/video/sun3fb.c	Mon Sep 17 22:52:35 2001
+++ linux/drivers/video/sun3fb.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/drivers/video/tdfxfb.c linux/drivers/video/tdfxfb.c
--- linux-2.4.11-pre1/drivers/video/tdfxfb.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/video/tdfxfb.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/fs/adfs/inode.c linux/fs/adfs/inode.c
--- linux-2.4.11-pre1/fs/adfs/inode.c	Mon Sep 10 07:31:25 2001
+++ linux/fs/adfs/inode.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/fs/affs/inode.c linux/fs/affs/inode.c
--- linux-2.4.11-pre1/fs/affs/inode.c	Mon Dec  3 23:13:56 2001
+++ linux/fs/affs/inode.c	Mon Dec  3 23:14: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;
@@ -413,3 +414,4 @@
 	affs_unlock_link(inode);
 	goto done;
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/autofs/init.c linux/fs/autofs/init.c
--- linux-2.4.11-pre1/fs/autofs/init.c	Fri Mar 10 10:48:47 2000
+++ linux/fs/autofs/init.c	Mon Dec  3 23:14:08 2001
@@ -38,3 +38,4 @@
 	printk(")\n");
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/autofs4/init.c linux/fs/autofs4/init.c
--- linux-2.4.11-pre1/fs/autofs4/init.c	Fri Apr 21 14:41:36 2000
+++ linux/fs/autofs4/init.c	Mon Dec  3 23:14:08 2001
@@ -28,3 +28,4 @@
 
 module_init(init_autofs4_fs) 
 module_exit(exit_autofs4_fs)
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/bfs/inode.c linux/fs/bfs/inode.c
--- linux-2.4.11-pre1/fs/bfs/inode.c	Tue Apr 17 23:16:38 2001
+++ linux/fs/bfs/inode.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/fs/binfmt_aout.c linux/fs/binfmt_aout.c
--- linux-2.4.11-pre1/fs/binfmt_aout.c	Thu Sep 13 16:04:43 2001
+++ linux/fs/binfmt_aout.c	Mon Dec  3 23:14:08 2001
@@ -513,3 +513,4 @@
 
 module_init(init_aout_binfmt);
 module_exit(exit_aout_binfmt);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- linux-2.4.11-pre1/fs/binfmt_elf.c	Thu Sep 13 16:04:43 2001
+++ linux/fs/binfmt_elf.c	Mon Dec  3 23:14:08 2001
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/smp_lock.h>
+#include <linux/compiler.h>
 
 #include <asm/uaccess.h>
 #include <asm/param.h>
@@ -408,7 +409,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;
@@ -609,8 +609,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 +616,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;
@@ -661,7 +675,6 @@
 		if (k > elf_brk)
 			elf_brk = k;
 	}
-	set_fs(old_fs);
 
 	elf_entry += load_bias;
 	elf_bss += load_bias;
diff -urN linux-2.4.11-pre1/fs/block_dev.c linux/fs/block_dev.c
--- linux-2.4.11-pre1/fs/block_dev.c	Mon Dec  3 23:13:56 2001
+++ linux/fs/block_dev.c	Mon Dec  3 23:14:08 2001
@@ -345,7 +345,6 @@
 			inode->i_rdev = kdev;
 			inode->i_dev = kdev;
 			inode->i_bdev = new_bdev;
-			inode->i_blkbits = blksize_bits(block_size(kdev));
 			inode->i_data.a_ops = &def_blk_aops;
 			inode->i_data.gfp_mask = GFP_USER;
 			spin_lock(&bdev_lock);
diff -urN linux-2.4.11-pre1/fs/devpts/inode.c linux/fs/devpts/inode.c
--- linux-2.4.11-pre1/fs/devpts/inode.c	Tue Apr 17 15:04:36 2001
+++ linux/fs/devpts/inode.c	Mon Dec  3 23:14:08 2001
@@ -250,3 +250,5 @@
 
 module_init(init_devpts_fs)
 module_exit(exit_devpts_fs)
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/fs/efs/inode.c linux/fs/efs/inode.c
--- linux-2.4.11-pre1/fs/efs/inode.c	Mon May  8 11:11:29 2000
+++ linux/fs/efs/inode.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/fs/lockd/clntlock.c linux/fs/lockd/clntlock.c
--- linux-2.4.11-pre1/fs/lockd/clntlock.c	Fri Sep  7 10:48:39 2001
+++ linux/fs/lockd/clntlock.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/host.c linux/fs/lockd/host.c
--- linux-2.4.11-pre1/fs/lockd/host.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/lockd/host.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/lockd_syms.c linux/fs/lockd/lockd_syms.c
--- linux-2.4.11-pre1/fs/lockd/lockd_syms.c	Thu Mar  9 06:57:08 2000
+++ linux/fs/lockd/lockd_syms.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/mon.c linux/fs/lockd/mon.c
--- linux-2.4.11-pre1/fs/lockd/mon.c	Mon Jun 11 19:15:27 2001
+++ linux/fs/lockd/mon.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/svc.c linux/fs/lockd/svc.c
--- linux-2.4.11-pre1/fs/lockd/svc.c	Fri Sep 14 14:16:08 2001
+++ linux/fs/lockd/svc.c	Mon Dec  3 23:14:08 2001
@@ -43,7 +43,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);
@@ -56,6 +56,25 @@
 unsigned long			nlm_grace_period;
 unsigned long			nlm_timeout = LOCKD_DFLT_TIMEO;
 
+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 +103,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 +112,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 +130,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 +142,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
@@ -345,7 +346,7 @@
  * 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 -urN linux-2.4.11-pre1/fs/lockd/svc4proc.c linux/fs/lockd/svc4proc.c
--- linux-2.4.11-pre1/fs/lockd/svc4proc.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/lockd/svc4proc.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/svcproc.c linux/fs/lockd/svcproc.c
--- linux-2.4.11-pre1/fs/lockd/svcproc.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/lockd/svcproc.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/svcsubs.c linux/fs/lockd/svcsubs.c
--- linux-2.4.11-pre1/fs/lockd/svcsubs.c	Fri Jun 23 21:12:53 2000
+++ linux/fs/lockd/svcsubs.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/xdr.c linux/fs/lockd/xdr.c
--- linux-2.4.11-pre1/fs/lockd/xdr.c	Sun Sep 23 09:48:01 2001
+++ linux/fs/lockd/xdr.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/lockd/xdr4.c linux/fs/lockd/xdr4.c
--- linux-2.4.11-pre1/fs/lockd/xdr4.c	Thu Sep 20 21:02:01 2001
+++ linux/fs/lockd/xdr4.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/minix/inode.c linux/fs/minix/inode.c
--- linux-2.4.11-pre1/fs/minix/inode.c	Fri Sep  7 09:45:51 2001
+++ linux/fs/minix/inode.c	Mon Dec  3 23:14:08 2001
@@ -529,3 +529,5 @@
 
 module_init(init_minix_fs)
 module_exit(exit_minix_fs)
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- linux-2.4.11-pre1/fs/ncpfs/inode.c	Mon Sep 10 07:31:30 2001
+++ linux/fs/ncpfs/inode.c	Mon Dec  3 23:14:08 2001
@@ -730,3 +730,4 @@
 
 module_init(init_ncp_fs)
 module_exit(exit_ncp_fs)
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/nfs/inode.c linux/fs/nfs/inode.c
--- linux-2.4.11-pre1/fs/nfs/inode.c	Fri Sep  7 09:40:04 2001
+++ linux/fs/nfs/inode.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/nfs/nfs3proc.c linux/fs/nfs/nfs3proc.c
--- linux-2.4.11-pre1/fs/nfs/nfs3proc.c	Sun Dec  3 18:01:01 2000
+++ linux/fs/nfs/nfs3proc.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/nfs/write.c linux/fs/nfs/write.c
--- linux-2.4.11-pre1/fs/nfs/write.c	Thu Aug 16 09:39:37 2001
+++ linux/fs/nfs/write.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/fs/nls/nls_cp1251.c linux/fs/nls/nls_cp1251.c
--- linux-2.4.11-pre1/fs/nls/nls_cp1251.c	Fri Apr  6 10:51:19 2001
+++ linux/fs/nls/nls_cp1251.c	Mon Dec  3 23:14:08 2001
@@ -315,3 +315,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp1255.c linux/fs/nls/nls_cp1255.c
--- linux-2.4.11-pre1/fs/nls/nls_cp1255.c	Sat May 19 17:47:55 2001
+++ linux/fs/nls/nls_cp1255.c	Mon Dec  3 23:14:08 2001
@@ -396,3 +396,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp437.c linux/fs/nls/nls_cp437.c
--- linux-2.4.11-pre1/fs/nls/nls_cp437.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp437.c	Mon Dec  3 23:14:08 2001
@@ -401,3 +401,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp737.c linux/fs/nls/nls_cp737.c
--- linux-2.4.11-pre1/fs/nls/nls_cp737.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp737.c	Mon Dec  3 23:14:08 2001
@@ -364,3 +364,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp775.c linux/fs/nls/nls_cp775.c
--- linux-2.4.11-pre1/fs/nls/nls_cp775.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp775.c	Mon Dec  3 23:14:08 2001
@@ -333,3 +333,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp850.c linux/fs/nls/nls_cp850.c
--- linux-2.4.11-pre1/fs/nls/nls_cp850.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp850.c	Mon Dec  3 23:14:08 2001
@@ -329,3 +329,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp852.c linux/fs/nls/nls_cp852.c
--- linux-2.4.11-pre1/fs/nls/nls_cp852.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp852.c	Mon Dec  3 23:14:08 2001
@@ -351,3 +351,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp855.c linux/fs/nls/nls_cp855.c
--- linux-2.4.11-pre1/fs/nls/nls_cp855.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp855.c	Mon Dec  3 23:14:08 2001
@@ -313,3 +313,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp857.c linux/fs/nls/nls_cp857.c
--- linux-2.4.11-pre1/fs/nls/nls_cp857.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp857.c	Mon Dec  3 23:14:08 2001
@@ -315,3 +315,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp860.c linux/fs/nls/nls_cp860.c
--- linux-2.4.11-pre1/fs/nls/nls_cp860.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp860.c	Mon Dec  3 23:14:08 2001
@@ -378,3 +378,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp861.c linux/fs/nls/nls_cp861.c
--- linux-2.4.11-pre1/fs/nls/nls_cp861.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp861.c	Mon Dec  3 23:14:08 2001
@@ -401,3 +401,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp862.c linux/fs/nls/nls_cp862.c
--- linux-2.4.11-pre1/fs/nls/nls_cp862.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp862.c	Mon Dec  3 23:14:08 2001
@@ -435,3 +435,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp863.c linux/fs/nls/nls_cp863.c
--- linux-2.4.11-pre1/fs/nls/nls_cp863.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp863.c	Mon Dec  3 23:14:08 2001
@@ -395,3 +395,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp864.c linux/fs/nls/nls_cp864.c
--- linux-2.4.11-pre1/fs/nls/nls_cp864.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp864.c	Mon Dec  3 23:14:08 2001
@@ -421,3 +421,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp865.c linux/fs/nls/nls_cp865.c
--- linux-2.4.11-pre1/fs/nls/nls_cp865.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp865.c	Mon Dec  3 23:14:08 2001
@@ -401,3 +401,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp866.c linux/fs/nls/nls_cp866.c
--- linux-2.4.11-pre1/fs/nls/nls_cp866.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp866.c	Mon Dec  3 23:14:08 2001
@@ -319,3 +319,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp869.c linux/fs/nls/nls_cp869.c
--- linux-2.4.11-pre1/fs/nls/nls_cp869.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp869.c	Mon Dec  3 23:14:08 2001
@@ -329,3 +329,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/nls/nls_cp874.c linux/fs/nls/nls_cp874.c
--- linux-2.4.11-pre1/fs/nls/nls_cp874.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp874.c	Mon Dec  3 23:14:08 2001
@@ -287,3 +287,4 @@
  * c-continued-brace-offset: 0
  * End:
  */
+MODULE_LICENSE("BSD without advertising clause");
diff -urN linux-2.4.11-pre1/fs/partitions/check.c linux/fs/partitions/check.c
--- linux-2.4.11-pre1/fs/partitions/check.c	Sat Sep  8 12:02:32 2001
+++ linux/fs/partitions/check.c	Mon Dec  3 23:14:08 2001
@@ -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
diff -urN linux-2.4.11-pre1/fs/proc/inode.c linux/fs/proc/inode.c
--- linux-2.4.11-pre1/fs/proc/inode.c	Tue Apr 17 23:16:39 2001
+++ linux/fs/proc/inode.c	Mon Dec  3 23:14:08 2001
@@ -209,3 +209,4 @@
 	iput(root_inode);
 	return NULL;
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/qnx4/inode.c linux/fs/qnx4/inode.c
--- linux-2.4.11-pre1/fs/qnx4/inode.c	Fri Sep  7 09:28:38 2001
+++ linux/fs/qnx4/inode.c	Mon Dec  3 23:14:08 2001
@@ -511,3 +511,5 @@
 
 module_init(init_qnx4_fs)
 module_exit(exit_qnx4_fs)
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/fs/ramfs/inode.c linux/fs/ramfs/inode.c
--- linux-2.4.11-pre1/fs/ramfs/inode.c	Tue May 22 09:31:25 2001
+++ linux/fs/ramfs/inode.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/fs/romfs/inode.c linux/fs/romfs/inode.c
--- linux-2.4.11-pre1/fs/romfs/inode.c	Mon Sep 10 09:04:53 2001
+++ linux/fs/romfs/inode.c	Mon Dec  3 23:14:08 2001
@@ -548,3 +548,4 @@
 
 module_init(init_romfs_fs)
 module_exit(exit_romfs_fs)
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- linux-2.4.11-pre1/fs/smbfs/inode.c	Mon Sep 10 07:31:30 2001
+++ linux/fs/smbfs/inode.c	Mon Dec  3 23:14:08 2001
@@ -653,3 +653,4 @@
 
 module_init(init_smb_fs)
 module_exit(exit_smb_fs)
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/sysv/super.c linux/fs/sysv/super.c
--- linux-2.4.11-pre1/fs/sysv/super.c	Sun Sep  2 10:34:36 2001
+++ linux/fs/sysv/super.c	Mon Dec  3 23:14:08 2001
@@ -502,3 +502,4 @@
 
 module_init(init_sysv_fs)
 module_exit(exit_sysv_fs)
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/fs/umsdos/inode.c linux/fs/umsdos/inode.c
--- linux-2.4.11-pre1/fs/umsdos/inode.c	Mon Sep 10 07:31:30 2001
+++ linux/fs/umsdos/inode.c	Mon Dec  3 23:14:08 2001
@@ -475,3 +475,4 @@
 
 module_init(init_umsdos_fs)
 module_exit(exit_umsdos_fs)
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/include/asm-i386/highmem.h linux/include/asm-i386/highmem.h
--- linux-2.4.11-pre1/include/asm-i386/highmem.h	Sun Sep 23 10:31:02 2001
+++ linux/include/asm-i386/highmem.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-i386/io_apic.h linux/include/asm-i386/io_apic.h
--- linux-2.4.11-pre1/include/asm-i386/io_apic.h	Sun Sep 23 10:31:01 2001
+++ linux/include/asm-i386/io_apic.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-ia64/module.h linux/include/asm-ia64/module.h
--- linux-2.4.11-pre1/include/asm-ia64/module.h	Thu Sep 13 16:33:03 2001
+++ linux/include/asm-ia64/module.h	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/include/asm-sparc/uaccess.h linux/include/asm-sparc/uaccess.h
--- linux-2.4.11-pre1/include/asm-sparc/uaccess.h	Tue Aug 29 14:09:16 2000
+++ linux/include/asm-sparc/uaccess.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-sparc64/ide.h linux/include/asm-sparc64/ide.h
--- linux-2.4.11-pre1/include/asm-sparc64/ide.h	Mon Jun 19 17:59:39 2000
+++ linux/include/asm-sparc64/ide.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-sparc64/pgalloc.h linux/include/asm-sparc64/pgalloc.h
--- linux-2.4.11-pre1/include/asm-sparc64/pgalloc.h	Tue Aug 28 07:09:44 2001
+++ linux/include/asm-sparc64/pgalloc.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-sparc64/shmparam.h linux/include/asm-sparc64/shmparam.h
--- linux-2.4.11-pre1/include/asm-sparc64/shmparam.h	Mon Dec 20 22:05:52 1999
+++ linux/include/asm-sparc64/shmparam.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-sparc64/spitfire.h linux/include/asm-sparc64/spitfire.h
--- linux-2.4.11-pre1/include/asm-sparc64/spitfire.h	Thu Apr 12 12:10:25 2001
+++ linux/include/asm-sparc64/spitfire.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-sparc64/string.h linux/include/asm-sparc64/string.h
--- linux-2.4.11-pre1/include/asm-sparc64/string.h	Tue Jun 12 11:08:46 2001
+++ linux/include/asm-sparc64/string.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/asm-sparc64/uaccess.h linux/include/asm-sparc64/uaccess.h
--- linux-2.4.11-pre1/include/asm-sparc64/uaccess.h	Tue Aug 29 14:09:16 2000
+++ linux/include/asm-sparc64/uaccess.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/capi.h linux/include/linux/capi.h
--- linux-2.4.11-pre1/include/linux/capi.h	Mon Dec 11 13:21:24 2000
+++ linux/include/linux/capi.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/concap.h linux/include/linux/concap.h
--- linux-2.4.11-pre1/include/linux/concap.h	Mon Dec 11 13:21:27 2000
+++ linux/include/linux/concap.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/hysdn_if.h linux/include/linux/hysdn_if.h
--- linux-2.4.11-pre1/include/linux/hysdn_if.h	Sat May 19 17:54:14 2001
+++ linux/include/linux/hysdn_if.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/isdn.h linux/include/linux/isdn.h
--- linux-2.4.11-pre1/include/linux/isdn.h	Sun Sep  9 10:45:43 2001
+++ linux/include/linux/isdn.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/isdn_divertif.h linux/include/linux/isdn_divertif.h
--- linux-2.4.11-pre1/include/linux/isdn_divertif.h	Mon Aug 21 07:49:03 2000
+++ linux/include/linux/isdn_divertif.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/isdn_lzscomp.h linux/include/linux/isdn_lzscomp.h
--- linux-2.4.11-pre1/include/linux/isdn_lzscomp.h	Sun May 23 10:03:42 1999
+++ linux/include/linux/isdn_lzscomp.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/isdn_ppp.h linux/include/linux/isdn_ppp.h
--- linux-2.4.11-pre1/include/linux/isdn_ppp.h	Sat May 19 17:54:14 2001
+++ linux/include/linux/isdn_ppp.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/isdnif.h linux/include/linux/isdnif.h
--- linux-2.4.11-pre1/include/linux/isdnif.h	Fri Jul  6 17:01:06 2001
+++ linux/include/linux/isdnif.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/kernel.h linux/include/linux/kernel.h
--- linux-2.4.11-pre1/include/linux/kernel.h	Sun Sep 23 10:31:01 2001
+++ linux/include/linux/kernel.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/lockd/lockd.h linux/include/linux/lockd/lockd.h
--- linux-2.4.11-pre1/include/linux/lockd/lockd.h	Sun Sep 23 10:32:16 2001
+++ linux/include/linux/lockd/lockd.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/lockd/nlm.h linux/include/linux/lockd/nlm.h
--- linux-2.4.11-pre1/include/linux/lockd/nlm.h	Mon Aug 13 12:28:01 2001
+++ linux/include/linux/lockd/nlm.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/miscdevice.h linux/include/linux/miscdevice.h
--- linux-2.4.11-pre1/include/linux/miscdevice.h	Sun Sep 23 10:32:38 2001
+++ linux/include/linux/miscdevice.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/module.h linux/include/linux/module.h
--- linux-2.4.11-pre1/include/linux/module.h	Sun Sep 23 10:31:02 2001
+++ linux/include/linux/module.h	Mon Dec  3 23:14:08 2001
@@ -346,12 +346,14 @@
 #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)
 
 #else
 
@@ -362,10 +364,19 @@
 __attribute__((section("__ksymtab"))) =			\
 { (unsigned long)&sym, __kstrtab_##sym }
 
+#define __EXPORT_SYMBOL_GPL(sym, str)			\
+const char __kstrtab_##sym[]				\
+__attribute__((section(".kstrtab"))) = str;		\
+const struct module_symbol __ksymtab_GPLONLY_##sym	\
+__attribute__((section("__ksymtab"))) =			\
+{ (unsigned long)&sym, __kstrtab_GPLONLY_##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 -urN linux-2.4.11-pre1/include/linux/nfs_fs_i.h linux/include/linux/nfs_fs_i.h
--- linux-2.4.11-pre1/include/linux/nfs_fs_i.h	Sun Sep 23 10:31:02 2001
+++ linux/include/linux/nfs_fs_i.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- linux-2.4.11-pre1/include/linux/pci_ids.h	Sun Sep  9 10:43:02 2001
+++ linux/include/linux/pci_ids.h	Mon Dec  3 23:14:08 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)"
diff -urN linux-2.4.11-pre1/include/linux/sem.h linux/include/linux/sem.h
--- linux-2.4.11-pre1/include/linux/sem.h	Sun Sep 23 10:31:01 2001
+++ linux/include/linux/sem.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/sysctl.h linux/include/linux/sysctl.h
--- linux-2.4.11-pre1/include/linux/sysctl.h	Sun Sep 23 10:31:02 2001
+++ linux/include/linux/sysctl.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/sysrq.h linux/include/linux/sysrq.h
--- linux-2.4.11-pre1/include/linux/sysrq.h	Mon Sep 17 22:52:35 2001
+++ linux/include/linux/sysrq.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/linux/timer.h linux/include/linux/timer.h
--- linux-2.4.11-pre1/include/linux/timer.h	Sun Sep 23 10:31:02 2001
+++ linux/include/linux/timer.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/include/net/tcp.h linux/include/net/tcp.h
--- linux-2.4.11-pre1/include/net/tcp.h	Sun Sep 23 10:31:58 2001
+++ linux/include/net/tcp.h	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/init/main.c linux/init/main.c
--- linux-2.4.11-pre1/init/main.c	Thu Sep 20 21:02:01 2001
+++ linux/init/main.c	Mon Dec  3 23:14:08 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
 
@@ -479,7 +479,7 @@
 
 #ifndef CONFIG_SMP
 
-#ifdef CONFIG_X86_IO_APIC
+#ifdef CONFIG_X86_LOCAL_APIC
 static void __init smp_init(void)
 {
 	APIC_init_uniprocessor();
diff -urN linux-2.4.11-pre1/ipc/sem.c linux/ipc/sem.c
--- linux-2.4.11-pre1/ipc/sem.c	Mon Feb 19 10:18:18 2001
+++ linux/ipc/sem.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/kernel/panic.c linux/kernel/panic.c
--- linux-2.4.11-pre1/kernel/panic.c	Sun Sep 16 21:22:40 2001
+++ linux/kernel/panic.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/kernel/sysctl.c linux/kernel/sysctl.c
--- linux-2.4.11-pre1/kernel/sysctl.c	Tue Sep 18 14:10:43 2001
+++ linux/kernel/sysctl.c	Mon Dec  3 23:14:08 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
diff -urN linux-2.4.11-pre1/net/appletalk/aarp.c linux/net/appletalk/aarp.c
--- linux-2.4.11-pre1/net/appletalk/aarp.c	Fri Jun 29 19:38:26 2001
+++ linux/net/appletalk/aarp.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/net/atm/common.c linux/net/atm/common.c
--- linux-2.4.11-pre1/net/atm/common.c	Sun Aug 12 11:13:59 2001
+++ linux/net/atm/common.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/net/atm/lec.c linux/net/atm/lec.c
--- linux-2.4.11-pre1/net/atm/lec.c	Wed Jun 27 17:10:55 2001
+++ linux/net/atm/lec.c	Mon Dec  3 23:14:08 2001
@@ -2193,3 +2193,4 @@
         lec_arp_put(priv->lec_arp_tables,entry);
         lec_arp_unlock(priv);  
 }
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/atm/mpc.c linux/net/atm/mpc.c
--- linux-2.4.11-pre1/net/atm/mpc.c	Wed Jun 27 17:10:55 2001
+++ linux/net/atm/mpc.c	Mon Dec  3 23:14:08 2001
@@ -1479,3 +1479,4 @@
 	return;
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/bluetooth/hci_core.c linux/net/bluetooth/hci_core.c
--- linux-2.4.11-pre1/net/bluetooth/hci_core.c	Sun Sep  9 10:52:35 2001
+++ linux/net/bluetooth/hci_core.c	Mon Dec  3 23:14:08 2001
@@ -2028,3 +2028,5 @@
 {
 	return 0;
 }
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/bluetooth/l2cap_core.c linux/net/bluetooth/l2cap_core.c
--- linux-2.4.11-pre1/net/bluetooth/l2cap_core.c	Fri Sep  7 09:28:38 2001
+++ linux/net/bluetooth/l2cap_core.c	Mon Dec  3 23:14:08 2001
@@ -2312,3 +2312,5 @@
 
 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
 MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
+MODULE_LICENSE("GPL");
+
diff -urN linux-2.4.11-pre1/net/bridge/br.c linux/net/bridge/br.c
--- linux-2.4.11-pre1/net/bridge/br.c	Mon Oct 23 21:59:03 2000
+++ linux/net/bridge/br.c	Mon Dec  3 23:14:08 2001
@@ -82,3 +82,4 @@
 
 module_init(br_init)
 module_exit(br_deinit)
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/core/dev.c linux/net/core/dev.c
--- linux-2.4.11-pre1/net/core/dev.c	Thu Sep 20 14:12:56 2001
+++ linux/net/core/dev.c	Mon Dec  3 23:14:08 2001
@@ -552,9 +552,32 @@
 {
 	int i;
 	char buf[32];
+	char *p, c;
 
 	/*
-	 *	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 = name;
+	while ((c = *p++) != 0) {
+		if (c == '%') {
+			c = *p++;
+			if (c != 'd')
+				return -EINVAL;
+
+			while ((c = *p++) != 0) {
+				if (c == '%')
+					return -EINVAL;
+			}
+			goto name_ok;
+		}
+	}
+	return -EINVAL;
+
+ name_ok:
+	/*
+	 * If you need over 100 please also fix the algorithm...
 	 */
 	for (i = 0; i < 100; i++) {
 		sprintf(buf,name,i);
diff -urN linux-2.4.11-pre1/net/core/neighbour.c linux/net/core/neighbour.c
--- linux-2.4.11-pre1/net/core/neighbour.c	Mon Jun 11 19:15:27 2001
+++ linux/net/core/neighbour.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/devinet.c linux/net/ipv4/devinet.c
--- linux-2.4.11-pre1/net/ipv4/devinet.c	Wed May 16 10:21:45 2001
+++ linux/net/ipv4/devinet.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/inetpeer.c linux/net/ipv4/inetpeer.c
--- linux-2.4.11-pre1/net/ipv4/inetpeer.c	Fri Jun 29 19:38:26 2001
+++ linux/net/ipv4/inetpeer.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/ip_gre.c linux/net/ipv4/ip_gre.c
--- linux-2.4.11-pre1/net/ipv4/ip_gre.c	Tue May 15 01:29:35 2001
+++ linux/net/ipv4/ip_gre.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/ipconfig.c linux/net/ipv4/ipconfig.c
--- linux-2.4.11-pre1/net/ipv4/ipconfig.c	Tue May  1 20:59:24 2001
+++ linux/net/ipv4/ipconfig.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/ipip.c linux/net/ipv4/ipip.c
--- linux-2.4.11-pre1/net/ipv4/ipip.c	Thu Sep 20 14:12:56 2001
+++ linux/net/ipv4/ipip.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/netfilter/ip_conntrack_ftp.c linux/net/ipv4/netfilter/ip_conntrack_ftp.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ip_conntrack_ftp.c	Wed Apr 25 15:02:09 2001
+++ linux/net/ipv4/netfilter/ip_conntrack_ftp.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/net/ipv4/netfilter/ip_conntrack_standalone.c linux/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ip_conntrack_standalone.c	Fri Sep 14 14:04:08 2001
+++ linux/net/ipv4/netfilter/ip_conntrack_standalone.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/net/ipv4/netfilter/ip_nat_ftp.c linux/net/ipv4/netfilter/ip_nat_ftp.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ip_nat_ftp.c	Wed Apr 25 15:02:35 2001
+++ linux/net/ipv4/netfilter/ip_nat_ftp.c	Mon Dec  3 23:14:08 2001
@@ -369,3 +369,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ip_nat_standalone.c linux/net/ipv4/netfilter/ip_nat_standalone.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ip_nat_standalone.c	Fri Apr 27 14:15:01 2001
+++ linux/net/ipv4/netfilter/ip_nat_standalone.c	Mon Dec  3 23:14: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 -urN linux-2.4.11-pre1/net/ipv4/netfilter/ip_queue.c linux/net/ipv4/netfilter/ip_queue.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ip_queue.c	Fri Sep 14 14:04:08 2001
+++ linux/net/ipv4/netfilter/ip_queue.c	Mon Dec  3 23:14:08 2001
@@ -685,5 +685,7 @@
 }
 
 MODULE_DESCRIPTION("IPv4 packet queue handler");
+MODULE_LICENSE("GPL");
+
 module_init(init);
 module_exit(fini);
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ip_tables.c linux/net/ipv4/netfilter/ip_tables.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ip_tables.c	Fri Sep 14 14:04:08 2001
+++ linux/net/ipv4/netfilter/ip_tables.c	Mon Dec  3 23:14:08 2001
@@ -1764,3 +1764,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipchains_core.c linux/net/ipv4/netfilter/ipchains_core.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipchains_core.c	Fri Sep 14 14:04:08 2001
+++ linux/net/ipv4/netfilter/ipchains_core.c	Mon Dec  3 23:14:08 2001
@@ -1765,3 +1765,4 @@
 #endif
 	return ret;
 }
+MODULE_LICENSE("BSD without advertisement clause");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_LOG.c linux/net/ipv4/netfilter/ipt_LOG.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_LOG.c	Mon Jan  1 09:54:07 2001
+++ linux/net/ipv4/netfilter/ipt_LOG.c	Mon Dec  3 23:14:08 2001
@@ -353,3 +353,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_MARK.c linux/net/ipv4/netfilter/ipt_MARK.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_MARK.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_MARK.c	Mon Dec  3 23:14:08 2001
@@ -64,3 +64,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_MASQUERADE.c linux/net/ipv4/netfilter/ipt_MASQUERADE.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_MASQUERADE.c	Fri Apr 27 14:15:01 2001
+++ linux/net/ipv4/netfilter/ipt_MASQUERADE.c	Mon Dec  3 23:14:08 2001
@@ -204,3 +204,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_MIRROR.c linux/net/ipv4/netfilter/ipt_MIRROR.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_MIRROR.c	Mon Dec 11 12:37:04 2000
+++ linux/net/ipv4/netfilter/ipt_MIRROR.c	Mon Dec  3 23:14:08 2001
@@ -151,3 +151,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_REDIRECT.c linux/net/ipv4/netfilter/ipt_REDIRECT.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_REDIRECT.c	Tue Jun 20 14:32:27 2000
+++ linux/net/ipv4/netfilter/ipt_REDIRECT.c	Mon Dec  3 23:14:08 2001
@@ -105,3 +105,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_REJECT.c linux/net/ipv4/netfilter/ipt_REJECT.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_REJECT.c	Mon Jun 11 19:15:27 2001
+++ linux/net/ipv4/netfilter/ipt_REJECT.c	Mon Dec  3 23:14:08 2001
@@ -374,3 +374,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_TCPMSS.c linux/net/ipv4/netfilter/ipt_TCPMSS.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_TCPMSS.c	Tue Mar  6 22:44:16 2001
+++ linux/net/ipv4/netfilter/ipt_TCPMSS.c	Mon Dec  3 23:14:08 2001
@@ -243,3 +243,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_TOS.c linux/net/ipv4/netfilter/ipt_TOS.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_TOS.c	Fri Feb  9 11:34:13 2001
+++ linux/net/ipv4/netfilter/ipt_TOS.c	Mon Dec  3 23:14:08 2001
@@ -83,3 +83,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_limit.c linux/net/ipv4/netfilter/ipt_limit.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_limit.c	Thu Aug 10 12:35:15 2000
+++ linux/net/ipv4/netfilter/ipt_limit.c	Mon Dec  3 23:14:08 2001
@@ -133,3 +133,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_mac.c linux/net/ipv4/netfilter/ipt_mac.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_mac.c	Thu Jul  6 21:20:00 2000
+++ linux/net/ipv4/netfilter/ipt_mac.c	Mon Dec  3 23:14:08 2001
@@ -62,3 +62,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_mark.c linux/net/ipv4/netfilter/ipt_mark.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_mark.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_mark.c	Mon Dec  3 23:14:08 2001
@@ -48,3 +48,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_multiport.c linux/net/ipv4/netfilter/ipt_multiport.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_multiport.c	Tue Jun 20 14:32:27 2000
+++ linux/net/ipv4/netfilter/ipt_multiport.c	Mon Dec  3 23:14:08 2001
@@ -101,3 +101,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_owner.c linux/net/ipv4/netfilter/ipt_owner.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_owner.c	Sun Aug 13 12:53:19 2000
+++ linux/net/ipv4/netfilter/ipt_owner.c	Mon Dec  3 23:14:08 2001
@@ -152,3 +152,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_state.c linux/net/ipv4/netfilter/ipt_state.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_state.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_state.c	Mon Dec  3 23:14:08 2001
@@ -61,3 +61,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_tcpmss.c linux/net/ipv4/netfilter/ipt_tcpmss.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_tcpmss.c	Tue Mar  6 22:44:16 2001
+++ linux/net/ipv4/netfilter/ipt_tcpmss.c	Mon Dec  3 23:14:08 2001
@@ -106,3 +106,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_tos.c linux/net/ipv4/netfilter/ipt_tos.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_tos.c	Thu Apr 27 15:43:15 2000
+++ linux/net/ipv4/netfilter/ipt_tos.c	Mon Dec  3 23:14:08 2001
@@ -49,3 +49,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/ipt_unclean.c linux/net/ipv4/netfilter/ipt_unclean.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/ipt_unclean.c	Fri Jul  6 17:07:55 2001
+++ linux/net/ipv4/netfilter/ipt_unclean.c	Mon Dec  3 23:14:08 2001
@@ -583,3 +583,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/iptable_filter.c linux/net/ipv4/netfilter/iptable_filter.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/iptable_filter.c	Fri May 12 11:45:26 2000
+++ linux/net/ipv4/netfilter/iptable_filter.c	Mon Dec  3 23:14:08 2001
@@ -179,3 +179,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/netfilter/iptable_mangle.c linux/net/ipv4/netfilter/iptable_mangle.c
--- linux-2.4.11-pre1/net/ipv4/netfilter/iptable_mangle.c	Fri Jul  6 17:07:55 2001
+++ linux/net/ipv4/netfilter/iptable_mangle.c	Mon Dec  3 23:14:08 2001
@@ -204,3 +204,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- linux-2.4.11-pre1/net/ipv4/tcp.c	Thu Sep 20 14:12:56 2001
+++ linux/net/ipv4/tcp.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- linux-2.4.11-pre1/net/ipv4/tcp_input.c	Thu Sep 20 14:12:56 2001
+++ linux/net/ipv4/tcp_input.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- linux-2.4.11-pre1/net/ipv4/tcp_ipv4.c	Fri Sep  7 11:01:21 2001
+++ linux/net/ipv4/tcp_ipv4.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/tcp_minisocks.c linux/net/ipv4/tcp_minisocks.c
--- linux-2.4.11-pre1/net/ipv4/tcp_minisocks.c	Thu Sep 20 14:12:56 2001
+++ linux/net/ipv4/tcp_minisocks.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- linux-2.4.11-pre1/net/ipv4/tcp_output.c	Thu Sep 20 14:12:56 2001
+++ linux/net/ipv4/tcp_output.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- linux-2.4.11-pre1/net/ipv4/tcp_timer.c	Thu Sep 20 14:12:56 2001
+++ linux/net/ipv4/tcp_timer.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- linux-2.4.11-pre1/net/ipv6/af_inet6.c	Wed Jun 20 21:00:55 2001
+++ linux/net/ipv6/af_inet6.c	Mon Dec  3 23:14:08 2001
@@ -718,3 +718,4 @@
 }
 module_exit(inet6_exit);
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv6/netfilter/ip6_tables.c linux/net/ipv6/netfilter/ip6_tables.c
--- linux-2.4.11-pre1/net/ipv6/netfilter/ip6_tables.c	Tue Aug  7 08:30:50 2001
+++ linux/net/ipv6/netfilter/ip6_tables.c	Mon Dec  3 23:14:08 2001
@@ -1801,3 +1801,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv6/netfilter/ip6t_MARK.c linux/net/ipv6/netfilter/ip6t_MARK.c
--- linux-2.4.11-pre1/net/ipv6/netfilter/ip6t_MARK.c	Mon Jan 22 13:30:21 2001
+++ linux/net/ipv6/netfilter/ip6t_MARK.c	Mon Dec  3 23:14:08 2001
@@ -65,3 +65,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv6/netfilter/ip6t_limit.c linux/net/ipv6/netfilter/ip6t_limit.c
--- linux-2.4.11-pre1/net/ipv6/netfilter/ip6t_limit.c	Mon May 22 09:50:55 2000
+++ linux/net/ipv6/netfilter/ip6t_limit.c	Mon Dec  3 23:14:08 2001
@@ -133,3 +133,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv6/netfilter/ip6t_mark.c linux/net/ipv6/netfilter/ip6t_mark.c
--- linux-2.4.11-pre1/net/ipv6/netfilter/ip6t_mark.c	Mon Jan 22 13:30:21 2001
+++ linux/net/ipv6/netfilter/ip6t_mark.c	Mon Dec  3 23:14:08 2001
@@ -48,3 +48,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv6/netfilter/ip6table_filter.c linux/net/ipv6/netfilter/ip6table_filter.c
--- linux-2.4.11-pre1/net/ipv6/netfilter/ip6table_filter.c	Fri Jul 28 12:35:30 2000
+++ linux/net/ipv6/netfilter/ip6table_filter.c	Mon Dec  3 23:14:08 2001
@@ -181,3 +181,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv6/netfilter/ip6table_mangle.c linux/net/ipv6/netfilter/ip6table_mangle.c
--- linux-2.4.11-pre1/net/ipv6/netfilter/ip6table_mangle.c	Mon Jan 22 13:30:21 2001
+++ linux/net/ipv6/netfilter/ip6table_mangle.c	Mon Dec  3 23:14:08 2001
@@ -187,3 +187,4 @@
 
 module_init(init);
 module_exit(fini);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/ipv6/sit.c linux/net/ipv6/sit.c
--- linux-2.4.11-pre1/net/ipv6/sit.c	Fri Sep  7 11:01:21 2001
+++ linux/net/ipv6/sit.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- linux-2.4.11-pre1/net/ipv6/tcp_ipv6.c	Fri Sep  7 11:01:21 2001
+++ linux/net/ipv6/tcp_ipv6.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- linux-2.4.11-pre1/net/ipx/af_ipx.c	Thu Sep 13 17:16:23 2001
+++ linux/net/ipx/af_ipx.c	Mon Dec  3 23:14:08 2001
@@ -2637,3 +2637,4 @@
 }
 
 module_exit(ipx_proto_finito);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/irda/af_irda.c linux/net/irda/af_irda.c
--- linux-2.4.11-pre1/net/irda/af_irda.c	Fri Sep 14 14:04:08 2001
+++ linux/net/irda/af_irda.c	Mon Dec  3 23:14:08 2001
@@ -2571,6 +2571,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 -urN linux-2.4.11-pre1/net/irda/ircomm/ircomm_core.c linux/net/irda/ircomm/ircomm_core.c
--- linux-2.4.11-pre1/net/irda/ircomm/ircomm_core.c	Fri Mar  2 11:12:12 2001
+++ linux/net/irda/ircomm/ircomm_core.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/irda/ircomm/ircomm_tty.c linux/net/irda/ircomm/ircomm_tty.c
--- linux-2.4.11-pre1/net/irda/ircomm/ircomm_tty.c	Wed Jul 25 14:12:03 2001
+++ linux/net/irda/ircomm/ircomm_tty.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/irda/irlan/irlan_common.c linux/net/irda/irlan/irlan_common.c
--- linux-2.4.11-pre1/net/irda/irlan/irlan_common.c	Wed Jul  4 11:50:38 2001
+++ linux/net/irda/irlan/irlan_common.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/irda/irnet/irnet_ppp.c linux/net/irda/irnet/irnet_ppp.c
--- linux-2.4.11-pre1/net/irda/irnet/irnet_ppp.c	Thu Sep 13 16:26:52 2001
+++ linux/net/irda/irnet/irnet_ppp.c	Mon Dec  3 23:14:08 2001
@@ -14,6 +14,7 @@
  */
 
 #include "irnet_ppp.h"		/* Private header */
+#include <linux/module.h>
 
 /************************* CONTROL CHANNEL *************************/
 /*
@@ -1095,3 +1096,4 @@
   return ppp_irnet_cleanup();
 }
 #endif /* MODULE */
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/cls_fw.c linux/net/sched/cls_fw.c
--- linux-2.4.11-pre1/net/sched/cls_fw.c	Fri Mar 17 10:56:20 2000
+++ linux/net/sched/cls_fw.c	Mon Dec  3 23:14:08 2001
@@ -383,3 +383,4 @@
 	unregister_tcf_proto_ops(&cls_fw_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/cls_route.c linux/net/sched/cls_route.c
--- linux-2.4.11-pre1/net/sched/cls_route.c	Tue Aug  7 08:30:50 2001
+++ linux/net/sched/cls_route.c	Mon Dec  3 23:14:08 2001
@@ -638,3 +638,4 @@
 	unregister_tcf_proto_ops(&cls_route4_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/cls_rsvp.c linux/net/sched/cls_rsvp.c
--- linux-2.4.11-pre1/net/sched/cls_rsvp.c	Wed Apr 29 22:46:59 1998
+++ linux/net/sched/cls_rsvp.c	Mon Dec  3 23:14:08 2001
@@ -39,3 +39,4 @@
 #define RSVP_OPS	cls_rsvp_ops
 
 #include "cls_rsvp.h"
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/cls_rsvp6.c linux/net/sched/cls_rsvp6.c
--- linux-2.4.11-pre1/net/sched/cls_rsvp6.c	Wed Apr 29 22:46:59 1998
+++ linux/net/sched/cls_rsvp6.c	Mon Dec  3 23:14:08 2001
@@ -40,3 +40,4 @@
 #define RSVP_OPS	cls_rsvp6_ops
 
 #include "cls_rsvp.h"
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/cls_tcindex.c linux/net/sched/cls_tcindex.c
--- linux-2.4.11-pre1/net/sched/cls_tcindex.c	Sun Mar 25 18:14:25 2001
+++ linux/net/sched/cls_tcindex.c	Mon Dec  3 23:14:08 2001
@@ -515,3 +515,4 @@
 	unregister_tcf_proto_ops(&cls_tcindex_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/cls_u32.c linux/net/sched/cls_u32.c
--- linux-2.4.11-pre1/net/sched/cls_u32.c	Tue Aug  7 08:30:50 2001
+++ linux/net/sched/cls_u32.c	Mon Dec  3 23:14:08 2001
@@ -726,3 +726,4 @@
 	unregister_tcf_proto_ops(&cls_u32_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_cbq.c linux/net/sched/sch_cbq.c
--- linux-2.4.11-pre1/net/sched/sch_cbq.c	Mon Sep 10 07:59:25 2001
+++ linux/net/sched/sch_cbq.c	Mon Dec  3 23:14:08 2001
@@ -2120,3 +2120,4 @@
 	unregister_qdisc(&cbq_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_csz.c linux/net/sched/sch_csz.c
--- linux-2.4.11-pre1/net/sched/sch_csz.c	Mon Aug 23 10:01:02 1999
+++ linux/net/sched/sch_csz.c	Mon Dec  3 23:14:08 2001
@@ -1069,3 +1069,4 @@
 	unregister_qdisc(&csz_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_dsmark.c linux/net/sched/sch_dsmark.c
--- linux-2.4.11-pre1/net/sched/sch_dsmark.c	Sun Mar 25 18:14:25 2001
+++ linux/net/sched/sch_dsmark.c	Mon Dec  3 23:14:08 2001
@@ -490,3 +490,4 @@
 	unregister_qdisc(&dsmark_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_gred.c linux/net/sched/sch_gred.c
--- linux-2.4.11-pre1/net/sched/sch_gred.c	Fri Jun 29 19:38:26 2001
+++ linux/net/sched/sch_gred.c	Mon Dec  3 23:14:08 2001
@@ -632,3 +632,4 @@
 	unregister_qdisc(&gred_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_ingress.c linux/net/sched/sch_ingress.c
--- linux-2.4.11-pre1/net/sched/sch_ingress.c	Fri Aug 18 10:26:25 2000
+++ linux/net/sched/sch_ingress.c	Mon Dec  3 23:14:08 2001
@@ -392,3 +392,4 @@
 	unregister_qdisc(&ingress_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_prio.c linux/net/sched/sch_prio.c
--- linux-2.4.11-pre1/net/sched/sch_prio.c	Fri Jan  7 16:57:13 2000
+++ linux/net/sched/sch_prio.c	Mon Dec  3 23:14:08 2001
@@ -421,3 +421,4 @@
 }
 
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_red.c linux/net/sched/sch_red.c
--- linux-2.4.11-pre1/net/sched/sch_red.c	Fri Jun 29 19:38:26 2001
+++ linux/net/sched/sch_red.c	Mon Dec  3 23:14:08 2001
@@ -497,3 +497,4 @@
 	unregister_qdisc(&red_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_sfq.c linux/net/sched/sch_sfq.c
--- linux-2.4.11-pre1/net/sched/sch_sfq.c	Mon Aug 23 10:01:02 1999
+++ linux/net/sched/sch_sfq.c	Mon Dec  3 23:14:08 2001
@@ -496,3 +496,4 @@
 	unregister_qdisc(&sfq_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_tbf.c linux/net/sched/sch_tbf.c
--- linux-2.4.11-pre1/net/sched/sch_tbf.c	Mon Sep 10 07:59:25 2001
+++ linux/net/sched/sch_tbf.c	Mon Dec  3 23:14:08 2001
@@ -427,3 +427,4 @@
 	unregister_qdisc(&tbf_qdisc_ops);
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sched/sch_teql.c linux/net/sched/sch_teql.c
--- linux-2.4.11-pre1/net/sched/sch_teql.c	Sun Jul  9 22:30:41 2000
+++ linux/net/sched/sch_teql.c	Mon Dec  3 23:14:08 2001
@@ -493,3 +493,4 @@
 	rtnl_unlock();
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/net/sunrpc/sched.c linux/net/sunrpc/sched.c
--- linux-2.4.11-pre1/net/sunrpc/sched.c	Fri Sep 21 11:24:50 2001
+++ linux/net/sunrpc/sched.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/sunrpc/xdr.c linux/net/sunrpc/xdr.c
--- linux-2.4.11-pre1/net/sunrpc/xdr.c	Thu Sep 20 21:02:01 2001
+++ linux/net/sunrpc/xdr.c	Mon Dec  3 23:14:08 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 -urN linux-2.4.11-pre1/net/wanrouter/af_wanpipe.c linux/net/wanrouter/af_wanpipe.c
--- linux-2.4.11-pre1/net/wanrouter/af_wanpipe.c	Thu Jun 28 14:42:40 2001
+++ linux/net/wanrouter/af_wanpipe.c	Mon Dec  3 23:14:08 2001
@@ -2763,3 +2763,4 @@
 	return 0;
 }
 #endif
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.11-pre1/scripts/kernel-doc linux/scripts/kernel-doc
--- linux-2.4.11-pre1/scripts/kernel-doc	Mon Jul  2 13:56:40 2001
+++ linux/scripts/kernel-doc	Mon Dec  3 23:14:08 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;
+
+    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);
 
-# output in html
-sub output_html(%) {
+    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) {
@@ -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,88 @@
     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";
+	output_highlight($args{'sections'}{$section});
+    }
+}
+
+##
+# 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";
@@ -608,12 +988,29 @@
     }
 }
 
+##
+# 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 = ();
