diff -Nru a/Documentation/filesystems/fat_cvf.txt b/Documentation/filesystems/fat_cvf.txt
--- a/Documentation/filesystems/fat_cvf.txt	Mon Feb  4 23:49:25 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,210 +0,0 @@
-This is the main documentation for the CVF-FAT filesystem extension.  18Nov1998
-
-
-Table of Contents:
-
-1. The idea of CVF-FAT
-2. Restrictions
-3. Mount options
-4. Description of the CVF-FAT interface
-5. CVF Modules
-
-------------------------------------------------------------------------------
-
-
-1. The idea of CVF-FAT
-------------------------------------------------------------------------------
-
-CVF-FAT is a FAT filesystem extension that provides a generic interface for
-Compressed Volume Files in FAT partitions. Popular CVF software, for
-example, are Microsoft's Doublespace/Drivespace and Stac's Stacker.
-Using the CVF-FAT interface, it is possible to load a module that handles
-all the low-level disk access that has to do with on-the-fly compression
-and decompression. Any other part of FAT filesystem access is still handled
-by the FAT, MSDOS or VFAT or even UMSDOS driver.
-
-CVF access works by redirecting certain low-level routines from the FAT
-driver to a loadable, CVF-format specific module. This module must fake
-a normal FAT filesystem to the FAT driver while doing all the extra stuff
-like compression and decompression silently.
-
-
-2. Restrictions
-------------------------------------------------------------------------------
-
-- BMAP problems
-
-  CVF filesystems cannot do bmap. It's impossible in principle. Thus
-  all actions that require bmap do not work (swapping, writable mmapping).
-  Read-only mmapping works because the FAT driver has a hack for this
-  situation :) Well, writable mmapping should now work using the readpage
-  interface function which has been hacked into the FAT driver just for 
-  CVF-FAT :)
-  
-- attention, DOSEmu users 
-
-  You may have to unmount all CVF partitions before running DOSEmu depending 
-  on your configuration. If DOSEmu is configured to use wholedisk or 
-  partition access (this is often the case to let DOSEmu access 
-  compressed partitions) there's a risk of destroying your compressed 
-  partitions or crashing your system because of confused drivers.
-  
-  Note that it is always safe to redirect the compressed partitions with 
-  lredir or emufs.sys. Refer to the DOSEmu documentation for details.
-
-
-3. Mount options
-------------------------------------------------------------------------------
-
-The CVF-FAT extension currently adds the following options to the FAT
-driver's standard options:
-
-  cvf_format=xxx
-    Forces the driver to use the CVF module "xxx" instead of auto-detection.
-    Without this option, the CVF-FAT interface asks all currently loaded
-    CVF modules whether they recognize the CVF. Therefore, this option is
-    only necessary if the CVF format is not recognized correctly
-    because of bugs or incompatibilities in the CVF modules. (It skips
-    the detect_cvf call.) "xxx" may be the text "none" (without the quotes)
-    to inhibit using any of the loaded CVF modules, just in case a CVF
-    module insists on mounting plain FAT filesystems by misunderstanding.
-    "xxx" may also be the text "autoload", which has a special meaning for
-    a module loader, but does not skip auto-detection.
-
-    If the kernel supports kmod, the cvf_format=xxx option also controls
-    on-demand CVF module loading. Without this option, nothing is loaded
-    on demand. With cvf_format=xxx, a module "xxx" is requested automatically
-    before mounting the compressed filesystem (unless "xxx" is "none"). In 
-    case there is a difference between the CVF format name and the module 
-    name, setup aliases in your modules configuration. If the string "xxx" 
-    is "autoload", a non-existent module "cvf_autoload" is requested which 
-    can be used together with a special modules configuration (alias and 
-    pre-install statements) in order to load more than one CVF module, let 
-    them detect automatically which kind of CVF is to be mounted, and only 
-    keep the "right" module in memory. For examples please refer to the 
-    dmsdos documentation (ftp and http addresses see below).
-
-  cvf_options=yyy
-    Option string passed to the CVF module. I.e. only the "yyy" is passed
-    (without the quotes). The documentation for each CVF module should 
-    explain it since it is interpreted only by the CVF module. Note that 
-    the string must not contain a comma (",") - this would lead to 
-    misinterpretation by the FAT driver, which would recognize the text 
-    after a comma as a FAT driver option and might get confused or print 
-    strange error messages. The documentation for the CVF module should 
-    offer a different separation symbol, for example the dot "." or the
-    plus sign "+", which is only valid inside the string "yyy".
-
-
-4. Description of the CVF-FAT interface
-------------------------------------------------------------------------------
-
-Assuming you want to write your own CVF module, you need to write a lot of
-interface functions. Most of them are covered in the kernel documentation
-you can find on the net, and thus won't be described here. They have been
-marked with "[...]" :-) Take a look at include/linux/fat_cvf.h.
-
-struct cvf_format
-{ int cvf_version;
-  char* cvf_version_text;
-  unsigned long int flags;
-  int (*detect_cvf) (struct super_block*sb);
-  int (*mount_cvf) (struct super_block*sb,char*options);
-  int (*unmount_cvf) (struct super_block*sb);
-  [...]
-  void (*zero_out_cluster) (struct inode*, int clusternr);
-}
-
-This structure defines the capabilities of a CVF module. It must be filled
-out completely by a CVF module. Consider it as a kind of form that is used
-to introduce the module to the FAT/CVF-FAT driver.
-
-It contains...
-  - cvf_version:
-      A version id which must be unique. Choose one.
-  - cvf_version_text:
-      A human readable version string that should be one short word 
-      describing the CVF format the module implements. This text is used
-      for the cvf_format option. This name must also be unique.
-  - flags:
-      Bit coded flags, currently only used for a readpage/mmap hack that 
-      provides both mmap and readpage functionality. If CVF_USE_READPAGE
-      is set, mmap is set to generic_file_mmap and readpage is caught
-      and redirected to the cvf_readpage function. If it is not set,
-      readpage is set to generic_readpage and mmap is caught and redirected
-      to cvf_mmap. (If you want writable mmap use the readpage interface.)
-  - detect_cvf:
-      A function that is called to decide whether the filesystem is a CVF of
-      the type the module supports. The detect_cvf function must return 0
-      for "NO, I DON'T KNOW THIS GARBAGE" or anything >0 for "YES, THIS IS
-      THE KIND OF CVF I SUPPORT". The function must maintain the module
-      usage counters for safety, i.e. do MOD_INC_USE_COUNT at the beginning
-      and MOD_DEC_USE_COUNT at the end. The function *must not* assume that
-      successful recognition would lead to a call of the mount_cvf function
-      later. 
-  - mount_cvf:
-      A function that sets up some values or initializes something additional
-      to what has to be done when a CVF is mounted. This is called at the
-      end of fat_read_super and must return 0 on success. Definitely, this
-      function must increment the module usage counter by MOD_INC_USE_COUNT.
-      This mount_cvf function is also responsible for interpreting a CVF
-      module specific option string (the "yyy" from the FAT mount option
-      "cvf_options=yyy") which cannot contain a comma (use for example the
-      dot "." as option separator symbol).
-  - unmount_cvf:
-      A function that is called when the filesystem is unmounted. Most likely
-      it only frees up some memory and calls MOD_DEC_USE_COUNT. The return
-      value might be ignored (it currently is ignored).
-  - [...]:
-      All other interface functions are "caught" FAT driver functions, i.e.
-      are executed by the FAT driver *instead* of the original FAT driver
-      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.
-  - 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
-      to the provided inode.
-
-Notes:
-  1. The cvf_bmap function should be ignored. It really should never
-     get called from somewhere. I recommend redirecting it to a panic
-     or fatal error message so bugs show up immediately.
-  2. The cvf_writepage function is ignored. This is because the fat
-     driver doesn't support it. This might change in future. I recommend
-     setting it to NULL (i.e use default).
-
-int register_cvf_format(struct cvf_format*cvf_format);
-  If you have just set up a variable containing the above structure,
-  call this function to introduce your CVF format to the FAT/CVF-FAT
-  driver. This is usually done in init_module. Be sure to check the
-  return value. Zero means success, everything else causes a kernel
-  message printed in the syslog describing the error that occurred.
-  Typical errors are:
-    - a module with the same version id is already registered or 
-    - too many CVF formats. Hack fs/fat/cvf.c if you need more.
-
-int unregister_cvf_format(struct cvf_format*cvf_format);
-  This is usually called in cleanup_module. Return value =0 means
-  success. An error only occurs if you try to unregister a CVF format
-  that has not been previously registered. The code uses the version id
-  to distinguish the modules, so be sure to keep it unique.
-
-5. CVF Modules
-------------------------------------------------------------------------------
-
-Refer to the dmsdos module (the successor of the dmsdos filesystem) for a
-sample implementation.  It can currently be found at
-
-  ftp://fb9nt.uni-duisburg.de/pub/linux/dmsdos/dmsdos-x.y.z.tgz
-  ftp://sunsite.unc.edu/pub/Linux/system/Filesystems/dosfs/dmsdos-x.y.z.tgz
-  ftp://ftp.uni-stuttgart.de/pub/systems/linux/local/system/dmsdos-x.y.z.tgz
-
-(where x.y.z is to be replaced with the actual version number). Full
-documentation about dmsdos is included in the dmsdos package, but can also
-be found at
-
-  http://fb9nt.uni-duisburg.de/mitarbeiter/gockel/software/dmsdos/index.html
-  http://www.yk.rim.or.jp/~takafumi/dmsdos/index.html (in Japanese).
diff -Nru a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt
--- a/Documentation/scsi/aic7xxx.txt	Thu May  1 10:04:05 2003
+++ b/Documentation/scsi/aic7xxx.txt	Wed May 14 15:22:44 2003
@@ -132,6 +132,11 @@
 
 2. Version History
 
+        6.2.34 - Fix locking regression instroduced in 6.2.29 that
+                 could cuase a lock order reversal between the io_request_lock
+                 and our per-softc lock.  This was only possible on RH9,
+                 SuSE, and kernel.org 2.4.X kernels.
+
         6.2.33 - Dynamically disable PCI parity error reporting after
 		 10 errors are reported to the user.  These errors are
 		 the result of some other device issuing PCI transactions
diff -Nru a/Documentation/scsi/dc395x.txt b/Documentation/scsi/dc395x.txt
--- a/Documentation/scsi/dc395x.txt	Sat Apr 26 14:17:46 2003
+++ b/Documentation/scsi/dc395x.txt	Fri May 23 15:57:18 2003
@@ -23,40 +23,70 @@
 Both can be overriden by command line parameters (module or kernel
 parameters).
 
-The syntax is as follows:
- dc395x = AdapterID, SpeedIdx, DevMode, AdaptMode, Tags, DelayReset
+The following parameters are available:
 
-AdapterID : Host Adapter SCSI ID
-SpeedIdx  : 0,1,...7 = 20,13.3,10,8,6.7,5.8,5,4 MHz               [ 7]
-DevMode   : Bitmap for Dev Cfg                                    [63]
-AdaptMode : Bitmap for Adapter Cfg                                [47]
-Tags      : The number of tags is 1<<x, if x has been specified   [ 4]
-DelayReset: The seconds to not accept commands after a SCSI Reset [ 1]
-
-DevMode bit definition:
-   Bit Val(hex) Val(dec)  Meaning
-   *0	 0x01	    1	  Parity check
-   *1	 0x02	    2	  Synchronous Negotiation
-   *2	 0x04	    4	  Disconnection
-   *3	 0x08	    8	  Send Start command on startup. (Not used)
-   *4	 0x10	   16	  Tagged Command Queueing
-   *5	 0x20	   32	  Wide Negotiation
-
-AdaptMode bit definition
-   Bit Val(hex) Val(dec)  Meaning
-   *0	 0x01	    1	  Support more than two drives. (Not used)
-   *1	 0x02	    2	  Use DOS compatible mapping for HDs greater than 1GB.
-   *2	 0x04	    4	  Reset SCSI Bus on startup.
-   *3	 0x08	    8	  Active Negation: Improves SCSI Bus noise immunity.
-    4	 0x10	   16	  Immediate return on BIOS seek command. (Not used)
- (*)5	 0x20	   32	  Check for LUNs >= 1.
-
-If you set AdapterID to -1, the adapter will use conservative
-("safe") default settings instead; more precisely, dc395x=-1 is a
-shortcut for dc395x=7,4,9,15,2,10
+ - safe
+   Default: 0, Acceptable values: 0 or 1
+
+   If safe is set to 1 then the adapter will use conservative
+   ("safe") default settings. This sets:
+
+		shortcut for dc395x=7,4,9,15,2,10
+
+ - adapter_id
+   Default: 7, Acceptable values: 0 to 15
+
+   Sets the host adapter SCSI ID.
+
+ - max_speed
+   Default: 1, Acceptable value: 0 to 7
+   0 = 20   Mhz
+   1 = 12.2 Mhz
+   2 = 10   Mhz
+   3 = 8    Mhz
+   4 = 6.7  Mhz
+   5 = 5.8  Hhz
+   6 = 5    Mhz
+   7 = 4    Mhz
+
+ - dev_mode
+   Bitmap for device configuration
+
+   DevMode bit definition:
+      Bit Val(hex) Val(dec)  Meaning
+      *0    0x01       1     Parity check
+      *1    0x02       2     Synchronous Negotiation
+      *2    0x04       4     Disconnection
+      *3    0x08       8     Send Start command on startup. (Not used)
+      *4    0x10      16     Tagged Command Queueing
+      *5    0x20      32     Wide Negotiation
+
+ - adapter_mode
+   Bitmap for adapter configuration
+
+   AdaptMode bit definition
+      Bit Val(hex) Val(dec)  Meaning
+      *0    0x01       1     Support more than two drives. (Not used)
+      *1    0x02       2     Use DOS compatible mapping for HDs greater than 1GB.
+      *2    0x04       4     Reset SCSI Bus on startup.
+      *3    0x08       8     Active Negation: Improves SCSI Bus noise immunity.
+       4    0x10      16     Immediate return on BIOS seek command. (Not used)
+    (*)5    0x20      32     Check for LUNs >= 1.
+
+ - tags
+   Default: 3, Acceptable values: 0-5
+   
+   The number of tags is 1<<x, if x has been specified
+
+ - reset_delay
+   Default: 1, Acceptable values: 0-180
+
+   The seconds to not accept commands after a SCSI Reset
+
+
+For the built  in driver the parameters should be prefixed with
+dc395x. (eg "dc395x.safe=1")
 
-If you specify -2 for a value, it will be ignored. You don't need to
-specify all six parameters.
 
 Copyright
 ---------
diff -Nru a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
--- a/Documentation/scsi/scsi_mid_low_api.txt	Mon Apr 21 07:42:33 2003
+++ b/Documentation/scsi/scsi_mid_low_api.txt	Mon Apr 28 16:34:05 2003
@@ -22,7 +22,10 @@
 a SCSI host and a PCI device is common but not required (e.g. with
 ISA or MCA adapters).]
 
-This version of the document roughly matches linux kernel version 2.5.67 .
+This version of the document roughly matches linux kernel version 2.5.68 .
+This document can be found in the Linux kernel source Documentation/scsi
+directory and is called scsi_mid_low_api.txt . A more recent copy may
+be found at http://www.torque.net/scsi/scsi_mid_low_api.txt.gz .
 
 Documentation
 =============
@@ -142,13 +145,14 @@
                     slave_configure() -->  scsi_adjust_queue_depth()
 			 |
 		    slave_alloc()
-                    slave_configure() -->  scsi_adjust_queue_depth()
+                    slave_configure()
 			 |
 		    slave_alloc()   **
                     slave_destroy() **
 
-The invocation of scsi_adjust_queue_depth() by the LLD is required
-if slave_configure() is supplied.
+If the LLD wants to adjust the default queue settings, it can invoke
+scsi_adjust_queue_depth() in its slave_configure() routine.
+
 ** For scsi devices that the mid level tries to scan but do not
    respond, a slave_alloc(), slave_destroy() pair is called.
 
@@ -179,7 +183,7 @@
 scsi_add_device()  ------+
                          |
 		    slave_alloc()
-                    slave_configure() -->  scsi_adjust_queue_depth()
+                    slave_configure()   [--> scsi_adjust_queue_depth()]
 
 [DEVICE unplug]
 LLD                      mid level                 LLD
@@ -228,13 +232,14 @@
 		      slave_destroy() **
                             |
 		      slave_alloc()
-                      slave_configure()  -->  scsi_adjust_queue_depth()
+                      slave_configure()
 		      slave_alloc()   **
 		      slave_destroy() **
 
-If the LLD does not supply a slave_configure() then the mid level invokes
-scsi_adjust_queue_depth() itself with tagged queuing off and "cmd_per_lun"
-for that host as the queue length.
+The mid level invokes scsi_adjust_queue_depth() with tagged queuing off and
+"cmd_per_lun" for that host as the queue length. These settings can be
+overridden by a slave_configure() supplied by the LLD.
+
 ** For scsi devices that the mid level tries to scan but do not
    respond, a slave_alloc(), slave_destroy() pair is called.
 
@@ -1093,11 +1098,6 @@
  *      Notes: Allows the driver to inspect the response to the initial
  *	INQUIRY done by the scanning code and take appropriate action.
  *	For more details see the hosts.h file.
- *	If this function is not supplied, the mid level will call
- *	scsi_adjust_queue_depth() with the struct Scsi_Host::cmd_per_lun
- *	value on behalf of the given device. If this function is
- *	supplied then its implementation must call
- *	scsi_adjust_queue_depth(). 	
  *
  *	Defined in: LLD
  **/
@@ -1277,8 +1277,9 @@
         Patrick Mansfield <patmans@us.ibm.com> 
 	Christoph Hellwig <hch@infradead.org>
 	Doug Ledford <dledford@redhat.com>
+        Andries Brouwer <Andries.Brouwer@cwi.nl>
 
 
 Douglas Gilbert
 dgilbert@interlog.com
-19th April 2003
+29th April 2003
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Mon May 26 17:57:52 2003
+++ b/Makefile	Wed May 28 04:31:54 2003
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 70
-EXTRAVERSION =
+EXTRAVERSION = -bk2
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c	Fri Apr  4 12:06:45 2003
+++ b/arch/alpha/kernel/pci.c	Wed May 21 08:28:01 2003
@@ -102,7 +102,7 @@
 {
 	unsigned int class = dev->class >> 8;
 
-	if (class == PCI_CLASS_BRIDGE_ISA || class == PCI_CLASS_BRIDGE_ISA) {
+	if (class == PCI_CLASS_BRIDGE_ISA || class == PCI_CLASS_BRIDGE_EISA) {
 		dev->dma_mask = MAX_ISA_DMA_ADDRESS - 1;
 		isa_bridge = dev;
 	}
diff -Nru a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
--- a/arch/alpha/kernel/ptrace.c	Tue May 20 10:47:24 2003
+++ b/arch/alpha/kernel/ptrace.c	Wed May 21 10:51:52 2003
@@ -366,8 +366,8 @@
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			break;
-		/* Set single stepping.  */
-		ptrace_set_bpt(child);
+		/* Mark single stepping.  */
+		child->thread_info->bpt_nsaved = -1;
 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		wake_up_process(child);
 		child->exit_code = data;
diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
--- a/arch/alpha/kernel/signal.c	Mon Feb 17 00:17:26 2003
+++ b/arch/alpha/kernel/signal.c	Wed May 21 11:17:01 2003
@@ -619,7 +619,10 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
+	/* This lets the debugger run, ... */
 	signr = get_signal_to_deliver(&info, regs, NULL);
+	/* ... so re-check the single stepping. */
+	single_stepping |= ptrace_cancel_bpt(current);
 
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c	Tue May 20 11:25:56 2003
+++ b/arch/alpha/kernel/smp.c	Wed May 21 08:27:23 2003
@@ -417,12 +417,7 @@
 	/* Don't care about the contents of regs since we'll never
 	   reschedule the forked task. */
 	struct pt_regs regs;
-	int pid;
-	pid = do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
-	if (pid < 0)
-		return NULL;
-
-	return find_task_by_pid (pid);
+	return copy_process(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }
 
 /*
@@ -441,8 +436,10 @@
 	   wish.  We can't use kernel_thread since we must avoid
 	   rescheduling the child.  */
 	idle = fork_by_hand();
-	if (!idle)
+	if (IS_ERR(idle))
 		panic("failed fork for CPU %d", cpuid);
+
+	wake_up_forked_process(idle);
 
 	init_idle(idle, cpuid);
 	unhash_process(idle);
diff -Nru a/arch/cris/drivers/serial.c b/arch/cris/drivers/serial.c
--- a/arch/cris/drivers/serial.c	Mon Apr 21 20:58:41 2003
+++ b/arch/cris/drivers/serial.c	Mon May 26 15:29:21 2003
@@ -335,13 +335,12 @@
 
 static DECLARE_TASK_QUEUE(tq_serial);
 
-struct tty_driver serial_driver, callout_driver;
+struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* serial subtype definitions */
 #ifndef SERIAL_TYPE_NORMAL
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 #endif
 
 /* number of characters left in xmit buffer before we ask for more */
@@ -3017,8 +3016,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -3063,8 +3060,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	restore_flags(flags);
 
@@ -3128,7 +3124,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -3166,44 +3162,18 @@
 	}
   
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-			return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 	
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -3228,11 +3198,9 @@
 	while (1) {
 		save_flags(flags);
 		cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE)) {
-			/* assert RTS and DTR */
-			e100_rts(info, 1);
-			e100_dtr(info, 1);
-		}
+		/* assert RTS and DTR */
+		e100_rts(info, 1);
+		e100_dtr(info, 1);
 		restore_flags(flags);
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -3247,8 +3215,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) && do_clocal)
+		if (!(info->flags & ASYNC_CLOSING) && do_clocal)
 			/* && (do_clocal || DCD_IS_ASSERTED) */
 			break;
 		if (signal_pending(current)) {
@@ -3358,16 +3325,10 @@
 	}
 
 	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-  
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open ttyS%d successful...\n", info->line);
 #endif
@@ -3538,23 +3499,8 @@
 	serial_driver.read_proc = rs_read_proc;
 #endif
 	  
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-#if (LINUX_VERSION_CODE >= 131343)
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-#endif
-  
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
   
 	/* do some initializing for the separate ports */
   
@@ -3574,7 +3520,6 @@
 		info->blocked_open = 0;
 		info->tqueue.routine = do_softint;
 		info->tqueue.data = info;
-		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
diff -Nru a/arch/cris/drivers/serial.h b/arch/cris/drivers/serial.h
--- a/arch/cris/drivers/serial.h	Tue Feb  5 07:24:37 2002
+++ b/arch/cris/drivers/serial.h	Mon May 26 15:29:21 2003
@@ -78,8 +78,6 @@
 	int			type;  /* PORT_ETRAX */
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	struct circ_buf		xmit;
 	struct circ_buf		recv;
 	unsigned char		*flag_buf;
@@ -87,7 +85,6 @@
 	struct tq_struct	tqueue;
 	struct async_icount	icount;   /* error-statistics etc.*/
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 #ifdef DECLARE_WAITQUEUE
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
diff -Nru a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
--- a/arch/ia64/hp/sim/simserial.c	Sat May 10 02:28:45 2003
+++ b/arch/ia64/hp/sim/simserial.c	Mon May 26 15:29:21 2003
@@ -104,7 +104,6 @@
 };
 
 struct tty_driver hp_simserial_driver;
-static struct tty_driver callout_driver;
 static int serial_refcount;
 
 static struct async_struct *IRQ_ports[NR_IRQS];
@@ -689,7 +688,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	MOD_DEC_USE_COUNT;
 }
@@ -723,7 +722,7 @@
 
 	info->event = 0;
 	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -937,10 +936,7 @@
 
 	if ((info->state->count == 1) &&
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else
-			*tty->termios = info->state->callout_termios;
+		*tty->termios = info->state->normal_termios;
 	}
 
 	/*
@@ -952,9 +948,6 @@
 		console = console->next;
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SIMSERIAL_DEBUG
 	printk("rs_open ttys%d successful\n", info->line);
 #endif
@@ -1084,22 +1077,9 @@
 		       state->port, state->irq,
 		       uart_config[state->type].name);
 	}
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = hp_simserial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
 
 	if (tty_register_driver(&hp_simserial_driver))
 		panic("Couldn't register simserial driver\n");
-
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
 
 	return 0;
 }
diff -Nru a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile
--- a/arch/m68knommu/kernel/Makefile	Mon Feb  3 14:19:35 2003
+++ b/arch/m68knommu/kernel/Makefile	Sun May 25 21:46:25 2003
@@ -2,7 +2,7 @@
 # Makefile for arch/m68knommu/kernel.
 #
 
-obj-y += entry.o init_task.o ints.o m68k_ksyms.o process.o ptrace.o \
+obj-y += entry.o init_task.o m68k_ksyms.o process.o ptrace.o \
 	 semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o \
 	 traps.o
 
diff -Nru a/arch/m68knommu/kernel/ints.c b/arch/m68knommu/kernel/ints.c
--- a/arch/m68knommu/kernel/ints.c	Mon Feb 24 12:31:17 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,271 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/ints.c -- General interrupt handling code
- *
- * Copyright (C) 1999-2002  Greg Ungerer (gerg@snapgear.com)
- * Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
- *                     Kenneth Albanowski <kjahds@kjahds.com>,
- * Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
- *
- * Based on:
- *
- * linux/arch/m68k/kernel/ints.c -- Linux/m68k general interrupt handling code
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <linux/errno.h>
-#include <linux/config.h>
-#include <linux/seq_file.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/traps.h>
-#include <asm/page.h>
-#include <asm/machdep.h>
-
-/*
- *	This table stores the address info for each vector handler.
- */
-irq_handler_t irq_list[SYS_IRQS];
-
-#define NUM_IRQ_NODES 16
-static irq_node_t nodes[NUM_IRQ_NODES];
-
-/* The number of spurious interrupts */
-volatile unsigned int num_spurious;
-
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
-
-static void default_irq_handler(int irq, void *ptr, struct pt_regs *regs)
-{
-#if 1
-	printk("%s(%d): default irq handler vec=%d [0x%x]\n",
-		__FILE__, __LINE__, irq, irq);
-#endif
-}
-
-/*
- * void init_IRQ(void)
- *
- * Parameters:	None
- *
- * Returns:	Nothing
- *
- * This function should be called during kernel startup to initialize
- * the IRQ handling routines.
- */
-
-void __init init_IRQ(void)
-{
-	int i;
-
-	for (i = 0; i < SYS_IRQS; i++) {
-		if (mach_default_handler)
-			irq_list[i].handler = (*mach_default_handler)[i];
-		else
-			irq_list[i].handler = default_irq_handler;
-		irq_list[i].flags   = IRQ_FLG_STD;
-		irq_list[i].dev_id  = NULL;
-		irq_list[i].devname = NULL;
-	}
-
-	for (i = 0; i < NUM_IRQ_NODES; i++)
-		nodes[i].handler = NULL;
-
-	if (mach_init_IRQ)
-		mach_init_IRQ();
-}
-
-irq_node_t *new_irq_node(void)
-{
-	irq_node_t *node;
-	short i;
-
-	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
-		if (!node->handler)
-			return node;
-
-	printk("new_irq_node: out of nodes\n");
-	return NULL;
-}
-
-int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-                unsigned long flags, const char *devname, void *dev_id)
-{
-	if (irq < 0 || irq >= NR_IRQS) {
-		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__,
-			irq, devname);
-		return -ENXIO;
-	}
-
-	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
-		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
-			printk("%s: IRQ %d from %s is not replaceable\n",
-			       __FUNCTION__, irq, irq_list[irq].devname);
-			return -EBUSY;
-		}
-		if (flags & IRQ_FLG_REPLACE) {
-			printk("%s: %s can't replace IRQ %d from %s\n",
-			       __FUNCTION__, devname, irq, irq_list[irq].devname);
-			return -EBUSY;
-		}
-	}
-
-#ifdef CONFIG_COLDFIRE
-	if (flags & IRQ_FLG_FAST) {
-		extern asmlinkage void fasthandler(void);
-		extern void set_evector(int vecnum, void (*handler)(void));
-		set_evector(irq, fasthandler);
-	}
-#endif
-
-	irq_list[irq].handler = handler;
-	irq_list[irq].flags   = flags;
-	irq_list[irq].dev_id  = dev_id;
-	irq_list[irq].devname = devname;
-	return 0;
-}
-
-void free_irq(unsigned int irq, void *dev_id)
-{
-	if (irq >= NR_IRQS) {
-		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
-		return;
-	}
-
-	if (irq_list[irq].dev_id != dev_id)
-		printk("%s: Removing probably wrong IRQ %d from %s\n",
-		       __FUNCTION__, irq, irq_list[irq].devname);
-
-#ifdef CONFIG_COLDFIRE
-	if (irq_list[irq].flags & IRQ_FLG_FAST) {
-		extern asmlinkage void inthandler(void);
-		extern void set_evector(int vecnum, void (*handler)(void));
-		set_evector(irq, inthandler);
-	}
-#endif
-
-	if (mach_default_handler)
-		irq_list[irq].handler = (*mach_default_handler)[irq];
-	else
-		irq_list[irq].handler = default_irq_handler;
-	irq_list[irq].flags   = IRQ_FLG_STD;
-	irq_list[irq].dev_id  = NULL;
-	irq_list[irq].devname = NULL;
-}
-
-
-int sys_request_irq(unsigned int irq, 
-                    void (*handler)(int, void *, struct pt_regs *), 
-                    unsigned long flags, const char *devname, void *dev_id)
-{
-	if (irq > IRQ7) {
-		printk("%s: Incorrect IRQ %d from %s\n",
-		       __FUNCTION__, irq, devname);
-		return -ENXIO;
-	}
-
-#if 0
-	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
-		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
-			printk("%s: IRQ %d from %s is not replaceable\n",
-			       __FUNCTION__, irq, irq_list[irq].devname);
-			return -EBUSY;
-		}
-		if (!(flags & IRQ_FLG_REPLACE)) {
-			printk("%s: %s can't replace IRQ %d from %s\n",
-			       __FUNCTION__, devname, irq, irq_list[irq].devname);
-			return -EBUSY;
-		}
-	}
-#endif
-
-	irq_list[irq].handler = handler;
-	irq_list[irq].flags   = flags;
-	irq_list[irq].dev_id  = dev_id;
-	irq_list[irq].devname = devname;
-	return 0;
-}
-
-void sys_free_irq(unsigned int irq, void *dev_id)
-{
-	if (irq > IRQ7) {
-		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
-		return;
-	}
-
-	if (irq_list[irq].dev_id != dev_id)
-		printk("%s: Removing probably wrong IRQ %d from %s\n",
-		       __FUNCTION__, irq, irq_list[irq].devname);
-
-	irq_list[irq].handler = (*mach_default_handler)[irq];
-	irq_list[irq].flags   = 0;
-	irq_list[irq].dev_id  = NULL;
-	irq_list[irq].devname = NULL;
-}
-
-/*
- * Do we need these probe functions on the m68k?
- *
- *  ... may be useful with ISA devices
- */
-unsigned long probe_irq_on (void)
-{
-	return 0;
-}
-
-int probe_irq_off (unsigned long irqs)
-{
-	return 0;
-}
-
-asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
-{
-	if (vec >= VEC_INT1 && vec <= VEC_INT7) {
-		vec -= VEC_SPUR;
-		kstat_cpu(0).irqs[vec]++;
-		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
-	} else {
-		if (mach_process_int)
-			mach_process_int(vec, fp);
-		else
-			panic("Can't process interrupt vector %ld\n", vec);
-		return;
-	}
-}
-
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-	int i;
-
-	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_list[i].flags & IRQ_FLG_STD)
-			continue;
-
-		seq_printf(p, "%3d: %10u ", i,
-			(i ? kstat_cpu(0).irqs[i] : num_spurious));
-		if (irq_list[i].flags & IRQ_FLG_LOCK)
-			seq_printf(p, "L ");
-		else
-			seq_printf(p, "  ");
-		seq_printf(p, "%s\n", irq_list[i].devname);
-	}
-
-	if (mach_get_irq_list)
-		mach_get_irq_list(p, v);
-	return(0);
-}
-
-void init_irq_proc(void)
-{
-	/* Insert /proc/irq driver here */
-}
-
diff -Nru a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
--- a/arch/m68knommu/platform/5307/Makefile	Thu May  8 15:47:43 2003
+++ b/arch/m68knommu/platform/5307/Makefile	Sun May 25 21:46:26 2003
@@ -16,7 +16,7 @@
 AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
 endif
 
-obj-$(CONFIG_COLDFIRE)	+= entry.o vectors.o
+obj-$(CONFIG_COLDFIRE)	+= entry.o vectors.o ints.o
 obj-$(CONFIG_M5206)	+= timers.o
 obj-$(CONFIG_M5206e)	+= timers.o
 obj-$(CONFIG_M5249)	+= timers.o
diff -Nru a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/platform/5307/ints.c	Sun May 25 21:46:26 2003
@@ -0,0 +1,267 @@
+/*
+ * linux/arch/m68knommu/kernel/ints.c -- General interrupt handling code
+ *
+ * Copyright (C) 1999-2002  Greg Ungerer (gerg@snapgear.com)
+ * Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                     Kenneth Albanowski <kjahds@kjahds.com>,
+ * Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * Based on:
+ *
+ * linux/arch/m68k/kernel/ints.c -- Linux/m68k general interrupt handling code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/config.h>
+#include <linux/seq_file.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+
+/*
+ *	This table stores the address info for each vector handler.
+ */
+irq_handler_t irq_list[SYS_IRQS];
+
+#define NUM_IRQ_NODES 16
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+
+static void default_irq_handler(int irq, void *ptr, struct pt_regs *regs)
+{
+#if 1
+	printk("%s(%d): default irq handler vec=%d [0x%x]\n",
+		__FILE__, __LINE__, irq, irq);
+#endif
+}
+
+/*
+ * void init_IRQ(void)
+ *
+ * Parameters:	None
+ *
+ * Returns:	Nothing
+ *
+ * This function should be called during kernel startup to initialize
+ * the IRQ handling routines.
+ */
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	for (i = 0; i < SYS_IRQS; i++) {
+		if (mach_default_handler)
+			irq_list[i].handler = (*mach_default_handler)[i];
+		else
+			irq_list[i].handler = default_irq_handler;
+		irq_list[i].flags   = IRQ_FLG_STD;
+		irq_list[i].dev_id  = NULL;
+		irq_list[i].devname = NULL;
+	}
+
+	for (i = 0; i < NUM_IRQ_NODES; i++)
+		nodes[i].handler = NULL;
+
+	if (mach_init_IRQ)
+		mach_init_IRQ();
+}
+
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__,
+			irq, devname);
+		return -ENXIO;
+	}
+
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (flags & IRQ_FLG_REPLACE) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+
+	if (flags & IRQ_FLG_FAST) {
+		extern asmlinkage void fasthandler(void);
+		extern void set_evector(int vecnum, void (*handler)(void));
+		set_evector(irq, fasthandler);
+	}
+
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq >= NR_IRQS) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	if (irq_list[irq].flags & IRQ_FLG_FAST) {
+		extern asmlinkage void inthandler(void);
+		extern void set_evector(int vecnum, void (*handler)(void));
+		set_evector(irq, inthandler);
+	}
+
+	if (mach_default_handler)
+		irq_list[irq].handler = (*mach_default_handler)[irq];
+	else
+		irq_list[irq].handler = default_irq_handler;
+	irq_list[irq].flags   = IRQ_FLG_STD;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = NULL;
+}
+
+
+int sys_request_irq(unsigned int irq, 
+                    void (*handler)(int, void *, struct pt_regs *), 
+                    unsigned long flags, const char *devname, void *dev_id)
+{
+	if (irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d from %s\n",
+		       __FUNCTION__, irq, devname);
+		return -ENXIO;
+	}
+
+#if 0
+	if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
+		if (irq_list[irq].flags & IRQ_FLG_LOCK) {
+			printk("%s: IRQ %d from %s is not replaceable\n",
+			       __FUNCTION__, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+		if (!(flags & IRQ_FLG_REPLACE)) {
+			printk("%s: %s can't replace IRQ %d from %s\n",
+			       __FUNCTION__, devname, irq, irq_list[irq].devname);
+			return -EBUSY;
+		}
+	}
+#endif
+
+	irq_list[irq].handler = handler;
+	irq_list[irq].flags   = flags;
+	irq_list[irq].dev_id  = dev_id;
+	irq_list[irq].devname = devname;
+	return 0;
+}
+
+void sys_free_irq(unsigned int irq, void *dev_id)
+{
+	if (irq > IRQ7) {
+		printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+		return;
+	}
+
+	if (irq_list[irq].dev_id != dev_id)
+		printk("%s: Removing probably wrong IRQ %d from %s\n",
+		       __FUNCTION__, irq, irq_list[irq].devname);
+
+	irq_list[irq].handler = (*mach_default_handler)[irq];
+	irq_list[irq].flags   = 0;
+	irq_list[irq].dev_id  = NULL;
+	irq_list[irq].devname = NULL;
+}
+
+/*
+ * Do we need these probe functions on the m68k?
+ *
+ *  ... may be useful with ISA devices
+ */
+unsigned long probe_irq_on (void)
+{
+	return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+	return 0;
+}
+
+asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
+{
+	if (vec >= VEC_INT1 && vec <= VEC_INT7) {
+		vec -= VEC_SPUR;
+		kstat_cpu(0).irqs[vec]++;
+		irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
+	} else {
+		if (mach_process_int)
+			mach_process_int(vec, fp);
+		else
+			panic("Can't process interrupt vector %ld\n", vec);
+		return;
+	}
+}
+
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		if (irq_list[i].flags & IRQ_FLG_STD)
+			continue;
+
+		seq_printf(p, "%3d: %10u ", i,
+			(i ? kstat_cpu(0).irqs[i] : num_spurious));
+		if (irq_list[i].flags & IRQ_FLG_LOCK)
+			seq_printf(p, "L ");
+		else
+			seq_printf(p, "  ");
+		seq_printf(p, "%s\n", irq_list[i].devname);
+	}
+
+	if (mach_get_irq_list)
+		mach_get_irq_list(p, v);
+	return(0);
+}
+
+void init_irq_proc(void)
+{
+	/* Insert /proc/irq driver here */
+}
+
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/config.c b/arch/m68knommu/platform/68VZ328/de2/config.c
--- a/arch/m68knommu/platform/68VZ328/de2/config.c	Sun May 25 21:46:27 2003
+++ b/arch/m68knommu/platform/68VZ328/de2/config.c	Tue May 27 06:56:10 2003
@@ -118,7 +118,7 @@
 
 static void init_hardware(void)
 {
-#if CONFIG_DIRECT_IO_ACCESS
+#ifdef CONFIG_DIRECT_IO_ACCESS
 	SCR = 0x10;					/* allow user access to internal registers */
 #endif
 
diff -Nru a/arch/mips/au1000/common/serial.c b/arch/mips/au1000/common/serial.c
--- a/arch/mips/au1000/common/serial.c	Wed May  7 15:51:55 2003
+++ b/arch/mips/au1000/common/serial.c	Mon May 26 15:29:21 2003
@@ -126,7 +126,7 @@
 
 static DECLARE_TASK_QUEUE(tq_serial);
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 
 static struct timer_list serial_timer;
@@ -136,7 +136,6 @@
 /* serial subtype definitions */
 #ifndef SERIAL_TYPE_NORMAL
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 #endif
 
 /* number of characters left in xmit buffer before we ask for more */
@@ -529,8 +528,7 @@
 #endif		
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+		else {
 #ifdef SERIAL_DEBUG_OPEN
 			printk("doing serial hangup...");
 #endif
@@ -1935,8 +1933,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->state->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->state->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1976,8 +1972,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	MOD_DEC_USE_COUNT;
 }
@@ -2066,7 +2061,7 @@
 	shutdown(info);
 	info->event = 0;
 	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -2102,44 +2097,18 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (state->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -2162,8 +2131,7 @@
 	info->blocked_open++;
 	while (1) {
 		save_flags(flags); cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
+		if (tty->termios->c_cflag & CBAUD)
 			serial_out(info, UART_MCR,
 				   serial_inp(info, UART_MCR) |
 				   (UART_MCR_DTR | UART_MCR_RTS));
@@ -2181,8 +2149,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (serial_in(info, UART_MSR) &
 				   UART_MSR_DCD)))
 			break;
@@ -2335,10 +2302,7 @@
 
 	if ((info->state->count == 1) &&
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else 
-			*tty->termios = info->state->callout_termios;
+		*tty->termios = info->state->normal_termios;
 		change_speed(info, 0);
 	}
 #ifdef CONFIG_AU1000_SERIAL_CONSOLE
@@ -2348,8 +2312,6 @@
 		change_speed(info, 0);
 	}
 #endif
-	info->session = current->session;
-	info->pgrp = current->pgrp;
 
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open %s successful...", tty->name);
@@ -2626,26 +2588,9 @@
 	serial_driver.wait_until_sent = rs_wait_until_sent;
 	serial_driver.read_proc = rs_read_proc;
 	
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
-	callout_driver.name = "cua/";
-#else
-	callout_driver.name = "cua";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-	
+
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
 		state->baud_base = get_au1000_uart_baud();
 		state->magic = SSTATE_MAGIC;
@@ -2654,7 +2599,6 @@
 		state->custom_divisor = 0;
 		state->close_delay = 5*HZ/10;
 		state->closing_wait = 30*HZ;
-		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
 		state->icount.cts = state->icount.dsr = 
 			state->icount.rng = state->icount.dcd = 0;
@@ -2682,7 +2626,6 @@
 		       state->port, state->irq,
 		       uart_config[state->type].name);
 		tty_register_device(&serial_driver, state->line, NULL);
-		tty_register_device(&callout_driver, state->line, NULL);
 	}
 	return 0;
 }
@@ -2770,7 +2713,6 @@
 	      state->iomem_base ? (unsigned long)state->iomem_base :
 	      state->port, state->irq, uart_config[state->type].name);
 	tty_register_device(&serial_driver, state->line, NULL); 
-	tty_register_device(&callout_driver, state->line, NULL);
 	return state->line + SERIAL_DEV_OFFSET;
 }
 
@@ -2815,9 +2757,6 @@
 	if ((e1 = tty_unregister_driver(&serial_driver)))
 		printk("serial: failed to unregister serial driver (%d)\n",
 		       e1);
-	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("serial: failed to unregister callout driver (%d)\n", 
-		       e2);
 	restore_flags(flags);
 
 	for (i = 0; i < NR_PORTS; i++) {
diff -Nru a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c
--- a/arch/mips/baget/vacserial.c	Mon May 26 17:51:43 2003
+++ b/arch/mips/baget/vacserial.c	Mon May 26 15:29:20 2003
@@ -95,7 +95,7 @@
 
 static DECLARE_TASK_QUEUE(tq_serial);
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* number of characters left in xmit buffer before we ask for more */
@@ -1690,8 +1690,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->state->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->state->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1731,8 +1729,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	MOD_DEC_USE_COUNT;
 	restore_flags(flags);
@@ -1811,7 +1808,7 @@
 	shutdown(info);
 	info->event = 0;
 	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1847,44 +1844,18 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (state->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1919,8 +1890,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING))
+		if (!(info->flags & ASYNC_CLOSING))
 			break;
 		if (signal_pending(current)) {
 			retval = -ERESTARTSYS;
@@ -2070,10 +2040,7 @@
 
 	if ((info->state->count == 1) &&
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else 
-			*tty->termios = info->state->callout_termios;
+		*tty->termios = info->state->normal_termios;
 		change_speed(info);
 	}
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -2083,8 +2050,6 @@
 		change_speed(info);
 	}
 #endif
-	info->session = current->session;
-	info->pgrp = current->pgrp;
 
 #ifdef SERIAL_DEBUG_OPEN
 	baget_printk("rs_open %s successful...", tty->name);
@@ -2393,21 +2358,8 @@
 	serial_driver.wait_until_sent = rs_wait_until_sent;
 	serial_driver.read_proc = rs_read_proc;
 	
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
 	
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
 		state->magic = SSTATE_MAGIC;
@@ -2416,7 +2368,6 @@
 		state->custom_divisor = 0;
 		state->close_delay = 5*HZ/10;
 		state->closing_wait = 30*HZ;
-		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
 		state->icount.cts = state->icount.dsr = 
 			state->icount.rng = state->icount.dcd = 0;
@@ -2533,9 +2484,6 @@
 	if ((e1 = tty_unregister_driver(&serial_driver)))
 		printk("SERIAL: failed to unregister serial driver (%d)\n",
 		       e1);
-	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("SERIAL: failed to unregister callout driver (%d)\n", 
-		       e2);
 	restore_flags(flags);
 
 	for (i = 0; i < NR_PORTS; i++) {
diff -Nru a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
--- a/arch/ppc/4xx_io/serial_sicc.c	Sun Apr 27 04:56:50 2003
+++ b/arch/ppc/4xx_io/serial_sicc.c	Mon May 26 15:29:20 2003
@@ -183,11 +183,6 @@
 #define SERIAL_SICC_MINOR   1
 #define SERIAL_SICC_NR      1
 
-#define CALLOUT_SICC_NAME   "cuasicc"
-#define CALLOUT_SICC_MAJOR  151
-#define CALLOUT_SICC_MINOR  1
-#define CALLOUT_SICC_NR     SERIAL_SICC_NR
-
 #ifndef TRUE
 #define TRUE 1
 #endif
@@ -202,7 +197,7 @@
 /*
  * Things needed by tty driver
  */
-static struct tty_driver siccnormal_driver, sicccallout_driver;
+static struct tty_driver siccnormal_driver;
 static int siccuart_refcount;
 static struct tty_struct *siccuart_table[SERIAL_SICC_NR];
 static struct termios *siccuart_termios[SERIAL_SICC_NR];
@@ -275,8 +270,6 @@
     unsigned int        custom_divisor;
     unsigned int        flags;
     struct termios      normal_termios;
-    struct termios      callout_termios;
-
     int         count;
     struct SICC_info    *info;
 };
@@ -304,8 +297,6 @@
     unsigned int        lcr_h;
     unsigned int        mctrl;
     int         blocked_open;
-    pid_t           session;
-    pid_t           pgrp;
 
     struct tasklet_struct   tlet;
 
@@ -1487,8 +1478,6 @@
      */
     if (info->flags & ASYNC_NORMAL_ACTIVE)
         info->state->normal_termios = *tty->termios;
-    if (info->flags & ASYNC_CALLOUT_ACTIVE)
-        info->state->callout_termios = *tty->termios;
     /*
      * Now we wait for the transmit buffer to clear; and we notify
      * the line discipline to only process XON/XOFF characters.
@@ -1524,8 +1513,7 @@
         }
         wake_up_interruptible(&info->open_wait);
     }
-    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-             ASYNC_CLOSING);
+    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
     wake_up_interruptible(&info->close_wait);
     MOD_DEC_USE_COUNT;
 }
@@ -1594,7 +1582,7 @@
     siccuart_shutdown(info);
     info->event = 0;
     state->count = 0;
-    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+    info->flags &= ~ASYNC_NORMAL_ACTIVE;
     info->tty = NULL;
     wake_up_interruptible(&info->open_wait);
 }
@@ -1620,43 +1608,17 @@
     }
 
     /*
-     * If this is a callout device, then just make sure the normal
-     * device isn't being used.
-     */
-    if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-        if (info->flags & ASYNC_NORMAL_ACTIVE)
-            return -EBUSY;
-        if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-            (info->flags & ASYNC_SESSION_LOCKOUT) &&
-            (info->session != current->session))
-            return -EBUSY;
-        if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-            (info->flags & ASYNC_PGRP_LOCKOUT) &&
-            (info->pgrp != current->pgrp))
-            return -EBUSY;
-        info->flags |= ASYNC_CALLOUT_ACTIVE;
-        return 0;
-    }
-
-    /*
      * If non-blocking mode is set, or the port is not enabled,
      * then make the check up front and then exit.
      */
     if ((filp->f_flags & O_NONBLOCK) ||
         (tty->flags & (1 << TTY_IO_ERROR))) {
-        if (info->flags & ASYNC_CALLOUT_ACTIVE)
-            return -EBUSY;
         info->flags |= ASYNC_NORMAL_ACTIVE;
         return 0;
     }
 
-    if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-        if (state->normal_termios.c_cflag & CLOCAL)
-            do_clocal = 1;
-    } else {
-        if (tty->termios->c_cflag & CLOCAL)
-            do_clocal = 1;
-    }
+    if (tty->termios->c_cflag & CLOCAL)
+	do_clocal = 1;
 
     /*
      * Block waiting for the carrier detect and the line to become
@@ -1676,8 +1638,7 @@
     info->blocked_open++;
     while (1) {
         save_flags(flags); cli();
-        if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-            (tty->termios->c_cflag & CBAUD)) {
+        if (tty->termios->c_cflag & CBAUD) {
             info->mctrl = TIOCM_DTR | TIOCM_RTS;
             info->port->set_mctrl(info->port, info->mctrl);
         }
@@ -1691,8 +1652,7 @@
                 retval = -ERESTARTSYS;
             break;
         }
-        if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-            !(info->flags & ASYNC_CLOSING) &&
+        if (!(info->flags & ASYNC_CLOSING) &&
             (do_clocal /*|| (UART_GET_FR(info->port) & SICC_UARTFR_DCD)*/))
             break;
         if (signal_pending(current)) {
@@ -1803,12 +1763,7 @@
 
     if ((info->state->count == 1) &&
         (info->flags & ASYNC_SPLIT_TERMIOS)) {
-        if (tty->driver->subtype == SERIAL_TYPE_NORMAL) {
-            *tty->termios = info->state->normal_termios;
-        }
-        else  {
-            *tty->termios = info->state->callout_termios;
-        }
+	*tty->termios = info->state->normal_termios;
     }
 #ifdef CONFIG_SERIAL_SICC_CONSOLE
     if (siccuart_cons.cflag && siccuart_cons.index == line) {
@@ -1817,8 +1772,6 @@
         siccuart_change_speed(info, NULL);
     }
 #endif
-    info->session = current->session;
-    info->pgrp = current->pgrp;
     return 0;
 }
 
@@ -1862,28 +1815,14 @@
     siccnormal_driver.wait_until_sent = siccuart_wait_until_sent;
     siccnormal_driver.read_proc = NULL;
 
-    /*
-     * The callout device is just like the normal device except for
-     * the major number and the subtype code.
-     */
-    sicccallout_driver = siccnormal_driver;
-    sicccallout_driver.name = CALLOUT_SICC_NAME;
-    sicccallout_driver.major = CALLOUT_SICC_MAJOR;
-    sicccallout_driver.subtype = SERIAL_TYPE_CALLOUT;
-    sicccallout_driver.read_proc = NULL;
-    sicccallout_driver.proc_entry = NULL;
-
     if (tty_register_driver(&siccnormal_driver))
         panic("Couldn't register SICC serial driver\n");
-    if (tty_register_driver(&sicccallout_driver))
-        panic("Couldn't register SICC callout driver\n");
 
     for (i = 0; i < SERIAL_SICC_NR; i++) {
         struct SICC_state *state = sicc_state + i;
         state->line     = i;
         state->close_delay  = 5 * HZ / 10;
         state->closing_wait = 30 * HZ;
-        state->callout_termios  = sicccallout_driver.init_termios;
         state->normal_termios   = siccnormal_driver.init_termios;
     }
 
diff -Nru a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c
--- a/arch/ppc/8260_io/uart.c	Sun Apr 27 04:56:50 2003
+++ b/arch/ppc/8260_io/uart.c	Mon May 26 15:29:20 2003
@@ -74,7 +74,7 @@
 static char *serial_name = "CPM UART driver";
 static char *serial_version = "0.02";
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 static int serial_console_setup(struct console *co, char *options);
 
@@ -200,8 +200,6 @@
 	unsigned long		event;
 	unsigned long		last_active;
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	struct work_struct	tqueue;
 	struct work_struct	tqueue_hangup;
 	wait_queue_head_t	open_wait;
@@ -531,8 +529,7 @@
 #endif		
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+		else {
 #ifdef SERIAL_DEBUG_OPEN
 			printk("scheduling hangup...");
 #endif
@@ -1667,8 +1664,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->state->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->state->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1716,8 +1711,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	MOD_DEC_USE_COUNT;
 	restore_flags(flags);
@@ -1799,7 +1793,7 @@
 	shutdown(info);
 	info->event = 0;
 	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1838,25 +1832,6 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 * If this is an SMC port, we don't have modem control to wait
@@ -1865,20 +1840,13 @@
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR)) ||
 	    (info->state->smc_scc_num < SCC_NUM_BASE)) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (state->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1900,8 +1868,7 @@
 	info->blocked_open++;
 	while (1) {
 		cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
+		if (tty->termios->c_cflag & CBAUD)
 			serial_out(info, UART_MCR,
 				   serial_inp(info, UART_MCR) |
 				   (UART_MCR_DTR | UART_MCR_RTS));
@@ -1919,8 +1886,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (serial_in(info, UART_MSR) &
 				   UART_MSR_DCD)))
 			break;
@@ -2010,16 +1976,10 @@
 
 	if ((info->state->count == 1) &&
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else 
-			*tty->termios = info->state->callout_termios;
+		*tty->termios = info->state->normal_termios;
 		change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open %s successful...", line);
 #endif
@@ -2544,26 +2504,9 @@
 	serial_driver.wait_until_sent = rs_8xx_wait_until_sent;
 	serial_driver.read_proc = rs_8xx_read_proc;
 	
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#ifdef CONFIG_DEVFS_FS
-	callout_driver.name = "cua/";
-#else
-	callout_driver.name = "cua";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-	
+
 	immap = immr;
 	cp = &immap->im_cpm;
 	io = &immap->im_ioport;
@@ -2644,7 +2587,6 @@
 		state->custom_divisor = 0;
 		state->close_delay = 5*HZ/10;
 		state->closing_wait = 30*HZ;
-		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
 		state->icount.cts = state->icount.dsr = 
 			state->icount.rng = state->icount.dcd = 0;
diff -Nru a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c
--- a/arch/ppc/8xx_io/uart.c	Thu Apr 24 03:30:40 2003
+++ b/arch/ppc/8xx_io/uart.c	Mon May 26 15:29:19 2003
@@ -85,7 +85,7 @@
 
 static DECLARE_TASK_QUEUE(tq_serial);
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 static int serial_console_setup(struct console *co, char *options);
 
@@ -199,8 +199,6 @@
 	unsigned long		event;
 	unsigned long		last_active;
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	struct tq_struct	tqueue;
 	struct tq_struct	tqueue_hangup;
 	wait_queue_head_t	open_wait;
@@ -590,8 +588,7 @@
 #endif		
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+		else {
 #ifdef SERIAL_DEBUG_OPEN
 			printk("scheduling hangup...");
 #endif
@@ -1714,8 +1711,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->state->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->state->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1764,8 +1759,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	MOD_DEC_USE_COUNT;
 	restore_flags(flags);
@@ -1858,7 +1852,7 @@
 	shutdown(info);
 	info->event = 0;
 	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1897,25 +1891,6 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 * If this is an SMC port, we don't have modem control to wait
@@ -1924,20 +1899,13 @@
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR)) ||
 	    !(info->state->smc_scc_num & NUM_IS_SCC)) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (state->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1959,8 +1927,7 @@
 	info->blocked_open++;
 	while (1) {
 		cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
+		if ((tty->termios->c_cflag & CBAUD))
 			serial_out(info, UART_MCR,
 				   serial_inp(info, UART_MCR) |
 				   (UART_MCR_DTR | UART_MCR_RTS));
@@ -1978,8 +1945,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (serial_in(info, UART_MSR) &
 				   UART_MSR_DCD)))
 			break;
@@ -2070,16 +2036,10 @@
 
 	if ((info->state->count == 1) &&
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else 
-			*tty->termios = info->state->callout_termios;
+		*tty->termios = info->state->normal_termios;
 		change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open %s successful...", tty->name);
 #endif
@@ -2597,25 +2557,8 @@
 	serial_driver.wait_until_sent = rs_8xx_wait_until_sent;
 	serial_driver.read_proc = rs_8xx_read_proc;
 	
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#ifdef CONFIG_DEVFS_FS
-	callout_driver.name = "cua/";
-#else
-	callout_driver.name = "cua";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
 	
 	cp = cpmp;	/* Get pointer to Communication Processor */
 	immap = (immap_t *)IMAP_ADDR;	/* and to internal registers */
@@ -2675,7 +2618,6 @@
 		state->custom_divisor = 0;
 		state->close_delay = 5*HZ/10;
 		state->closing_wait = 30*HZ;
-		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
 		state->icount.cts = state->icount.dsr = 
 			state->icount.rng = state->icount.dcd = 0;
diff -Nru a/arch/v850/as85ep1-rom.ld b/arch/v850/as85ep1-rom.ld
--- a/arch/v850/as85ep1-rom.ld	Fri Dec 20 22:18:52 2002
+++ b/arch/v850/as85ep1-rom.ld	Tue May 27 00:09:43 2003
@@ -1,9 +1,6 @@
 /* Linker script for the NEC AS85EP1 V850E evaluation board
    (CONFIG_V850E_AS85EP1), with kernel in ROM (CONFIG_ROM_KERNEL).  */
 
-/* Note, all symbols are prefixed with an extra `_' for compatibility with
-   the existing linux sources.  */
-
 MEMORY {
 	/* 4MB of flash ROM.  */
 	ROM   : ORIGIN = 0,          LENGTH = 0x00400000
@@ -12,7 +9,7 @@
 	SRAM  : ORIGIN = 0x00400000, LENGTH = 0x00100000
 
 	/* About 58MB of DRAM.  This can actually be at one of two
-	   positions, determined by jump JP3; we have to use the first
+	   positions, determined by jumper JP3; we have to use the first
 	   position because the second is partially out of processor
 	   instruction addressing range (though in the second position
 	   there's actually 64MB available).  */
diff -Nru a/arch/v850/kernel/entry.S b/arch/v850/kernel/entry.S
--- a/arch/v850/kernel/entry.S	Thu Apr  3 14:58:04 2003
+++ b/arch/v850/kernel/entry.S	Tue May 27 00:53:39 2003
@@ -29,28 +29,28 @@
 #define CSYM	C_SYMBOL_NAME
 
 
-/* The offset of the struct pt_regs in a `state save frame' on the stack.  */
+/* The offset of the struct pt_regs in a state-save-frame on the stack.  */
 #define PTO	STATE_SAVE_PT_OFFSET
 
 
-/* Save argument registers to the struct pt_regs pointed to by EP.  */
+/* Save argument registers to the state-save-frame pointed to by EP.  */
 #define SAVE_ARG_REGS							      \
 	sst.w	r6, PTO+PT_GPR(6)[ep];					      \
 	sst.w	r7, PTO+PT_GPR(7)[ep];					      \
 	sst.w	r8, PTO+PT_GPR(8)[ep];					      \
 	sst.w	r9, PTO+PT_GPR(9)[ep]
-/* Restore argument registers from the struct pt_regs pointed to by EP.  */
+/* Restore argument registers from the state-save-frame pointed to by EP.  */
 #define RESTORE_ARG_REGS						      \
 	sld.w	PTO+PT_GPR(6)[ep], r6;					      \
 	sld.w	PTO+PT_GPR(7)[ep], r7;					      \
 	sld.w	PTO+PT_GPR(8)[ep], r8;					      \
 	sld.w	PTO+PT_GPR(9)[ep], r9
 
-/* Save value return registers to the struct pt_regs pointed to by EP.  */
+/* Save value return registers to the state-save-frame pointed to by EP.  */
 #define SAVE_RVAL_REGS							      \
 	sst.w	r10, PTO+PT_GPR(10)[ep];				      \
 	sst.w	r11, PTO+PT_GPR(11)[ep]
-/* Restore value return registers from the struct pt_regs pointed to by EP.  */
+/* Restore value return registers from the state-save-frame pointed to by EP.  */
 #define RESTORE_RVAL_REGS						      \
 	sld.w	PTO+PT_GPR(10)[ep], r10;				      \
 	sld.w	PTO+PT_GPR(11)[ep], r11
@@ -81,13 +81,13 @@
 	sld.w	PTO+PT_GPR(18)[ep], r18;				      \
 	sld.w	PTO+PT_GPR(19)[ep], r19
 
-/* Save `call clobbered' registers to the struct pt_regs pointed to by EP.  */
+/* Save `call clobbered' registers to the state-save-frame pointed to by EP.  */
 #define SAVE_CALL_CLOBBERED_REGS					      \
 	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
 	SAVE_ARG_REGS;							      \
 	SAVE_RVAL_REGS;							      \
 	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL
-/* Restore `call clobbered' registers from the struct pt_regs pointed to
+/* Restore `call clobbered' registers from the state-save-frame pointed to
    by EP.  */
 #define RESTORE_CALL_CLOBBERED_REGS					      \
 	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
@@ -96,19 +96,19 @@
 	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL
 
 /* Save `call clobbered' registers except for the return-value registers
-   to the struct pt_regs pointed to by EP.  */
+   to the state-save-frame pointed to by EP.  */
 #define SAVE_CALL_CLOBBERED_REGS_NO_RVAL				      \
 	SAVE_CALL_CLOBBERED_REGS_BEFORE_ARGS;				      \
 	SAVE_ARG_REGS;							      \
 	SAVE_CALL_CLOBBERED_REGS_AFTER_RVAL
 /* Restore `call clobbered' registers except for the return-value registers
-   from the struct pt_regs pointed to by EP.  */
+   from the state-save-frame pointed to by EP.  */
 #define RESTORE_CALL_CLOBBERED_REGS_NO_RVAL				      \
 	RESTORE_CALL_CLOBBERED_REGS_BEFORE_ARGS;			      \
 	RESTORE_ARG_REGS;						      \
 	RESTORE_CALL_CLOBBERED_REGS_AFTER_RVAL
 
-/* Save `call saved' registers to the struct pt_regs pointed to by EP.  */
+/* Save `call saved' registers to the state-save-frame pointed to by EP.  */
 #define SAVE_CALL_SAVED_REGS						      \
 	sst.w	r2, PTO+PT_GPR(2)[ep];					      \
 	sst.w	r20, PTO+PT_GPR(20)[ep];				      \
@@ -121,7 +121,7 @@
 	sst.w	r27, PTO+PT_GPR(27)[ep];				      \
 	sst.w	r28, PTO+PT_GPR(28)[ep];				      \
 	sst.w	r29, PTO+PT_GPR(29)[ep]
-/* Restore `call saved' registers from the struct pt_regs pointed to by EP.  */
+/* Restore `call saved' registers from the state-save-frame pointed to by EP.  */
 #define RESTORE_CALL_SAVED_REGS						      \
 	sld.w	PTO+PT_GPR(2)[ep], r2;					      \
 	sld.w	PTO+PT_GPR(20)[ep], r20;				      \
@@ -136,12 +136,12 @@
 	sld.w	PTO+PT_GPR(29)[ep], r29
 
 
-/* Save the PC stored in the special register SAVEREG to the struct pt_regs
+/* Save the PC stored in the special register SAVEREG to the state-save-frame
    pointed to by EP.  r19 is clobbered.  */
 #define SAVE_PC(savereg)						      \
 	stsr	SR_ ## savereg, r19;					      \
 	sst.w	r19, PTO+PT_PC[ep]
-/* Restore the PC from the struct pt_regs pointed to by EP, to the special
+/* Restore the PC from the state-save-frame pointed to by EP, to the special
    register SAVEREG.  LP is clobbered (it is used as a scratch register
    because the POP_STATE macro restores it, and this macro is usually used
    inside POP_STATE).  */
@@ -149,11 +149,11 @@
 	sld.w	PTO+PT_PC[ep], lp;					      \
 	ldsr	lp, SR_ ## savereg
 /* Save the PSW register stored in the special register SAVREG to the
-   struct pt_regs pointed to by EP r19 is clobbered.  */
+   state-save-frame pointed to by EP.  r19 is clobbered.  */
 #define SAVE_PSW(savereg)						      \
 	stsr	SR_ ## savereg, r19;					      \
 	sst.w	r19, PTO+PT_PSW[ep]
-/* Restore the PSW register from the struct pt_regs pointed to by EP, to
+/* Restore the PSW register from the state-save-frame pointed to by EP, to
    the special register SAVEREG.  LP is clobbered (it is used as a scratch
    register because the POP_STATE macro restores it, and this macro is
    usually used inside POP_STATE).  */
@@ -161,7 +161,7 @@
 	sld.w	PTO+PT_PSW[ep], lp;					      \
 	ldsr	lp, SR_ ## savereg
 
-/* Save CTPC/CTPSW/CTBP registers to the struct pt_regs pointed to by REG.  
+/* Save CTPC/CTPSW/CTBP registers to the state-save-frame pointed to by REG.
    r19 is clobbered.  */
 #define SAVE_CT_REGS							      \
 	stsr	SR_CTPC, r19;						      \
@@ -170,7 +170,7 @@
 	sst.w	r19, PTO+PT_CTPSW[ep];					      \
 	stsr	SR_CTBP, r19;						      \
 	sst.w	r19, PTO+PT_CTBP[ep]
-/* Restore CTPC/CTPSW/CTBP registers from the struct pt_regs pointed to by EP.
+/* Restore CTPC/CTPSW/CTBP registers from the state-save-frame pointed to by EP.
    LP is clobbered (it is used as a scratch register because the POP_STATE
    macro restores it, and this macro is usually used inside POP_STATE).  */
 #define RESTORE_CT_REGS							      \
@@ -182,10 +182,11 @@
 	ldsr	lp, SR_CTBP
 
 
-/* Push register state, except for the stack pointer, on the stack in the form
-   of a struct pt_regs, in preparation for a system call.  This macro makes
-   sure that `special' registers, system registers; TYPE identifies the set of
-   extra registers to be saved as well.  EP is clobbered.  */
+/* Push register state, except for the stack pointer, on the stack in the
+   form of a state-save-frame (plus some extra padding), in preparation for
+   a system call.  This macro makes sure that the EP, GP, and LP
+   registers are saved, and TYPE identifies the set of extra registers to
+   be saved as well.  Also copies (the new value of) SP to EP.  */
 #define PUSH_STATE(type)						      \
 	addi	-STATE_SAVE_SIZE, sp, sp; /* Make room on the stack.  */      \
 	st.w	ep, PTO+PT_GPR(GPR_EP)[sp];				      \
@@ -193,8 +194,8 @@
 	sst.w	gp, PTO+PT_GPR(GPR_GP)[ep];				      \
 	sst.w	lp, PTO+PT_GPR(GPR_LP)[ep];				      \
 	type ## _STATE_SAVER
-/* Pop a register state, except for the stack pointer, from the struct pt_regs
-   on the stack.  */
+/* Pop a register state pushed by PUSH_STATE, except for the stack pointer,
+   from the the stack.  */
 #define POP_STATE(type)							      \
 	mov	sp, ep;							      \
 	type ## _STATE_RESTORER;					      \
@@ -205,7 +206,7 @@
 
 
 /* Switch to the kernel stack if necessary, and push register state on the
-   stack in the form of a struct pt_regs.  Also load the current task
+   stack in the form of a state-save-frame.  Also load the current task
    pointer if switching from user mode.  The stack-pointer (r3) should have
    already been saved to the memory location SP_SAVE_LOC (the reason for
    this is that the interrupt vectors may be beyond a 22-bit signed offset
@@ -234,25 +235,30 @@
 	sst.w	syscall_num, PTO+PT_CUR_SYSCALL[ep]
 
 
-/* Save register state not normally saved by PUSH_STATE for TYPE.  */
+/* Save register state not normally saved by PUSH_STATE for TYPE, to the
+   state-save-frame on the stack; also copies SP to EP.  r19 may be trashed. */
 #define SAVE_EXTRA_STATE(type)						      \
-        mov	sp, ep;							      \
+	mov	sp, ep;							      \
 	type ## _EXTRA_STATE_SAVER
-/* Restore register state not normally restored by POP_STATE for TYPE.  */
+/* Restore register state not normally restored by POP_STATE for TYPE,
+   from the state-save-frame on the stack; also copies SP to EP.
+   r19 may be trashed.  */
 #define RESTORE_EXTRA_STATE(type)					      \
-        mov	sp, ep;							      \
+	mov	sp, ep;							      \
 	type ## _EXTRA_STATE_RESTORER
 
-/* Save any call-clobbered registers not normally saved by PUSH_STATE
-   for TYPE.  */
-#define SAVE_EXTRA_STATE_FOR_FUNCALL(type)				      \
-        mov	sp, ep;							      \
-	type ## _FUNCALL_EXTRA_STATE_SAVER
-/* Restore any call-clobbered registers not normally restored by POP_STATE for
-   TYPE.  */
-#define RESTORE_EXTRA_STATE_FOR_FUNCALL(type)				      \
-        mov	sp, ep;							      \
-	type ## _FUNCALL_EXTRA_STATE_RESTORER
+/* Save any call-clobbered registers not normally saved by PUSH_STATE for
+   TYPE, to the state-save-frame on the stack.
+   EP may be trashed, but is not guaranteed to contain a copy of SP
+   (unlike after most SAVE_... macros).  r19 may be trashed.  */
+#define SAVE_EXTRA_STATE_FOR_SCHEDULE(type)				      \
+	type ## _SCHEDULE_EXTRA_STATE_SAVER
+/* Restore any call-clobbered registers not normally restored by
+   POP_STATE for TYPE, to the state-save-frame on the stack.
+   EP may be trashed, but is not guaranteed to contain a copy of SP
+   (unlike after most RESTORE_... macros).  r19 may be trashed.  */
+#define RESTORE_EXTRA_STATE_FOR_SCHEDULE(type)				      \
+	type ## _SCHEDULE_EXTRA_STATE_RESTORER
 
 
 /* These are extra_state_saver/restorer values for a user trap.  Note
@@ -263,36 +269,48 @@
    caller of the syscall function should have saved them.  */
 
 #define TRAP_RET reti
-/* Traps don't save call-clobbered registers (but do still save arg regs).  */
+/* Traps don't save call-clobbered registers (but do still save arg regs).
+   We preserve PSw to keep long-term state, namely interrupt status (for traps
+   from kernel-mode), and the single-step flag (for user traps).  */
 #define TRAP_STATE_SAVER						      \
 	SAVE_ARG_REGS;							      \
-	SAVE_PC(EIPC)
+	SAVE_PC(EIPC);							      \
+	SAVE_PSW(EIPSW)
 /* When traps return, they just leave call-clobbered registers (except for arg
-   regs) with whatever value they have from the kernel.  */
+   regs) with whatever value they have from the kernel.  Traps don't preserve
+   the PSW, but we zero EIPSW to ensure it doesn't contain anything dangerous
+   (in particular, the single-step flag).  */
 #define TRAP_STATE_RESTORER						      \
 	RESTORE_ARG_REGS;						      \
-	RESTORE_PC(EIPC)
+	RESTORE_PC(EIPC);						      \
+	RESTORE_PSW(EIPSW)
 /* Save registers not normally saved by traps.  We need to save r12, even
    though it's nominally call-clobbered, because it's used when restarting
    a system call (the signal-handling path uses SAVE_EXTRA_STATE, and
-   expects r12 to be restored when the trap returns).  Similarly, we must
-   save the PSW, so that it's at least in a known state in the the pt_regs
-   structure.  */
+   expects r12 to be restored when the trap returns).  */
 #define TRAP_EXTRA_STATE_SAVER						      \
 	SAVE_RVAL_REGS;							      \
 	sst.w	r12, PTO+PT_GPR(12)[ep];				      \
 	SAVE_CALL_SAVED_REGS;						      \
-	SAVE_PSW(EIPSW);						      \
 	SAVE_CT_REGS
 #define TRAP_EXTRA_STATE_RESTORER					      \
 	RESTORE_RVAL_REGS;						      \
 	sld.w	PTO+PT_GPR(12)[ep], r12;				      \
 	RESTORE_CALL_SAVED_REGS;					      \
-	RESTORE_PSW(EIPSW);						      \
 	RESTORE_CT_REGS
-#define TRAP_FUNCALL_EXTRA_STATE_SAVER					      \
+/* Save registers prior to calling scheduler (just before trap returns).
+   We have to save the return-value registers to preserve the trap's return
+   value.  Note that ..._SCHEDULE_EXTRA_STATE_SAVER, unlike most ..._SAVER
+   macros, is required to setup EP itself if EP is needed (this is because
+   in many cases, the macro is empty).  */
+#define TRAP_SCHEDULE_EXTRA_STATE_SAVER					      \
+	mov sp, ep;							      \
 	SAVE_RVAL_REGS
-#define TRAP_FUNCALL_EXTRA_STATE_RESTORER				      \
+/* Note that ..._SCHEDULE_EXTRA_STATE_RESTORER, unlike most ..._RESTORER
+   macros, is required to setup EP itself if EP is needed (this is because
+   in many cases, the macro is empty).  */
+#define TRAP_SCHEDULE_EXTRA_STATE_RESTORER				      \
+	mov sp, ep;							      \
 	RESTORE_RVAL_REGS
 
 /* Register saving/restoring for maskable interrupts.  */
@@ -311,8 +329,8 @@
 #define IRQ_EXTRA_STATE_RESTORER					      \
 	RESTORE_CALL_SAVED_REGS;					      \
 	RESTORE_CT_REGS
-#define IRQ_FUNCALL_EXTRA_STATE_SAVER       /* nothing */
-#define IRQ_FUNCALL_EXTRA_STATE_RESTORER    /* nothing */
+#define IRQ_SCHEDULE_EXTRA_STATE_SAVER	     /* nothing */
+#define IRQ_SCHEDULE_EXTRA_STATE_RESTORER    /* nothing */
 
 /* Register saving/restoring for non-maskable interrupts.  */
 #define NMI_RET reti
@@ -330,8 +348,8 @@
 #define NMI_EXTRA_STATE_RESTORER					      \
 	RESTORE_CALL_SAVED_REGS;					      \
 	RESTORE_CT_REGS
-#define NMI_FUNCALL_EXTRA_STATE_SAVER       /* nothing */
-#define NMI_FUNCALL_EXTRA_STATE_RESTORER    /* nothing */
+#define NMI_SCHEDULE_EXTRA_STATE_SAVER	     /* nothing */
+#define NMI_SCHEDULE_EXTRA_STATE_RESTORER    /* nothing */
 
 /* Register saving/restoring for debug traps.  */
 #define DBTRAP_RET .long 0x014607E0 /* `dbret', but gas doesn't support it. */
@@ -349,8 +367,8 @@
 #define DBTRAP_EXTRA_STATE_RESTORER					      \
 	RESTORE_CALL_SAVED_REGS;					      \
 	RESTORE_CT_REGS
-#define DBTRAP_FUNCALL_EXTRA_STATE_SAVER       /* nothing */
-#define DBTRAP_FUNCALL_EXTRA_STATE_RESTORER    /* nothing */
+#define DBTRAP_SCHEDULE_EXTRA_STATE_SAVER	/* nothing */
+#define DBTRAP_SCHEDULE_EXTRA_STATE_RESTORER	/* nothing */
 
 /* Register saving/restoring for a context switch.  We don't need to save
    too many registers, because context-switching looks like a function call
@@ -372,14 +390,14 @@
 	RESTORE_CT_REGS
 
 
-/* Restore register state from the struct pt_regs on the stack, switch back
+/* Restore register state from the state-save-frame on the stack, switch back
    to the user stack if necessary, and return from the trap/interrupt.
    EXTRA_STATE_RESTORER is a sequence of assembly language statements to
    restore anything not restored by this macro.  Only registers not saved by
    the C compiler are restored (that is, R3(sp), R4(gp), R31(lp), and
    anything restored by EXTRA_STATE_RESTORER).  */
 #define RETURN(type)							      \
-        ld.b	PTO+PT_KERNEL_MODE[sp], r19;				      \
+	ld.b	PTO+PT_KERNEL_MODE[sp], r19;				      \
 	di;				/* Disable interrupts */	      \
 	cmp	r19, r0;		/* See if returning to kernel mode, */\
 	bne	2f;			/* ... if so, skip resched &c.  */    \
@@ -390,33 +408,34 @@
 	ld.w	TI_FLAGS[r18], r19;					      \
 	andi	_TIF_NEED_RESCHED, r19, r0;				      \
 	bnz	3f;			/* Call the scheduler.  */	      \
-	andi	_TIF_SIGPENDING, r19, r0;				      \
-	bnz	4f;			/* Signals to handle, handle them */  \
+5:	andi	_TIF_SIGPENDING, r19, r18;				      \
+	ld.w	TASK_PTRACE[CURRENT_TASK], r19; /* ptrace flags */	      \
+	or	r18, r19;		/* see if either is non-zero */	      \
+	bnz	4f;			/* if so, handle them */	      \
 									      \
-/* Return to user state.  */					   	      \
+/* Return to user state.  */						      \
 1:	st.b	r0, KM;			/* Now officially in user state. */   \
 									      \
 /* Final return.  The stack-pointer fiddling is not needed when returning     \
    to kernel-mode, but they don't hurt, and this way we can share the	      \
-   (somtimes rather lengthy) POP_STATE macro.  */			      \
+   (sometimes rather lengthy) POP_STATE macro.  */			      \
 2:	POP_STATE(type);						      \
 	st.w	sp, KSP;		/* Save the kernel stack pointer. */  \
-	ld.w    PT_GPR(GPR_SP)-PT_SIZE[sp], sp; /* Restore stack pointer. */  \
+	ld.w	PT_GPR(GPR_SP)-PT_SIZE[sp], sp; /* Restore stack pointer. */  \
 	type ## _RET;			/* Return from the trap/interrupt. */ \
 									      \
 /* Call the scheduler before returning from a syscall/trap. */		      \
-3:	SAVE_EXTRA_STATE_FOR_FUNCALL(type); /* Prepare for funcall. */	      \
-	jarl	CSYM(schedule), lp;	/* Call scheduler */		      \
+3:	SAVE_EXTRA_STATE_FOR_SCHEDULE(type); /* Prepare to call scheduler. */ \
+	jarl	call_scheduler, lp;	/* Call scheduler */		      \
 	di;				/* The scheduler enables interrupts */\
-	RESTORE_EXTRA_STATE_FOR_FUNCALL(type);				      \
+	RESTORE_EXTRA_STATE_FOR_SCHEDULE(type);				      \
 	GET_CURRENT_THREAD(r18);					      \
 	ld.w	TI_FLAGS[r18], r19;					      \
-	andi	_TIF_SIGPENDING, r19, r0;				      \
-	bz	1b;			/* No signals, return.  */	      \
-	/* Signals to handle, fall through to handle them.  */		      \
+	br	5b;			/* Continue with return path. */      \
 									      \
-/* Handle a signal return.  */						      \
-4:      /* Not all registers are saved by the normal trap/interrupt entry     \
+/* Handle a signal or ptraced process return.				      \
+   r18 should be non-zero if there are pending signals.  */		      \
+4:	/* Not all registers are saved by the normal trap/interrupt entry     \
 	   points (for instance, call-saved registers (because the normal     \
 	   C-compiler calling sequence in the kernel makes sure they're	      \
 	   preserved), and call-clobbered registers in the case of	      \
@@ -424,12 +443,9 @@
 	   complete register state.  Here we save anything not saved by	      \
 	   the normal entry sequence, so that it may be safely restored	      \
 	   (in a possibly modified form) after do_signal returns.  */	      \
-        SAVE_EXTRA_STATE(type);		/* Save state not saved by entry. */  \
-	movea	PTO, sp, r6;		/* Arg 1: struct pt_regs *regs */     \
-	mov	r0, r7;			/* Arg 2: sigset_t *oldset */	      \
-	jarl	CSYM(do_signal), lp;	/* Handle any signals */	      \
-	di;				/* sig handling enables interrupts */ \
-        RESTORE_EXTRA_STATE(type);	/* Restore extra regs.  */	      \
+	SAVE_EXTRA_STATE(type);		/* Save state not saved by entry. */  \
+	jarl	handle_signal_or_ptrace_return, lp;			      \
+	RESTORE_EXTRA_STATE(type);	/* Restore extra regs.  */	      \
 	br	1b
 
 
@@ -471,7 +487,7 @@
  *   Return value in r10
  */
 G_ENTRY(trap):
-	SAVE_STATE (TRAP, r12, ENTRY_SP) // Save registers. 
+	SAVE_STATE (TRAP, r12, ENTRY_SP) // Save registers.
 	stsr	SR_ECR, r19		// Find out which trap it was.
 	ei				// Enable interrupts.
 	mov	hilo(ret_from_trap), lp	// where the trap should return
@@ -481,12 +497,12 @@
 	// numbers into the (0-31) << 2 range we want, (3) set the flags.
 	shl	27, r19			// chop off all high bits
 	shr	25, r19			// scale back down and then << 2
-	bnz	2f			// See if not trap 0. 
+	bnz	2f			// See if not trap 0.
 
-	// Trap 0 is a `short' system call, skip general trap table. 
-	MAKE_SYS_CALL			// Jump to the syscall function. 
+	// Trap 0 is a `short' system call, skip general trap table.
+	MAKE_SYS_CALL			// Jump to the syscall function.
 
-2:	// For other traps, use a table lookup. 
+2:	// For other traps, use a table lookup.
 	mov	hilo(CSYM(trap_table)), r18
 	add	r19, r18
 	ld.w	0[r18], r18
@@ -505,6 +521,7 @@
 	RETURN(TRAP)
 END(ret_from_trap)
 
+
 /* This the initial entry point for a new child thread, with an appropriate
    stack in place that makes it look the the child is in the middle of an
    syscall.  This function is actually `returned to' from switch_thread
@@ -538,7 +555,7 @@
 	mov	hilo(ret_from_long_syscall), lp
 
 	MAKE_SYS_CALL			// Jump to the syscall function.
-END(syscall_long)	
+END(syscall_long)
 
 /* Entry point used to return from a long syscall.  Only needed to restore
    r13/r14 if the general trap mechanism doesnt' do so.  */
@@ -554,11 +571,14 @@
 
 L_ENTRY(sys_fork_wrapper):
 #ifdef CONFIG_MMU
-	addi	SIGCHLD, r0, r6		// Arg 0: flags
+	addi	SIGCHLD, r0, r6		   // Arg 0: flags
 	ld.w	PTO+PT_GPR(GPR_SP)[sp], r7 // Arg 1: child SP (use parent's)
-	movea	PTO, sp, r8		// Arg 2: parent context
-	mov	hilo(CSYM(fork_common)), r18// Where the real work gets done
-	br	save_extra_state_tramp	// Save state and go there
+	movea	PTO, sp, r8		   // Arg 2: parent context
+	mov	r0, r9			   // Arg 3/4/5: 0
+	st.w	r0, 16[sp]
+	st.w	r0, 20[sp]
+	mov	hilo(CSYM(do_fork)), r18   // Where the real work gets done
+	br	save_extra_state_tramp	   // Save state and go there
 #else
 	// fork almost works, enough to trick you into looking elsewhere :-(
 	addi	-EINVAL, r0, r10
@@ -569,18 +589,24 @@
 L_ENTRY(sys_vfork_wrapper):
 	addi	CLONE_VFORK | CLONE_VM | SIGCHLD, r0, r6 // Arg 0: flags
 	ld.w	PTO+PT_GPR(GPR_SP)[sp], r7 // Arg 1: child SP (use parent's)
-	movea	PTO, sp, r8		// Arg 2: parent context
-	mov	hilo(CSYM(fork_common)), r18// Where the real work gets done
-	br	save_extra_state_tramp	// Save state and go there
+	movea	PTO, sp, r8		   // Arg 2: parent context
+	mov	r0, r9			   // Arg 3/4/5: 0
+	st.w	r0, 16[sp]
+	st.w	r0, 20[sp]
+	mov	hilo(CSYM(do_fork)), r18   // Where the real work gets done
+	br	save_extra_state_tramp	   // Save state and go there
 END(sys_vfork_wrapper)
 
 L_ENTRY(sys_clone_wrapper):
-	ld.w	PTO+PT_GPR(GPR_SP)[sp], r19 // parent's stack pointer
-        cmp	r7, r0			// See if child SP arg (arg 1) is 0.
-	cmov	z, r19, r7, r7		// ... and use the parent's if so. 
-	movea	PTO, sp, r8		// Arg 2: parent context
-	mov	hilo(CSYM(fork_common)), r18// Where the real work gets done
-	br	save_extra_state_tramp	// Save state and go there
+	ld.w	PTO+PT_GPR(GPR_SP)[sp], r19// parent's stack pointer
+	cmp	r7, r0			   // See if child SP arg (arg 1) is 0.
+	cmov	z, r19, r7, r7		   // ... and use the parent's if so.
+	movea	PTO, sp, r8		   // Arg 2: parent context
+	mov	r0, r9			   // Arg 3/4/5: 0
+	st.w	r0, 16[sp]
+	st.w	r0, 20[sp]
+	mov	hilo(CSYM(do_fork)), r18   // Where the real work gets done
+	br	save_extra_state_tramp	   // Save state and go there
 END(sys_clone_wrapper)
 
 
@@ -598,8 +624,8 @@
 END(sys_sigsuspend_wrapper)
 L_ENTRY(sys_rt_sigsuspend_wrapper):
 	movea	PTO, sp, r8		// add user context as 3rd arg
-	mov	hilo(CSYM(sys_rt_sigsuspend)), r18	// syscall function
-	jarl	save_extra_state_tramp, lp	// Save state and do it
+	mov	hilo(CSYM(sys_rt_sigsuspend)), r18 // syscall function
+	jarl	save_extra_state_tramp, lp	   // Save state and do it
 	br	restore_extra_regs_and_ret_from_trap
 END(sys_rt_sigsuspend_wrapper)
 
@@ -610,10 +636,9 @@
 	br	restore_extra_regs_and_ret_from_trap
 END(sys_sigreturn_wrapper)
 L_ENTRY(sys_rt_sigreturn_wrapper):
-        SAVE_EXTRA_STATE(TRAP)		// Save state not saved by entry.
 	movea	PTO, sp, r6		// add user context as 1st arg
-	mov	hilo(CSYM(sys_rt_sigreturn)), r18	// syscall function
-	jarl	save_extra_state_tramp, lp	// Save state and do it
+	mov	hilo(CSYM(sys_rt_sigreturn)), r18// syscall function
+	jarl	save_extra_state_tramp, lp	 // Save state and do it
 	br	restore_extra_regs_and_ret_from_trap
 END(sys_rt_sigreturn_wrapper)
 
@@ -637,7 +662,7 @@
  * indirect jump).
  */
 G_ENTRY(irq):
-	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers. 
+	SAVE_STATE (IRQ, r0, ENTRY_SP)	// Save registers.
 
 	stsr	SR_ECR, r6		// Find out which interrupt it was.
 	movea	PTO, sp, r7		// User regs are arg2
@@ -657,7 +682,7 @@
 	RETURN(IRQ)
 END(irq)
 
-	
+
 /*
  * Debug trap / illegal-instruction exception
  *
@@ -668,22 +693,50 @@
  * indirect jump).
  */
 G_ENTRY(dbtrap):
-	SAVE_STATE (DBTRAP, r0, ENTRY_SP)// Save registers. 
+	SAVE_STATE (DBTRAP, r0, ENTRY_SP)// Save registers.
+
+	/* First see if we came from kernel mode; if so, the dbtrap
+	   instruction has a special meaning, to set the DIR (`debug
+	   information register') register.  This is because the DIR register
+	   can _only_ be manipulated/read while in `debug mode,' and debug
+	   mode is only active while we're inside the dbtrap handler.  The
+	   exact functionality is:  { DIR = (DIR | r6) & ~r7; return DIR; }. */
+	ld.b	PTO+PT_KERNEL_MODE[sp], r19
+	cmp	r19, r0
+	bz	1f
+
+	stsr	SR_DIR, r10
+	or	r6, r10
+	not	r7, r7
+	and	r7, r10
+	ldsr	r10, SR_DIR
+	stsr	SR_DIR, r10		// Confirm the value we set
+	st.w	r10, PTO+PT_GPR(10)[sp]	// return it
+	br	3f
+
+1:	ei				// Enable interrupts.
+
+	/* The default signal type we raise.  */
+	mov	SIGTRAP, r6
+
+	/* See if it's a single-step trap.  */
+	stsr	SR_DBPSW, r19
+	andi	0x0800, r19, r19
+	bnz	2f
 
 	/* Look to see if the preceding instruction was is a dbtrap or not,
 	   to decide which signal we should use.  */
 	stsr	SR_DBPC, r19		// PC following trapping insn
 	ld.hu	-2[r19], r19
-	mov	SIGTRAP, r6
 	ori	0xf840, r0, r20		// DBTRAP insn
 	cmp	r19, r20		// Was this trap caused by DBTRAP?
 	cmov	ne, SIGILL, r6, r6	// Choose signal appropriately
 
 	/* Raise the desired signal.  */
-	mov	CURRENT_TASK, r7	// Arg 1: task
-	jarl	CSYM(force_sig), lp	// tail call
+2:	mov	CURRENT_TASK, r7	// Arg 1: task
+	jarl	CSYM(send_sig), lp	// tail call
 
-	RETURN(DBTRAP)
+3:	RETURN(DBTRAP)
 END(dbtrap)
 
 
@@ -725,9 +778,93 @@
 
 
 /*
+ * Invoke the scheduler, called from the trap/irq kernel exit path.
+ *
+ * This basically just calls `schedule', but also arranges for extra
+ * registers to be saved for ptrace'd processes, so ptrace can modify them.
+ */
+L_ENTRY(call_scheduler):
+	ld.w	TASK_PTRACE[CURRENT_TASK], r19	// See if task is ptrace'd
+	cmp	r19, r0
+	bnz	1f			// ... yes, do special stuff
+	jr	CSYM(schedule)		// ... no, just tail-call scheduler
+
+	// Save extra regs for ptrace'd task.  We want to save anything
+	// that would otherwise only be `implicitly' saved by the normal
+	// compiler calling-convention.
+1:	mov	sp, ep			// Setup EP for SAVE_CALL_SAVED_REGS
+	SAVE_CALL_SAVED_REGS		// Save call-saved registers to stack
+	mov	lp, r20			// Save LP in a callee-saved register
+
+	jarl	CSYM(schedule), lp	// Call scheduler
+
+	mov	r20, lp
+	mov	sp, ep			// We can't rely on EP after return
+	RESTORE_CALL_SAVED_REGS		// Restore (possibly modified) regs
+	jmp	[lp]			// Return to the return path
+END(call_scheduler)
+
+
+/*
+ * This is an out-of-line handler for two special cases during the kernel
+ * trap/irq exit sequence:
+ *
+ *  (1) If r18 is non-zero then a signal needs to be handled, which is
+ *	done, and then the caller returned to.
+ *
+ *  (2) If r18 is non-zero then we're returning to a ptraced process, which
+ *	has several special cases -- single-stepping and trap tracing, both
+ *	of which require using the `dbret' instruction to exit the kernel
+ *	instead of the normal `reti' (this is because the CPU not correctly
+ *	single-step after a reti).  In this case, of course, this handler
+ *	never returns to the caller.
+ *
+ * In either case, all registers should have been saved to the current
+ * state-save-frame on the stack, except for callee-saved registers.
+ *
+ * [These two different cases are combined merely to avoid bloating the
+ * macro-inlined code, not because they really make much sense together!]
+ */
+L_ENTRY(handle_signal_or_ptrace_return):
+	cmp	r18, r0			// See if handling a signal
+	bz	1f			// ... nope, go do ptrace return
+
+	// Handle a signal
+	mov	lp, r20			// Save link-pointer
+	mov	r10, r21		// Save return-values (for trap)
+	mov	r11, r22
+
+	movea	PTO, sp, r6		// Arg 1: struct pt_regs *regs
+	mov	r0, r7			// Arg 2: sigset_t *oldset
+	jarl	CSYM(do_signal), lp	// Handle the signal
+	di				// sig handling enables interrupts
+
+	mov	r20, lp			// Restore link-pointer
+	mov	r21, r10		// Restore return-values (for trap)
+	mov	r22, r11
+	ld.w	TASK_PTRACE[CURRENT_TASK], r19  // check ptrace flags too
+	cmp	r19, r0
+	bnz	1f			// ... some set, so look more
+2:	jmp	[lp]			// ... none set, so return normally
+
+	// ptrace return
+1:	ld.w	PTO+PT_PSW[sp], r19	// Look at user-processes's flags
+	andi	0x0800, r19, r19	// See if single-step flag is set
+	bz	2b			// ... nope, return normally
+
+	// Return as if from a dbtrap insn
+	st.b	r0, KM			// Now officially in user state.
+	POP_STATE(DBTRAP)		// Restore regs
+	st.w	sp, KSP			// Save the kernel stack pointer.
+	ld.w	PT_GPR(GPR_SP)-PT_SIZE[sp], sp // Restore user stack pointer.
+	DBTRAP_RET			// Return from the trap/interrupt.
+END(handle_signal_or_ptrace_return)
+
+
+/*
  * This is where we switch between two threads.  The arguments are:
  *   r6 -- pointer to the struct thread for the `current' process
- *   r7 -- pointer to the struct thread for the `new' process.  
+ *   r7 -- pointer to the struct thread for the `new' process.
  * when this function returns, it will return to the new thread.
  */
 C_ENTRY(switch_thread):
@@ -754,8 +891,8 @@
 
 	.align 4
 C_DATA(trap_table):
-	.long bad_trap_wrapper		// trap 0, doesn't use trap table. 
-	.long syscall_long		// trap 1, `long' syscall. 
+	.long bad_trap_wrapper		// trap 0, doesn't use trap table.
+	.long syscall_long		// trap 1, `long' syscall.
 	.long bad_trap_wrapper
 	.long bad_trap_wrapper
 	.long bad_trap_wrapper
@@ -774,7 +911,7 @@
 
 
 	.section .rodata
-	
+
 	.align 4
 C_DATA(sys_call_table):
 	.long CSYM(sys_restart_syscall)	// 0
@@ -835,7 +972,7 @@
 	.long CSYM(sys_fcntl)		// 55
 	.long CSYM(sys_ni_syscall)	// was: mpx
 	.long CSYM(sys_setpgid)
-	.long CSYM(sys_ni_syscall) 	// was: ulimit
+	.long CSYM(sys_ni_syscall)	// was: ulimit
 	.long CSYM(sys_ni_syscall)
 	.long CSYM(sys_umask)		// 60
 	.long CSYM(sys_chroot)
@@ -875,7 +1012,7 @@
 	.long CSYM(sys_fchown)		// 95
 	.long CSYM(sys_getpriority)
 	.long CSYM(sys_setpriority)
-	.long CSYM(sys_ni_syscall) 	// was: profil
+	.long CSYM(sys_ni_syscall)	// was: profil
 	.long CSYM(sys_statfs)
 	.long CSYM(sys_fstatfs)		// 100
 	.long CSYM(sys_ni_syscall)	// i386: ioperm
@@ -900,7 +1037,7 @@
 	.long sys_clone_wrapper		// 120
 	.long CSYM(sys_setdomainname)
 	.long CSYM(sys_newuname)
-	.long CSYM(sys_ni_syscall)	// i386: modify_ldt, m68k: cacheflush 
+	.long CSYM(sys_ni_syscall)	// i386: modify_ldt, m68k: cacheflush
 	.long CSYM(sys_adjtimex)
 	.long CSYM(sys_ni_syscall)	// 125 - sys_mprotect
 	.long CSYM(sys_sigprocmask)
@@ -937,7 +1074,7 @@
 	.long CSYM(sys_sched_getscheduler)
 	.long CSYM(sys_sched_yield)
 	.long CSYM(sys_sched_get_priority_max)
-	.long CSYM(sys_sched_get_priority_min)  // 160
+	.long CSYM(sys_sched_get_priority_min)	// 160
 	.long CSYM(sys_sched_rr_get_interval)
 	.long CSYM(sys_nanosleep)
 	.long CSYM(sys_ni_syscall)	// sys_mremap
diff -Nru a/arch/v850/kernel/head.S b/arch/v850/kernel/head.S
--- a/arch/v850/kernel/head.S	Sun Nov 24 17:34:43 2002
+++ b/arch/v850/kernel/head.S	Tue May 27 00:09:43 2003
@@ -39,7 +39,7 @@
 	cmp	r19, r20
 	bne	1f			// Guard was not active
 
-	// If we get here, the reset guard was active.	Load up some
+	// If we get here, the reset guard was active.  Load up some
 	// interesting values as arguments, and jump to the handler.
 	st.w	r0, RESET_GUARD		// Allow further resets to succeed
 	mov	lp, r6			// Arg 0: return address
@@ -53,7 +53,7 @@
 
 1:	st.w	r20, RESET_GUARD	// Turn on reset guard
 #endif /* CONFIG_RESET_GUARD */
-  
+
 	// Setup a temporary stack for doing pre-initialization function calls.
 	// 
 	// We can't use the initial kernel stack, because (1) it may be
diff -Nru a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c
--- a/arch/v850/kernel/irq.c	Sat Mar  8 14:50:43 2003
+++ b/arch/v850/kernel/irq.c	Tue May 27 00:09:43 2003
@@ -1,7 +1,7 @@
 /*
  * arch/v850/kernel/irq.c -- High-level interrupt handling
  *
- *  Copyright (C) 2001,02,03  NEC Corporation
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *  Copyright (C) 1994-2000  Ralf Baechle
  *  Copyright (C) 1992  Linus Torvalds
@@ -35,7 +35,7 @@
  * Special irq handlers.
  */
 
-void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
 
 /*
  * Generic no controller code
@@ -352,7 +352,7 @@
  */
  
 int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
+		irqreturn_t (*handler)(int, void *, struct pt_regs *),
 		unsigned long irqflags, 
 		const char * devname,
 		void *dev_id)
diff -Nru a/arch/v850/kernel/ma.c b/arch/v850/kernel/ma.c
--- a/arch/v850/kernel/ma.c	Mon Feb 24 12:42:23 2003
+++ b/arch/v850/kernel/ma.c	Tue May 27 00:09:43 2003
@@ -1,8 +1,8 @@
 /*
  * arch/v850/kernel/ma.c -- V850E/MA series of cpu chips
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
diff -Nru a/arch/v850/kernel/mach.h b/arch/v850/kernel/mach.h
--- a/arch/v850/kernel/mach.h	Sun Feb  9 17:30:00 2003
+++ b/arch/v850/kernel/mach.h	Tue May 27 00:09:43 2003
@@ -1,8 +1,8 @@
 /*
  * arch/v850/kernel/mach.h -- Machine-dependent functions used by v850 port
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
diff -Nru a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
--- a/arch/v850/kernel/process.c	Thu Apr  3 14:56:44 2003
+++ b/arch/v850/kernel/process.c	Tue May 27 00:54:00 2003
@@ -1,7 +1,7 @@
 /*
  * arch/v850/kernel/process.c -- Arch-dependent process handling
  *
- *  Copyright (C) 2001,02,03  NEC Corporation
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
@@ -198,14 +198,6 @@
 	}
 
 	return error;
-}
-
-/* This is the common part of the various fork-like system calls (which
-   are in entry.S).  */
-int fork_common (int flags, unsigned long new_sp, struct pt_regs *regs)
-{
-	struct task_struct *p = do_fork (flags, new_sp, regs, 0, 0, 0);
-	return IS_ERR (p) ? PTR_ERR (p) : p->pid;
 }
 
 
diff -Nru a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
--- a/arch/v850/kernel/ptrace.c	Fri Nov  1 07:20:35 2002
+++ b/arch/v850/kernel/ptrace.c	Tue May 27 00:09:43 2003
@@ -1,8 +1,8 @@
 /*
  * arch/v850/kernel/ptrace.c -- `ptrace' system call
  *
- *  Copyright (C) 2002  NEC Corporation
- *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
  *
  * Derived from arch/mips/kernel/ptrace.c:
  *
@@ -29,6 +29,89 @@
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 
+/* Returns the address where the register at REG_OFFS in P is stashed away.  */
+static v850_reg_t *reg_save_addr (unsigned reg_offs, struct task_struct *t)
+{
+	struct pt_regs *regs;
+
+	/* Three basic cases:
+
+	   (1) A register normally saved before calling the scheduler, is
+	       available in the kernel entry pt_regs structure at the top
+	       of the kernel stack.  The kernel trap/irq exit path takes
+	       care to save/restore almost all registers for ptrace'd
+	       processes.
+
+	   (2) A call-clobbered register, where the process P entered the
+	       kernel via [syscall] trap, is not stored anywhere; that's
+	       OK, because such registers are not expected to be preserved
+	       when the trap returns anyway (so we don't actually bother to
+	       test for this case).
+
+	   (3) A few registers not used at all by the kernel, and so
+	       normally never saved except by context-switches, are in the
+	       context switch state.  */
+
+	if (reg_offs == PT_CTPC || reg_offs == PT_CTPSW || reg_offs == PT_CTBP)
+		/* Register saved during context switch.  */
+		regs = thread_saved_regs (t);
+	else
+		/* Register saved during kernel entry (or not available).  */
+		regs = task_regs (t);
+
+	return (v850_reg_t *)((char *)regs + reg_offs);
+}
+
+/* Set the bits SET and clear the bits CLEAR in the v850e DIR
+   (`debug information register').  Returns the new value of DIR.  */
+static inline v850_reg_t set_dir (v850_reg_t set, v850_reg_t clear)
+{
+	register v850_reg_t rval asm ("r10");
+	register v850_reg_t arg0 asm ("r6") = set;
+	register v850_reg_t arg1 asm ("r7") = clear;
+
+	/* The dbtrap handler has exactly this functionality when called
+	   from kernel mode.  0xf840 is a `dbtrap' insn.  */
+	asm (".short 0xf840" : "=r" (rval) : "r" (arg0), "r" (arg1));
+
+	return rval;
+}
+
+/* Makes sure hardware single-stepping is (globally) enabled.
+   Returns true if successful.  */
+static inline int enable_single_stepping (void)
+{
+	static int enabled = 0;	/* Remember whether we already did it.  */
+	if (! enabled) {
+		/* Turn on the SE (`single-step enable') bit, 0x100, in the
+		   DIR (`debug information register').  This may fail if a
+		   processor doesn't support it or something.  We also try
+		   to clear bit 0x40 (`INI'), which is necessary to use the
+		   debug stuff on the v850e2; on the v850e, clearing 0x40
+		   shouldn't cause any problem.  */
+		v850_reg_t dir = set_dir (0x100, 0x40);
+		/* Make sure it really got set.  */
+		if (dir & 0x100)
+			enabled = 1;
+	}
+	return enabled;
+}
+
+/* Try to set CHILD's single-step flag to VAL.  Returns true if successful.  */
+static int set_single_step (struct task_struct *t, int val)
+{
+	v850_reg_t *psw_addr = reg_save_addr(PT_PSW, t);
+	if (val) {
+		/* Make sure single-stepping is enabled.  */
+		if (! enable_single_stepping ())
+			return 0;
+		/* Set T's single-step flag.  */
+		*psw_addr |= 0x800;
+	} else
+		*psw_addr &= ~0x800;
+	return 1;
+}
+
 int sys_ptrace(long request, long pid, long addr, long data)
 {
 	struct task_struct *child;
@@ -36,12 +119,6 @@
 
 	lock_kernel();
 
-#if 0
-	printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
-	       (int) request, (int) pid, (unsigned long) addr,
-	       (unsigned long) data);
-#endif
-
 	if (request == PTRACE_TRACEME) {
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED) {
@@ -81,31 +158,15 @@
 		goto out_tsk;
 
 	switch (request) {
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-	case PTRACE_PEEKDATA:{
-		unsigned long tmp;
-		int copied;
+		unsigned long val, copied;
 
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA:
+		copied = access_process_vm(child, addr, &val, sizeof(val), 0);
 		rval = -EIO;
-		if (copied != sizeof(tmp))
+		if (copied != sizeof(val))
 			break;
-		rval = put_user(tmp,(unsigned long *) data);
-
-		goto out;
-		}
-
-	/* Read the word at location addr in the USER area.  */
-	case PTRACE_PEEKUSR: 
-		if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
-			struct pt_regs *regs = task_regs (child);
-			unsigned long val =
-				*(unsigned long *)((char *)regs + addr);
-			rval = put_user (val, (unsigned long *)data);
-		} else {
-			rval = 0;
-			rval = -EIO;			
-		}
+		rval = put_user(val, (unsigned long *)data);
 		goto out;
 
 	case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -117,35 +178,62 @@
 		rval = -EIO;
 		goto out;
 
+	/* Read/write the word at location ADDR in the registers.  */
+	case PTRACE_PEEKUSR:
 	case PTRACE_POKEUSR:
-		if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
-			struct pt_regs *regs = task_regs (child);
-			unsigned long *loc =
-				(unsigned long *)((char *)regs + addr);
-			*loc = data;
-		} else {
-			rval = 0;
-			rval = -EIO;			
-		}
+		rval = 0;
+		if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
+			/* Special requests that don't actually correspond
+			   to offsets in struct pt_regs.  */
+			if (addr == PT_TEXT_ADDR)
+				val = child->mm->start_code;
+			else if (addr == PT_DATA_ADDR)
+				val = child->mm->start_data;
+			else if (addr == PT_TEXT_LEN)
+				val = child->mm->end_code
+					- child->mm->start_code;
+			else
+				rval = -EIO;
+		} else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
+			v850_reg_t *reg_addr = reg_save_addr(addr, child);
+			if (request == PTRACE_PEEKUSR)
+				val = *reg_addr;
+			else
+				*reg_addr = data;
+		} else
+			rval = -EIO;
+
+		if (rval == 0 && request == PTRACE_PEEKUSR)
+			rval = put_user (val, (unsigned long *)data);
 		goto out;
 
-	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-	case PTRACE_CONT: /* rvaltart after signal. */
+	/* Continue and stop at next (return from) syscall */
+	case PTRACE_SYSCALL:
+	/* Restart after a signal.  */
+	case PTRACE_CONT:
+	/* Execute a single instruction. */
+	case PTRACE_SINGLESTEP:
 		rval = -EIO;
 		if ((unsigned long) data > _NSIG)
 			break;
+
+		/* Turn CHILD's single-step flag on or off.  */
+		if (! set_single_step (child, request == PTRACE_SINGLESTEP))
+			break;
+
 		if (request == PTRACE_SYSCALL)
 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		else
 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
 		child->exit_code = data;
 		wake_up_process(child);
 		rval = 0;
 		break;
 
 	/*
-	 * make the child exit.  Best I can do is send it a sigkill. 
-	 * perhaps it should be put in the status that it wants to 
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
 	 * exit.
 	 */
 	case PTRACE_KILL:
@@ -157,6 +245,7 @@
 		break;
 
 	case PTRACE_DETACH: /* detach a process that was attached. */
+		set_single_step (child, 0);  /* Clear single-step flag */
 		rval = ptrace_detach(child, data);
 		break;
 
@@ -181,7 +270,7 @@
 	/* The 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
 	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-	                                ? 0x80 : 0);
+					? 0x80 : 0);
 	current->state = TASK_STOPPED;
 	notify_parent(current, SIGCHLD);
 	schedule();
diff -Nru a/arch/v850/kernel/rte_cb_leds.c b/arch/v850/kernel/rte_cb_leds.c
--- a/arch/v850/kernel/rte_cb_leds.c	Sun Nov 24 17:34:44 2002
+++ b/arch/v850/kernel/rte_cb_leds.c	Tue May 27 00:09:43 2003
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/rte_cb_leds.c -- Midas lab RTE-CB board LED device support
  *
- *  Copyright (C) 2002  NEC Corporation
- *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2002,03  NEC Electronics Corporation
+ *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/fs.h>
 #include <linux/miscdevice.h>
 
 #include <asm/uaccess.h>
diff -Nru a/arch/v850/kernel/rte_cb_multi.c b/arch/v850/kernel/rte_cb_multi.c
--- a/arch/v850/kernel/rte_cb_multi.c	Thu Apr  3 15:01:04 2003
+++ b/arch/v850/kernel/rte_cb_multi.c	Tue May 27 00:09:43 2003
@@ -2,7 +2,7 @@
  * include/asm-v850/rte_multi.c -- Support for Multi debugger monitor ROM
  * 	on Midas lab RTE-CB series of evaluation boards
  *
- *  Copyright (C) 2001,02,03  NEC Corporation
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
diff -Nru a/arch/v850/kernel/rte_ma1_cb.c b/arch/v850/kernel/rte_ma1_cb.c
--- a/arch/v850/kernel/rte_ma1_cb.c	Thu Apr  3 15:01:04 2003
+++ b/arch/v850/kernel/rte_ma1_cb.c	Tue May 27 00:09:43 2003
@@ -1,7 +1,7 @@
 /*
  * arch/v850/kernel/rte_ma1_cb.c -- Midas labs RTE-V850E/MA1-CB board
  *
- *  Copyright (C) 2001,02,03  NEC Corporation
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
  *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
diff -Nru a/arch/v850/vmlinux.lds.S b/arch/v850/vmlinux.lds.S
--- a/arch/v850/vmlinux.lds.S	Wed Apr  2 00:42:56 2003
+++ b/arch/v850/vmlinux.lds.S	Tue May 27 00:09:43 2003
@@ -105,9 +105,9 @@
 #define RAMK_INIT_CONTENTS_NO_END					      \
 		. = ALIGN (4096) ;					      \
 		__init_start = . ;					      \
-			_sinittext = .;					      \
+			__sinittext = .;				      \
 			*(.init.text)	/* 2.5 convention */		      \
-			_einittext = .;					      \
+			__einittext = .;				      \
 			*(.init.data)					      \
 			*(.text.init)	/* 2.4 convention */		      \
 			*(.data.init)					      \
diff -Nru a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
--- a/arch/x86_64/kernel/reboot.c	Fri May 23 03:22:07 2003
+++ b/arch/x86_64/kernel/reboot.c	Tue May 27 03:48:22 2003
@@ -124,7 +124,7 @@
 {
 	int i;
 
-#if CONFIG_SMP
+#ifdef CONFIG_SMP
 	smp_halt(); 
 #endif
 
diff -Nru a/crypto/sha512.c b/crypto/sha512.c
--- a/crypto/sha512.c	Tue Jan 14 03:44:40 2003
+++ b/crypto/sha512.c	Tue May 27 00:09:39 2003
@@ -48,33 +48,33 @@
 }
 
 const u64 sha512_K[80] = {
-        0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
-        0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
-        0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
-        0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
-        0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
-        0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
-        0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
-        0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
-        0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
-        0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
-        0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
-        0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
-        0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
-        0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
-        0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
-        0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
-        0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
-        0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
-        0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
-        0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
-        0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
-        0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
-        0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
-        0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
-        0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
-        0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
-        0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
+        0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+        0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+        0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+        0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+        0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+        0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+        0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+        0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+        0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+        0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+        0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+        0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+        0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+        0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+        0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+        0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+        0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+        0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+        0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+        0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+        0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+        0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+        0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+        0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+        0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+        0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+        0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
 };
 
 #define e0(x)       (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
@@ -83,24 +83,24 @@
 #define s1(x)       (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
 
 /* H* initial state for SHA-512 */
-#define H0         0x6a09e667f3bcc908
-#define H1         0xbb67ae8584caa73b
-#define H2         0x3c6ef372fe94f82b
-#define H3         0xa54ff53a5f1d36f1
-#define H4         0x510e527fade682d1
-#define H5         0x9b05688c2b3e6c1f
-#define H6         0x1f83d9abfb41bd6b
-#define H7         0x5be0cd19137e2179
+#define H0         0x6a09e667f3bcc908ULL
+#define H1         0xbb67ae8584caa73bULL
+#define H2         0x3c6ef372fe94f82bULL
+#define H3         0xa54ff53a5f1d36f1ULL
+#define H4         0x510e527fade682d1ULL
+#define H5         0x9b05688c2b3e6c1fULL
+#define H6         0x1f83d9abfb41bd6bULL
+#define H7         0x5be0cd19137e2179ULL
 
 /* H'* initial state for SHA-384 */
-#define HP0 0xcbbb9d5dc1059ed8
-#define HP1 0x629a292a367cd507
-#define HP2 0x9159015a3070dd17
-#define HP3 0x152fecd8f70e5939
-#define HP4 0x67332667ffc00b31
-#define HP5 0x8eb44a8768581511
-#define HP6 0xdb0c2e0d64f98fa7
-#define HP7 0x47b5481dbefa4fa4
+#define HP0 0xcbbb9d5dc1059ed8ULL
+#define HP1 0x629a292a367cd507ULL
+#define HP2 0x9159015a3070dd17ULL
+#define HP3 0x152fecd8f70e5939ULL
+#define HP4 0x67332667ffc00b31ULL
+#define HP5 0x8eb44a8768581511ULL
+#define HP6 0xdb0c2e0d64f98fa7ULL
+#define HP7 0x47b5481dbefa4fa4ULL
 
 static inline void LOAD_OP(int I, u64 *W, const u8 *input)
 {
diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
--- a/drivers/block/cciss_scsi.c	Wed May 14 23:48:56 2003
+++ b/drivers/block/cciss_scsi.c	Mon May 12 07:33:45 2003
@@ -54,11 +54,11 @@
 const char *cciss_scsi_info(struct Scsi_Host *sa);
 
 int cciss_scsi_proc_info(
+		struct Scsi_Host *sh,
 		char *buffer, /* data buffer */
 		char **start, 	   /* where data in buffer starts */
 		off_t offset,	   /* offset from start of imaginary file */
 		int length, 	   /* length of data in buffer */
-		int hostnum, 	   /* which host adapter (always zero for me) */
 		int func);	   /* 0 == read, 1 == write */
 
 int cciss_scsi_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *));
@@ -1121,24 +1121,19 @@
 
 
 int
-cciss_scsi_proc_info(char *buffer, /* data buffer */
+cciss_scsi_proc_info(struct Scsi_Host *sh,
+		char *buffer, /* data buffer */
 		char **start, 	   /* where data in buffer starts */
 		off_t offset,	   /* offset from start of imaginary file */
 		int length, 	   /* length of data in buffer */
-		int hostnum, 	   /* which host adapter (always zero for me) */
 		int func)	   /* 0 == read, 1 == write */
 {
 
 	int buflen, datalen;
-	struct Scsi_Host *sh;
 	ctlr_info_t *ci;
 	int cntl_num;
 
 
-	sh = scsi_host_hn_get(hostnum);
-	if (sh == NULL) /* This really shouldn't ever happen. */
-		return -EINVAL;
-
 	ci = (ctlr_info_t *) sh->hostdata[0];
 	if (ci == NULL)  /* This really shouldn't ever happen. */
 		return -EINVAL;
@@ -1146,7 +1141,7 @@
 	cntl_num = ci->ctlr;	/* Get our index into the hba[] array */
 
 	if (func == 0) {	/* User is reading from /proc/scsi/ciss*?/?*  */
-		buflen = sprintf(buffer, "hostnum=%d\n", hostnum); 	
+		buflen = sprintf(buffer, "hostnum=%d\n", sh->host_no); 	
 
 		datalen = buflen - offset;
 		if (datalen < 0) { 	/* they're reading past EOF. */
@@ -1156,7 +1151,7 @@
 			*start = buffer + offset;
 		return(datalen);
 	} else 	/* User is writing to /proc/scsi/cciss*?/?*  ... */
-		return cciss_scsi_user_command(cntl_num, hostnum,
+		return cciss_scsi_user_command(cntl_num, sh->host_no,
 			buffer, length);	
 } 
 
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Thu May  8 02:30:11 2003
+++ b/drivers/block/ll_rw_blk.c	Tue May 27 13:21:00 2003
@@ -413,11 +413,12 @@
 {
 	struct blk_queue_tag *bqt = q->queue_tags;
 
-	if (unlikely(bqt == NULL || bqt->max_depth < tag))
+	if (unlikely(bqt == NULL || tag >= bqt->real_max_depth))
 		return NULL;
 
 	return bqt->tag_index[tag];
 }
+
 /**
  * blk_queue_free_tags - release tag maintenance info
  * @q:  the request queue for the device
@@ -448,39 +449,28 @@
 	q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);
 }
 
-/**
- * blk_queue_init_tags - initialize the queue tag info
- * @q:  the request queue for the device
- * @depth:  the maximum queue depth supported
- **/
-int blk_queue_init_tags(request_queue_t *q, int depth)
+static int init_tag_map(struct blk_queue_tag *tags, int depth)
 {
-	struct blk_queue_tag *tags;
 	int bits, i;
 
 	if (depth > (queue_nr_requests*2)) {
 		depth = (queue_nr_requests*2);
-		printk("blk_queue_init_tags: adjusted depth to %d\n", depth);
+		printk(KERN_ERR "%s: adjusted depth to %d\n", __FUNCTION__, depth);
 	}
 
-	tags = kmalloc(sizeof(struct blk_queue_tag),GFP_ATOMIC);
-	if (!tags)
-		goto fail;
-
 	tags->tag_index = kmalloc(depth * sizeof(struct request *), GFP_ATOMIC);
 	if (!tags->tag_index)
-		goto fail_index;
+		goto fail;
 
 	bits = (depth / BLK_TAGS_PER_LONG) + 1;
 	tags->tag_map = kmalloc(bits * sizeof(unsigned long), GFP_ATOMIC);
 	if (!tags->tag_map)
-		goto fail_map;
+		goto fail;
 
 	memset(tags->tag_index, 0, depth * sizeof(struct request *));
 	memset(tags->tag_map, 0, bits * sizeof(unsigned long));
-	INIT_LIST_HEAD(&tags->busy_list);
-	tags->busy = 0;
 	tags->max_depth = depth;
+	tags->real_max_depth = bits * BITS_PER_LONG;
 
 	/*
 	 * set the upper bits if the depth isn't a multiple of the word size
@@ -488,22 +478,89 @@
 	for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++)
 		__set_bit(i, tags->tag_map);
 
+	return 0;
+fail:
+	kfree(tags->tag_index);
+	return -ENOMEM;
+}
+
+
+/**
+ * blk_queue_init_tags - initialize the queue tag info
+ * @q:  the request queue for the device
+ * @depth:  the maximum queue depth supported
+ **/
+int blk_queue_init_tags(request_queue_t *q, int depth)
+{
+	struct blk_queue_tag *tags;
+
+	tags = kmalloc(sizeof(struct blk_queue_tag),GFP_ATOMIC);
+	if (!tags)
+		goto fail;
+
+	if (init_tag_map(tags, depth))
+		goto fail;
+
+	INIT_LIST_HEAD(&tags->busy_list);
+	tags->busy = 0;
+
 	/*
 	 * assign it, all done
 	 */
 	q->queue_tags = tags;
 	q->queue_flags |= (1 << QUEUE_FLAG_QUEUED);
 	return 0;
-
-fail_map:
-	kfree(tags->tag_index);
-fail_index:
-	kfree(tags);
 fail:
+	kfree(tags);
 	return -ENOMEM;
 }
 
 /**
+ * blk_queue_resize_tags - change the queueing depth
+ * @q:  the request queue for the device
+ * @new_depth: the new max command queueing depth
+ *
+ *  Notes:
+ *    Must be called with the queue lock held.
+ **/
+int blk_queue_resize_tags(request_queue_t *q, int new_depth)
+{
+	struct blk_queue_tag *bqt = q->queue_tags;
+	struct request **tag_index;
+	unsigned long *tag_map;
+	int bits, max_depth;
+
+	if (!bqt)
+		return -ENXIO;
+
+	/*
+	 * don't bother sizing down
+	 */
+	if (new_depth <= bqt->real_max_depth) {
+		bqt->max_depth = new_depth;
+		return 0;
+	}
+
+	/*
+	 * save the old state info, so we can copy it back
+	 */
+	tag_index = bqt->tag_index;
+	tag_map = bqt->tag_map;
+	max_depth = bqt->real_max_depth;
+
+	if (init_tag_map(bqt, new_depth))
+		return -ENOMEM;
+
+	memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));
+	bits = max_depth / BLK_TAGS_PER_LONG;
+	memcpy(bqt->tag_map, bqt->tag_map, bits * sizeof(unsigned long));
+
+	kfree(tag_index);
+	kfree(tag_map);
+	return 0;
+}
+
+/**
  * blk_queue_end_tag - end tag operations for a request
  * @q:  the request queue for the device
  * @tag:  the tag that has completed
@@ -524,7 +581,7 @@
 
 	BUG_ON(tag == -1);
 
-	if (unlikely(tag >= bqt->max_depth))
+	if (unlikely(tag >= bqt->real_max_depth))
 		return;
 
 	if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
diff -Nru a/drivers/char/amiserial.c b/drivers/char/amiserial.c
--- a/drivers/char/amiserial.c	Tue May  6 06:50:50 2003
+++ b/drivers/char/amiserial.c	Mon May 26 15:29:19 2003
@@ -102,13 +102,12 @@
 
 static char *serial_name = "Amiga-builtin serial driver";
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* serial subtype definitions */
 #ifndef SERIAL_TYPE_NORMAL
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 #endif
 
 /* number of characters left in xmit buffer before we ask for more */
@@ -448,8 +447,7 @@
 #endif
 		if (!(status & SER_DCD))
 			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+		else {
 #ifdef SERIAL_DEBUG_OPEN
 			printk("doing serial hangup...");
 #endif
@@ -1567,8 +1565,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->state->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->state->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1613,8 +1609,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	local_irq_restore(flags);
 }
@@ -1698,7 +1693,7 @@
 	shutdown(info);
 	info->event = 0;
 	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1738,43 +1733,17 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (state->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 
 	/*
 	 * Block waiting for the carrier detect and the line to become
@@ -1798,8 +1767,7 @@
 	info->blocked_open++;
 	while (1) {
 		local_irq_save(flags);
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
+		if (tty->termios->c_cflag & CBAUD)
 		        rtsdtr_ctrl(SER_DTR|SER_RTS);
 		local_irq_restore(flags);
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -1815,8 +1783,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (!(ciab.pra & SER_DCD)) ))
 			break;
 		if (signal_pending(current)) {
@@ -1957,14 +1924,9 @@
 
 	if ((info->state->count == 1) &&
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else 
-			*tty->termios = info->state->callout_termios;
+		*tty->termios = info->state->normal_termios;
 		change_speed(info, 0);
 	}
-	info->session = current->session;
-	info->pgrp = current->pgrp;
 
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open %s successful...", tty->name);
@@ -2150,21 +2112,8 @@
 	serial_driver.wait_until_sent = rs_wait_until_sent;
 	serial_driver.read_proc = rs_read_proc;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
 
 	state = rs_table;
 	state->magic = SSTATE_MAGIC;
@@ -2173,7 +2122,6 @@
 	state->custom_divisor = 0;
 	state->close_delay = 5*HZ/10;
 	state->closing_wait = 30*HZ;
-	state->callout_termios = callout_driver.init_termios;
 	state->normal_termios = serial_driver.init_termios;
 	state->icount.cts = state->icount.dsr = 
 	  state->icount.rng = state->icount.dcd = 0;
@@ -2229,9 +2177,6 @@
 	if ((e1 = tty_unregister_driver(&serial_driver)))
 		printk("SERIAL: failed to unregister serial driver (%d)\n",
 		       e1);
-	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("SERIAL: failed to unregister callout driver (%d)\n", 
-		       e2);
 
 	if (info) {
 	  rs_table[0].info = NULL;
diff -Nru a/drivers/char/cyclades.c b/drivers/char/cyclades.c
--- a/drivers/char/cyclades.c	Wed May  7 07:11:08 2003
+++ b/drivers/char/cyclades.c	Mon May 26 15:29:19 2003
@@ -712,7 +712,7 @@
 
 #define	JIFFIES_DIFF(n, j)	((j) - (n))
 
-static struct tty_driver cy_serial_driver, cy_callout_driver;
+static struct tty_driver cy_serial_driver;
 static int serial_refcount;
 
 #ifdef CONFIG_ISA
@@ -968,8 +968,7 @@
     if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
         tty_hangup(info->tty);
         wake_up_interruptible(&info->open_wait);
-        info->flags &= ~(ASYNC_NORMAL_ACTIVE|
-                             ASYNC_CALLOUT_ACTIVE);
+        info->flags &= ~ASYNC_NORMAL_ACTIVE;
     }
     if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
         wake_up_interruptible(&info->open_wait);
@@ -1448,10 +1447,7 @@
                             if(mdm_status & CyDCD){
                                 cy_sched_event(info,
 				    Cy_EVENT_OPEN_WAKEUP);
-                            }else if(!((info->flags
-			                & ASYNC_CALLOUT_ACTIVE)
-				 &&(info->flags
-				    & ASYNC_CALLOUT_NOHUP))){
+                            }else{
                                 cy_sched_event(info,
 				    Cy_EVENT_HANGUP);
                             }
@@ -1823,8 +1819,7 @@
 			  ((u_long)param) : 
 			  cy_readl(&ch_ctrl->rs_status)) & C_RS_DCD) {
 			cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
-		    }else if(!((info->flags & ASYNC_CALLOUT_ACTIVE)
-			     &&(info->flags & ASYNC_CALLOUT_NOHUP))){
+		    }else{
 			cy_sched_event(info, Cy_EVENT_HANGUP);
 		    }
 		}
@@ -2376,36 +2371,11 @@
     }
 
     /*
-     * If this is a callout device, then just make sure the normal
-     * device isn't being used.
-     */
-    if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-        if (info->flags & ASYNC_NORMAL_ACTIVE){
-            return -EBUSY;
-        }
-        if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-            (info->flags & ASYNC_SESSION_LOCKOUT) &&
-            (info->session != current->session)){
-            return -EBUSY;
-        }
-        if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-            (info->flags & ASYNC_PGRP_LOCKOUT) &&
-            (info->pgrp != current->pgrp)){
-            return -EBUSY;
-        }
-        info->flags |= ASYNC_CALLOUT_ACTIVE;
-        return 0;
-    }
-
-    /*
      * If non-blocking mode is set, then make the check up front
      * and then exit.
      */
     if ((filp->f_flags & O_NONBLOCK) ||
 	(tty->flags & (1 << TTY_IO_ERROR))) {
-        if (info->flags & ASYNC_CALLOUT_ACTIVE){
-            return -EBUSY;
-        }
         info->flags |= ASYNC_NORMAL_ACTIVE;
         return 0;
     }
@@ -2442,8 +2412,7 @@
 
 	while (1) {
 	    CY_LOCK(info, flags);
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD)){
+		if ((tty->termios->c_cflag & CBAUD)){
 		    cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
 		    cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
 		    cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
@@ -2466,8 +2435,7 @@
 
 	    CY_LOCK(info, flags);
 		cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
-		&& !(info->flags & ASYNC_CLOSING)
+		if (!(info->flags & ASYNC_CLOSING)
 		&& (C_CLOCAL(tty)
 		    || (cy_readb(base_addr+(CyMSVR1<<index)) & CyDCD))) {
 			CY_UNLOCK(info, flags);
@@ -2507,8 +2475,7 @@
 	ch_ctrl = zfw_ctrl->ch_ctrl;
 
 	while (1) {
-	    if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		(tty->termios->c_cflag & CBAUD)){
+	    if ((tty->termios->c_cflag & CBAUD)){
 		cy_writel(&ch_ctrl[channel].rs_control,
 			cy_readl(&ch_ctrl[channel].rs_control) |
 			(C_RS_RTS | C_RS_DTR));
@@ -2530,8 +2497,7 @@
 		    -EAGAIN : -ERESTARTSYS);
 		break;
 	    }
-	    if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
-	    && !(info->flags & ASYNC_CLOSING)
+	    if (!(info->flags & ASYNC_CLOSING)
 	    && (C_CLOCAL(tty)
 	      || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) {
 		break;
@@ -2680,15 +2646,9 @@
     }
 
     if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-        if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-            *tty->termios = info->normal_termios;
-        else 
-            *tty->termios = info->callout_termios;
+	*tty->termios = info->normal_termios;
     }
 
-    info->session = current->session;
-    info->pgrp = current->pgrp;
-
 #ifdef CY_DEBUG_OPEN
     printk(" cyc:cy_open done\n");/**/
 #endif
@@ -2839,8 +2799,6 @@
      */
     if (info->flags & ASYNC_NORMAL_ACTIVE)
         info->normal_termios = *tty->termios;
-    if (info->flags & ASYNC_CALLOUT_ACTIVE)
-        info->callout_termios = *tty->termios;
 
     /*
     * Now we wait for the transmit buffer to clear; and we notify
@@ -2917,8 +2875,7 @@
         wake_up_interruptible(&info->open_wait);
 	CY_LOCK(info, flags);
     }
-    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-                     ASYNC_CLOSING);
+    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
     wake_up_interruptible(&info->close_wait);
 
 #ifdef CY_DEBUG_OTHER
@@ -4701,7 +4658,7 @@
     printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
 #endif
     info->tty = 0;
-    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+    info->flags &= ~ASYNC_NORMAL_ACTIVE;
     wake_up_interruptible(&info->open_wait);
 } /* cy_hangup */
 
@@ -5523,22 +5480,8 @@
     cy_serial_driver.wait_until_sent = cy_wait_until_sent;
     cy_serial_driver.read_proc = cyclades_get_proc_info;
 
-    /*
-     * The callout device is just like normal device except for
-     * major number and the subtype code.
-     */
-    cy_callout_driver = cy_serial_driver;
-    cy_callout_driver.name = "cub";
-    cy_callout_driver.major = CYCLADESAUX_MAJOR;
-    cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-    cy_callout_driver.read_proc = 0;
-    cy_callout_driver.proc_entry = 0;
-
-
     if (tty_register_driver(&cy_serial_driver))
             panic("Couldn't register Cyclades serial driver\n");
-    if (tty_register_driver(&cy_callout_driver))
-            panic("Couldn't register Cyclades callout driver\n");
 
     for (i = 0; i < NR_CARDS; i++) {
             /* base_addr=0 indicates board not found */
@@ -5629,8 +5572,6 @@
                     info->default_threshold = 0;
                     info->default_timeout = 0;
 		    INIT_WORK(&info->tqueue, do_softint, info);
-                    info->callout_termios =
-		                cy_callout_driver.init_termios;
                     info->normal_termios =
 		                cy_serial_driver.init_termios;
 		    init_waitqueue_head(&info->open_wait);
@@ -5708,8 +5649,6 @@
                     info->default_threshold = 0;
                     info->default_timeout = 0;
 		    INIT_WORK(&info->tqueue, do_softint, info);
-                    info->callout_termios =
-		               cy_callout_driver.init_termios;
                     info->normal_termios =
 		               cy_serial_driver.init_termios;
 		    init_waitqueue_head(&info->open_wait);
@@ -5761,9 +5700,6 @@
     if ((e1 = tty_unregister_driver(&cy_serial_driver)))
             printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
 		e1);
-    if ((e2 = tty_unregister_driver(&cy_callout_driver)))
-            printk("cyc: failed to unregister Cyclades callout driver (%d)\n", 
-		e2);
 
     restore_flags(flags);
 
diff -Nru a/drivers/char/dz.c b/drivers/char/dz.c
--- a/drivers/char/dz.c	Wed May  7 15:51:55 2003
+++ b/drivers/char/dz.c	Mon May 26 15:29:19 2003
@@ -1095,8 +1095,6 @@
 	 */
 	if (info->flags & DZ_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & DZ_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify the line
 	 * discipline to only process XON/XOFF characters.
@@ -1136,7 +1134,7 @@
 		wake_up_interruptible(&info->open_wait);
 	}
 
-	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING);
+	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 
 	restore_flags(flags);
@@ -1153,7 +1151,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE);
+	info->flags &= ~DZ_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1180,47 +1178,18 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & DZ_NORMAL_ACTIVE)
-			return -EBUSY;
-    
-		if ((info->flags & DZ_CALLOUT_ACTIVE) &&
-		    (info->flags & DZ_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-			return -EBUSY;
-    
-		if ((info->flags & DZ_CALLOUT_ACTIVE) &&
-		    (info->flags & DZ_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-			return -EBUSY;
-
-		info->flags |= DZ_CALLOUT_ACTIVE;
-		return 0;
-	}
-
-	/*
 	 * If non-blocking mode is set, or the port is not enabled, then make
 	 * the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & DZ_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= DZ_NORMAL_ACTIVE;
 
 		return 0;
 	}
 
-	if (info->flags & DZ_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
+	if (tty->termios->c_cflag & CLOCAL)
 		do_clocal = 1;
-	}
 
 	/*
 	 * Block waiting for the carrier detect and the line to become free
@@ -1239,8 +1208,7 @@
 			retval = -EAGAIN;
 			break;
 		}
-		if (!(info->flags & DZ_CALLOUT_ACTIVE) &&
-		    !(info->flags & DZ_CLOSING) && do_clocal)
+		if (!(info->flags & DZ_CLOSING) && do_clocal)
 			break;
 		if (signal_pending(current)) {
 			retval = -ERESTARTSYS;
@@ -1301,16 +1269,10 @@
 		return retval;
 
 	if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 	return 0;
 }
 
@@ -1369,23 +1331,8 @@
 	serial_driver.start = dz_start;
 	serial_driver.hangup = dz_hangup;
 
-	/*
-	 * The callout device is just like normal device except for major
-	 * number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
-	callout_driver.name = "cua";
-#else
-	callout_driver.name = "cua/";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	if (tty_register_driver (&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver (&callout_driver))
-		panic("Couldn't register callout driver\n");
 
 	save_flags(flags); cli();
 	for (i=0; i < DZ_NB_PORT;  i++) {
@@ -1411,7 +1358,6 @@
 		info->tqueue.data = info;
 		info->tqueue_hangup.routine = do_serial_hangup;
 		info->tqueue_hangup.data = info;
-		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait); 
 		init_waitqueue_head(&info->close_wait); 
@@ -1427,7 +1373,6 @@
 		       info->port, SERIAL);
 
 		tty_register_device(&serial_driver, info->line, NULL);
-		tty_register_device(&callout_driver, info->line, NULL);
 	}
 
 	/* Reset the chip */
diff -Nru a/drivers/char/dz.h b/drivers/char/dz.h
--- a/drivers/char/dz.h	Tue Feb  5 09:40:06 2002
+++ b/drivers/char/dz.h	Mon May 26 15:29:25 2003
@@ -157,12 +157,8 @@
   struct tq_struct        tqueue;              /* Queue for BH */
   struct tq_struct        tqueue_hangup;
   struct termios          normal_termios;
-  struct termios          callout_termios;
   wait_queue_head_t       open_wait;
   wait_queue_head_t       close_wait;
-
-  long                    session;             /* Session of opening process */
-  long                    pgrp;                /* pgrp of opening process */
 
   unsigned char           is_console;          /* flag indicating a serial console */
   unsigned char           is_initialized;
diff -Nru a/drivers/char/epca.c b/drivers/char/epca.c
--- a/drivers/char/epca.c	Mon Apr 21 20:58:41 2003
+++ b/drivers/char/epca.c	Mon May 26 15:29:18 2003
@@ -98,7 +98,6 @@
 /* ------------- Begin structures used for driver registeration ---------- */
 
 struct tty_driver pc_driver;
-struct tty_driver pc_callout;
 struct tty_driver pc_info;
 
 /* The below structures are used to initialize the tty_driver structures. */
@@ -562,9 +561,6 @@
 		if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
 			ch->normal_termios = *tty->termios;
 
-		if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
-			ch->callout_termios = *tty->termios;
-
 		tty->closing = 1;
 
 		if (ch->asyncflags & ASYNC_INITIALIZED) 
@@ -599,7 +595,7 @@
 		} /* End if blocked_open */
 
 		ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | 
-		                      ASYNC_CALLOUT_ACTIVE | ASYNC_CLOSING);
+		                      ASYNC_CLOSING);
 		wake_up_interruptible(&ch->close_wait);
 
 
@@ -693,7 +689,7 @@
 		ch->event = 0;
 		ch->count = 0;
 		restore_flags(flags);
-		ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | ASYNC_CALLOUT_ACTIVE);
+		ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
 		wake_up_interruptible(&ch->open_wait);
 
 	} /* End if ch != NULL */
@@ -1233,31 +1229,6 @@
 			return -ERESTARTSYS;
 	}
 
-	/* ----------------------------------------------------------------- 
-	   If this is a callout device, then just make sure the normal
-	   device isn't being used.
-	-------------------------------------------------------------------- */
-
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) 
-	{ /* A cud device has been opened */
-		if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-
-		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
-		    (ch->asyncflags & ASYNC_SESSION_LOCKOUT) &&
-		    (ch->session != current->session))
-		    return -EBUSY;
-
-		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
-		    (ch->asyncflags & ASYNC_PGRP_LOCKOUT) &&
-		    (ch->pgrp != current->pgrp))
-		    return -EBUSY;
- 
-		ch->asyncflags |= ASYNC_CALLOUT_ACTIVE;
-
-		return 0;
-	} /* End a cud device has been opened */
-
 	if (filp->f_flags & O_NONBLOCK) 
 	{
 		/* ----------------------------------------------------------------- 
@@ -1265,25 +1236,14 @@
 	  	 and then exit.
 		-------------------------------------------------------------------- */
 
-		if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
-
 		ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
 
 		return 0;
 	}
 
 
-	if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE) 
-	{
-		if (ch->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	else 
-	{
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 	
    /* Block waiting for the carrier detect and the line to become free */
 	
@@ -1317,7 +1277,6 @@
 		}
 
 		if (!(ch->asyncflags & ASYNC_CLOSING) && 
-		    !(ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
 			  (do_clocal || (ch->imodem & ch->dcd)))
 			break;
 
@@ -1453,15 +1412,9 @@
 	/* Should this be here except for SPLIT termios ? */
 	if (ch->count == 1) 
 	{
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = ch->normal_termios;
-		else 
-			*tty->termios = ch->callout_termios;
+		*tty->termios = ch->normal_termios;
 	}
 
-	ch->session = current->session;
-	ch->pgrp = current->pgrp;
-
 	save_flags(flags);
 	cli();
 
@@ -1558,7 +1511,6 @@
 	cli();
 
 	if ((tty_unregister_driver(&pc_driver)) ||  
-	    (tty_unregister_driver(&pc_callout)) ||
 	    (tty_unregister_driver(&pc_info)))
 	{
 		printk(KERN_WARNING "<Error> - DIGI : cleanup_module failed to un-register tty driver\n");
@@ -1701,7 +1653,6 @@
 #endif /* ENABLE_PCI */
 
 	memset(&pc_driver, 0, sizeof(struct tty_driver));
-	memset(&pc_callout, 0, sizeof(struct tty_driver));
 	memset(&pc_info, 0, sizeof(struct tty_driver));
 
 	pc_driver.magic = TTY_DRIVER_MAGIC;
@@ -1747,13 +1698,6 @@
 	pc_driver.throttle = pc_throttle;
 	pc_driver.unthrottle = pc_unthrottle;
 	pc_driver.hangup = pc_hangup;
-	pc_callout = pc_driver;
-
-	pc_callout.name = "cud";
-	pc_callout.major = DIGICU_MAJOR;
-	pc_callout.minor_start = 0;
-	pc_callout.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
-	pc_callout.subtype = SERIAL_TYPE_CALLOUT;
 
 	pc_info = pc_driver;
 	pc_info.name = "digi_ctl";
@@ -1889,9 +1833,6 @@
 	if (tty_register_driver(&pc_driver))
 		panic("Couldn't register Digi PC/ driver");
 
-	if (tty_register_driver(&pc_callout))
-		panic("Couldn't register Digi PC/ callout");
-
 	if (tty_register_driver(&pc_info))
 		panic("Couldn't register Digi PC/ info ");
 
@@ -2165,7 +2106,6 @@
 		ch->close_delay = 50;
 		ch->count = 0;
 		ch->blocked_open = 0;
-		ch->callout_termios = pc_callout.init_termios;
 		ch->normal_termios = pc_driver.init_termios;
 		init_waitqueue_head(&ch->open_wait);
 		init_waitqueue_head(&ch->close_wait);
@@ -2712,7 +2652,7 @@
 			the driver will wait on carrier detect.
 		------------------------------------------------------------------- */
 
-		if ((ts->c_cflag & CLOCAL) || (tty->driver->subtype == SERIAL_TYPE_CALLOUT))
+		if (ts->c_cflag & CLOCAL)
 		{ /* Begin it is a cud device or a ttyD device with CLOCAL on */
 			ch->asyncflags &= ~ASYNC_CHECK_CD;
 		} /* End it is a cud device or a ttyD device with CLOCAL on */
@@ -3406,7 +3346,7 @@
 
 				tty_hangup(tty);	/* FIXME: module removal race here - AKPM */
 				wake_up_interruptible(&ch->open_wait);
-				ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
+				ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
 
 			} /* End if clear_bit */
 		}
diff -Nru a/drivers/char/epca.h b/drivers/char/epca.h
--- a/drivers/char/epca.h	Tue Oct  1 08:49:32 2002
+++ b/drivers/char/epca.h	Mon May 26 15:29:18 2003
@@ -78,7 +78,6 @@
 
 #define FEPTIMEOUT 200000  
 #define SERIAL_TYPE_NORMAL  1
-#define SERIAL_TYPE_CALLOUT 2
 #define SERIAL_TYPE_INFO    3
 #define EPCA_EVENT_HANGUP   1
 #define EPCA_MAGIC          0x5c6df104L
@@ -124,8 +123,6 @@
 	ulong  event;
 	int    asyncflags;
 	uint   dev;
-	long   session;
-	long   pgrp;
 	ulong  statusflags;
 	ulong  c_iflag;
 	ulong  c_cflag;
@@ -139,7 +136,6 @@
 	struct digi_struct          digiext;
 	struct tty_struct           *tty;
 	struct termios              normal_termios;
-	struct termios              callout_termios;
 	wait_queue_head_t           open_wait;
 	wait_queue_head_t           close_wait;
 	struct work_struct            tqueue;
diff -Nru a/drivers/char/esp.c b/drivers/char/esp.c
--- a/drivers/char/esp.c	Wed May  7 07:24:33 2003
+++ b/drivers/char/esp.c	Mon May 26 15:29:18 2003
@@ -109,12 +109,11 @@
 
 static DECLARE_TASK_QUEUE(tq_esp);
 
-static struct tty_driver esp_driver, esp_callout_driver;
+static struct tty_driver esp_driver;
 static int serial_refcount;
 
 /* serial subtype definitions */
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 
 /*
  * Serial driver configuration section.  Here are the various options:
@@ -638,8 +637,7 @@
 #endif		
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+		else {
 #ifdef SERIAL_DEBUG_OPEN
 			printk("scheduling hangup...");
 #endif
@@ -2077,8 +2075,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -2126,8 +2122,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 out:
 	restore_flags(flags);
@@ -2185,7 +2180,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -2222,44 +2217,18 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -2282,8 +2251,7 @@
 	while (1) {
 		save_flags(flags);
 		cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			(tty->termios->c_cflag & CBAUD)) {
+		if ((tty->termios->c_cflag & CBAUD)) {
 			unsigned int scratch;
 
 			serial_out(info, UART_ESI_CMD1, ESI_READ_UART);
@@ -2313,8 +2281,7 @@
 		if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD)
 			do_clocal = 1;
 
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal))
 			break;
 		if (signal_pending(current)) {
@@ -2399,16 +2366,10 @@
 	}
 
 	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
 	printk("esp_open %s successful...", tty->name);
 #endif
@@ -2581,35 +2542,18 @@
 	esp_driver.break_ctl = esp_break;
 	esp_driver.wait_until_sent = rs_wait_until_sent;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	esp_callout_driver = esp_driver;
-	esp_callout_driver.name = "cup";
-	esp_callout_driver.major = ESP_OUT_MAJOR;
-	esp_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	if (tty_register_driver(&esp_driver))
 	{
 		printk(KERN_ERR "Couldn't register esp serial driver");
 		return 1;
 	}
 
-	if (tty_register_driver(&esp_callout_driver))
-	{
-		printk(KERN_ERR "Couldn't register esp callout driver");
-		tty_unregister_driver(&esp_driver);
-		return 1;
-	}
-	
 	info = kmalloc(sizeof(struct esp_struct), GFP_KERNEL);
 
 	if (!info)
 	{
 		printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
 		tty_unregister_driver(&esp_driver);
-		tty_unregister_driver(&esp_callout_driver);
 		return 1;
 	}
 
@@ -2643,7 +2587,6 @@
 		info->tqueue.data = info;
 		info->tqueue_hangup.routine = do_serial_hangup;
 		info->tqueue_hangup.data = info;
-		info->callout_termios = esp_callout_driver.init_termios;
 		info->normal_termios = esp_driver.init_termios;
 		info->config.rx_timeout = rx_timeout;
 		info->config.flow_on = flow_on;
@@ -2717,9 +2660,6 @@
 	if ((e1 = tty_unregister_driver(&esp_driver)))
 		printk("SERIAL: failed to unregister serial driver (%d)\n",
 		       e1);
-	if ((e2 = tty_unregister_driver(&esp_callout_driver)))
-		printk("SERIAL: failed to unregister callout driver (%d)\n", 
-		       e2);
 	restore_flags(flags);
 
 	while (ports) {
diff -Nru a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
--- a/drivers/char/generic_serial.c	Mon Apr 21 20:58:42 2003
+++ b/drivers/char/generic_serial.c	Mon May 26 15:29:12 2003
@@ -554,7 +554,7 @@
 		return;
 
 	gs_shutdown_port (port);
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE |GS_ACTIVE);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE);
 	port->tty = NULL;
 	port->count = 0;
 
@@ -619,47 +619,19 @@
 	gs_dprintk (GS_DEBUG_BTR, "after hung up\n"); 
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == GS_TYPE_CALLOUT) {
-		if (port->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (port->session != current->session))
-			return -EBUSY;
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (port->pgrp != current->pgrp))
-			return -EBUSY;
-		port->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-
-	gs_dprintk (GS_DEBUG_BTR, "after subtype\n");
-
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (port->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		port->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
 	gs_dprintk (GS_DEBUG_BTR, "after nonblock\n"); 
  
-	if (port->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (port->normal_termios.c_cflag & CLOCAL) 
-			do_clocal = 1;
-	} else {
-		if (C_CLOCAL(tty))
-			do_clocal = 1;
-	}
+	if (C_CLOCAL(tty))
+		do_clocal = 1;
 
 	/*
 	 * Block waiting for the carrier detect and the line to become
@@ -690,8 +662,7 @@
 				retval = -ERESTARTSYS;
 			break;
 		}
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(port->flags & ASYNC_CLOSING) &&
+		if (!(port->flags & ASYNC_CLOSING) &&
 		    (do_clocal || CD))
 			break;
 		gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", 
@@ -769,8 +740,6 @@
 	 */
 	if (port->flags & ASYNC_NORMAL_ACTIVE)
 		port->normal_termios = *tty->termios;
-	if (port->flags & ASYNC_CALLOUT_ACTIVE)
-		port->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -812,8 +781,7 @@
 		}
 		wake_up_interruptible(&port->open_wait);
 	}
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-	                 ASYNC_CLOSING | ASYNC_INITIALIZED);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED);
 	wake_up_interruptible(&port->close_wait);
 
 	restore_flags(flags);
diff -Nru a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
--- a/drivers/char/ip2/i2lib.c	Sun Oct 27 08:53:03 2002
+++ b/drivers/char/ip2/i2lib.c	Mon May 26 15:29:26 2003
@@ -326,8 +326,6 @@
 		pCh->speed       = CBR_9600;
 
 		pCh->flags    = 0;
-		pCh->session  = 0;
-		pCh->pgrp     = 0;
 
 		pCh->ClosingDelay     = 5*HZ/10;
 		pCh->ClosingWaitTime  = 30*HZ;
diff -Nru a/drivers/char/ip2/i2lib.h b/drivers/char/ip2/i2lib.h
--- a/drivers/char/ip2/i2lib.h	Tue Oct  1 08:35:18 2002
+++ b/drivers/char/ip2/i2lib.h	Mon May 26 15:29:18 2003
@@ -92,8 +92,6 @@
 	int      throttled;		// Set if upper layer can take no data
 
 	int      flags;         // Defined in tty.h
-	int      session;       // Defined in tty.h
-	int      pgrp;          // Defined in tty.h
 
 	PWAITQ   open_wait;     // Pointer for OS sleep function.
 	PWAITQ   close_wait;    // Pointer for OS sleep function.
@@ -104,7 +102,6 @@
 	wait_queue_head_t pBookmarkWait;   // Used by i2DrainOutput
 
 	struct termios NormalTermios;
-	struct termios CalloutTermios;
 
 	int      BaudBase;
 	int      BaudDivisor;
diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c
--- a/drivers/char/ip2main.c	Wed May  7 23:16:25 2003
+++ b/drivers/char/ip2main.c	Mon May 26 15:29:18 2003
@@ -194,7 +194,6 @@
 #define ioremap(a,b) vremap((a),(b))
 #define iounmap(a) vfree((a))
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 #define schedule_timeout(a){current->timeout = jiffies + (a); schedule();}
 #define signal_pending(a) ((a)->signal & ~(a)->blocked)
 #define in_interrupt()	intr_count
@@ -232,16 +231,13 @@
 static char *pcDriver_name   = "ip2";
 #ifdef	CONFIG_DEVFS_FS
 static char *pcTty    		 = "tts/F%d";
-static char *pcCallout		 = "cua/F%d";
 #else
 static char *pcTty    		 = "ttyF";
-static char *pcCallout		 = "cuf";
 #endif
 static char *pcIpl    		 = "ip2ipl";
 
 /* Serial subtype definitions */
 #define SERIAL_TYPE_NORMAL    1
-#define SERIAL_TYPE_CALLOUT   2
 
 // cheezy kludge or genius - you decide?
 int ip2_loadmain(int *, int *, unsigned char *, int);
@@ -307,7 +303,6 @@
 /***************/
 
 static struct tty_driver ip2_tty_driver;
-static struct tty_driver ip2_callout_driver;
 
 static int ref_count;
 
@@ -523,9 +518,6 @@
 	if ( ( err = tty_unregister_driver ( &ip2_tty_driver ) ) ) {
 		printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
 	}
-	if ( ( err = tty_unregister_driver ( &ip2_callout_driver ) ) ) {
-		printk(KERN_ERR "IP2: failed to unregister callout driver (%d)\n", err);
-	}
 	if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
 		printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
 	}
@@ -834,27 +826,12 @@
 	ip2_tty_driver.start           = ip2_start;
 	ip2_tty_driver.hangup          = ip2_hangup;
 
-	/* Initialise the callout driver structure from the tty driver, and
-	 * make the needed adjustments.
-	 */
-	ip2_callout_driver         = ip2_tty_driver;
-	ip2_callout_driver.name    = pcCallout;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
-	ip2_callout_driver.driver_name = pcDriver_name;
-	ip2_callout_driver.read_proc  = NULL;
-#endif
-	ip2_callout_driver.major   = IP2_CALLOUT_MAJOR;
-	ip2_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
 
 	/* Register the tty devices. */
 	if ( ( err = tty_register_driver ( &ip2_tty_driver ) ) ) {
 		printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
 	} else
-	if ( ( err = tty_register_driver ( &ip2_callout_driver ) ) ) {
-		printk(KERN_ERR "IP2: failed to register callout driver (%d)\n", err);
-	} else
 	/* Register the IPL driver. */
 	if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
 		printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
@@ -893,9 +870,6 @@
 				        tty_register_device(&ip2_tty_driver,
 					    j + ABS_BIGGEST_BOX *
 						    (box+i*ABS_MAX_BOXES), NULL);
-				            tty_register_device(&ip2_callout_driver,
-					    j + ABS_BIGGEST_BOX *
-						    (box+i*ABS_MAX_BOXES), NULL);
 			    	    }
 			        }
 			    }
@@ -1497,7 +1471,7 @@
 				if ( pCh->wopen ) {
 					wake_up_interruptible ( &pCh->open_wait );
 				}
-			} else if ( !(pCh->flags & ASYNC_CALLOUT_ACTIVE) ) {
+			} else {
 				if (pCh->pTTY &&  (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
 					tty_hangup( pCh->pTTY );
 				}
@@ -1603,35 +1577,9 @@
 	remove_wait_queue(&pCh->close_wait, &wait);
 
 	/*
-	 * 2. If this is a callout device, make sure the normal port is not in
-	 *    use, and that someone else doesn't have the callout device locked.
-	 *    (These are the only tests the standard serial driver makes for
-	 *    callout devices.)
-	 */
-	if ( tty->driver->subtype == SERIAL_TYPE_CALLOUT ) {
-		if ( pCh->flags & ASYNC_NORMAL_ACTIVE ) {
-			return -EBUSY;
-		}
-		if ( ( pCh->flags & ASYNC_CALLOUT_ACTIVE )  &&
-		    ( pCh->flags & ASYNC_SESSION_LOCKOUT ) &&
-		    ( pCh->session != current->session ) ) {
-			return -EBUSY;
-		}
-		if ( ( pCh->flags & ASYNC_CALLOUT_ACTIVE ) &&
-		    ( pCh->flags & ASYNC_PGRP_LOCKOUT )   &&
-		    ( pCh->pgrp != current->pgrp ) ) {
-			return -EBUSY;
-		}
-		pCh->flags |= ASYNC_CALLOUT_ACTIVE;
-		goto noblock;
-	}
-	/*
 	 * 3. Handle a non-blocking open of a normal port.
 	 */
 	if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
-		if ( pCh->flags & ASYNC_CALLOUT_ACTIVE ) {
-			return -EBUSY;
-		}
 		pCh->flags |= ASYNC_NORMAL_ACTIVE;
 		goto noblock;
 	}
@@ -1639,15 +1587,8 @@
 	 * 4. Now loop waiting for the port to be free and carrier present
 	 *    (if required).
 	 */
-	if ( pCh->flags & ASYNC_CALLOUT_ACTIVE ) {
-		if ( pCh->NormalTermios.c_cflag & CLOCAL ) {
-			do_clocal = 1;
-		}
-	} else {
-		if ( tty->termios->c_cflag & CLOCAL ) {
-			do_clocal = 1;
-		}
-	}
+	if ( tty->termios->c_cflag & CLOCAL )
+		do_clocal = 1;
 
 #ifdef IP2DEBUG_OPEN
 	printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
@@ -1659,32 +1600,27 @@
 	add_wait_queue(&pCh->open_wait, &wait);
 
 	for(;;) {
-		if ( !(pCh->flags & ASYNC_CALLOUT_ACTIVE)) {
-			i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
-			pCh->dataSetOut |= (I2_DTR | I2_RTS);
-			set_current_state( TASK_INTERRUPTIBLE );
-			serviceOutgoingFifo( pCh->pMyBord );
-		}
+		i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
+		pCh->dataSetOut |= (I2_DTR | I2_RTS);
+		set_current_state( TASK_INTERRUPTIBLE );
+		serviceOutgoingFifo( pCh->pMyBord );
 		if ( tty_hung_up_p(pFile) ) {
 			set_current_state( TASK_RUNNING );
 			remove_wait_queue(&pCh->open_wait, &wait);
 			return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
 		}
-		if ( !(pCh->flags & ASYNC_CALLOUT_ACTIVE) &&
-				!(pCh->flags & ASYNC_CLOSING) && 
+		if (!(pCh->flags & ASYNC_CLOSING) && 
 				(do_clocal || (pCh->dataSetIn & I2_DCD) )) {
 			rc = 0;
 			break;
 		}
 
 #ifdef IP2DEBUG_OPEN
-		printk(KERN_DEBUG "ASYNC_CALLOUT_ACTIVE = %s\n",
-			(pCh->flags & ASYNC_CALLOUT_ACTIVE)?"True":"False");
 		printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
 			(pCh->flags & ASYNC_CLOSING)?"True":"False");
 		printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
 #endif
-		ip2trace (CHANN, ITRC_OPEN, 3, 2, (pCh->flags & ASYNC_CALLOUT_ACTIVE),
+		ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
 				(pCh->flags & ASYNC_CLOSING) );
 		/* check for signal */
 		if (signal_pending(current)) {
@@ -1711,20 +1647,12 @@
 	if ( tty->count == 1 ) {
 		i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
 		if ( pCh->flags & ASYNC_SPLIT_TERMIOS ) {
-			if ( tty->driver->subtype == SERIAL_TYPE_NORMAL ) {
-				*tty->termios = pCh->NormalTermios;
-			} else {
-				*tty->termios = pCh->CalloutTermios;
-			}
+			*tty->termios = pCh->NormalTermios;
 		}
 		/* Now we must send the termios settings to the loadware */
 		set_params( pCh, NULL );
 	}
 
-	/* override previous and never reset ??? */
-	pCh->session = current->session;
-	pCh->pgrp = current->pgrp;
-
 	/*
 	 * Now set any i2lib options. These may go away if the i2lib code ends
 	 * up rolled into the mainline.
@@ -1786,8 +1714,6 @@
 	 */
 	if (pCh->flags & ASYNC_NORMAL_ACTIVE)
 		pCh->NormalTermios = *tty->termios;
-	if (pCh->flags & ASYNC_CALLOUT_ACTIVE)
-		pCh->CalloutTermios = *tty->termios;
 
 	tty->closing = 1;
 
@@ -1833,7 +1759,7 @@
 		wake_up_interruptible(&pCh->open_wait);
 	}
 
-	pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
+	pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&pCh->close_wait);
 
 #ifdef IP2DEBUG_OPEN
@@ -1883,7 +1809,7 @@
 
 	wake_up_interruptible ( &pCh->delta_msr_wait );
 
-	pCh->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
 	pCh->pTTY = NULL;
 	wake_up_interruptible ( &pCh->open_wait );
 
diff -Nru a/drivers/char/isicom.c b/drivers/char/isicom.c
--- a/drivers/char/isicom.c	Wed May  7 07:24:28 2003
+++ b/drivers/char/isicom.c	Mon May 26 15:29:13 2003
@@ -76,7 +76,7 @@
 static int isicom_refcount;
 static int prev_card = 3;	/*	start servicing isi_card[0]	*/
 static struct isi_board * irq_to_board[16];
-static struct tty_driver isicom_normal, isicom_callout;
+static struct tty_driver isicom_normal;
 static struct tty_struct * isicom_table[PORT_COUNT];
 static struct termios * isicom_termios[PORT_COUNT];
 static struct termios * isicom_termios_locked[PORT_COUNT];
@@ -588,10 +588,7 @@
 							printk(KERN_DEBUG "ISICOM: interrupt: DCD->low.\n");
 #endif							
 							port->status &= ~ISI_DCD;
-							if (!((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-								(port->flags & ASYNC_CALLOUT_NOHUP))) {
-								schedule_task(&port->hangup_tq);
-							}
+							schedule_task(&port->hangup_tq);
 						}
 					}
 					else {
@@ -903,49 +900,18 @@
 			return -ERESTARTSYS;
 	}
 	
-	/* trying to open a callout device... check for constraints */
-	
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-#ifdef ISICOM_DEBUG
-		printk(KERN_DEBUG "ISICOM: bl_ti_rdy: callout open.\n");	
-#endif		
-		if (port->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (port->session != current->session))
-			return -EBUSY;
-			
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (port->pgrp != current->pgrp))
-			return -EBUSY;
-		port->flags |= ASYNC_CALLOUT_ACTIVE;
-		cli();
-		raise_dtr_rts(port);
-		sti();
-		return 0;
-	}
-	
 	/* if non-blocking mode is set ... */
 	
 	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
 #ifdef ISICOM_DEBUG	
 		printk(KERN_DEBUG "ISICOM: block_til_ready: non-block mode.\n");
 #endif		
-		if (port->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		port->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;	
 	}	
 	
-	if (port->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (port->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1; 
-	} else {
-		if (C_CLOCAL(tty))
-			do_clocal = 1;
-	}
+	if (C_CLOCAL(tty))
+		do_clocal = 1;
 #ifdef ISICOM_DEBUG	
 	if (do_clocal)
 		printk(KERN_DEBUG "ISICOM: block_til_ready: CLOCAL set.\n");
@@ -965,9 +931,7 @@
 #endif	
 	while (1) {
 		cli();
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE)) 
-			raise_dtr_rts(port);
-		
+		raise_dtr_rts(port);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { 	
@@ -980,8 +944,7 @@
 #endif			
 			break;
 		}	
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(port->flags & ASYNC_CLOSING) &&
+		if (!(port->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (port->status & ISI_DCD))) {
 #ifdef ISICOM_DEBUG		    
 		 	printk(KERN_DEBUG "ISICOM: block_til_ready: do_clocal || DCD.\n");   
@@ -1070,17 +1033,12 @@
 		return error;
 		
 	if ((port->count == 1) && (port->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = port->normal_termios;
-		else 
-			*tty->termios = port->callout_termios;
+		*tty->termios = port->normal_termios;
 		save_flags(flags); cli();
 		isicom_config_port(port);
 		restore_flags(flags);		
 	}	
 	
-	port->session = current->session;	
-	port->pgrp = current->pgrp;
 #ifdef ISICOM_DEBUG	
 	printk(KERN_DEBUG "ISICOM: open end!!!.\n");
 #endif	
@@ -1180,8 +1138,6 @@
 	 */	
 	if (port->flags & ASYNC_NORMAL_ACTIVE)
 		port->normal_termios = *tty->termios;
-	if (port->flags & ASYNC_CALLOUT_ACTIVE)
-		port->callout_termios = *tty->termios;
 	
 	tty->closing = 1;
 	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
@@ -1209,8 +1165,7 @@
 		}
 		wake_up_interruptible(&port->open_wait);
 	}	
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE | 
-			ASYNC_CLOSING);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
 	wake_up_interruptible(&port->close_wait);
 	restore_flags(flags);
 #ifdef ISICOM_DEBUG	
@@ -1651,7 +1606,7 @@
 	
 	isicom_shutdown_port(port);
 	port->count = 0;
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
+	port->flags &= ~ASYNC_NORMAL_ACTIVE;
 	port->tty = 0;
 	wake_up_interruptible(&port->open_wait);
 }
@@ -1743,32 +1698,17 @@
 	isicom_normal.hangup	= isicom_hangup;
 	isicom_normal.flush_buffer	= isicom_flush_buffer;
 	
-	/*	callout device	*/
-	
-	isicom_callout	= isicom_normal;
-	isicom_callout.name	= "cum"; 
-	isicom_callout.major	= ISICOM_CMAJOR;
-	isicom_callout.subtype	= SERIAL_TYPE_CALLOUT;
-	
 	if ((error=tty_register_driver(&isicom_normal))!=0) {
 		printk(KERN_DEBUG "ISICOM: Couldn't register the dialin driver, error=%d\n",
 			error);
 		return error;
 	}
-	if ((error=tty_register_driver(&isicom_callout))!=0) {
-		tty_unregister_driver(&isicom_normal);
-		printk(KERN_DEBUG "ISICOM: Couldn't register the callout driver, error=%d\n",
-			error);
-		return error;	
-	}
 	return 0;
 }
 
 static void unregister_drivers(void)
 {
 	int error;
-	if ((error=tty_unregister_driver(&isicom_callout))!=0)
-		printk(KERN_DEBUG "ISICOM: couldn't unregister callout driver error=%d.\n",error);
 	if (tty_unregister_driver(&isicom_normal))
 		printk(KERN_DEBUG "ISICOM: couldn't unregister normal driver error=%d.\n",error);
 }
@@ -1897,7 +1837,6 @@
 			port->card = &isi_card[card];
 			port->channel = channel;		
 			port->normal_termios = isicom_normal.init_termios;
-			port->callout_termios = isicom_callout.init_termios;
 		 	port->close_delay = 50 * HZ/100;
 		 	port->closing_wait = 3000 * HZ/100;
 			port->hangup_tq.routine = do_isicom_hangup;
diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c
--- a/drivers/char/istallion.c	Wed May  7 23:16:25 2003
+++ b/drivers/char/istallion.c	Mon May 26 15:29:26 2003
@@ -159,9 +159,6 @@
 #define	STL_CALLOUTMAJOR	25
 #endif
 
-#define	STL_DRVTYPSERIAL	1
-#define	STL_DRVTYPCALLOUT	2
-
 /*****************************************************************************/
 
 /*
@@ -172,10 +169,8 @@
 static char	*stli_drvname = "istallion";
 static char	*stli_drvversion = "5.6.0";
 static char	*stli_serialname = "ttyE";
-static char	*stli_calloutname = "cue";
 
 static struct tty_driver	stli_serial;
-static struct tty_driver	stli_callout;
 static struct tty_struct	*stli_ttys[STL_MAXDEVS];
 static struct termios		*stli_termios[STL_MAXDEVS];
 static struct termios		*stli_termioslocked[STL_MAXDEVS];
@@ -857,10 +852,9 @@
 	}
 
 	i = tty_unregister_driver(&stli_serial);
-	j = tty_unregister_driver(&stli_callout);
-	if (i || j) {
+	if (i) {
 		printk("STALLION: failed to un-register tty driver, "
-			"errno=%d,%d\n", -i, -j);
+			"errno=%d,%d\n", -i);
 		restore_flags(flags);
 		return;
 	}
@@ -1114,39 +1108,16 @@
  *	previous opens still in effect. If we are a normal serial device
  *	then also we might have to wait for carrier.
  */
-	if (tty->driver->subtype == STL_DRVTYPCALLOUT) {
-		if (portp->flags & ASYNC_NORMAL_ACTIVE)
-			return(-EBUSY);
-		if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
-			if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
-			    (portp->session != current->session))
-				return(-EBUSY);
-			if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
-			    (portp->pgrp != current->pgrp))
-				return(-EBUSY);
-		}
-		portp->flags |= ASYNC_CALLOUT_ACTIVE;
-	} else {
-		if (filp->f_flags & O_NONBLOCK) {
-			if (portp->flags & ASYNC_CALLOUT_ACTIVE)
-				return(-EBUSY);
-		} else {
-			if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
-				return(rc);
-		}
-		portp->flags |= ASYNC_NORMAL_ACTIVE;
+	if (!(filp->f_flags & O_NONBLOCK)) {
+		if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
+			return(rc);
 	}
+	portp->flags |= ASYNC_NORMAL_ACTIVE;
 
 	if ((portp->refcount == 1) && (portp->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == STL_DRVTYPSERIAL)
-			*tty->termios = portp->normaltermios;
-		else
-			*tty->termios = portp->callouttermios;
+		*tty->termios = portp->normaltermios;
 		stli_setport(portp);
 	}
-
-	portp->session = current->session;
-	portp->pgrp = current->pgrp;
 	return(0);
 }
 
@@ -1183,8 +1154,6 @@
 
 	if (portp->flags & ASYNC_NORMAL_ACTIVE)
 		portp->normaltermios = *tty->termios;
-	if (portp->flags & ASYNC_CALLOUT_ACTIVE)
-		portp->callouttermios = *tty->termios;
 
 /*
  *	May want to wait for data to drain before closing. The BUSY flag
@@ -1226,8 +1195,7 @@
 		wake_up_interruptible(&portp->open_wait);
 	}
 
-	portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE |
-		ASYNC_CLOSING);
+	portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&portp->close_wait);
 	restore_flags(flags);
 }
@@ -1558,13 +1526,8 @@
 	rc = 0;
 	doclocal = 0;
 
-	if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (portp->normaltermios.c_cflag & CLOCAL)
-			doclocal++;
-	} else {
-		if (portp->tty->termios->c_cflag & CLOCAL)
-			doclocal++;
-	}
+	if (portp->tty->termios->c_cflag & CLOCAL)
+		doclocal++;
 
 	save_flags(flags);
 	cli();
@@ -1573,12 +1536,10 @@
 		portp->refcount--;
 
 	for (;;) {
-		if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) {
-			stli_mkasysigs(&portp->asig, 1, 1);
-			if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
-			    &portp->asig, sizeof(asysigs_t), 0)) < 0)
-				break;
-		}
+		stli_mkasysigs(&portp->asig, 1, 1);
+		if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
+		    &portp->asig, sizeof(asysigs_t), 0)) < 0)
+			break;
 		if (tty_hung_up_p(filp) ||
 		    ((portp->flags & ASYNC_INITIALIZED) == 0)) {
 			if (portp->flags & ASYNC_HUP_NOTIFY)
@@ -1587,8 +1548,7 @@
 				rc = -ERESTARTSYS;
 			break;
 		}
-		if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
-		    ((portp->flags & ASYNC_CLOSING) == 0) &&
+		if (((portp->flags & ASYNC_CLOSING) == 0) &&
 		    (doclocal || (portp->sigs & TIOCM_CD))) {
 			break;
 		}
@@ -2420,7 +2380,7 @@
 	clear_bit(ST_RXSTOP, &portp->state);
 	set_bit(TTY_IO_ERROR, &tty->flags);
 	portp->tty = (struct tty_struct *) NULL;
-	portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
+	portp->flags &= ~ASYNC_NORMAL_ACTIVE;
 	portp->refcount = 0;
 	wake_up_interruptible(&portp->open_wait);
 }
@@ -2996,12 +2956,8 @@
 			if ((oldsigs & TIOCM_CD) &&
 			    ((portp->sigs & TIOCM_CD) == 0)) {
 				if (portp->flags & ASYNC_CHECK_CD) {
-					if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
-					    (portp->flags & ASYNC_CALLOUT_NOHUP))) {
-						if (tty != (struct tty_struct *) NULL) {
-							schedule_task(&portp->tqhangup);
-						}
-					}
+					if (tty)
+						schedule_task(&portp->tqhangup);
 				}
 			}
 		}
@@ -3370,7 +3326,6 @@
 		init_waitqueue_head(&portp->close_wait);
 		init_waitqueue_head(&portp->raw_wait);
 		portp->normaltermios = stli_deftermios;
-		portp->callouttermios = stli_deftermios;
 		panelport++;
 		if (panelport >= brdp->panels[panelnr]) {
 			panelport = 0;
@@ -5336,7 +5291,6 @@
 
 /*
  *	Set up the tty driver structure and register us as a driver.
- *	Also setup the callout tty device.
  */
 	memset(&stli_serial, 0, sizeof(struct tty_driver));
 	stli_serial.magic = TTY_DRIVER_MAGIC;
@@ -5347,7 +5301,7 @@
 	stli_serial.minor_start = 0;
 	stli_serial.num = STL_MAXBRDS * STL_MAXPORTS;
 	stli_serial.type = TTY_DRIVER_TYPE_SERIAL;
-	stli_serial.subtype = STL_DRVTYPSERIAL;
+	stli_serial.subtype = SERIAL_TYPE_NORMAL;
 	stli_serial.init_termios = stli_deftermios;
 	stli_serial.flags = TTY_DRIVER_REAL_RAW;
 	stli_serial.refcount = &stli_refcount;
@@ -5375,17 +5329,8 @@
 	stli_serial.send_xchar = stli_sendxchar;
 	stli_serial.read_proc = stli_readproc;
 
-	stli_callout = stli_serial;
-	stli_callout.name = stli_calloutname;
-	stli_callout.major = STL_CALLOUTMAJOR;
-	stli_callout.subtype = STL_DRVTYPCALLOUT;
-	stli_callout.read_proc = 0;
-
 	if (tty_register_driver(&stli_serial))
 		printk(KERN_ERR "STALLION: failed to register serial driver\n");
-	if (tty_register_driver(&stli_callout))
-		printk(KERN_ERR "STALLION: failed to register callout driver\n");
-
 	return(0);
 }
 
diff -Nru a/drivers/char/moxa.c b/drivers/char/moxa.c
--- a/drivers/char/moxa.c	Wed May  7 07:24:21 2003
+++ b/drivers/char/moxa.c	Mon May 26 15:29:17 2003
@@ -151,12 +151,9 @@
 	int blocked_open;
 	long event; /* long req'd for set_bit --RR */
 	int asyncflags;
-	long session;
-	long pgrp;
 	unsigned long statusflags;
 	struct tty_struct *tty;
 	struct termios normal_termios;
-	struct termios callout_termios;
 	wait_queue_head_t open_wait;
 	wait_queue_head_t close_wait;
 	struct work_struct tqueue;
@@ -185,7 +182,6 @@
 
 
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 
 #define WAKEUP_CHARS		256
 
@@ -193,7 +189,6 @@
 
 static int verbose = 0;
 static int ttymajor = MOXAMAJOR;
-static int calloutmajor = MOXACUMAJOR;
 #ifdef MODULE
 /* Variables for insmod */
 static int baseaddr[] 	= 	{0, 0, 0, 0};
@@ -207,13 +202,11 @@
 MODULE_PARM(baseaddr, "1-4i");
 MODULE_PARM(numports, "1-4i");
 MODULE_PARM(ttymajor, "i");
-MODULE_PARM(calloutmajor, "i");
 MODULE_PARM(verbose, "i");
 
 #endif				//MODULE
 
 static struct tty_driver moxaDriver;
-static struct tty_driver moxaCallout;
 static struct tty_struct *moxaTable[MAX_PORTS + 1];
 static struct termios *moxaTermios[MAX_PORTS + 1];
 static struct termios *moxaTermiosLocked[MAX_PORTS + 1];
@@ -319,8 +312,6 @@
 		if (moxaEmptyTimer_on[i])
 			del_timer(&moxaEmptyTimer[i]);
 
-	if (tty_unregister_driver(&moxaCallout))
-		printk("Couldn't unregister MOXA Intellio family callout driver\n");
 	if (tty_unregister_driver(&moxaDriver))
 		printk("Couldn't unregister MOXA Intellio family serial driver\n");
 	if (verbose)
@@ -339,7 +330,6 @@
 
 	init_MUTEX(&moxaBuffSem);
 	memset(&moxaDriver, 0, sizeof(struct tty_driver));
-	memset(&moxaCallout, 0, sizeof(struct tty_driver));
 	moxaDriver.magic = TTY_DRIVER_MAGIC;
 	moxaDriver.owner = THIS_MODULE;
 	moxaDriver.name = "ttya";
@@ -375,11 +365,6 @@
 	moxaDriver.start = moxa_start;
 	moxaDriver.hangup = moxa_hangup;
 
-	moxaCallout = moxaDriver;
-	moxaCallout.name = "ttyA";
-	moxaCallout.major = calloutmajor;
-	moxaCallout.subtype = SERIAL_TYPE_CALLOUT;
-
 	moxaXmitBuff = 0;
 
 	for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {
@@ -391,7 +376,6 @@
 		ch->closing_wait = 30 * HZ;
 		ch->count = 0;
 		ch->blocked_open = 0;
-		ch->callout_termios = moxaCallout.init_termios;
 		ch->normal_termios = moxaDriver.init_termios;
 		init_waitqueue_head(&ch->open_wait);
 		init_waitqueue_head(&ch->close_wait);
@@ -406,17 +390,10 @@
 		moxa_boards[i].pciInfo.devNum = 0;
 	}
 	MoxaDriverInit();
-	printk("Tty devices major number = %d, callout devices major number = %d\n", ttymajor, calloutmajor);
+	printk("Tty devices major number = %d\n", ttymajor);
 
-	ret1 = 0;
-	ret2 = 0;
-	if ((ret1 = tty_register_driver(&moxaDriver))) {
+	if (tty_register_driver(&moxaDriver)) {
 		printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
-	} else if ((ret2 = tty_register_driver(&moxaCallout))) {
-		tty_unregister_driver(&moxaDriver);
-		printk(KERN_ERR "Couldn't install MOXA Smartio family callout driver !\n");
-	}
-	if (ret1 || ret2) {
 		return -1;
 	}
 	for (i = 0; i < MAX_PORTS; i++) {
@@ -542,7 +519,7 @@
 		if (test_and_clear_bit(MOXA_EVENT_HANGUP, &ch->event)) {
 			tty_hangup(tty);	/* FIXME: module removal race here - AKPM */
 			wake_up_interruptible(&ch->open_wait);
-			ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
+			ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
 		}
 	}
 }
@@ -583,13 +560,8 @@
 	tty->driver_data = ch;
 	ch->tty = tty;
 	if (ch->count == 1 && (ch->asyncflags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = ch->normal_termios;
-		else
-			*tty->termios = ch->callout_termios;
+		*tty->termios = ch->normal_termios;
 	}
-	ch->session = current->session;
-	ch->pgrp = current->pgrp;
 	if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
 		ch->statusflags = 0;
 		set_tty_param(tty);
@@ -655,8 +627,6 @@
 	 */
 	if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
 		ch->normal_termios = *tty->termios;
-	if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
-		ch->callout_termios = *tty->termios;
 	if (ch->asyncflags & ASYNC_INITIALIZED) {
 		setup_empty_event(tty);
 		tty_wait_until_sent(tty, 30 * HZ);	/* 30 seconds timeout */
@@ -680,8 +650,7 @@
 		}
 		wake_up_interruptible(&ch->open_wait);
 	}
-	ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE |
-			    ASYNC_CLOSING);
+	ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
 	wake_up_interruptible(&ch->close_wait);
 }
 
@@ -963,7 +932,7 @@
 	shut_down(ch);
 	ch->event = 0;
 	ch->count = 0;
-	ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
+	ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
 	ch->tty = 0;
 	wake_up_interruptible(&ch->open_wait);
 }
@@ -1083,30 +1052,10 @@
 #endif
 	}
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
-			return (-EBUSY);
-		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
-		    (ch->asyncflags & ASYNC_SESSION_LOCKOUT) &&
-		    (ch->session != current->session))
-			return (-EBUSY);
-		if ((ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
-		    (ch->asyncflags & ASYNC_PGRP_LOCKOUT) &&
-		    (ch->pgrp != current->pgrp))
-			return (-EBUSY);
-		ch->asyncflags |= ASYNC_CALLOUT_ACTIVE;
-		return (0);
-	}
-	/*
 	 * If non-blocking mode is set, then make the check up front
 	 * and then exit.
 	 */
 	if (filp->f_flags & O_NONBLOCK) {
-		if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
-			return (-EBUSY);
 		ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
 		return (0);
 	}
@@ -1139,8 +1088,7 @@
 #endif
 			break;
 		}
-		if (!(ch->asyncflags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
+		if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
 						MoxaPortDCDON(ch->port)))
 			break;
 
@@ -1717,7 +1665,8 @@
 			return -EFAULT;
 		return 0;
 	case MOXA_GET_CUMAJOR:
-		if(copy_to_user((void *)arg, &calloutmajor, sizeof(int)))
+		i = 0;
+		if(copy_to_user((void *)arg, &i, sizeof(int)))
 			return -EFAULT;
 		return 0;
 	case MOXA_GETMSTATUS:
diff -Nru a/drivers/char/mxser.c b/drivers/char/mxser.c
--- a/drivers/char/mxser.c	Wed May  7 07:24:11 2003
+++ b/drivers/char/mxser.c	Mon May 26 15:29:16 2003
@@ -87,7 +87,6 @@
 #define		MXSER_ERR_VECTOR	-4
 
 #define 	SERIAL_TYPE_NORMAL	1
-#define 	SERIAL_TYPE_CALLOUT	2
 
 #define 	WAKEUP_CHARS		256
 
@@ -208,7 +207,6 @@
 
 static int ioaddr[MXSER_BOARDS];
 static int ttymajor = MXSERMAJOR;
-static int calloutmajor = MXSERCUMAJOR;
 static int verbose;
 
 /* Variables for insmod */
@@ -218,7 +216,6 @@
 MODULE_LICENSE("GPL");
 MODULE_PARM(ioaddr, "1-4i");
 MODULE_PARM(ttymajor, "i");
-MODULE_PARM(calloutmajor, "i");
 MODULE_PARM(verbose, "i");
 
 struct mxser_hwconf {
@@ -256,15 +253,12 @@
 	unsigned long event;
 	int count;		/* # of fd on device */
 	int blocked_open;	/* # of blocked opens */
-	long session;		/* Session of opening process */
-	long pgrp;		/* pgrp of opening process */
 	unsigned char *xmit_buf;
 	int xmit_head;
 	int xmit_tail;
 	int xmit_cnt;
 	struct work_struct tqueue;
 	struct termios normal_termios;
-	struct termios callout_termios;
 	wait_queue_head_t open_wait;
 	wait_queue_head_t close_wait;
 	wait_queue_head_t delta_msr_wait;
@@ -294,7 +288,7 @@
 };
 
 
-static struct tty_driver mxvar_sdriver, mxvar_cdriver;
+static struct tty_driver mxvar_sdriver;
 static int mxvar_refcount;
 static struct mxser_struct mxvar_table[MXSER_PORTS];
 static struct tty_struct *mxvar_tty[MXSER_PORTS + 1];
@@ -374,8 +368,6 @@
 
 	if (verbose)
 		printk("Unloading module mxser ...\n");
-	if ((err |= tty_unregister_driver(&mxvar_cdriver)))
-		printk("Couldn't unregister MOXA Smartio family callout driver\n");
 	if ((err |= tty_unregister_driver(&mxvar_sdriver)))
 		printk("Couldn't unregister MOXA Smartio family serial driver\n");
 
@@ -428,7 +420,6 @@
 		info->close_delay = 5 * HZ / 10;
 		info->closing_wait = 30 * HZ;
 		INIT_WORK(&info->tqueue, mxser_do_softint, info);
-		info->callout_termios = mxvar_cdriver.init_termios;
 		info->normal_termios = mxvar_sdriver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
@@ -532,16 +523,7 @@
 	mxvar_sdriver.start = mxser_start;
 	mxvar_sdriver.hangup = mxser_hangup;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	mxvar_cdriver = mxvar_sdriver;
-	mxvar_cdriver.name = "cum";
-	mxvar_cdriver.major = calloutmajor;
-	mxvar_cdriver.subtype = SERIAL_TYPE_CALLOUT;
-
-	printk("Tty devices major number = %d, callout devices major number = %d\n", ttymajor, calloutmajor);
+	printk("Tty devices major number = %d\n", ttymajor);
 
 	mxvar_diagflag = 0;
 	memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
@@ -666,30 +648,17 @@
 	}
 
 
-	ret1 = 0;
-	ret2 = 0;
-	if (!(ret1 = tty_register_driver(&mxvar_sdriver))) {
-		if (!(ret2 = tty_register_driver(&mxvar_cdriver))) {
-			return 0;
-		} else {
-			tty_unregister_driver(&mxvar_sdriver);
-			printk("Couldn't install MOXA Smartio family callout driver !\n");
-		}
-	} else
-		printk("Couldn't install MOXA Smartio family driver !\n");
+	if (!tty_register_driver(&mxvar_sdriver))
+		return 0;
 
+	printk("Couldn't install MOXA Smartio family driver !\n");
 
-	if (ret1 || ret2) {
-		for (i = 0; i < MXSER_BOARDS; i++) {
-			if (mxsercfg[i].board_type == -1)
-				continue;
-			else {
-				free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
-			}
-		}
-		return -1;
+	for (i = 0; i < MXSER_BOARDS; i++) {
+		if (mxsercfg[i].board_type == -1)
+			continue;
+		free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
 	}
-	return (0);
+	return -1;
 }
 
 static void mxser_do_softint(void *private_)
@@ -758,15 +727,9 @@
 		return (retval);
 
 	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		mxser_change_speed(info, 0);
 	}
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 	return (0);
 }
 
@@ -823,8 +786,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
@@ -872,8 +833,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE |
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	restore_flags(flags);
 
@@ -1154,7 +1114,8 @@
 		return 0;
 
 	case MOXA_GET_CUMAJOR:
-		if(copy_to_user((int *) arg, &calloutmajor, sizeof(int)))
+		result = 0;
+		if(copy_to_user((int *) arg, &result, sizeof(int)))
 			return -EFAULT;
 		return 0;
 
@@ -1349,7 +1310,7 @@
 	mxser_shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1513,8 +1474,7 @@
 	if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP)))
+		else
 			set_bit(MXSER_EVENT_HANGUP, &info->event);
 		schedule_work(&info->tqueue);
 	}
@@ -1563,41 +1523,16 @@
 #endif
 	}
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return (-EBUSY);
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-			return (-EBUSY);
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-			return (-EBUSY);
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return (0);
-	}
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return (-EBUSY);
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return (0);
 	}
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 
 	/*
 	 * Block waiting for the carrier detect and the line to become
@@ -1617,9 +1552,8 @@
 	while (1) {
 		save_flags(flags);
 		cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE))
-			outb(inb(info->base + UART_MCR) | UART_MCR_DTR | UART_MCR_RTS,
-			     info->base + UART_MCR);
+		outb(inb(info->base + UART_MCR) | UART_MCR_DTR | UART_MCR_RTS,
+		     info->base + UART_MCR);
 		restore_flags(flags);
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)) {
@@ -1633,8 +1567,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (inb(info->base + UART_MSR) & UART_MSR_DCD)))
 			break;
 		if (signal_pending(current)) {
diff -Nru a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
--- a/drivers/char/pcmcia/synclink_cs.c	Wed May 14 23:44:02 2003
+++ b/drivers/char/pcmcia/synclink_cs.c	Mon May 26 15:29:14 2003
@@ -155,14 +155,11 @@
 	struct mgsl_icount	icount;
 	
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	
 	struct tty_struct 	*tty;
 	int			timeout;
 	int			x_char;		/* xon/xoff character */
 	int			blocked_open;	/* # of blocked opens */
-	long			session;	/* Session of opening process */
-	long			pgrp;		/* pgrp of opening process */
 	unsigned char		read_status_mask;
 	unsigned char		ignore_status_mask;	
 
@@ -500,7 +497,7 @@
 static char *driver_name = "SyncLink PC Card driver";
 static char *driver_version = "$Revision: 4.10 $";
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* number of characters left in xmit buffer before we ask for more */
@@ -617,8 +614,7 @@
     memset(serial_table,0,sizeof(struct tty_struct*)*MAX_DEVICE_COUNT);
     memset(serial_termios,0,sizeof(struct termios*)*MAX_DEVICE_COUNT);
     memset(serial_termios_locked,0,sizeof(struct termios*)*MAX_DEVICE_COUNT);
-		
-    info->callout_termios = callout_driver.init_termios;
+
     info->normal_termios  = serial_driver.init_termios;
 
     return link;
@@ -1307,7 +1303,7 @@
 			       (info->serial_signals & SerialSignal_DCD) ? "on" : "off");
 		if (info->serial_signals & SerialSignal_DCD)
 			wake_up_interruptible(&info->open_wait);
-		else if (!(info->flags & (ASYNC_CALLOUT_ACTIVE | ASYNC_CALLOUT_NOHUP))) {
+		else if (!(info->flags & ASYNC_CALLOUT_NOHUP)) {
 			if (debug_level >= DEBUG_LEVEL_ISR)
 				printk("doing serial hangup...");
 			if (info->tty)
@@ -2589,9 +2585,7 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
-		
+
 	/* set tty->closing to notify line discipline to 
 	 * only process XON/XOFF characters. Only the N_TTY
 	 * discipline appears to use this (ppp does not).
@@ -2629,8 +2623,7 @@
 		wake_up_interruptible(&info->open_wait);
 	}
 	
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 			 
 	wake_up_interruptible(&info->close_wait);
 	
@@ -2723,7 +2716,7 @@
 	shutdown(info);
 	
 	info->count = 0;	
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 
 	wake_up_interruptible(&info->open_wait);
@@ -2744,40 +2737,16 @@
 		printk("%s(%d):block_til_ready on %s\n",
 			 __FILE__,__LINE__, tty->driver->name );
 
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		/* this is a callout device */
-		/* just verify that normal device is not in use */
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
 	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
 		/* nonblock mode is set or port is not enabled */
 		/* just verify that callout device is not active */
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/* Wait for carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
 	 * this loop, info->count is dropped by one, so that
@@ -2801,8 +2770,7 @@
 	info->blocked_open++;
 	
 	while (1) {
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    (tty->termios->c_cflag & CBAUD)) {
+		if ((tty->termios->c_cflag & CBAUD)) {
 			spin_lock_irqsave(&info->lock,flags);
 			info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
 		 	set_signals(info);
@@ -2821,8 +2789,7 @@
 	 	get_signals(info);
 		spin_unlock_irqrestore(&info->lock,flags);
 		
- 		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    !(info->flags & ASYNC_CLOSING) &&
+ 		if (!(info->flags & ASYNC_CLOSING) &&
  		    (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
  			break;
 		}
@@ -2926,16 +2893,10 @@
 
 	if ((info->count == 1) &&
 	    info->flags & ASYNC_SPLIT_TERMIOS) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		mgslpc_change_params(info);
 	}
 	
-	info->session = current->session;
-	info->pgrp    = current->pgrp;
-
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):mgslpc_open(%s) success\n",
 			 __FILE__,__LINE__, info->device_name);
@@ -3232,28 +3193,13 @@
     serial_driver.tiocmget = tiocmget;
     serial_driver.tiocmset = tiocmset;
 	
-    /*
-     * The callout device is just like normal device except for
-     * major number and the subtype code.
-     */
-    callout_driver = serial_driver;
-    callout_driver.name = "cuaSLP";
-    callout_driver.major = cuamajor;
-    callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-    callout_driver.read_proc = 0;
-    callout_driver.proc_entry = 0;
-
     if (tty_register_driver(&serial_driver) < 0)
 	    printk("%s(%d):Couldn't register serial driver\n",
 		   __FILE__,__LINE__);
 			
-    if (tty_register_driver(&callout_driver) < 0)
-	    printk("%s(%d):Couldn't register callout driver\n",
-		   __FILE__,__LINE__);
-
-    printk("%s %s, tty major#%d callout major#%d\n",
+    printk("%s %s, tty major#%d\n",
 	   driver_name, driver_version,
-	   serial_driver.major, callout_driver.major);
+	   serial_driver.major);
 	
     return 0;
 }
@@ -3269,9 +3215,6 @@
 
 	if ((rc = tty_unregister_driver(&serial_driver)))
 		printk("%s(%d) failed to unregister tty driver err=%d\n",
-		       __FILE__,__LINE__,rc);
-	if ((rc = tty_unregister_driver(&callout_driver)))
-		printk("%s(%d) failed to unregister callout driver err=%d\n",
 		       __FILE__,__LINE__,rc);
 
 	unregister_pccard_driver(&dev_info);
diff -Nru a/drivers/char/pcxx.c b/drivers/char/pcxx.c
--- a/drivers/char/pcxx.c	Wed May  7 07:24:09 2003
+++ b/drivers/char/pcxx.c	Mon May 26 15:29:16 2003
@@ -141,11 +141,9 @@
 
 #define FEPTIMEOUT 200000  
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 #define PCXE_EVENT_HANGUP   1
 
 struct tty_driver pcxe_driver;
-struct tty_driver pcxe_callout;
 static int pcxe_refcount;
 
 static struct timer_list pcxx_timer;
@@ -240,8 +238,6 @@
 
 	if ((e1 = tty_unregister_driver(&pcxe_driver)))
 		printk("SERIAL: failed to unregister serial driver (%d)\n", e1);
-	if ((e2 = tty_unregister_driver(&pcxe_callout)))
-		printk("SERIAL: failed to unregister callout driver (%d)\n",e2);
 
 	cleanup_board_resources();
 	kfree(digi_channels);
@@ -341,13 +337,8 @@
 	int	retval = 0;
 	int	do_clocal = 0;
 
-	if (info->asyncflags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 
 	/*
 	 * Block waiting for the carrier detect and the line to become free
@@ -360,12 +351,10 @@
 
 	for (;;) {
 		cli();
-		if ((info->asyncflags & ASYNC_CALLOUT_ACTIVE) == 0) {
-			globalwinon(info);
-			info->omodem |= DTR|RTS;
-			fepcmd(info, SETMODEM, DTR|RTS, 0, 10, 1);
-			memoff(info);
-		}
+		globalwinon(info);
+		info->omodem |= DTR|RTS;
+		fepcmd(info, SETMODEM, DTR|RTS, 0, 10, 1);
+		memoff(info);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if(tty_hung_up_p(filp) || (info->asyncflags & ASYNC_INITIALIZED) == 0) {
@@ -375,8 +364,7 @@
 				retval = -ERESTARTSYS;	
 			break;
 		}
-		if ((info->asyncflags & ASYNC_CALLOUT_ACTIVE) == 0 &&
-		    (info->asyncflags & ASYNC_CLOSING) == 0 &&
+		if ((info->asyncflags & ASYNC_CLOSING) == 0 &&
 			(do_clocal || (info->imodem & info->dcd)))
 			break;
 		if(signal_pending(current)) {
@@ -476,56 +464,29 @@
 		else
 			return -ERESTARTSYS;
 	}
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE) {
-			if ((ch->asyncflags & ASYNC_SESSION_LOCKOUT) &&
-		    		(ch->session != current->session))
-			    return -EBUSY;
-			if((ch->asyncflags & ASYNC_PGRP_LOCKOUT) &&
-			    (ch->pgrp != current->pgrp))
-			    return -EBUSY;
-		}
-		ch->asyncflags |= ASYNC_CALLOUT_ACTIVE;
-	}
-	else {
-		if (filp->f_flags & O_NONBLOCK) {
-			if(ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
-				return -EBUSY;
-		}
-		else {
-			/* this has to be set in order for the "block until
-			 * CD" code to work correctly.  i'm not sure under
-			 * what circumstances asyncflags should be set to
-			 * ASYNC_NORMAL_ACTIVE though
-			 * brian@ilinx.com
-			 */
-			ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
-			if ((retval = pcxx_waitcarrier(tty, filp, ch)) != 0)
-				return retval;
-		}
+
+	if (!(filp->f_flags & O_NONBLOCK)) {
+		/* this has to be set in order for the "block until
+		 * CD" code to work correctly.  i'm not sure under
+		 * what circumstances asyncflags should be set to
+		 * ASYNC_NORMAL_ACTIVE though
+		 * brian@ilinx.com
+		 */
 		ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+		if ((retval = pcxx_waitcarrier(tty, filp, ch)) != 0)
+			return retval;
 	}
+	ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
  	
 	save_flags(flags);
 	cli();
 	if((ch->count == 1) && (ch->asyncflags & ASYNC_SPLIT_TERMIOS)) {
-		if(tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = ch->normal_termios;
-		else 
-			*tty->termios = ch->callout_termios;
+		*tty->termios = ch->normal_termios;
 		globalwinon(ch);
 		pcxxparam(tty,ch);
 		memoff(ch);
 	}
 
-	ch->session = current->session;
-	ch->pgrp = current->pgrp;
 	restore_flags(flags);
 	return 0;
 } 
@@ -605,8 +566,6 @@
 		*/
 		if(info->asyncflags & ASYNC_NORMAL_ACTIVE)
 			info->normal_termios = *tty->termios;
-		if(info->asyncflags & ASYNC_CALLOUT_ACTIVE)
-			info->callout_termios = *tty->termios;
 		tty->closing = 1;
 		if(info->asyncflags & ASYNC_INITIALIZED) {
 			setup_empty_event(tty,info);		
@@ -644,8 +603,7 @@
 			}
 			wake_up_interruptible(&info->open_wait);
 		}
-		info->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|
-							  ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
+		info->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 		wake_up_interruptible(&info->close_wait);
 		restore_flags(flags);
 	}
@@ -665,7 +623,7 @@
 		ch->event = 0;
 		ch->count = 0;
 		ch->tty = NULL;
-		ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+		ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
 		wake_up_interruptible(&ch->open_wait);
 		restore_flags(flags);
 	}
@@ -1257,12 +1215,6 @@
 	pcxe_driver.start = pcxe_start;
 	pcxe_driver.hangup = pcxe_hangup;
 
-	pcxe_callout = pcxe_driver;
-	pcxe_callout.name = "cud";
-	pcxe_callout.major = DIGICU_MAJOR;
-	pcxe_callout.subtype = SERIAL_TYPE_CALLOUT;
-	pcxe_callout.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-
 	for(crd=0; crd < numcards; crd++) {
 		bd = &boards[crd];
 		outb(FEPRST, bd->port);
@@ -1619,7 +1571,6 @@
 			ch->close_delay = 50;
 			ch->count = 0;
 			ch->blocked_open = 0;
-			ch->callout_termios = pcxe_callout.init_termios;
 			ch->normal_termios = pcxe_driver.init_termios;
 			init_waitqueue_head(&ch->open_wait);
 			init_waitqueue_head(&ch->close_wait);
@@ -1651,12 +1602,6 @@
 		goto cleanup_boards;
 	}
 
-	ret = tty_register_driver(&pcxe_callout);
-	if(ret) {
-		printk(KERN_ERR "Couldn't register PC/Xe callout\n");
-		goto cleanup_pcxe_driver;
-	}
-
 	/*
 	 * Start up the poller to check for events on all enabled boards
 	 */
@@ -1760,7 +1705,7 @@
 
 		if (event & MODEMCHG_IND) {
 			ch->imodem = mstat;
-			if (ch->asyncflags & (ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE)) {
+			if (ch->asyncflags & ASYNC_NORMAL_ACTIVE) {
 				if (ch->asyncflags & ASYNC_CHECK_CD) {
 					if (mstat & ch->dcd) {
 						wake_up_interruptible(&ch->open_wait);
@@ -2377,7 +2322,7 @@
 			if(test_and_clear_bit(PCXE_EVENT_HANGUP, &info->event)) {
 				tty_hangup(tty);
 				wake_up_interruptible(&info->open_wait);
-				info->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+				info->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
 			}
 		}
 	}
diff -Nru a/drivers/char/pcxx.h b/drivers/char/pcxx.h
--- a/drivers/char/pcxx.h	Mon Feb  4 23:40:22 2002
+++ b/drivers/char/pcxx.h	Mon May 26 15:29:16 2003
@@ -68,7 +68,6 @@
 
 #define FEPTIMEOUT 200000  
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 #define PCXE_EVENT_HANGUP   1
 #define PCXX_MAGIC	0x5c6df104L
 
@@ -78,8 +77,6 @@
 	unchar						boardnum;
 	unchar						channelnum;
 	uint						dev;
-	long						session;
-	long						pgrp;
 	struct tty_struct			*tty;
 	struct board_info			*board;
 	volatile struct board_chan	*brdchan;
@@ -127,7 +124,6 @@
 	ulong						c_lflag;
 	ulong						c_oflag;
 	struct termios				normal_termios;
-	struct termios				callout_termios;
 	struct digi_struct			digiext;
 	ulong						dummy[8];
 };
diff -Nru a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
--- a/drivers/char/rio/rio_linux.c	Wed May  7 07:23:59 2003
+++ b/drivers/char/rio/rio_linux.c	Mon May 26 15:29:26 2003
@@ -111,18 +111,11 @@
 of boards in rio.h.  You'll have to allocate more majors if you need
 more than 512 ports.... */
 
-
-/* Why the hell am I defining these here? */
-#define RIO_TYPE_NORMAL 1
-#define RIO_TYPE_CALLOUT 2
-
 #ifndef RIO_NORMAL_MAJOR0
 /* This allows overriding on the compiler commandline, or in a "major.h" 
    include or something like that */
 #define RIO_NORMAL_MAJOR0  154
-#define RIO_CALLOUT_MAJOR0 155
 #define RIO_NORMAL_MAJOR1  156
-#define RIO_CALLOUT_MAJOR1 157
 #endif
 
 #ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8
@@ -208,8 +201,7 @@
 
 void my_hd (void *addr, int len);
 
-static struct tty_driver rio_driver, rio_callout_driver;
-static struct tty_driver rio_driver2, rio_callout_driver2;
+static struct tty_driver rio_driver, rio_driver2;
 
 static struct tty_struct * rio_table[RIO_NPORTS];
 static struct termios ** rio_termios;
@@ -889,7 +881,7 @@
   rio_driver.major = RIO_NORMAL_MAJOR0;
   rio_driver.num = 256;
   rio_driver.type = TTY_DRIVER_TYPE_SERIAL;
-  rio_driver.subtype = RIO_TYPE_NORMAL;
+  rio_driver.subtype = SERIAL_TYPE_NORMAL;
   rio_driver.init_termios = tty_std_termios;
   rio_driver.init_termios.c_cflag =
     B9600 | CS8 | CREAD | HUPCL | CLOCAL;
@@ -920,28 +912,14 @@
   rio_driver2.termios += 256;
   rio_driver2.termios_locked += 256;
 
-  rio_callout_driver = rio_driver;
-  rio_callout_driver.name = "cusr";
-  rio_callout_driver.major = RIO_CALLOUT_MAJOR0;
-  rio_callout_driver.subtype = RIO_TYPE_CALLOUT;
-
-  rio_callout_driver2 = rio_callout_driver;
-  rio_callout_driver2.major = RIO_CALLOUT_MAJOR1;
-  rio_callout_driver2.termios += 256;
-  rio_callout_driver2.termios_locked += 256;
-
   rio_dprintk (RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios);
 
   if ((error = tty_register_driver(&rio_driver))) goto bad1;
   if ((error = tty_register_driver(&rio_driver2))) goto bad2;
-  if ((error = tty_register_driver(&rio_callout_driver))) goto bad3;
-  if ((error = tty_register_driver(&rio_callout_driver2))) goto bad4;
 
   func_exit();
   return 0;
   /* 
- bad5:tty_unregister_driver (&rio_callout_driver2); */
- bad4:tty_unregister_driver (&rio_callout_driver);
  bad3:tty_unregister_driver (&rio_driver2);
  bad2:tty_unregister_driver (&rio_driver);
  bad1:printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n",
@@ -1006,7 +984,6 @@
     }
     rio_dprintk (RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped);
     port->PortNum = i;
-    port->gs.callout_termios = tty_std_termios;
     port->gs.normal_termios  = tty_std_termios;
     port->gs.magic = RIO_MAGIC;
     port->gs.close_delay = HZ/2;
@@ -1051,8 +1028,6 @@
 static void  __exit rio_release_drivers(void)
 {
   func_enter();
-  tty_unregister_driver (&rio_callout_driver2);
-  tty_unregister_driver (&rio_callout_driver);
   tty_unregister_driver (&rio_driver2);
   tty_unregister_driver (&rio_driver);
   func_exit();
diff -Nru a/drivers/char/riscom8.c b/drivers/char/riscom8.c
--- a/drivers/char/riscom8.c	Wed May  7 07:24:02 2003
+++ b/drivers/char/riscom8.c	Mon May 26 15:29:26 2003
@@ -83,11 +83,8 @@
 
 static DECLARE_TASK_QUEUE(tq_riscom);
 
-#define RISCOM_TYPE_NORMAL	1
-#define RISCOM_TYPE_CALLOUT	2
-
 static struct riscom_board * IRQ_to_board[16];
-static struct tty_driver riscom_driver, riscom_callout_driver;
+static struct tty_driver riscom_driver;
 static int    riscom_refcount;
 static struct tty_struct * riscom_table[RC_NBOARD * RC_NPORT];
 static struct termios * riscom_termios[RC_NBOARD * RC_NPORT];
@@ -550,10 +547,8 @@
 	if (mcr & MCR_CDCHG)  {
 		if (rc_in(bp, CD180_MSVR) & MSVR_CD) 
 			wake_up_interruptible(&port->open_wait);
-		else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (port->flags & ASYNC_CALLOUT_NOHUP))) {
+		else
 			schedule_task(&port->tqueue_hangup);
-		}
 	}
 	
 #ifdef RISCOM_BRAIN_DAMAGED_CTS
@@ -986,44 +981,18 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == RISCOM_TYPE_CALLOUT) {
-		if (port->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (port->session != current->session))
-		    return -EBUSY;
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (port->pgrp != current->pgrp))
-		    return -EBUSY;
-		port->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (port->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		port->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (port->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (port->normal_termios.c_cflag & CLOCAL) 
-			do_clocal = 1;
-	} else {
-		if (C_CLOCAL(tty))  
-			do_clocal = 1;
-	}
-	
+	if (C_CLOCAL(tty))  
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1042,11 +1011,9 @@
 		cli();
 		rc_out(bp, CD180_CAR, port_No(port));
 		CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE))  {
-			rc_out(bp, CD180_MSVR, MSVR_RTS);
-			bp->DTR &= ~(1u << port_No(port));
-			rc_out(bp, RC_DTR, bp->DTR);
-		}
+		rc_out(bp, CD180_MSVR, MSVR_RTS);
+		bp->DTR &= ~(1u << port_No(port));
+		rc_out(bp, RC_DTR, bp->DTR);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -1057,8 +1024,7 @@
 				retval = -ERESTARTSYS;	
 			break;
 		}
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(port->flags & ASYNC_CLOSING) &&
+		if (!(port->flags & ASYNC_CLOSING) &&
 		    (do_clocal || CD))
 			break;
 		if (signal_pending(current)) {
@@ -1110,18 +1076,11 @@
 		return error;
 	
 	if ((port->count == 1) && (port->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == RISCOM_TYPE_NORMAL)
-			*tty->termios = port->normal_termios;
-		else
-			*tty->termios = port->callout_termios;
+		*tty->termios = port->normal_termios;
 		save_flags(flags); cli();
 		rc_change_speed(bp, port);
 		restore_flags(flags);
 	}
-
-	port->session = current->session;
-	port->pgrp = current->pgrp;
-	
 	return 0;
 }
 
@@ -1161,8 +1120,6 @@
 	 */
 	if (port->flags & ASYNC_NORMAL_ACTIVE)
 		port->normal_termios = *tty->termios;
-	if (port->flags & ASYNC_CALLOUT_ACTIVE)
-		port->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1210,8 +1167,7 @@
 		}
 		wake_up_interruptible(&port->open_wait);
 	}
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&port->close_wait);
 out:	restore_flags(flags);
 }
@@ -1689,7 +1645,7 @@
 	rc_shutdown_port(bp, port);
 	port->event = 0;
 	port->count = 0;
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	port->flags &= ~ASYNC_NORMAL_ACTIVE;
 	port->tty = 0;
 	wake_up_interruptible(&port->open_wait);
 }
@@ -1757,7 +1713,7 @@
 	riscom_driver.major = RISCOM8_NORMAL_MAJOR;
 	riscom_driver.num = RC_NBOARD * RC_NPORT;
 	riscom_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	riscom_driver.subtype = RISCOM_TYPE_NORMAL;
+	riscom_driver.subtype = SERIAL_TYPE_NORMAL;
 	riscom_driver.init_termios = tty_std_termios;
 	riscom_driver.init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
@@ -1783,11 +1739,6 @@
 	riscom_driver.start = rc_start;
 	riscom_driver.hangup = rc_hangup;
 
-	riscom_callout_driver = riscom_driver;
-	riscom_callout_driver.name = "cul";
-	riscom_callout_driver.major = RISCOM8_CALLOUT_MAJOR;
-	riscom_callout_driver.subtype = RISCOM_TYPE_CALLOUT;
-	
 	if ((error = tty_register_driver(&riscom_driver)))  {
 		free_page((unsigned long)tmp_buf);
 		printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, "
@@ -1795,18 +1746,9 @@
 		       error);
 		return 1;
 	}
-	if ((error = tty_register_driver(&riscom_callout_driver)))  {
-		free_page((unsigned long)tmp_buf);
-		tty_unregister_driver(&riscom_driver);
-		printk(KERN_ERR "rc: Couldn't register RISCom/8 callout "
-				"driver, error = %d\n",
-		       error);
-		return 1;
-	}
-	
+
 	memset(rc_port, 0, sizeof(rc_port));
 	for (i = 0; i < RC_NPORT * RC_NBOARD; i++)  {
-		rc_port[i].callout_termios = riscom_callout_driver.init_termios;
 		rc_port[i].normal_termios  = riscom_driver.init_termios;
 		rc_port[i].magic = RISCOM8_MAGIC;
 		rc_port[i].tqueue.routine = do_softint;
@@ -1831,7 +1773,6 @@
 	remove_bh(RISCOM8_BH);
 	free_page((unsigned long)tmp_buf);
 	tty_unregister_driver(&riscom_driver);
-	tty_unregister_driver(&riscom_callout_driver);
 	restore_flags(flags);
 }
 
diff -Nru a/drivers/char/riscom8.h b/drivers/char/riscom8.h
--- a/drivers/char/riscom8.h	Tue Feb  5 09:40:05 2002
+++ b/drivers/char/riscom8.h	Mon May 26 15:29:11 2003
@@ -74,15 +74,12 @@
 	long			event; /* long req'd for set_bit --RR */
 	int			timeout;
 	int			close_delay;
-	long			session;
-	long			pgrp;
 	unsigned char 		* xmit_buf;
 	int			custom_divisor;
 	int			xmit_head;
 	int			xmit_tail;
 	int			xmit_cnt;
 	struct termios          normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 	struct tq_struct	tqueue;
diff -Nru a/drivers/char/rocket.c b/drivers/char/rocket.c
--- a/drivers/char/rocket.c	Wed May  7 07:23:51 2003
+++ b/drivers/char/rocket.c	Mon May 26 15:29:15 2003
@@ -120,7 +120,7 @@
 static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
 static void rp_flush_buffer(struct tty_struct *tty);
 
-static struct tty_driver rocket_driver, callout_driver;
+static struct tty_driver rocket_driver;
 static int rocket_refcount;
 
 static int rp_num_ports_open;
@@ -410,10 +410,7 @@
 		printk("ttyR%d CD now %s...", info->line,
 		       (ChanStatus & CD_ACT) ? "on" : "off");
 #endif
-		if (!(ChanStatus & CD_ACT) &&
-		    info->cd_status &&
-		    !((info->flags & ROCKET_CALLOUT_ACTIVE) &&
-		      (info->flags & ROCKET_CALLOUT_NOHUP))) {
+		if (!(ChanStatus & CD_ACT) && info->cd_status) {
 #ifdef ROCKET_DEBUG_HANGUP
 			printk("CD drop, calling hangup.\n");
 #endif
@@ -551,7 +548,6 @@
 	info->chan = chan;
 	info->closing_wait = 3000;
 	info->close_delay = 50;
-	info->callout_termios =callout_driver.init_termios;
 	info->normal_termios = rocket_driver.init_termios;
 	init_waitqueue_head(&info->open_wait);
 	init_waitqueue_head(&info->close_wait);
@@ -707,44 +703,18 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ROCKET_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ROCKET_CALLOUT_ACTIVE) &&
-		    (info->flags & ROCKET_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ROCKET_CALLOUT_ACTIVE) &&
-		    (info->flags & ROCKET_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ROCKET_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ROCKET_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ROCKET_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ROCKET_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -766,8 +736,7 @@
 	restore_flags(flags);
 	info->blocked_open++;
 	while (1) {
-		if (!(info->flags & ROCKET_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD)) {
+		if ((tty->termios->c_cflag & CBAUD)) {
 			sSetDTR(&info->channel);
 			sSetRTS(&info->channel);
 		}
@@ -780,8 +749,7 @@
 				retval = -ERESTARTSYS;	
 			break;
 		}
-		if (!(info->flags & ROCKET_CALLOUT_ACTIVE) &&
-		    !(info->flags & ROCKET_CLOSING) &&
+		if (!(info->flags & ROCKET_CLOSING) &&
 		    (do_clocal || (sGetChanStatusLo(&info->channel) &
 				   CD_ACT)))
 			break;
@@ -885,8 +853,6 @@
 	/*
 	 * Info->count is now 1; so it's safe to sleep now.
 	 */
-	info->session = current->session;
-	info->pgrp = current->pgrp;
 	
 	cp = &info->channel;
 	sSetRxTrigger(cp, TRIG_1);
@@ -943,10 +909,7 @@
 	}
 
 	if ((info->count == 1) && (info->flags & ROCKET_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		configure_r_port(info);
 	}
 
@@ -1001,8 +964,6 @@
 	 */
 	if (info->flags & ROCKET_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ROCKET_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	
 	cp = &info->channel;
 
@@ -1063,8 +1024,7 @@
 			info->xmit_buf = 0;
 		}
 	}
-	info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING |
-			 ROCKET_CALLOUT_ACTIVE | ROCKET_NORMAL_ACTIVE);
+	info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
 	tty->closing = 0;
 	wake_up_interruptible(&info->close_wait);
 	
@@ -1270,7 +1230,7 @@
 		return -EFAULT;
 	memset(&tmp, 0, sizeof(tmp));
 	tmp.tty_major = rocket_driver.major;
-	tmp.callout_major = callout_driver.major;
+	tmp.callout_major = 0;
 	for (board = 0; board < 4; board++) {
 		index = board << 5;
 		for (port = 0; port < 32; port++, index++) {
@@ -1503,7 +1463,7 @@
 	
 	xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
 	info->count = 0;
-	info->flags &= ~(ROCKET_NORMAL_ACTIVE|ROCKET_CALLOUT_ACTIVE);
+	info->flags &= ~ROCKET_NORMAL_ACTIVE;
 	info->tty = 0;
 
 	cp = &info->channel;
@@ -2041,28 +2001,6 @@
 	rocket_driver.send_xchar = rp_send_xchar;
 	rocket_driver.wait_until_sent = rp_wait_until_sent;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * the minor number and the subtype code.
-	 */
-	callout_driver = rocket_driver;
-#ifdef CONFIG_DEVFS_FS
-	callout_driver.name = "cua/R";
-#else
-	callout_driver.name = "cur";
-#endif
-	callout_driver.major = CUA_ROCKET_MAJOR;
-	callout_driver.minor_start = 0;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	
-	retval = tty_register_driver(&callout_driver);
-	if (retval < 0) {
-		printk("Couldn't install Rocketport callout driver "
-		       "(error %d)\n", -retval);
-		release_region(controller, 4);
-		return -1;
-	}
-
 	retval = tty_register_driver(&rocket_driver);
 	if (retval < 0) {
 		printk("Couldn't install tty Rocketport driver "
@@ -2071,8 +2009,8 @@
 		return -1;
 	}
 #ifdef ROCKET_DEBUG_OPEN
-	printk("Rocketport driver is major %d, callout is %d\n",
-	       rocket_driver.major, callout_driver.major);
+	printk("Rocketport driver is major %d\n",
+	       rocket_driver.major);
 #endif
 
 	return 0;
@@ -2092,11 +2030,6 @@
 
 	del_timer_sync(&rocket_timer);
 
-	retval = tty_unregister_driver(&callout_driver);
-	if (retval) {
-		printk("Error %d while trying to unregister "
-		       "rocketport callout driver\n", -retval);
-	}
 	retval = tty_unregister_driver(&rocket_driver);
 	if (retval) {
 		printk("Error %d while trying to unregister "
diff -Nru a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
--- a/drivers/char/rocket_int.h	Tue Feb 25 10:47:06 2003
+++ b/drivers/char/rocket_int.h	Mon May 26 15:29:16 2003
@@ -1135,14 +1135,11 @@
 	int			xmit_head;
 	int			xmit_tail;
 	int			xmit_cnt;
-	int			session;
-	int			pgrp;
 	int			cd_status;
 	int		        ignore_status_mask;
 	int			read_status_mask;
 	int			cps;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 };
@@ -1171,7 +1168,6 @@
  *
  */
 #define SERIAL_TYPE_NORMAL 1
-#define SERIAL_TYPE_CALLOUT 2
 
 /*
  * Assigned major numbers for the Comtrol Rocketport
diff -Nru a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
--- a/drivers/char/ser_a2232.c	Fri May  9 03:21:31 2003
+++ b/drivers/char/ser_a2232.c	Mon May 26 15:29:26 2003
@@ -172,7 +172,6 @@
 
 /* TTY driver structs */
 static struct tty_driver a2232_driver;
-static struct tty_driver a2232_callout_driver;
 
 /* Variables used by the TTY driver */
 static int a2232_refcount;
@@ -474,16 +473,10 @@
 	}
 
 	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)){
-		if (tty->driver->subtype == A2232_TTY_SUBTYPE_NORMAL)
-			*tty->termios = port->gs.normal_termios;
-		else 
-			*tty->termios = port->gs.callout_termios;
+		*tty->termios = port->gs.normal_termios;
 		a2232_set_real_termios (port);
 	}
 
-	port->gs.session = current->session;
-	port->gs.pgrp = current->pgrp;
-
 	a2232_enable_rx_interrupts(port);
 	
 	return 0;
@@ -649,18 +642,13 @@
 						if (!(port->gs.flags & ASYNC_CHECK_CD))
 							;	/* Don't report DCD changes */
 						else if (port->cd_status) { // if DCD on: DCD went UP!
-							if (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) ||
-							    ~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) {
-								/* Are we blocking in open?*/
-								wake_up_interruptible(&port->gs.open_wait);
-							}
+							
+							/* Are we blocking in open?*/
+							wake_up_interruptible(&port->gs.open_wait);
 						}
 						else { // if DCD off: DCD went DOWN!
-							if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) &&
-							      (port->gs.flags & ASYNC_CALLOUT_NOHUP))) {
-								if (port->gs.tty)
-									tty_hangup (port->gs.tty);
-							}
+							if (port->gs.tty)
+								tty_hangup (port->gs.tty);
 						}
 						
 					} // if CD changed for this port
@@ -686,7 +674,6 @@
 		port->which_a2232 = i/NUMLINES;
 		port->which_port_on_a2232 = i%NUMLINES;
 		port->disable_rx = port->throttle_input = port->cd_status = 0;
-		port->gs.callout_termios = tty_std_termios;
 		port->gs.normal_termios = tty_std_termios;
 		port->gs.magic = A2232_MAGIC;
 		port->gs.close_delay = HZ/2;
@@ -712,7 +699,7 @@
 	a2232_driver.major = A2232_NORMAL_MAJOR;
 	a2232_driver.num = NUMLINES * nr_a2232;
 	a2232_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	a2232_driver.subtype = A2232_TTY_SUBTYPE_NORMAL;
+	a2232_driver.subtype = SERIAL_TTY_NORMAL;
 	a2232_driver.init_termios = tty_std_termios;
 	a2232_driver.init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
@@ -738,22 +725,11 @@
 	a2232_driver.start = gs_start;
 	a2232_driver.hangup = gs_hangup;
 
-	a2232_callout_driver = a2232_driver;
-	a2232_callout_driver.name = "cuy";
-	a2232_callout_driver.major = A2232_CALLOUT_MAJOR;
-	a2232_callout_driver.subtype = A2232_TTY_SUBTYPE_CALLOUT;
-
 	if ((error = tty_register_driver(&a2232_driver))) {
 		printk(KERN_ERR "A2232: Couldn't register A2232 driver, error = %d\n",
 		       error);
 		return 1;
 	}
-	if ((error = tty_register_driver(&a2232_callout_driver))) {
-		tty_unregister_driver(&a2232_driver);
-		printk(KERN_ERR "A2232: Couldn't register A2232 callout driver, error = %d\n",
-		       error);
-		return 1;
-	}
 	return 0;
 }
 
@@ -865,7 +841,6 @@
 	}
 
 	tty_unregister_driver(&a2232_driver);
-	tty_unregister_driver(&a2232_callout_driver);
 	free_irq(IRQ_AMIGA_VERTB, a2232_driver_ID);
 }
 #endif
diff -Nru a/drivers/char/ser_a2232.h b/drivers/char/ser_a2232.h
--- a/drivers/char/ser_a2232.h	Tue Feb  5 11:10:31 2002
+++ b/drivers/char/ser_a2232.h	Mon May 26 15:29:26 2003
@@ -49,10 +49,6 @@
 /* Some magic is always good - Who knows :) */
 #define A2232_MAGIC 0x000a2232
 
-/* for the tty_struct subtype field */
-#define A2232_TTY_SUBTYPE_NORMAL	1
-#define A2232_TTY_SUBTYPE_CALLOUT	2
-
 /* A2232 port structure to keep track of the
    status of every single line used */
 struct a2232_port{
diff -Nru a/drivers/char/serial167.c b/drivers/char/serial167.c
--- a/drivers/char/serial167.c	Fri May  9 03:21:31 2003
+++ b/drivers/char/serial167.c	Mon May 26 15:29:15 2003
@@ -97,12 +97,10 @@
 #define STD_COM_FLAGS (0)
 
 #define SERIAL_TYPE_NORMAL  1
-#define SERIAL_TYPE_CALLOUT 2
-
 
 DECLARE_TASK_QUEUE(tq_cyclades);
 
-struct tty_driver cy_serial_driver, cy_callout_driver;
+struct tty_driver cy_serial_driver;
 extern int serial_console;
 static struct cyclades_port *serial_console_info = NULL;
 static unsigned int serial_console_cflag = 0;
@@ -517,8 +515,7 @@
 	    if(mdm_status & CyDCD){
 /* CP('!'); */
 		cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
-	    }else if(!((info->flags & ASYNC_CALLOUT_ACTIVE)
-		     &&(info->flags & ASYNC_CALLOUT_NOHUP))){
+	    } else {
 /* CP('@'); */
 		cy_sched_event(info, Cy_EVENT_HANGUP);
 	    }
@@ -769,8 +766,7 @@
     if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
 	tty_hangup(info->tty);
 	wake_up_interruptible(&info->open_wait);
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|
-			     ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
     }
     if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
 	wake_up_interruptible(&info->open_wait);
@@ -1912,8 +1908,6 @@
      */
     if (info->flags & ASYNC_NORMAL_ACTIVE)
 	info->normal_termios = *tty->termios;
-    if (info->flags & ASYNC_CALLOUT_ACTIVE)
-	info->callout_termios = *tty->termios;
     if (info->flags & ASYNC_INITIALIZED)
 	tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
     shutdown(info);
@@ -1938,8 +1932,7 @@
 	}
 	wake_up_interruptible(&info->open_wait);
     }
-    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-		     ASYNC_CLOSING);
+    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
     wake_up_interruptible(&info->close_wait);
 
 #ifdef SERIAL_DEBUG_OTHER
@@ -1973,7 +1966,7 @@
 #endif
     info->tty = 0;
 #endif
-    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+    info->flags &= ~ASYNC_NORMAL_ACTIVE;
     wake_up_interruptible(&info->open_wait);
 } /* cy_hangup */
 
@@ -2009,35 +2002,10 @@
     }
 
     /*
-     * If this is a callout device, then just make sure the normal
-     * device isn't being used.
-     */
-    if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-	if (info->flags & ASYNC_NORMAL_ACTIVE){
-	    return -EBUSY;
-	}
-	if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-	    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-	    (info->session != current->session)){
-	    return -EBUSY;
-	}
-	if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-	    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-	    (info->pgrp != current->pgrp)){
-	    return -EBUSY;
-	}
-	info->flags |= ASYNC_CALLOUT_ACTIVE;
-	return 0;
-    }
-
-    /*
      * If non-blocking mode is set, then make the check up front
      * and then exit.
      */
     if (filp->f_flags & O_NONBLOCK) {
-	if (info->flags & ASYNC_CALLOUT_ACTIVE){
-	    return -EBUSY;
-	}
 	info->flags |= ASYNC_NORMAL_ACTIVE;
 	return 0;
     }
@@ -2065,16 +2033,14 @@
 
     while (1) {
 	local_irq_save(flags);
-	    if (!(info->flags & ASYNC_CALLOUT_ACTIVE)){
-		base_addr[CyCAR] = (u_char)channel;
-		base_addr[CyMSVR1] = CyRTS;
+	base_addr[CyCAR] = (u_char)channel;
+	base_addr[CyMSVR1] = CyRTS;
 /* CP('S');CP('4'); */
-		base_addr[CyMSVR2] = CyDTR;
+	base_addr[CyMSVR2] = CyDTR;
 #ifdef SERIAL_DEBUG_DTR
-                printk("cyc: %d: raising DTR\n", __LINE__);
-                printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
+	printk("cyc: %d: raising DTR\n", __LINE__);
+	printk("     status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
 #endif
-	    }
 	local_irq_restore(flags);
 	set_current_state(TASK_INTERRUPTIBLE);
 	if (tty_hung_up_p(filp)
@@ -2089,8 +2055,7 @@
 	local_irq_save(flags);
 	    base_addr[CyCAR] = (u_char)channel;
 /* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */
-	    if (!(info->flags & ASYNC_CALLOUT_ACTIVE)
-	    && !(info->flags & ASYNC_CLOSING)
+	    if (!(info->flags & ASYNC_CLOSING)
 	    && (C_CLOCAL(tty)
 	        || (base_addr[CyMSVR1] & CyDCD))) {
 		    local_irq_restore(flags);
@@ -2169,10 +2134,7 @@
     }
 
     if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-	if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-	    *tty->termios = info->normal_termios;
-	else 
-	    *tty->termios = info->callout_termios;
+	*tty->termios = info->normal_termios;
     }
     /*
      * Start up serial port
@@ -2191,9 +2153,6 @@
 	return retval;
     }
 
-    info->session = current->session;
-    info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
     printk("cy_open done\n");/**/
 #endif
@@ -2434,29 +2393,11 @@
     cy_serial_driver.start = cy_start;
     cy_serial_driver.hangup = cy_hangup;
 
-    /*
-     * The callout device is just like normal device except for
-     * major number and the subtype code.
-     */
-    cy_callout_driver = cy_serial_driver;
-#ifdef CONFIG_DEVFS_FS
-    cy_callout_driver.name = "cua/";
-#else
-    cy_callout_driver.name = "cua";
-#endif
-    cy_callout_driver.major = TTYAUX_MAJOR;
-    cy_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
     ret = tty_register_driver(&cy_serial_driver);
     if (ret) {
 	    printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
 	    return ret;
     }
-    ret = tty_register_driver(&cy_callout_driver);
-    if (ret) {
-	    printk(KERN_ERR "Couldn't register MVME166/7 callout driver\n");
-	    goto cleanup_serial_driver;
-    }
 
     init_bh(CYCLADES_BH, do_cyclades_bh);
 
@@ -2499,7 +2440,6 @@
 		info->default_timeout = 0;
 		info->tqueue.routine = do_softint;
 		info->tqueue.data = info;
-		info->callout_termios =cy_callout_driver.init_termios;
 		info->normal_termios = cy_serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
@@ -2530,7 +2470,7 @@
 				"cd2401_errors", cd2401_rxerr_interrupt);
     if (ret) {
 	    printk(KERN_ERR "Could't get cd2401_errors IRQ");
-	    goto cleanup_callout_driver;
+	    goto cleanup_serial_driver;
     }
 
     ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
@@ -2569,9 +2509,6 @@
     free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
 cleanup_irq_cd2401_errors:
     free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
-cleanup_callout_driver:
-    if (tty_unregister_driver(&cy_callout_driver))
-	    printk(KERN_ERR "Couldn't unregister MVME166/7 callout driver\n");
 cleanup_serial_driver:
     if (tty_unregister_driver(&cy_serial_driver))
 	    printk(KERN_ERR "Couldn't unregister MVME166/7 serial driver\n");
@@ -2607,8 +2544,8 @@
              info->close_delay, info->event, info->count);
     printk("  x_char blocked_open = %x %x\n",
              info->x_char, info->blocked_open);
-    printk("  session pgrp open_wait = %lx %lx %lx\n",
-             info->session, info->pgrp, (long)info->open_wait);
+    printk("  open_wait = %lx %lx %lx\n",
+             (long)info->open_wait);
 
 
     local_irq_save(flags);
diff -Nru a/drivers/char/serial_tx3912.c b/drivers/char/serial_tx3912.c
--- a/drivers/char/serial_tx3912.c	Wed May  7 07:23:38 2003
+++ b/drivers/char/serial_tx3912.c	Mon May 26 15:29:12 2003
@@ -59,7 +59,7 @@
 /*
  * Structures and such for TTY sessions and usage counts
  */
-static struct tty_driver rs_driver, rs_callout_driver;
+static struct tty_driver rs_driver;
 static struct tty_struct * rs_table[TX3912_UART_NPORTS] = { NULL, };
 static struct termios ** rs_termios;
 static struct termios ** rs_termios_locked;
@@ -594,15 +594,10 @@
 	/* tty->low_latency = 1; */
 
 	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = port->gs.normal_termios;
-		else 
-			*tty->termios = port->gs.callout_termios;
+		*tty->termios = port->gs.normal_termios;
 		rs_set_real_termios (port);
 	}
 
-	port->gs.session = current->session;
-	port->gs.pgrp = current->pgrp;
 	func_exit();
 
 	/* Jim */
@@ -773,7 +768,6 @@
 	port = rs_ports;
 	for (i=0; i < TX3912_UART_NPORTS;i++) {
 		rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
-		port->gs.callout_termios = tty_std_termios;
 		port->gs.normal_termios	= tty_std_termios;
 		port->gs.magic = SERIAL_MAGIC;
 		port->gs.close_delay = HZ/2;
@@ -837,24 +831,11 @@
 	rs_driver.start = gs_start;
 	rs_driver.hangup = gs_hangup;
 
-	rs_callout_driver = rs_driver;
-	rs_callout_driver.name = "cua";
-	rs_callout_driver.major = TTYAUX_MAJOR;
-	rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	if ((error = tty_register_driver(&rs_driver))) {
 		printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
 		       error);
 		return 1;
 	}
-	if ((error = tty_register_driver(&rs_callout_driver))) {
-		tty_unregister_driver(&rs_driver);
-		printk(KERN_ERR "Couldn't register callout driver, error = %d\n",
-		       error);
-		return 1;
-	}
-
-	func_exit();
 	return 0;
 }
 
diff -Nru a/drivers/char/sh-sci.c b/drivers/char/sh-sci.c
--- a/drivers/char/sh-sci.c	Wed May  7 07:23:41 2003
+++ b/drivers/char/sh-sci.c	Mon May 26 15:29:11 2003
@@ -76,7 +76,7 @@
 static void sci_free_irq(struct sci_port *port);
 static int sci_init_drivers(void);
 
-static struct tty_driver sci_driver, sci_callout_driver;
+static struct tty_driver sci_driver;
 
 static struct sci_port sci_ports[SCI_NPORTS] = SCI_INIT;
 static struct tty_struct *sci_table[SCI_NPORTS] = { NULL, };
@@ -844,10 +844,7 @@
 	}
 
 	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = port->gs.normal_termios;
-		else 
-			*tty->termios = port->gs.callout_termios;
+		*tty->termios = port->gs.normal_termios;
 		sci_set_real_termios(port);
 	}
 
@@ -862,9 +859,6 @@
 
 	sci_enable_rx_interrupts(port);
 
-	port->gs.session = current->session;
-	port->gs.pgrp = current->pgrp;
-
 	return 0;
 
 failed_3:
@@ -1038,30 +1032,13 @@
 	sci_driver.read_proc = sci_read_proc;
 #endif
 
-	sci_callout_driver = sci_driver;
-#ifdef CONFIG_DEVFS_FS
-	sci_callout_driver.name = "cusc/";
-#else
-	sci_callout_driver.name = "cusc";
-#endif
-	sci_callout_driver.major = SCI_MAJOR+1;
-	sci_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	sci_callout_driver.read_proc = NULL;
-
 	if ((error = tty_register_driver(&sci_driver))) {
 		printk(KERN_ERR "sci: Couldn't register SCI driver, error = %d\n",
 		       error);
 		return 1;
 	}
-	if ((error = tty_register_driver(&sci_callout_driver))) {
-		tty_unregister_driver(&sci_driver);
-		printk(KERN_ERR "sci: Couldn't register SCI callout driver, error = %d\n",
-		       error);
-		return 1;
-	}
 
 	for (port = &sci_ports[0]; port < &sci_ports[SCI_NPORTS]; port++) {
-		port->gs.callout_termios = sci_callout_driver.init_termios;
 		port->gs.normal_termios	= sci_driver.init_termios;
 		port->gs.magic = SCI_MAGIC;
 		port->gs.close_delay = HZ/2;
@@ -1142,7 +1119,6 @@
 void cleanup_module(void)
 {
 	tty_unregister_driver(&sci_driver);
-	tty_unregister_driver(&sci_callout_driver);
 }
 
 #include "generic_serial.c"
diff -Nru a/drivers/char/specialix.c b/drivers/char/specialix.c
--- a/drivers/char/specialix.c	Wed May  7 07:23:29 2003
+++ b/drivers/char/specialix.c	Mon May 26 15:29:26 2003
@@ -176,10 +176,7 @@
 #undef RS_EVENT_WRITE_WAKEUP
 #define RS_EVENT_WRITE_WAKEUP	0
 
-#define SPECIALIX_TYPE_NORMAL	1
-#define SPECIALIX_TYPE_CALLOUT	2
-
-static struct tty_driver specialix_driver, specialix_callout_driver;
+static struct tty_driver specialix_driver;
 static int    specialix_refcount;
 static struct tty_struct * specialix_table[SX_NBOARD * SX_NPORT];
 static struct termios * specialix_termios[SX_NBOARD * SX_NPORT];
@@ -827,17 +824,11 @@
 			printk ( "Waking up guys in open.\n");
 #endif
 			wake_up_interruptible(&port->open_wait);
-		}
-		else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		           (port->flags & ASYNC_CALLOUT_NOHUP))) {
+		} else {
 #ifdef SPECIALIX_DEBUG
 			printk ( "Sending HUP.\n");
 #endif
 			schedule_task(&port->tqueue_hangup);
-		} else {
-#ifdef SPECIALIX_DEBUG
-			printk ( "Don't need to send HUP.\n");
-#endif
 		}
 	}
 	
@@ -1341,25 +1332,6 @@
 		else
 			return -ERESTARTSYS;
 	}
-
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SPECIALIX_TYPE_CALLOUT) {
-		if (port->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (port->session != current->session))
-			return -EBUSY;
-		if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (port->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (port->pgrp != current->pgrp))
-			return -EBUSY;
-		port->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
 	
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
@@ -1367,20 +1339,13 @@
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (port->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		port->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (port->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (port->normal_termios.c_cflag & CLOCAL) 
-			do_clocal = 1;
-	} else {
-		if (C_CLOCAL(tty))
-			do_clocal = 1;
-	}
-	
+	if (C_CLOCAL(tty))
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1399,17 +1364,15 @@
 		cli();
 		sx_out(bp, CD186x_CAR, port_No(port));
 		CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE)) {
-			if (SX_CRTSCTS (tty)) {
-				/* Activate RTS */
-				port->MSVR |= MSVR_DTR;
-				sx_out (bp, CD186x_MSVR, port->MSVR);
-			} else {
-				/* Activate DTR */
-				port->MSVR |= MSVR_DTR;
-				sx_out (bp, CD186x_MSVR, port->MSVR);
-			} 
-		}
+		if (SX_CRTSCTS (tty)) {
+			/* Activate RTS */
+			port->MSVR |= MSVR_DTR;		/* WTF? */
+			sx_out (bp, CD186x_MSVR, port->MSVR);
+		} else {
+			/* Activate DTR */
+			port->MSVR |= MSVR_DTR;
+			sx_out (bp, CD186x_MSVR, port->MSVR);
+		} 
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -1420,8 +1383,7 @@
 				retval = -ERESTARTSYS;	
 			break;
 		}
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(port->flags & ASYNC_CLOSING) &&
+		if (!(port->flags & ASYNC_CLOSING) &&
 		    (do_clocal || CD))
 			break;
 		if (signal_pending(current)) {
@@ -1481,17 +1443,11 @@
 		return error;
 
 	if ((port->count == 1) && (port->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SPECIALIX_TYPE_NORMAL)
-			*tty->termios = port->normal_termios;
-		else
-			*tty->termios = port->callout_termios;
+		*tty->termios = port->normal_termios;
 		save_flags(flags); cli();
 		sx_change_speed(bp, port);
 		restore_flags(flags);
 	}
-
-	port->session = current->session;
-	port->pgrp = current->pgrp;
 	return 0;
 }
 
@@ -1535,8 +1491,6 @@
 	 */
 	if (port->flags & ASYNC_NORMAL_ACTIVE)
 		port->normal_termios = *tty->termios;
-	if (port->flags & ASYNC_CALLOUT_ACTIVE)
-		port->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1587,8 +1541,7 @@
 		}
 		wake_up_interruptible(&port->open_wait);
 	}
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&port->close_wait);
 	restore_flags(flags);
 }
@@ -2162,7 +2115,7 @@
 	sx_shutdown_port(bp, port);
 	port->event = 0;
 	port->count = 0;
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	port->flags &= ~ASYNC_NORMAL_ACTIVE;
 	port->tty = 0;
 	wake_up_interruptible(&port->open_wait);
 }
@@ -2233,7 +2186,7 @@
 	specialix_driver.major = SPECIALIX_NORMAL_MAJOR;
 	specialix_driver.num = SX_NBOARD * SX_NPORT;
 	specialix_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	specialix_driver.subtype = SPECIALIX_TYPE_NORMAL;
+	specialix_driver.subtype = SERIAL_TYPE_NORMAL;
 	specialix_driver.init_termios = tty_std_termios;
 	specialix_driver.init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
@@ -2259,28 +2212,14 @@
 	specialix_driver.start = sx_start;
 	specialix_driver.hangup = sx_hangup;
 
-	specialix_callout_driver = specialix_driver;
-	specialix_callout_driver.name = "cuw";
-	specialix_callout_driver.major = SPECIALIX_CALLOUT_MAJOR;
-	specialix_callout_driver.subtype = SPECIALIX_TYPE_CALLOUT;
-	
 	if ((error = tty_register_driver(&specialix_driver))) {
 		free_page((unsigned long)tmp_buf);
 		printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
 		       error);
 		return 1;
 	}
-	if ((error = tty_register_driver(&specialix_callout_driver))) {
-		free_page((unsigned long)tmp_buf);
-		tty_unregister_driver(&specialix_driver);
-		printk(KERN_ERR "sx: Couldn't register specialix IO8+ callout driver, error = %d\n",
-		       error);
-		return 1;
-	}
-	
 	memset(sx_port, 0, sizeof(sx_port));
 	for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
-		sx_port[i].callout_termios = specialix_callout_driver.init_termios;
 		sx_port[i].normal_termios  = specialix_driver.init_termios;
 		sx_port[i].magic = SPECIALIX_MAGIC;
 		sx_port[i].tqueue.routine = do_softint;
@@ -2301,7 +2240,6 @@
 {
 	free_page((unsigned long)tmp_buf);
 	tty_unregister_driver(&specialix_driver);
-	tty_unregister_driver(&specialix_callout_driver);
 }
 
 
diff -Nru a/drivers/char/specialix_io8.h b/drivers/char/specialix_io8.h
--- a/drivers/char/specialix_io8.h	Sun Jul 21 08:35:45 2002
+++ b/drivers/char/specialix_io8.h	Mon May 26 15:29:10 2003
@@ -113,15 +113,12 @@
 	ulong			event;
 	int			timeout;
 	int			close_delay;
-	long			session;
-	long			pgrp;
 	unsigned char 		* xmit_buf;
 	int			custom_divisor;
 	int			xmit_head;
 	int			xmit_tail;
 	int			xmit_cnt;
 	struct termios          normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 	struct tq_struct	tqueue;
diff -Nru a/drivers/char/stallion.c b/drivers/char/stallion.c
--- a/drivers/char/stallion.c	Wed May  7 23:16:25 2003
+++ b/drivers/char/stallion.c	Mon May 26 15:29:26 2003
@@ -120,9 +120,6 @@
 #define	STL_CALLOUTMAJOR	25
 #endif
 
-#define	STL_DRVTYPSERIAL	1
-#define	STL_DRVTYPCALLOUT	2
-
 /*
  *	Set the TX buffer size. Bigger is better, but we don't want
  *	to chew too much memory with buffers!
@@ -141,14 +138,11 @@
 static char	*stl_drvversion = "5.6.0";
 #ifdef CONFIG_DEVFS_FS
 static char	*stl_serialname = "tts/E%d";
-static char	*stl_calloutname = "cua/E%d";
 #else
 static char	*stl_serialname = "ttyE";
-static char	*stl_calloutname = "cue";
 #endif
 
 static struct tty_driver	stl_serial;
-static struct tty_driver	stl_callout;
 static struct tty_struct	*stl_ttys[STL_MAXDEVS];
 static struct termios		*stl_termios[STL_MAXDEVS];
 static struct termios		*stl_termioslocked[STL_MAXDEVS];
@@ -799,10 +793,9 @@
  *	hanging onto ports.
  */
 	i = tty_unregister_driver(&stl_serial);
-	j = tty_unregister_driver(&stl_callout);
-	if (i || j) {
+	if (i) {
 		printk("STALLION: failed to un-register tty driver, "
-			"errno=%d,%d\n", -i, -j);
+			"errno=%d\n", -i);
 		restore_flags(flags);
 		return;
 	}
@@ -1087,39 +1080,16 @@
  *	previous opens still in effect. If we are a normal serial device
  *	then also we might have to wait for carrier.
  */
-	if (tty->driver->subtype == STL_DRVTYPCALLOUT) {
-		if (portp->flags & ASYNC_NORMAL_ACTIVE)
-			return(-EBUSY);
-		if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
-			if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
-			    (portp->session != current->session))
-				return(-EBUSY);
-			if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
-			    (portp->pgrp != current->pgrp))
-				return(-EBUSY);
-		}
-		portp->flags |= ASYNC_CALLOUT_ACTIVE;
-	} else {
-		if (filp->f_flags & O_NONBLOCK) {
-			if (portp->flags & ASYNC_CALLOUT_ACTIVE)
-				return(-EBUSY);
-		} else {
-			if ((rc = stl_waitcarrier(portp, filp)) != 0)
-				return(rc);
-		}
-		portp->flags |= ASYNC_NORMAL_ACTIVE;
+	if (!(filp->f_flags & O_NONBLOCK)) {
+		if ((rc = stl_waitcarrier(portp, filp)) != 0)
+			return(rc);
 	}
+	portp->flags |= ASYNC_NORMAL_ACTIVE;
 
 	if ((portp->refcount == 1) && (portp->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == STL_DRVTYPSERIAL)
-			*tty->termios = portp->normaltermios;
-		else
-			*tty->termios = portp->callouttermios;
+		*tty->termios = portp->normaltermios;
 		stl_setport(portp, tty->termios);
 	}
-
-	portp->session = current->session;
-	portp->pgrp = current->pgrp;
 	return(0);
 }
 
@@ -1142,13 +1112,8 @@
 	rc = 0;
 	doclocal = 0;
 
-	if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (portp->normaltermios.c_cflag & CLOCAL)
-			doclocal++;
-	} else {
-		if (portp->tty->termios->c_cflag & CLOCAL)
-			doclocal++;
-	}
+	if (portp->tty->termios->c_cflag & CLOCAL)
+		doclocal++;
 
 	save_flags(flags);
 	cli();
@@ -1157,8 +1122,7 @@
 		portp->refcount--;
 
 	for (;;) {
-		if ((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0)
-			stl_setsignals(portp, 1, 1);
+		stl_setsignals(portp, 1, 1);
 		if (tty_hung_up_p(filp) ||
 		    ((portp->flags & ASYNC_INITIALIZED) == 0)) {
 			if (portp->flags & ASYNC_HUP_NOTIFY)
@@ -1167,8 +1131,7 @@
 				rc = -ERESTARTSYS;
 			break;
 		}
-		if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) &&
-		    ((portp->flags & ASYNC_CLOSING) == 0) &&
+		if (((portp->flags & ASYNC_CLOSING) == 0) &&
 		    (doclocal || (portp->sigs & TIOCM_CD))) {
 			break;
 		}
@@ -1220,8 +1183,6 @@
 
 	if (portp->flags & ASYNC_NORMAL_ACTIVE)
 		portp->normaltermios = *tty->termios;
-	if (portp->flags & ASYNC_CALLOUT_ACTIVE)
-		portp->callouttermios = *tty->termios;
 
 /*
  *	May want to wait for any data to drain before closing. The BUSY
@@ -1260,8 +1221,7 @@
 		wake_up_interruptible(&portp->open_wait);
 	}
 
-	portp->flags &= ~(ASYNC_CALLOUT_ACTIVE | ASYNC_NORMAL_ACTIVE |
-		ASYNC_CLOSING);
+	portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&portp->close_wait);
 	restore_flags(flags);
 }
@@ -1838,7 +1798,7 @@
 		portp->tx.tail = (char *) NULL;
 	}
 	portp->tty = (struct tty_struct *) NULL;
-	portp->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
+	portp->flags &= ~ASYNC_NORMAL_ACTIVE;
 	portp->refcount = 0;
 	wake_up_interruptible(&portp->open_wait);
 }
@@ -2256,12 +2216,8 @@
 		if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
 			wake_up_interruptible(&portp->open_wait);
 		if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
-			if (portp->flags & ASYNC_CHECK_CD) {
-				if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) &&
-				    (portp->flags & ASYNC_CALLOUT_NOHUP))) {
-					tty_hangup(tty);	/* FIXME: module removal race here - AKPM */
-				}
-			}
+			if (portp->flags & ASYNC_CHECK_CD)
+				tty_hangup(tty);	/* FIXME: module removal race here - AKPM */
 		}
 	}
 	unlock_kernel();
@@ -2340,7 +2296,6 @@
 		portp->close_delay = STL_CLOSEDELAY;
 		portp->closing_wait = 30 * HZ;
 		portp->normaltermios = stl_deftermios;
-		portp->callouttermios = stl_deftermios;
 		INIT_WORK(&portp->tqueue, stl_offintr, portp);
 		init_waitqueue_head(&portp->open_wait);
 		init_waitqueue_head(&portp->close_wait);
@@ -3218,7 +3173,6 @@
 
 /*
  *	Set up the tty driver structure and register us as a driver.
- *	Also setup the callout tty device.
  */
 	memset(&stl_serial, 0, sizeof(struct tty_driver));
 	stl_serial.magic = TTY_DRIVER_MAGIC;
@@ -3229,7 +3183,7 @@
 	stl_serial.minor_start = 0;
 	stl_serial.num = STL_MAXBRDS * STL_MAXPORTS;
 	stl_serial.type = TTY_DRIVER_TYPE_SERIAL;
-	stl_serial.subtype = STL_DRVTYPSERIAL;
+	stl_serial.subtype = SERIAL_TYPE_NORMAL;
 	stl_serial.init_termios = stl_deftermios;
 	stl_serial.flags = TTY_DRIVER_REAL_RAW;
 	stl_serial.refcount = &stl_refcount;
@@ -3257,16 +3211,8 @@
 	stl_serial.send_xchar = stl_sendxchar;
 	stl_serial.read_proc = stl_readproc;
 
-	stl_callout = stl_serial;
-	stl_callout.name = stl_calloutname;
-	stl_callout.major = STL_CALLOUTMAJOR;
-	stl_callout.subtype = STL_DRVTYPCALLOUT;
-	stl_callout.read_proc = 0;
-
 	if (tty_register_driver(&stl_serial))
 		printk("STALLION: failed to register serial driver\n");
-	if (tty_register_driver(&stl_callout))
-		printk("STALLION: failed to register callout driver\n");
 
 	return(0);
 }
diff -Nru a/drivers/char/sx.c b/drivers/char/sx.c
--- a/drivers/char/sx.c	Sun May 25 23:18:34 2003
+++ b/drivers/char/sx.c	Mon May 26 15:29:26 2003
@@ -249,12 +249,6 @@
    one machine. You'll have to increase the number of boards in sx.h
    if you want more than 4 boards.  */
 
-
-/* Why the hell am I defining these here? */
-#define SX_TYPE_NORMAL 1
-#define SX_TYPE_CALLOUT 2
-
-
 #ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8
 #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000
 #endif
@@ -314,7 +308,7 @@
 static int sx_init_drivers(void);
 
 
-static struct tty_driver sx_driver, sx_callout_driver;
+static struct tty_driver sx_driver;
 
 static struct tty_struct * sx_table[SX_NPORTS];
 static struct termios ** sx_termios;
@@ -1168,9 +1162,7 @@
 			port->c_dcd = c_dcd;
 			if (sx_get_CD (port)) {
 				/* DCD went UP */
-				if( (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) || 
-						 ~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) &&
-						(sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) &&
+				if ((sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) &&
 						!(port->gs.tty->termios->c_cflag & CLOCAL) ) {
 					/* Are we blocking in open?*/
 					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD active, unblocking open\n");
@@ -1180,9 +1172,7 @@
 				}
 			} else {
 				/* DCD went down! */
-				if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) &&
-				      (port->gs.flags & ASYNC_CALLOUT_NOHUP)) &&
-				    !(port->gs.tty->termios->c_cflag & CLOCAL) ) {
+				if (!(port->gs.tty->termios->c_cflag & CLOCAL) ) {
 					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. hanging up....\n");
 					tty_hangup (port->gs.tty);
 				} else {
@@ -1497,15 +1487,10 @@
 	/* tty->low_latency = 1; */
 
 	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = port->gs.normal_termios;
-		else 
-			*tty->termios = port->gs.callout_termios;
+		*tty->termios = port->gs.normal_termios;
 		sx_set_real_termios (port);
 	}
 
-	port->gs.session = current->session;
-	port->gs.pgrp = current->pgrp;
 	port->c_dcd = sx_get_CD (port);
 	sx_dprintk (SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd);
 	func_exit();
@@ -2250,7 +2235,7 @@
 	sx_driver.major = SX_NORMAL_MAJOR;
 	sx_driver.num = sx_nports;
 	sx_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	sx_driver.subtype = SX_TYPE_NORMAL;
+	sx_driver.subtype = SERIAL_TYPE_NORMAL;
 	sx_driver.init_termios = tty_std_termios;
 	sx_driver.init_termios.c_cflag =
 	  B9600 | CS8 | CREAD | HUPCL | CLOCAL;
@@ -2277,23 +2262,11 @@
 	sx_driver.start = gs_start;
 	sx_driver.hangup = gs_hangup;
 
-	sx_callout_driver = sx_driver;
-	sx_callout_driver.name = "cux";
-	sx_callout_driver.major = SX_CALLOUT_MAJOR;
-	sx_callout_driver.subtype = SX_TYPE_CALLOUT;
-
 	if ((error = tty_register_driver(&sx_driver))) {
 		printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n",
 		       error);
 		return 1;
 	}
-	if ((error = tty_register_driver(&sx_callout_driver))) {
-		tty_unregister_driver(&sx_driver);
-		printk(KERN_ERR "sx: Couldn't register sx callout driver, error = %d\n",
-		       error);
-		return 1;
-	}
-
 	func_exit();
 	return 0;
 }
@@ -2349,7 +2322,6 @@
 		board->ports = port;
 		for (j=0; j < boards[i].nports;j++) {
 			sx_dprintk (SX_DEBUG_INIT, "initing port %d\n", j);
-			port->gs.callout_termios = tty_std_termios;
 			port->gs.normal_termios	= tty_std_termios;
 			port->gs.magic = SX_MAGIC;
 			port->gs.close_delay = HZ/2;
@@ -2410,7 +2382,6 @@
 {
 	func_enter();
 	tty_unregister_driver(&sx_driver);
-	tty_unregister_driver(&sx_callout_driver);
 	func_exit();
 }
 
diff -Nru a/drivers/char/synclink.c b/drivers/char/synclink.c
--- a/drivers/char/synclink.c	Tue May  6 14:29:47 2003
+++ b/drivers/char/synclink.c	Mon May 26 15:29:15 2003
@@ -200,14 +200,11 @@
 	struct mgsl_icount	icount;
 	
 	struct termios		normal_termios;
-	struct termios		callout_termios;
-	
+
 	struct tty_struct 	*tty;
 	int			timeout;
 	int			x_char;		/* xon/xoff character */
 	int			blocked_open;	/* # of blocked opens */
-	long			session;	/* Session of opening process */
-	long			pgrp;		/* pgrp of opening process */
 	u16			read_status_mask;
 	u16			ignore_status_mask;	
 	unsigned char 		*xmit_buf;
@@ -891,8 +888,6 @@
  */
 static int ttymajor;
 
-static int cuamajor;
-
 /*
  * Array of user specified options for ISA adapters.
  */
@@ -907,7 +902,6 @@
 	
 MODULE_PARM(break_on_load,"i");
 MODULE_PARM(ttymajor,"i");
-MODULE_PARM(cuamajor,"i");
 MODULE_PARM(io,"1-" __MODULE_STRING(MAX_ISA_DEVICES) "i");
 MODULE_PARM(irq,"1-" __MODULE_STRING(MAX_ISA_DEVICES) "i");
 MODULE_PARM(dma,"1-" __MODULE_STRING(MAX_ISA_DEVICES) "i");
@@ -940,7 +934,7 @@
 	.remove		= __devexit_p(synclink_remove_one),
 };
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* number of characters left in xmit buffer before we ask for more */
@@ -1377,8 +1371,7 @@
 				       (status & MISCSTATUS_DCD) ? "on" : "off");
 			if (status & MISCSTATUS_DCD)
 				wake_up_interruptible(&info->open_wait);
-			else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-				   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+			else {
 				if ( debug_level >= DEBUG_LEVEL_ISR )
 					printk("doing serial hangup...");
 				if (info->tty)
@@ -3218,9 +3211,7 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
-		
+
 	/* set tty->closing to notify line discipline to 
 	 * only process XON/XOFF characters. Only the N_TTY
 	 * discipline appears to use this (ppp does not).
@@ -3258,8 +3249,7 @@
 		wake_up_interruptible(&info->open_wait);
 	}
 	
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 			 
 	wake_up_interruptible(&info->close_wait);
 	
@@ -3369,7 +3359,7 @@
 	shutdown(info);
 	
 	info->count = 0;	
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 
 	wake_up_interruptible(&info->open_wait);
@@ -3401,40 +3391,15 @@
 		printk("%s(%d):block_til_ready on %s\n",
 			 __FILE__,__LINE__, tty->driver->name );
 
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		/* this is a callout device */
-		/* just verify that normal device is not in use */
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
 	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
 		/* nonblock mode is set or port is not enabled */
-		/* just verify that callout device is not active */
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/* Wait for carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
 	 * this loop, info->count is dropped by one, so that
@@ -3458,8 +3423,7 @@
 	info->blocked_open++;
 	
 	while (1) {
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    (tty->termios->c_cflag & CBAUD)) {
+		if (tty->termios->c_cflag & CBAUD) {
 			spin_lock_irqsave(&info->irq_spinlock,flags);
 			info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
 		 	usc_set_serial_signals(info);
@@ -3478,8 +3442,7 @@
 	 	usc_get_serial_signals(info);
 		spin_unlock_irqrestore(&info->irq_spinlock,flags);
 		
- 		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    !(info->flags & ASYNC_CLOSING) &&
+ 		if (!(info->flags & ASYNC_CLOSING) &&
  		    (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
  			break;
 		}
@@ -3607,16 +3570,10 @@
 
 	if ((info->count == 1) &&
 	    info->flags & ASYNC_SPLIT_TERMIOS) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		mgsl_change_params(info);
 	}
 	
-	info->session = current->session;
-	info->pgrp    = current->pgrp;
-
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):mgsl_open(%s) success\n",
 			 __FILE__,__LINE__, info->device_name);
@@ -4548,34 +4505,18 @@
 	serial_driver.tiocmget = tiocmget;
 	serial_driver.tiocmset = tiocmset;
 	
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cuaSL";
-	callout_driver.major = cuamajor;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver) < 0)
 		printk("%s(%d):Couldn't register serial driver\n",
 			__FILE__,__LINE__);
 			
-	if (tty_register_driver(&callout_driver) < 0)
-		printk("%s(%d):Couldn't register callout driver\n",
-			__FILE__,__LINE__);
-
- 	printk("%s %s, tty major#%d callout major#%d\n",
+ 	printk("%s %s, tty major#%d\n",
 		driver_name, driver_version,
-		serial_driver.major, callout_driver.major);
+		serial_driver.major);
 		
 	/* Propagate these values to all device instances */
 	
 	info = mgsl_device_list;
 	while(info){
-		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios  = serial_driver.init_termios;
 		info = info->next_device;
 	}
@@ -4670,9 +4611,6 @@
 
 	if ((rc = tty_unregister_driver(&serial_driver)))
 		printk("%s(%d) failed to unregister tty driver err=%d\n",
-		       __FILE__,__LINE__,rc);
-	if ((rc = tty_unregister_driver(&callout_driver)))
-		printk("%s(%d) failed to unregister callout driver err=%d\n",
 		       __FILE__,__LINE__,rc);
 
 	info = mgsl_device_list;
diff -Nru a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
--- a/drivers/char/synclinkmp.c	Thu Apr 24 05:17:30 2003
+++ b/drivers/char/synclinkmp.c	Mon May 26 15:29:15 2003
@@ -167,14 +167,11 @@
 	struct mgsl_icount	icount;
 
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 
 	struct tty_struct 	*tty;
 	int			timeout;
 	int			x_char;		/* xon/xoff character */
 	int			blocked_open;	/* # of blocked opens */
-	long			session;	/* Session of opening process */
-	long			pgrp;		/* pgrp of opening process */
 	u16			read_status_mask1;  /* break detection (SR1 indications) */
 	u16			read_status_mask2;  /* parity/framing/overun (SR2 indications) */
 	unsigned char 		ignore_status_mask1;  /* break detection (SR1 indications) */
@@ -524,7 +521,7 @@
 };
 
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* number of characters left in xmit buffer before we ask for more */
@@ -807,16 +804,10 @@
 
 	if ((info->count == 1) &&
 	    info->flags & ASYNC_SPLIT_TERMIOS) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_params(info);
 	}
 
-	info->session = current->session;
-	info->pgrp    = current->pgrp;
-
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):%s open() success\n",
 			 __FILE__,__LINE__, info->device_name);
@@ -873,8 +864,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 
 	/* set tty->closing to notify line discipline to
 	 * only process XON/XOFF characters. Only the N_TTY
@@ -913,8 +902,7 @@
 		wake_up_interruptible(&info->open_wait);
 	}
 
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 
 	wake_up_interruptible(&info->close_wait);
 
@@ -942,7 +930,7 @@
 	shutdown(info);
 
 	info->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 
 	wake_up_interruptible(&info->open_wait);
@@ -2402,8 +2390,7 @@
 				       (status & SerialSignal_DCD) ? "on" : "off");
 			if (status & SerialSignal_DCD)
 				wake_up_interruptible(&info->open_wait);
-			else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-				   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+			else {
 				if ( debug_level >= DEBUG_LEVEL_ISR )
 					printk("doing serial hangup...");
 				if (info->tty)
@@ -3202,39 +3189,15 @@
 		printk("%s(%d):%s block_til_ready()\n",
 			 __FILE__,__LINE__, tty->driver->name );
 
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		/* this is a callout device */
-		/* just verify that normal device is not in use */
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-
 	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
 		/* nonblock mode is set or port is not enabled */
 		/* just verify that callout device is not active */
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 
 	/* Wait for carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -3259,8 +3222,7 @@
 	info->blocked_open++;
 
 	while (1) {
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    (tty->termios->c_cflag & CBAUD)) {
+		if ((tty->termios->c_cflag & CBAUD)) {
 			spin_lock_irqsave(&info->lock,flags);
 			info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR;
 		 	set_signals(info);
@@ -3279,8 +3241,7 @@
 	 	get_signals(info);
 		spin_unlock_irqrestore(&info->lock,flags);
 
- 		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    !(info->flags & ASYNC_CLOSING) &&
+ 		if (!(info->flags & ASYNC_CLOSING) &&
  		    (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
  			break;
 		}
@@ -3873,34 +3834,18 @@
 	serial_driver.tiocmget = tiocmget;
 	serial_driver.tiocmset = tiocmset;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cuaSLM";
-	callout_driver.major = cuamajor;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver) < 0)
 		printk("%s(%d):Couldn't register serial driver\n",
 			__FILE__,__LINE__);
 
-	if (tty_register_driver(&callout_driver) < 0)
-		printk("%s(%d):Couldn't register callout driver\n",
-			__FILE__,__LINE__);
-
- 	printk("%s %s, tty major#%d callout major#%d\n",
+ 	printk("%s %s, tty major#%d\n",
 		driver_name, driver_version,
-		serial_driver.major, callout_driver.major);
+		serial_driver.major);
 
 	/* Propagate these values to all device instances */
 
 	info = synclinkmp_device_list;
 	while(info){
-		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios  = serial_driver.init_termios;
 		info = info->next_device;
 	}
@@ -3919,9 +3864,6 @@
 
 	if ((rc = tty_unregister_driver(&serial_driver)))
 		printk("%s(%d) failed to unregister tty driver err=%d\n",
-		       __FILE__,__LINE__,rc);
-	if ((rc = tty_unregister_driver(&callout_driver)))
-		printk("%s(%d) failed to unregister callout driver err=%d\n",
 		       __FILE__,__LINE__,rc);
 
 	info = synclinkmp_device_list;
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Mon May 26 12:20:47 2003
+++ b/drivers/char/tty_io.c	Mon May 26 15:29:29 2003
@@ -1305,7 +1305,6 @@
 	int index;
 	kdev_t device;
 	unsigned short saved_flags;
-	char	buf[64];
 
 	saved_flags = filp->f_flags;
 retry_open:
@@ -1379,7 +1378,7 @@
 	    tty->driver->subtype == PTY_TYPE_MASTER)
 		noctty = 1;
 #ifdef TTY_DEBUG_HANGUP
-	printk(KERN_DEBUG "opening %s...", tty_name(tty, buf));
+	printk(KERN_DEBUG "opening %s...", tty->name);
 #endif
 	if (tty->driver->open)
 		retval = tty->driver->open(tty, filp);
@@ -1393,7 +1392,7 @@
 	if (retval) {
 #ifdef TTY_DEBUG_HANGUP
 		printk(KERN_DEBUG "error %d in opening %s...", retval,
-		       tty_name(tty, buf));
+		       tty->name);
 #endif
 
 		release_dev(filp);
@@ -1418,19 +1417,6 @@
 		current->tty_old_pgrp = 0;
 		tty->session = current->session;
 		tty->pgrp = current->pgrp;
-	}
-	if ((tty->driver->type == TTY_DRIVER_TYPE_SERIAL) &&
-	    (tty->driver->subtype == SERIAL_TYPE_CALLOUT) &&
-	    (tty->count == 1)) {
-		static int nr_warns;
-		if (nr_warns < 5) {
-			printk(KERN_WARNING "tty_io.c: "
-				"process %d (%s) used obsolete /dev/%s - "
-				"update software to use /dev/ttyS%d\n",
-				current->pid, current->comm,
-				tty_name(tty, buf), TTY_NUMBER(tty));
-			nr_warns++;
-		}
 	}
 	return 0;
 }
diff -Nru a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
--- a/drivers/char/vme_scc.c	Fri May  9 03:21:31 2003
+++ b/drivers/char/vme_scc.c	Mon May 26 15:29:12 2003
@@ -90,7 +90,7 @@
 static void scc_setsignals(struct scc_port *port, int dtr, int rts);
 static void scc_break_ctl(struct tty_struct *tty, int break_state);
 
-static struct tty_driver scc_driver, scc_callout_driver;
+static struct tty_driver scc_driver;
 
 static struct tty_struct *scc_table[2] = { NULL, };
 static struct termios * scc_termios[2];
@@ -167,26 +167,11 @@
 	scc_driver.hangup = gs_hangup;
 	scc_driver.break_ctl = scc_break_ctl;
 
-	scc_callout_driver = scc_driver;
-#ifdef CONFIG_DEVFS_FS
-	scc_callout_driver.name = "cua/";
-#else
-	scc_callout_driver.name = "cua";
-#endif
-	scc_callout_driver.major = TTYAUX_MAJOR;
-	scc_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	if ((error = tty_register_driver(&scc_driver))) {
 		printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n",
 		       error);
 		return 1;
 	}
-	if ((error = tty_register_driver(&scc_callout_driver))) {
-		tty_unregister_driver(&scc_driver);
-		printk(KERN_ERR "scc: Couldn't register scc callout driver, error = %d\n",
-		       error);
-		return 1;
-	}
 
 	return 0;
 }
@@ -202,7 +187,6 @@
 
 	for (i = 0; i < 2; i++) {
 		port = scc_ports + i;
-		port->gs.callout_termios = tty_std_termios;
 		port->gs.normal_termios = tty_std_termios;
 		port->gs.magic = SCC_MAGIC;
 		port->gs.close_delay = HZ/2;
@@ -599,18 +583,11 @@
 		if (!(port->gs.flags & ASYNC_CHECK_CD))
 			;	/* Don't report DCD changes */
 		else if (port->c_dcd) {
-			if (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) ||
-				~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) {
-				/* Are we blocking in open?*/
-				wake_up_interruptible(&port->gs.open_wait);
-			}
+			wake_up_interruptible(&port->gs.open_wait);
 		}
 		else {
-			if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) &&
-					(port->gs.flags & ASYNC_CALLOUT_NOHUP))) {
-				if (port->gs.tty)
-					tty_hangup (port->gs.tty);
-			}
+			if (port->gs.tty)
+				tty_hangup (port->gs.tty);
 		}
 	}
 	SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET);
@@ -949,15 +926,10 @@
 	}
 
 	if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = port->gs.normal_termios;
-		else 
-			*tty->termios = port->gs.callout_termios;
+		*tty->termios = port->gs.normal_termios;
 		scc_set_real_termios (port);
 	}
 
-	port->gs.session = current->session;
-	port->gs.pgrp = current->pgrp;
 	port->c_dcd = scc_get_CD (port);
 
 	scc_enable_rx_interrupts(port);
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	Wed May 14 03:16:09 2003
+++ b/drivers/ide/ide-cd.c	Thu May  8 01:39:34 2003
@@ -2993,12 +2993,6 @@
 	long block = (long)rq->hard_sector / (hard_sect >> 9);
 	unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
 
-	BUG_ON(sizeof(rq->hard_sector) > 4 && (rq->hard_sector >> 32));
-
-	if (rq->hard_nr_sectors != rq->nr_sectors) {
-		printk(KERN_ERR "ide-cd: hard_nr_sectors differs from nr_sectors! %lu %lu\n",
-				rq->nr_sectors, rq->hard_nr_sectors);
-	}
 	memset(rq->cmd, 0, sizeof(rq->cmd));
 
 	if (rq_data_dir(rq) == READ)
diff -Nru a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
--- a/drivers/ieee1394/eth1394.c	Mon May 19 07:50:28 2003
+++ b/drivers/ieee1394/eth1394.c	Mon May 19 19:56:23 2003
@@ -3,6 +3,7 @@
  * 
  * Copyright (C) 2001 Ben Collins <bcollins@debian.org>
  *               2000 Bonin Franck <boninf@free.fr>
+ *               2003 Steve Kinneberg <kinnebergsteve@acmsystems.com>
  *
  * Mainly based on work by Emanuel Pirker and Andreas E. Bombe
  *
@@ -21,22 +22,28 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/* State of this driver:
- *
- * This driver intends to support RFC 2734, which describes a method for
+/* This driver intends to support RFC 2734, which describes a method for
  * transporting IPv4 datagrams over IEEE-1394 serial busses. This driver
  * will ultimately support that method, but currently falls short in
- * several areas. A few issues are:
+ * several areas.
+ *
+ * TODO:
+ * RFC 2734 related:
+ * - Add support for broadcast messages
+ * - Use EUI instead of node id in internal ARP tables
+ * - Add Config ROM entry
+ * - Add MCAP and multicast
  *
- *   - Does not support send/recv over Async streams using GASP
- *     packet formats, as per the RFC for ARP requests.
- *   - Does not yet support fragmented packets.
- *   - Relies on hardware address being equal to the nodeid for some things.
- *   - Does not support multicast
- *   - Hardcoded address for sending packets, instead of using discovery
- *     (ARP, see first item)
+ * Non-RFC 2734 related:
+ * - Move generic GASP reception to core 1394 code
+ * - Convert kmalloc/kfree for link fragments to use kmem_cache_* instead
+ * - Stability improvements
+ * - Performance enhancements
+ * - Change hardcoded 1394 bus address region to a dynamic memory space allocation
+ * - Consider garbage collecting old partial datagrams after X amount of time
  */
 
+
 #include <linux/module.h>
 
 #include <linux/sched.h>
@@ -56,7 +63,6 @@
 #include <linux/tcp.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
-#include <linux/workqueue.h>
 #include <asm/delay.h>
 #include <asm/semaphore.h>
 #include <net/arp.h>
@@ -76,10 +82,27 @@
 	printk(level ETHER1394_DRIVER_NAME": %s: " fmt, dev_name, ## args)
 
 #define DEBUG(fmt, args...) \
-	printk(KERN_ERR fmt, ## args)
+	printk(KERN_ERR "eth1394:%s[%d]: "fmt"\n", __FUNCTION__, __LINE__, ## args)
+#define TRACE() printk(KERN_ERR "eth1394:%s[%d] ---- TRACE\n", __FUNCTION__, __LINE__)
 
 static char version[] __devinitdata =
-	"$Rev: 931 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 938 $ Ben Collins <bcollins@debian.org>";
+
+struct fragment_info {
+	struct list_head list;
+	int offset;
+	int len;
+};
+
+struct partial_datagram {
+	struct list_head list;
+	u16 dgl;
+	u16 dg_size;
+	u16 ether_type;
+	struct sk_buff *skb;
+	char *pbuf;
+	struct list_head frag_info;
+};
 
 /* Our ieee1394 highlevel driver */
 #define ETHER1394_DRIVER_NAME "ether1394"
@@ -89,7 +112,7 @@
 static struct hpsb_highlevel eth1394_highlevel;
 
 /* Use common.lf to determine header len */
-static int hdr_type_len[] = {
+static const int hdr_type_len[] = {
 	sizeof (struct eth1394_uf_hdr),
 	sizeof (struct eth1394_ff_hdr),
 	sizeof (struct eth1394_sf_hdr),
@@ -100,16 +123,111 @@
 MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)");
 MODULE_LICENSE("GPL");
 
+/* The max_partial_datagrams parameter is the maximum number of fragmented datagrams
+ * per node that eth1394 will keep in memory.  Providing an upper bound allows us to
+ * limit the amount of memory that partial datagrams consume in the event that some
+ * partial datagrams are never completed.  This should probably change to a sysctl
+ * item or the like if possible.
+ */
+MODULE_PARM(max_partial_datagrams, "i");
+MODULE_PARM_DESC(max_partial_datagrams,
+                 "Maximum number of partially received fragmented datagrams (default = 25).");
+static int max_partial_datagrams = 25;
+
+
+static inline void purge_partial_datagram(struct list_head *old);
+static int ether1394_tx(struct sk_buff *skb, struct net_device *dev);
 static void ether1394_iso(struct hpsb_iso *iso);
 
 
+static int ether1394_init_bc(struct net_device *dev)
+{
+	int ret = 0;
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+
+	/* First time sending?  Need a broadcast channel for ARP and for
+	 * listening on */
+	if(priv->bc_state == ETHER1394_BC_CHECK) {
+		quadlet_t bc;
+
+		/* Get the local copy of the broadcast channel and check its
+		 * validity (the IRM should validate it for us) */
+
+		bc = priv->host->csr.broadcast_channel;
+
+		if((bc & 0xc0000000) != 0xc0000000) {
+			/* broadcast channel not validated yet */
+			ETH1394_PRINT(KERN_WARNING, dev->name,
+				      "Error BROADCAST_CHANNEL register valid "
+				      "bit not set, can't send IP traffic\n");
+			if(!in_interrupt()) {
+				hpsb_iso_shutdown(priv->iso);
+				priv->bc_state = ETHER1394_BC_CLOSED;
+			}
+			ret = -EAGAIN;
+			goto fail;
+		}
+		if(priv->broadcast_channel != (bc & 0x3f)) {
+			/* This really shouldn't be possible, but just in case
+			 * the IEEE 1394 spec changes regarding broadcast
+			 * channels in the future. */
+
+			if(in_interrupt()) {
+				ret = -EAGAIN;
+				goto fail;
+
+			}
+
+			hpsb_iso_shutdown(priv->iso);
+
+			priv->broadcast_channel = bc & 0x3f;
+			ETH1394_PRINT(KERN_INFO, dev->name,
+				      "Changing to broadcast channel %d...\n",
+				      priv->broadcast_channel);
+
+			priv->iso = hpsb_iso_recv_init(priv->host, 16 * 4096,
+						       16, priv->broadcast_channel,
+						       1, ether1394_iso);
+			if(priv->iso == NULL) {
+				ETH1394_PRINT(KERN_ERR, dev->name,
+					      "failed to change broadcast "
+					      "channel\n");
+				ret = -EAGAIN;
+				goto fail;
+			}
+		}
+		if(hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) {
+			ETH1394_PRINT(KERN_ERR, dev->name,
+				      "Could not start data stream reception\n");
+			if(!in_interrupt()) {
+				hpsb_iso_shutdown(priv->iso);
+				priv->bc_state = ETHER1394_BC_CLOSED;
+			}
+			ret = -EAGAIN;
+			goto fail;
+		}
+		priv->bc_state = ETHER1394_BC_OPENED;
+	}
+    
+fail:
+	return ret;
+}
+
 /* This is called after an "ifup" */
 static int ether1394_open (struct net_device *dev)
 {
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+	unsigned long flags;
+	int ret;
 
 	/* Set the spinlock before grabbing IRQ! */
 	priv->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_irqsave(&priv->lock, flags);
+	ret = ether1394_init_bc(dev);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if(ret)
+		return ret;
 
 	netif_start_queue (dev);
 	return 0;
@@ -140,34 +258,6 @@
 	netif_wake_queue (dev);
 }
 
-/* We need to encapsulate the standard header with our own. We use the
- * ethernet header's proto for our own.
- *
- * XXX: This is where we need to create a list of skb's for fragmented
- * packets.  */
-static inline void ether1394_encapsulate (struct sk_buff *skb, struct net_device *dev,
-                                          int proto, struct packet_task *ptask)
-{
-	union eth1394_hdr *hdr =
-		(union eth1394_hdr *)skb_push (skb, hdr_type_len[ETH1394_HDR_LF_UF]);
-
-	hdr->words.word1 = 0;
-	hdr->common.lf = ETH1394_HDR_LF_UF;
-	hdr->words.word1 = htons(hdr->words.word1);
-	hdr->uf.ether_type = proto;
-
-	/* Set the transmission type for the packet.  Right now only ARP
-	 * packets are sent via GASP.  IP broadcast and IP multicast are not
-	 * yet supported properly, they too should use GASP. */
-	switch(proto) {
-	case __constant_htons(ETH_P_ARP):
-		ptask->tx_type = ETH1394_GASP;
-		break;
-	default:
-		ptask->tx_type = ETH1394_WRREQ;
-	}
-	return;
-}
 
 /* Convert a standard ARP packet to 1394 ARP. The first 8 bytes (the
  * entire arphdr) is the same format as the ip1394 header, so they
@@ -223,8 +313,6 @@
 				       unsigned char sspd, u64 eui, u16 fifo_hi,
 				       u32 fifo_lo, struct eth1394_priv *priv)
 {
-	int i;
-
 	if (nodeid < 0 || nodeid >= ALL_NODES) {
 		ETH1394_PRINT_G (KERN_ERR, "Cannot register invalid nodeid %d\n", nodeid);
 		return;
@@ -236,20 +324,8 @@
 	priv->fifo_lo[nodeid]	= fifo_lo;
 	priv->eui[nodeid]	= eui;
 
-	/* 63 is used for broadcasts to all hosts. It is equal to the
-	 * minimum of all registered nodes. A registered node is one with
-	 * a nonzero offset. Set the values rediculously high to start. We
-	 * know we have atleast one to change the default to.  */
-	sspd = 0xff;
-	max_rec = 0xff;
-	for (i = 0; i < ALL_NODES; i++) {
-		if (!priv->fifo_hi && !priv->fifo_lo) continue; /* Unregistered */
-		if (priv->max_rec[i] < max_rec) max_rec = priv->max_rec[i];
-		if (priv->sspd[i] < sspd) sspd = priv->sspd[i];
-	}
-
-	priv->max_rec[ALL_NODES] = max_rec;
-	priv->sspd[ALL_NODES] = sspd;
+	priv->max_rec[ALL_NODES] = min(priv->max_rec[ALL_NODES], max_rec);
+	priv->sspd[ALL_NODES] = min(priv->sspd[ALL_NODES], sspd);
 
 	return;
 }
@@ -257,6 +333,7 @@
 static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
 {
 	unsigned long flags;
+	int i;
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
 	int phy_id = NODEID_TO_NODE(priv->host->node_id);
 	struct hpsb_host *host = priv->host;
@@ -264,7 +341,7 @@
 	spin_lock_irqsave (&priv->lock, flags);
 
 	/* Clear the speed/payload/offset tables */
-	memset (priv->max_rec, 0, sizeof (priv->max_rec));
+	memset (priv->max_rec, 8, sizeof (priv->max_rec));
 	memset (priv->sspd, 0, sizeof (priv->sspd));
 	memset (priv->fifo_hi, 0, sizeof (priv->fifo_hi));
 	memset (priv->fifo_lo, 0, sizeof (priv->fifo_lo));
@@ -281,16 +358,28 @@
 
 	/* We'll use our max_rec as the default mtu */
 	if (set_mtu)
-		dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) - /* mtu = max_rec - */
-			(sizeof (union eth1394_hdr) + 8);	/* (hdr + GASP) */
+		dev->mtu = (1 << (priv->max_rec[phy_id] + 1)) -
+			(sizeof (union eth1394_hdr) + ETHER1394_OVERHEAD);
 
 	/* Set our hardware address while we're at it */
 	*(nodeid_t *)dev->dev_addr = htons (host->node_id);
 
 	spin_unlock_irqrestore (&priv->lock, flags);
-}
 
-static int ether1394_tx (struct sk_buff *skb, struct net_device *dev);
+	for(i = 0; i < ALL_NODES; i++) {
+		struct list_head *lh, *n;
+
+		spin_lock_irqsave(&priv->pdg[i].lock, flags);
+		if(!set_mtu) {
+			list_for_each_safe(lh, n, &priv->pdg[i].list) {
+				purge_partial_datagram(lh);
+			}
+		}
+		INIT_LIST_HEAD(&(priv->pdg[i].list));
+		priv->pdg[i].sz = 0;
+		spin_unlock_irqrestore(&priv->pdg[i].lock, flags);
+	}
+}
 
 /* This function is called by register_netdev */
 static int ether1394_init_dev (struct net_device *dev)
@@ -321,6 +410,7 @@
  */
 static void ether1394_add_host (struct hpsb_host *host)
 {
+	int i;
 	struct host_info *hi = NULL;
 	struct net_device *dev = NULL;
 	struct eth1394_priv *priv;
@@ -343,6 +433,12 @@
 	priv->host = host;
 	spin_lock_init(&priv->lock);
 
+	for(i = 0; i < ALL_NODES; i++) {
+                spin_lock_init(&priv->pdg[i].lock);
+		INIT_LIST_HEAD(&priv->pdg[i].list);
+		priv->pdg[i].sz = 0;
+	}
+
 	hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
 
 	if (hi == NULL)
@@ -360,10 +456,10 @@
 	hi->dev = dev;
 
 	/* Ignore validity in hopes that it will be set in the future.  It'll
-	 * check it on transmit. */
+	 * be checked when the eth device is opened. */
 	priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
 
-	priv->iso = hpsb_iso_recv_init(host, 8 * 4096, 8, priv->broadcast_channel,
+	priv->iso = hpsb_iso_recv_init(host, 16 * 4096, 16, priv->broadcast_channel,
 				       1, ether1394_iso);
 	if (priv->iso == NULL) {
 		priv->bc_state = ETHER1394_BC_CLOSED;
@@ -372,7 +468,7 @@
 
 out:
 	if (dev != NULL)
-		kfree (dev);
+		kfree (dev); dev = NULL;
 	if (hi)
 		hpsb_destroy_hostinfo(&eth1394_highlevel, host);
 
@@ -393,7 +489,7 @@
 		unregister_netdev (hi->dev);
 		hpsb_iso_shutdown(priv->iso);
 
-		kfree (hi->dev);
+		kfree (hi->dev); hi->dev = NULL;
 	}
 
 	return;
@@ -417,6 +513,11 @@
 	netif_wake_queue (dev);
 }
 
+
+/******************************************
+ * Datagram reception code
+ ******************************************/
+
 /* Copied from net/ethernet/eth.c */
 static inline unsigned short ether1394_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
@@ -451,9 +552,8 @@
 /* Parse an encapsulated IP1394 header into an ethernet frame packet.
  * We also perform ARP translation here, if need be.  */
 static inline unsigned short ether1394_parse_encap (struct sk_buff *skb, struct net_device *dev,
-					     nodeid_t srcid, nodeid_t destid)
+						    nodeid_t srcid, nodeid_t destid, u16 ether_type)
 {
-	union eth1394_hdr *hdr = (union eth1394_hdr *)skb->data;
 	unsigned char src_hw[ETH_ALEN], dest_hw[ETH_ALEN];
 	unsigned short ret = 0;
 
@@ -462,14 +562,10 @@
 	*(u16 *)dest_hw = htons(destid);
 	*(u16 *)src_hw = htons(srcid);
 
-	/* Remove the encapsulation header */
-	hdr->words.word1 = ntohs(hdr->words.word1);
-	skb_pull (skb, hdr_type_len[hdr->common.lf]);
-
 	/* If this is an ARP packet, convert it. First, we want to make
 	 * use of some of the fields, since they tell us a little bit
 	 * about the sending machine.  */
-	if (hdr->uf.ether_type == __constant_htons (ETH_P_ARP)) {
+	if (ether_type == __constant_htons (ETH_P_ARP)) {
 		unsigned long flags;
 		u16 phy_id = NODEID_TO_NODE(srcid);
 		struct eth1394_priv *priv =
@@ -503,49 +599,318 @@
 	}
 
 	/* Now add the ethernet header. */
-	if (dev->hard_header (skb, dev, __constant_ntohs (hdr->uf.ether_type),
+	if (dev->hard_header (skb, dev, __constant_ntohs (ether_type),
 			      dest_hw, src_hw, skb->len) >= 0)
 		ret = ether1394_type_trans(skb, dev);
 
 	return ret;
 }
 
+static inline int fragment_overlap(struct list_head *frag_list, int offset, int len)
+{
+	struct list_head *lh;
+	struct fragment_info *fi;
+
+	list_for_each(lh, frag_list) {
+		fi = list_entry(lh, struct fragment_info, list);
+
+		if( ! ((offset > (fi->offset + fi->len - 1)) ||
+		       ((offset + len - 1) < fi->offset)))
+			return 1;
+	}
+	return 0;
+}
+
+static inline struct list_head *find_partial_datagram(struct list_head *pdgl, int dgl)
+{
+	struct list_head *lh;
+	struct partial_datagram *pd;
+
+	list_for_each(lh, pdgl) {
+		pd = list_entry(lh, struct partial_datagram, list);
+		if(pd->dgl == dgl)
+			return lh;
+	}
+	return NULL;
+}
+
+/* Assumes that new fragment does not overlap any existing fragments */
+static inline int new_fragment(struct list_head *frag_info, int offset, int len)
+{
+	struct list_head *lh;
+	struct fragment_info *fi, *fi2, *new;
+
+	list_for_each(lh, frag_info) {
+		fi = list_entry(lh, struct fragment_info, list);
+		if((fi->offset + fi->len) == offset) {
+			/* The new fragment can be tacked on to the end */
+			fi->len += len;
+			/* Did the new fragment plug a hole? */
+			fi2 = list_entry(lh->next, struct fragment_info, list);
+			if((fi->offset + fi->len) == fi2->offset) {
+				/* glue fragments together */
+				fi->len += fi2->len;
+				list_del(lh->next);
+				kfree(fi2); fi2 = NULL;
+			}
+			return 0;
+		} else if((offset + len) == fi->offset) {
+			/* The new fragment can be tacked on to the beginning */
+			fi->offset = offset;
+			fi->len += len;
+			/* Did the new fragment plug a hole? */
+			fi2 = list_entry(lh->prev, struct fragment_info, list);
+			if((fi2->offset + fi2->len) == fi->offset) {
+				/* glue fragments together */
+				fi2->len += fi->len;
+				list_del(lh);
+				kfree(fi); fi = NULL;
+			}
+			return 0;
+		} else if(offset > (fi->offset + fi->len)) {
+			break;
+		} else if ((offset + len) < fi->offset) {
+			lh = lh->prev;
+			break;
+		}
+	}
+
+	new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC);
+	if(!new) 
+		return -ENOMEM;
+
+	new->offset = offset;
+	new->len = len;
+
+	list_add(&new->list, lh);
+
+	return 0;
+}
+
+static inline int new_partial_datagram(struct net_device *dev,
+				       struct list_head *pdgl, int dgl,
+				       int dg_size, char *frag_buf,
+				       int frag_off, int frag_len)
+{
+	struct partial_datagram *new;
+
+	new = kmalloc(sizeof(struct partial_datagram), GFP_ATOMIC);
+	if(!new)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&new->frag_info);
+
+	if(new_fragment(&new->frag_info, frag_off, frag_len) < 0) {
+		kfree(new); new = NULL;
+		return -ENOMEM;
+	}
+
+	new->dgl = dgl;
+	new->dg_size = dg_size;
+
+	new->skb = dev_alloc_skb(dg_size + dev->hard_header_len + 15);
+	if(!new->skb) {
+		struct fragment_info *fi = list_entry(new->frag_info.next,
+						      struct fragment_info,
+						      list);
+		kfree(fi); fi = NULL;
+		kfree(new); new = NULL;
+		return -ENOMEM;
+	}
+
+	skb_reserve(new->skb, (dev->hard_header_len + 15) & ~15);
+	new->pbuf = skb_put(new->skb, dg_size);
+	memcpy(new->pbuf + frag_off, frag_buf, frag_len);
+
+	list_add(&new->list, pdgl);
+
+	return 0;
+}
+
+static inline int update_partial_datagram(struct list_head *pdgl, struct list_head *lh,
+					  char *frag_buf, int frag_off, int frag_len)
+{
+	struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list);
+
+	if(new_fragment(&pd->frag_info, frag_off, frag_len) < 0) {
+		return -ENOMEM;
+	}
+
+	memcpy(pd->pbuf + frag_off, frag_buf, frag_len);
+
+	/* Move list entry to beginnig of list so that oldest partial
+	 * datagrams percolate to the end of the list */
+	list_del(lh);
+	list_add(lh, pdgl);
+
+	return 0;
+}
+
+static inline void purge_partial_datagram(struct list_head *old)
+{
+	struct partial_datagram *pd = list_entry(old, struct partial_datagram, list);
+	struct list_head *lh, *n;
+
+	list_for_each_safe(lh, n, &pd->frag_info) {
+		struct fragment_info *fi = list_entry(lh, struct fragment_info, list);
+		list_del(lh);
+		kfree(fi); fi = NULL;
+	}
+	list_del(old);
+	kfree_skb(pd->skb); pd->skb = NULL;
+	kfree(pd); pd = NULL;
+}
+
+static inline int is_datagram_complete(struct list_head *lh, int dg_size)
+{
+	struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list);
+	struct fragment_info *fi = list_entry(pd->frag_info.next,
+					      struct fragment_info, list);
+
+	return (fi->len == dg_size);
+}
+
 /* Packet reception. We convert the IP1394 encapsulation header to an
  * ethernet header, and fill it with some of our other fields. This is
  * an incoming packet from the 1394 bus.  */
-static int ether1394_write (struct hpsb_host *host, int srcid, int destid,
-			    quadlet_t *data, u64 addr, unsigned int len, u16 fl)
+static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
+				  char *buf, int len)
 {
 	struct sk_buff *skb;
-	char *buf = (char *)data;
 	unsigned long flags;
-	struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
-	struct net_device *dev;
 	struct eth1394_priv *priv;
+	union eth1394_hdr *hdr = (union eth1394_hdr *)buf;
+	u16 ether_type = 0;  /* initialized to clear warning */
+	int hdr_len;
 
-	if (hi == NULL) {
-		ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %p\n",
-				 host);
-		return RCODE_ADDRESS_ERROR;
-	}
+	priv = (struct eth1394_priv *)dev->priv;
 
-	dev = hi->dev;
+	/* First, did we receive a fragmented or unfragmented datagram? */
+	hdr->words.word1 = ntohs(hdr->words.word1);
 
-	priv = (struct eth1394_priv *)dev->priv;
+	hdr_len = hdr_type_len[hdr->common.lf];
 
-	/* A packet has been received by the ieee1394 bus. Build an skbuff
-	 * around it so we can pass it to the high level network layer. */
+	if(hdr->common.lf == ETH1394_HDR_LF_UF) {
+		/* An unfragmented datagram has been received by the ieee1394
+		 * bus. Build an skbuff around it so we can pass it to the
+		 * high level network layer. */
 
-	skb = dev_alloc_skb (len + dev->hard_header_len + 15);
-	if (!skb) {
-		HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
-		priv->stats.rx_dropped++;
-		return RCODE_ADDRESS_ERROR;
+		skb = dev_alloc_skb(len + dev->hard_header_len + 15);
+		if (!skb) {
+			HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
+			priv->stats.rx_dropped++;
+			return -1;
+		}
+		skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+		memcpy(skb_put(skb, len - hdr_len), buf + hdr_len, len - hdr_len);
+		ether_type = hdr->uf.ether_type;
+	} else {
+#if 0
+		return 0;
 	}
+	if(0) {
+#endif
+		/* A datagram fragment has been received, now the fun begins. */
+
+		struct list_head *pdgl, *lh;
+		struct partial_datagram *pd;
+		int fg_off;
+		int fg_len = len - hdr_len;
+		int dg_size;
+		int dgl;
+		int retval;
+		int sid = NODEID_TO_NODE(srcid);
+                struct pdg_list *pdg = &(priv->pdg[sid]);
+
+		hdr->words.word3 = ntohs(hdr->words.word3);
+		/* The 4th header word is reserved so no need to do ntohs() */
+
+		if(hdr->common.lf == ETH1394_HDR_LF_FF) {
+			ether_type = hdr->ff.ether_type;
+			dgl = hdr->ff.dgl;
+			dg_size = hdr->ff.dg_size;
+			fg_off = 0;
+		} else {
+			hdr->words.word2 = ntohs(hdr->words.word2);
+			dgl = hdr->sf.dgl;
+			dg_size = hdr->sf.dg_size;
+			fg_off = hdr->sf.fg_off;
+		}
 
-	skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+		spin_lock_irqsave(&pdg->lock, flags);
 
-	memcpy (skb_put (skb, len), buf, len);
+		pdgl = &(pdg->list);
+		lh = find_partial_datagram(pdgl, dgl);
+
+		if(lh == NULL) {
+			if(pdg->sz == max_partial_datagrams) {
+				/* remove the oldest */
+				purge_partial_datagram(pdgl->prev);
+				pdg->sz--;
+			}
+            
+			retval = new_partial_datagram(dev, pdgl, dgl, dg_size,
+						      buf + hdr_len, fg_off,
+						      fg_len);
+			if(retval < 0) {
+				spin_unlock_irqrestore(&pdg->lock, flags);
+				goto bad_proto;
+			}
+			pdg->sz++;
+			lh = find_partial_datagram(pdgl, dgl);
+		} else {
+			struct partial_datagram *pd;
+
+			pd = list_entry(lh, struct partial_datagram, list);
+
+			if(fragment_overlap(&pd->frag_info, fg_off, fg_len)) {
+				/* Overlapping fragments, obliterate old
+				 * datagram and start new one. */
+				purge_partial_datagram(lh);
+				retval = new_partial_datagram(dev, pdgl, dgl,
+							      dg_size,
+							      buf + hdr_len,
+							      fg_off, fg_len);
+				if(retval < 0) {
+					pdg->sz--;
+					spin_unlock_irqrestore(&pdg->lock, flags);
+					goto bad_proto;
+				}
+			} else {
+				retval = update_partial_datagram(pdgl, lh,
+								 buf + hdr_len,
+								 fg_off, fg_len);
+				if(retval < 0) {
+					/* Couldn't save off fragment anyway
+					 * so might as well obliterate the
+					 * datagram now. */
+					purge_partial_datagram(lh);
+					pdg->sz--;
+					spin_unlock_irqrestore(&pdg->lock, flags);
+					goto bad_proto;
+				}
+			} /* fragment overlap */
+		} /* new datagram or add to existing one */
+
+		pd = list_entry(lh, struct partial_datagram, list);
+
+		if(hdr->common.lf == ETH1394_HDR_LF_FF) {
+			pd->ether_type = ether_type;
+		}
+
+		if(is_datagram_complete(lh, dg_size)) {
+			ether_type = pd->ether_type;
+			pdg->sz--;
+			skb = skb_get(pd->skb);
+			purge_partial_datagram(lh);
+			spin_unlock_irqrestore(&pdg->lock, flags);
+		} else {
+			/* Datagram is not complete, we're done for the
+			 * moment. */
+			spin_unlock_irqrestore(&pdg->lock, flags);
+			return 0;
+		}
+	} /* unframgented datagram or fragmented one */
 
 	/* Write metadata, and then pass to the receive level */
 	skb->dev = dev;
@@ -555,18 +920,19 @@
 	 * converting to an ethernet frame header, aswell as arp
 	 * conversion if needed. ARP conversion is easier in this
 	 * direction, since we are using ethernet as our backend.  */
-	skb->protocol = ether1394_parse_encap (skb, dev, srcid, destid);
+	skb->protocol = ether1394_parse_encap(skb, dev, srcid, destid,
+					      ether_type);
 
-	spin_lock_irqsave (&priv->lock, flags);
-	if (!skb->protocol) {
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if(!skb->protocol) {
 		priv->stats.rx_errors++;
 		priv->stats.rx_dropped++;
 		dev_kfree_skb_any(skb);
 		goto bad_proto;
 	}
 
-	netif_stop_queue(dev);
-	if (netif_rx (skb) == NET_RX_DROP) {
+	if(netif_rx(skb) == NET_RX_DROP) {
 		priv->stats.rx_errors++;
 		priv->stats.rx_dropped++;
 		goto bad_proto;
@@ -577,20 +943,36 @@
 	priv->stats.rx_bytes += skb->len;
 
 bad_proto:
-	netif_start_queue(dev);
-	spin_unlock_irqrestore (&priv->lock, flags);
+	if(netif_queue_stopped(dev))
+		netif_wake_queue(dev);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	dev->last_rx = jiffies;
 
-	return RCODE_COMPLETE;
+	return 0;
+}
+
+static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
+			   quadlet_t *data, u64 addr, unsigned int len, u16 flags)
+{
+	struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, host);
+
+	if(hi == NULL) {
+		ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n",
+				host->driver->name);
+		return RCODE_ADDRESS_ERROR;
+	}
+
+	if(ether1394_data_handler(hi->dev, srcid, destid, (char*)data, len))
+		return RCODE_ADDRESS_ERROR;
+	else
+		return RCODE_COMPLETE;
 }
 
 static void ether1394_iso(struct hpsb_iso *iso)
 {
-	struct sk_buff *skb;
 	quadlet_t *data;
 	char *buf;
-	unsigned long flags;
 	struct host_info *hi = hpsb_get_hostinfo(&eth1394_highlevel, iso->host);
 	struct net_device *dev;
 	struct eth1394_priv *priv;
@@ -600,9 +982,9 @@
 	int i;
 	int nready;
 
-	if (hi == NULL) {
-		ETH1394_PRINT_G (KERN_ERR, "Could not find net device for host %s\n",
-				 iso->host->driver->name);
+	if(hi == NULL) {
+		ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n",
+				iso->host->driver->name);
 		return;
 	}
 
@@ -623,186 +1005,289 @@
 
 		priv = (struct eth1394_priv *)dev->priv;
 
-		if (info->channel != priv->broadcast_channel ||
-		    specifier_id != ETHER1394_GASP_SPECIFIER_ID) {
+		if(info->channel != (iso->host->csr.broadcast_channel & 0x3f) ||
+		   specifier_id != ETHER1394_GASP_SPECIFIER_ID) {
 			/* This packet is not for us */
 			continue;
 		}
+		ether1394_data_handler(dev, source_id, iso->host->node_id, buf, len);
+	}
 
-		/* A packet has been received by the ieee1394 bus. Build an skbuff
-		 * around it so we can pass it to the high level network layer. */
-		skb = dev_alloc_skb (len + dev->hard_header_len + 15);
-		if (!skb) {
-			HPSB_PRINT (KERN_ERR, "ether1394 rx: low on mem\n");
-			priv->stats.rx_dropped++;
-			break;
-		}
+	hpsb_iso_recv_release_packets(iso, i);
 
-		skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
+	dev->last_rx = jiffies;
+}
 
-		memcpy (skb_put (skb, len), buf, len);
+/******************************************
+ * Datagram transmission code
+ ******************************************/
 
-		/* Write metadata, and then pass to the receive level */
-		skb->dev = dev;
-		skb->ip_summed = CHECKSUM_UNNECESSARY;	/* don't check it */
-
-		/* Parse the encapsulation header. This actually does the job of
-		 * converting to an ethernet frame header, aswell as arp
-		 * conversion if needed. ARP conversion is easier in this
-		 * direction, since we are using ethernet as our backend.  */
-		skb->protocol = ether1394_parse_encap (skb, dev, source_id,
-						       LOCAL_BUS | ALL_NODES);
+/* We need to encapsulate the standard header with our own. We use the
+ * ethernet header's proto for our own. */
+static inline unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
+						      int proto,
+						      union eth1394_hdr *hdr,
+						      u16 dg_size, u16 dgl)
+{
+	unsigned int adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_UF];
 
-		spin_lock_irqsave (&priv->lock, flags);
-		if (!skb->protocol) {
-			priv->stats.rx_errors++;
-			priv->stats.rx_dropped++;
-			dev_kfree_skb_any(skb);
-			goto bad_proto;
-		}
+	/* Does it all fit in one packet? */
+	if(dg_size <= adj_max_payload) {
+		hdr->uf.lf = ETH1394_HDR_LF_UF;
+		hdr->uf.ether_type = proto;
+	} else {
+		hdr->ff.lf = ETH1394_HDR_LF_FF;
+		hdr->ff.ether_type = proto;
+		hdr->ff.dg_size = dg_size;
+		hdr->ff.dgl = dgl;
+		adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
+	}
 
-		netif_stop_queue(dev);
-		if (netif_rx (skb) == NET_RX_DROP) {
-			priv->stats.rx_errors++;
-			priv->stats.rx_dropped++;
-			goto bad_proto;
-		}
+	return((dg_size + (adj_max_payload - 1)) / adj_max_payload);
+}
 
-		/* Statistics */
-		priv->stats.rx_packets++;
-		priv->stats.rx_bytes += skb->len;
+static inline unsigned int ether1394_encapsulate(struct sk_buff *skb,
+						 unsigned int max_payload,
+						 union eth1394_hdr *hdr)
+{
+	union eth1394_hdr *bufhdr;
+	int ftype = hdr->common.lf;
+	int hdrsz = hdr_type_len[ftype];
+	unsigned int adj_max_payload = max_payload - hdrsz;
+
+	switch(ftype) {
+	case ETH1394_HDR_LF_UF:
+		bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz);
+		bufhdr->words.word1 = htons(hdr->words.word1);
+		bufhdr->words.word2 = hdr->words.word2;
+		break;
 
-	bad_proto:
-		spin_unlock_irqrestore (&priv->lock, flags);
+	case ETH1394_HDR_LF_FF:
+		bufhdr = (union eth1394_hdr *)skb_push(skb, hdrsz);
+		bufhdr->words.word1 = htons(hdr->words.word1);
+		bufhdr->words.word2 = hdr->words.word2;
+		bufhdr->words.word3 = htons(hdr->words.word3);
+		bufhdr->words.word4 = 0;
+
+		/* Set frag type here for future interior fragments */
+		hdr->common.lf = ETH1394_HDR_LF_IF;
+		hdr->sf.fg_off = 0;
+		break;
+		
+	default:
+		hdr->sf.fg_off += adj_max_payload;
+		bufhdr = (union eth1394_hdr *)skb_pull(skb, adj_max_payload);
+		if(max_payload >= skb->len)
+			hdr->common.lf = ETH1394_HDR_LF_LF;
+		bufhdr->words.word1 = htons(hdr->words.word1);
+		bufhdr->words.word2 = htons(hdr->words.word2);
+		bufhdr->words.word3 = htons(hdr->words.word3);
+		bufhdr->words.word4 = 0;
 	}
 
-	hpsb_iso_recv_release_packets(iso, i);
+	return min(max_payload, skb->len);
+}
 
-	netif_start_queue(dev);
-	
-	dev->last_rx = jiffies;
+static inline struct hpsb_packet *ether1394_alloc_common_packet(struct hpsb_host *host)
+{
+	struct hpsb_packet *p;
 
-	return;
+	p = alloc_hpsb_packet(0);
+	if(p) {
+		p->host = host;
+		p->data = NULL;
+		p->generation = get_hpsb_generation(host);
+		p->type = hpsb_async;
+	}
+	return p;
 }
 
+static inline int ether1394_prep_write_packet(struct hpsb_packet *p,
+					      struct hpsb_host *host,
+					      nodeid_t node, u64 addr,
+					      void * data, int tx_len)
+{
+	p->node_id = node;
+	p->data = NULL;
+
+	p->tcode = TCODE_WRITEB;
+	p->header[1] = (host->node_id << 16) | (addr >> 32);
+	p->header[2] = addr & 0xffffffff;
+
+	p->header_size = 16;
+	p->expect_response = 1;
+
+	if(hpsb_get_tlabel(p, !in_interrupt())) {
+		ETH1394_PRINT_G(KERN_ERR, "No more tlabels left");
+		return -1;
+	}		
+	p->header[0] = (p->node_id << 16) | (p->tlabel << 10)
+		| (1 << 8) | (TCODE_WRITEB << 4);
+
+	p->header[3] = tx_len << 16;
+	p->data_size = tx_len + (tx_len % 4 ? 4 - (tx_len % 4) : 0);
+	p->data = (quadlet_t*)data;
+
+	return 0;
+}
 
-/* This function is our scheduled write */
-static void hpsb_write_sched (void *__ptask)
+static inline void ether1394_prep_gasp_packet(struct hpsb_packet *p,
+					      struct hpsb_host *host,
+					      struct sk_buff *skb, int length)
 {
-	struct packet_task *ptask = (struct packet_task *)__ptask;
-	struct sk_buff *skb = ptask->skb;
-	struct net_device *dev = ptask->skb->dev;
-	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
-	unsigned long flags;
-	int status;
- 
-	if (ptask->tx_type == ETH1394_GASP) {
-		status  = hpsb_send_gasp(priv->host, priv->broadcast_channel,
-					 get_hpsb_generation(priv->host),
-					 (quadlet_t *)skb->data, skb->len,
-					 ETHER1394_GASP_SPECIFIER_ID,
-					 ETHER1394_GASP_VERSION);
+	p->header_size = 4;
+	p->tcode = TCODE_STREAM_DATA;
+
+	p->header[0] = (length << 16) | (3 << 14)
+		| ((host->csr.broadcast_channel & 0x3f) << 8)
+		| (TCODE_STREAM_DATA << 4);
+	p->data_size = length;
+	p->data = (quadlet_t*)skb_push(skb, 2 * sizeof(quadlet_t));
+	p->data[0] = cpu_to_be32((host->node_id << 16) |
+				      ETHER1394_GASP_SPECIFIER_ID_HI);
+	p->data[1] = cpu_to_be32((ETHER1394_GASP_SPECIFIER_ID_LO << 24) |
+				      ETHER1394_GASP_VERSION);
+}
+
+static inline void ether1394_free_packet(struct hpsb_packet *packet)
+{
+	packet->data = NULL;
+	free_hpsb_packet(packet); packet = NULL;
+}
+
+static void ether1394_complete_cb(void *__ptask);
+static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
+{
+	struct eth1394_priv *priv = ptask->priv;
+	struct hpsb_packet *packet;
+
+	packet = ether1394_alloc_common_packet(priv->host);
+	if(!packet)
+		return -1;
+
+	if(ptask->tx_type == ETH1394_GASP) {
+		int length = tx_len + (2 * sizeof(quadlet_t));
+
+		ether1394_prep_gasp_packet(packet, priv->host,
+						    ptask->skb, length);
+
 	} else {
-		status = hpsb_write(priv->host, ptask->dest_node,
-				    get_hpsb_generation(priv->host),
-				    ptask->addr, (quadlet_t *)skb->data,
-				    skb->len);
+		if(ether1394_prep_write_packet(packet, priv->host,
+					       ptask->dest_node,
+					       ptask->addr, ptask->skb->data,
+					       tx_len))
+			goto fail;
 	}
 
+	ptask->packet = packet;
+	hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb,
+				      ptask);
 
+	if(hpsb_send_packet(packet)) {
+		return 0;
+	}
+fail:
+	return -1;
+}
+
+
+/* Task function to be run when a datagram transmission is completed */
+static inline void ether1394_dg_complete(struct packet_task *ptask, int fail)
+{
+	struct sk_buff *skb = ptask->skb;
+	struct net_device *dev = skb->dev;
+	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
+        unsigned long flags;
+		
 	/* Statistics */
-	spin_lock_irqsave (&priv->lock, flags);
-	if (!status) {
-		priv->stats.tx_bytes += skb->len;
-		priv->stats.tx_packets++;
-	} else {
-		//printk("Failed in hpsb_write_sched\n");
+	if(fail) {
+		spin_lock_irqsave(&priv->lock, flags);
 		priv->stats.tx_dropped++;
 		priv->stats.tx_errors++;
-		if (netif_queue_stopped (dev))
-			netif_wake_queue (dev);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	} else {
+		spin_lock_irqsave(&priv->lock, flags);
+		priv->stats.tx_bytes += skb->len;
+		priv->stats.tx_packets++;
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
-	spin_unlock_irqrestore (&priv->lock, flags);
 
-	dev->trans_start = jiffies;
-	dev_kfree_skb(skb);
-	kmem_cache_free(packet_task_cache, ptask);
+	dev_kfree_skb_any(skb); skb = NULL;
+	kmem_cache_free(packet_task_cache, ptask); ptask = NULL;
+}
 
-	return;
+
+/* Callback for when a packet has been sent and the status of that packet is
+ * known */
+static void ether1394_complete_cb(void *__ptask)
+{
+	struct packet_task *ptask = (struct packet_task *)__ptask;
+	struct hpsb_packet *packet = ptask->packet;
+	int fail = 0;
+
+	if(packet->tcode != TCODE_STREAM_DATA) {
+		fail = hpsb_packet_success(packet);
+		hpsb_free_tlabel(packet);
+	}
+
+	ether1394_free_packet(packet); packet = ptask->packet = NULL;
+
+	ptask->outstanding_pkts--;
+	if(ptask->outstanding_pkts > 0 && !fail)
+	{
+		int tx_len;
+
+		/* Add the encapsulation header to the fragment */
+		tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
+					       &ptask->hdr);
+		if(ether1394_send_packet(ptask, tx_len))
+			ether1394_dg_complete(ptask, 1);
+	} else {
+		ether1394_dg_complete(ptask, fail);
+	}
 }
 
+
+
 /* Transmit a packet (called by kernel) */
 static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
 {
-	int kmflags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
+	int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
 	struct ethhdr *eth;
 	struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv;
 	int proto;
 	unsigned long flags;
 	nodeid_t dest_node;
-	u64 addr;
-	struct packet_task *ptask = NULL;
+	eth1394_tx_type tx_type;
 	int ret = 0;
+	unsigned int tx_len;
+	unsigned int max_payload;
+	u16 dg_size;
+	u16 dgl;
+	struct packet_task *ptask;
+
+	ptask = kmem_cache_alloc(packet_task_cache, kmflags);
+	if(ptask == NULL) {
+		ret = -ENOMEM;
+		goto fail;
+	}
 
 	spin_lock_irqsave (&priv->lock, flags);
 	if (priv->bc_state == ETHER1394_BC_CLOSED) {
 		ETH1394_PRINT(KERN_ERR, dev->name,
-			      "Cannot send packet, no broadcast channel available.");
+			      "Cannot send packet, no broadcast channel available.\n");
 		ret = -EAGAIN;
+		spin_unlock_irqrestore (&priv->lock, flags);
 		goto fail;
 	}
 
-	/* First time sending?  Need a broadcast channel for ARP and for
-	 * listening on */
 	if (priv->bc_state == ETHER1394_BC_CHECK) {
-		quadlet_t bc;
-
-		/* Get the local copy of the broadcast channel and check its
-		 * validity (the IRM should validate it for us) */
-
-		bc = priv->host->csr.broadcast_channel;
-
-		if ((bc & 0xc0000000) != 0xc0000000) {
-			/* broadcast channel not validated yet */
-			ETH1394_PRINT(KERN_WARNING, dev->name,
-				      "Error BROADCAST_CHANNEL register valid "
-				      "bit not set, can't send IP traffic\n");
-			hpsb_iso_shutdown(priv->iso);
-			priv->bc_state = ETHER1394_BC_CLOSED;
-			ret = -EAGAIN;
+		if(ether1394_init_bc(dev)) {
 			spin_unlock_irqrestore (&priv->lock, flags);
 			goto fail;
 		}
-		if (priv->broadcast_channel != (bc & 0x3f)) {
-			/* This really shouldn't be possible, but just in case
-			 * the IEEE 1394 spec changes regarding broadcast
-			 * channels in the future. */
-			hpsb_iso_shutdown(priv->iso);
-
-			priv->broadcast_channel = bc & 0x3f;
-			ETH1394_PRINT(KERN_WARNING, dev->name,
-				      "Changing to broadcast channel %d...\n",
-				      priv->broadcast_channel);
-
-			priv->iso = hpsb_iso_recv_init(priv->host, 8 * 4096,
-						       8, priv->broadcast_channel,
-						       1, ether1394_iso);
-			if (priv->iso == NULL) {
-				ret = -EAGAIN;
-				goto fail;
-			}
-		}
-		if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) {
-			ETH1394_PRINT(KERN_ERR, dev->name,
-				      "Could not start async reception\n");
-			hpsb_iso_shutdown(priv->iso);
-			priv->bc_state = ETHER1394_BC_CLOSED;
-			ret = -EAGAIN;
-			spin_unlock_irqrestore (&priv->lock, flags);
-			goto fail;
-		}
-		priv->bc_state = ETHER1394_BC_OPENED;
 	}
+
 	spin_unlock_irqrestore (&priv->lock, flags);
 
 	if ((skb = skb_share_check (skb, kmflags)) == NULL) {
@@ -823,53 +1308,82 @@
 	if (proto == __constant_htons (ETH_P_ARP))
 		ether1394_arp_to_1394arp (skb, dev);
 
-	ptask = kmem_cache_alloc(packet_task_cache, kmflags);
-	if (ptask == NULL) {
-		ret = -ENOMEM;
-		goto fail;
-	}
+	max_payload = 1 << (min(priv->max_rec[NODEID_TO_NODE(priv->host->node_id)],
+                                priv->max_rec[NODEID_TO_NODE(dest_node)]) + 1);
 
-	/* Now add our encapsulation header */
-	ether1394_encapsulate (skb, dev, proto, ptask);
+	if(max_payload < 512)
+		max_payload = 512;
 
-	/* TODO: The above encapsulate function needs to recognize when a
-	 * packet needs to be split for a specified node. It should create
-	 * a list of skb's that we could then iterate over for the below
-	 * call to schedule our writes.  */
-
-	/* XXX: Right now we accept that we don't exactly follow RFC. When
-	 * we do, we will send ARP requests via GASP format, and so we won't
-	 * need this hack.  */
+	/* Set the transmission type for the packet.  Right now only ARP
+	 * packets are sent via GASP.  IP broadcast and IP multicast are not
+	 * yet supported properly, they too should use GASP. */
+	switch(proto) {
+	case __constant_htons(ETH_P_ARP):
+		tx_type = ETH1394_GASP;
+                max_payload -= ETHER1394_OVERHEAD;
+		break;
+	default:
+		tx_type = ETH1394_WRREQ;
+	}
+
+	dg_size = skb->len;
 
 	spin_lock_irqsave (&priv->lock, flags);
-	addr = (u64)priv->fifo_hi[NODEID_TO_NODE(dest_node)] << 32 |
-		priv->fifo_lo[NODEID_TO_NODE(dest_node)];
+	dgl = priv->dgl[NODEID_TO_NODE(dest_node)];
+	if(max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF])
+		priv->dgl[NODEID_TO_NODE(dest_node)]++;
 	spin_unlock_irqrestore (&priv->lock, flags);
 
-	if (!addr)
-		addr = ETHER1394_REGION_ADDR;
-
+	ptask->hdr.words.word1 = 0;
+	ptask->hdr.words.word2 = 0;
+	ptask->hdr.words.word3 = 0;
+	ptask->hdr.words.word4 = 0;
 	ptask->skb = skb;
-	ptask->addr = addr;
-	ptask->dest_node = dest_node;
-	/* TODO: When 2.4 is out of the way, give each of our ethernet
-	 * dev's a workqueue to handle these.  */
-	INIT_WORK(&ptask->tq, hpsb_write_sched, ptask);
-	schedule_work(&ptask->tq);
+	ptask->priv = priv;
+	ptask->tx_type = tx_type;
+
+	if(tx_type != ETH1394_GASP) {
+		u64 addr;
 
+		spin_lock_irqsave(&priv->lock, flags);
+		addr = (u64)priv->fifo_hi[NODEID_TO_NODE(dest_node)] << 32 |
+			priv->fifo_lo[NODEID_TO_NODE(dest_node)];
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+		ptask->addr = addr;
+		ptask->dest_node = dest_node;
+	}
+
+	ptask->tx_type = tx_type;
+	ptask->max_payload = max_payload;
+        ptask->outstanding_pkts = ether1394_encapsulate_prep(max_payload, proto,
+							     &ptask->hdr, dg_size,
+							     dgl);
+
+	/* Add the encapsulation header to the fragment */
+	tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
+	dev->trans_start = jiffies;
+	if(ether1394_send_packet(ptask, tx_len))
+		goto fail;
+
+	netif_wake_queue(dev);
 	return 0;
 fail:
-	printk("Failed in ether1394_tx\n");
-
-	if (skb != NULL)
-		dev_kfree_skb (skb);
+	if(ptask->packet)
+		ether1394_free_packet(ptask->packet); ptask->packet = NULL;
+	if(ptask)
+		kmem_cache_free(packet_task_cache, ptask); ptask = NULL;
+	if(skb != NULL) {
+		dev_kfree_skb(skb); skb = NULL;
+	}
 
 	spin_lock_irqsave (&priv->lock, flags);
 	priv->stats.tx_dropped++;
 	priv->stats.tx_errors++;
-	if (netif_queue_stopped (dev))
-		netif_wake_queue (dev);
 	spin_unlock_irqrestore (&priv->lock, flags);
+
+	if (netif_queue_stopped(dev))
+		netif_wake_queue(dev);
 
 	return 0;  /* returning non-zero causes serious problems */
 }
diff -Nru a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h
--- a/drivers/ieee1394/eth1394.h	Fri May  2 05:50:36 2003
+++ b/drivers/ieee1394/eth1394.h	Mon May 19 19:56:24 2003
@@ -24,6 +24,8 @@
 #ifndef __ETH1394_H
 #define __ETH1394_H
 
+#include "ieee1394.h"
+
 /* Register for incoming packets. This is 8192 bytes, which supports up to
  * 1600mbs. We'll need to change this if that ever becomes "small" :)  */
 #define ETHER1394_REGION_ADDR_LEN	8192
@@ -32,14 +34,24 @@
 
 /* GASP identifier numbers for IPv4 over IEEE 1394 */
 #define ETHER1394_GASP_SPECIFIER_ID	0x00005E
+#define ETHER1394_GASP_SPECIFIER_ID_HI	((ETHER1394_GASP_SPECIFIER_ID >> 8) & 0xffff)
+#define ETHER1394_GASP_SPECIFIER_ID_LO	(ETHER1394_GASP_SPECIFIER_ID & 0xff)
 #define ETHER1394_GASP_VERSION		1
 
+#define ETHER1394_OVERHEAD (2 * sizeof(quadlet_t))  /* GASP header overhead */
+
 /* Node set == 64 */
 #define NODE_SET			(ALL_NODES + 1)
 
 enum eth1394_bc_states { ETHER1394_BC_CLOSED, ETHER1394_BC_OPENED,
 			 ETHER1394_BC_CHECK };
 
+struct pdg_list {
+	struct list_head list;		/* partial datagram list per node */
+	unsigned int sz;		/* partial datagram list size per node	*/
+	spinlock_t lock;		/* partial datagram lock		*/
+};
+
 /* Private structure for our ethernet driver */
 struct eth1394_priv {
 	struct net_device_stats stats;	/* Device stats			 */
@@ -53,6 +65,8 @@
 	int broadcast_channel;		/* Async stream Broadcast Channel */
 	enum eth1394_bc_states bc_state; /* broadcast channel state	 */
 	struct hpsb_iso *iso;		/* Async stream recv handle	 */
+	struct pdg_list pdg[ALL_NODES]; /* partial RX datagram lists     */
+	int dgl[NODE_SET];              /* Outgoing datagram label per node */
 };
 
 struct host_info {
@@ -62,29 +76,20 @@
 
 typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
 
-/* This is our task struct. It's used for the packet complete callback.  */
-struct packet_task {
-	struct sk_buff *skb;	/* Socket buffer we are sending */
-	nodeid_t dest_node;	/* Destination of the packet */
-	u64 addr;		/* Address */
-	struct work_struct tq;	/* The task */
-	eth1394_tx_type tx_type;	/* Send data via GASP or Write Req. */
-};
-
 /* IP1394 headers */
 #include <asm/byteorder.h>
 
 /* Unfragmented */
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_uf_hdr {
-	u8 lf:2;
+	u16 lf:2;
 	u16 res:14;
 	u16 ether_type;		/* Ethernet packet type */
 } __attribute__((packed));
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_uf_hdr {
 	u16 res:14;
-	u8 lf:2;
+	u16 lf:2;
 	u16 ether_type;
 } __attribute__((packed));
 #else
@@ -94,8 +99,8 @@
 /* First fragment */
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_ff_hdr {
-	u8 lf:2;
-	u8 res1:2;
+	u16 lf:2;
+	u16 res1:2;
 	u16 dg_size:12;		/* Datagram size */
 	u16 ether_type;		/* Ethernet packet type */
 	u16 dgl;		/* Datagram label */
@@ -104,8 +109,8 @@
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_ff_hdr {
 	u16 dg_size:12;
-	u8 res1:2;
-	u8 lf:2;
+	u16 res1:2;
+	u16 lf:2;
 	u16 ether_type;
 	u16 dgl;
 	u16 res2;
@@ -117,21 +122,21 @@
 /* XXX: Subsequent fragments, including last */
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_sf_hdr {
-	u8 lf:2;
-	u8 res1:2;
+	u16 lf:2;
+	u16 res1:2;
 	u16 dg_size:12;		/* Datagram size */
-	u8 res2:6;
-	u16 fg_off:10;		/* Fragment offset */
+	u16 res2:4;
+	u16 fg_off:12;		/* Fragment offset */
 	u16 dgl;		/* Datagram label */
 	u16 res3;
 } __attribute__((packed));
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_sf_hdr {
 	u16 dg_size:12;
-	u8 res1:2;
-	u8 lf:2;
-	u16 fg_off:10;
-	u8 res2:6;
+	u16 res1:2;
+	u16 lf:2;
+	u16 fg_off:12;
+	u16 res2:4;
 	u16 dgl;
 	u16 res3;
 } __attribute__((packed));
@@ -141,13 +146,13 @@
 
 #if defined __BIG_ENDIAN_BITFIELD
 struct eth1394_common_hdr {
-	u8 lf:2;
+	u16 lf:2;
 	u16 pad1:14;
 } __attribute__((packed));
 #elif defined __LITTLE_ENDIAN_BITFIELD
 struct eth1394_common_hdr {
 	u16 pad1:14;
-	u8 lf:2;
+	u16 lf:2;
 } __attribute__((packed));
 #else
 #error Unknown bit field type
@@ -198,5 +203,18 @@
 
 /* Network timeout */
 #define ETHER1394_TIMEOUT	100000
+
+/* This is our task struct. It's used for the packet complete callback.  */
+struct packet_task {
+	struct sk_buff *skb;
+	int outstanding_pkts;
+	eth1394_tx_type tx_type;
+	int max_payload;
+	struct hpsb_packet *packet;
+	struct eth1394_priv *priv;
+	union eth1394_hdr hdr;
+	u64 addr;
+	u16 dest_node;
+};
 
 #endif /* __ETH1394_H */
diff -Nru a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
--- a/drivers/ieee1394/ieee1394_core.c	Fri May  2 05:58:06 2003
+++ b/drivers/ieee1394/ieee1394_core.c	Mon May 19 19:56:20 2003
@@ -80,9 +80,12 @@
 static void run_packet_complete(struct hpsb_packet *packet)
 {
 	if (packet->complete_routine != NULL) {
-		packet->complete_routine(packet->complete_data);
+		void (*complete_routine)(void*) = packet->complete_routine;
+		void *complete_data = packet->complete_data;
+
 		packet->complete_routine = NULL;
 		packet->complete_data = NULL;
+		complete_routine(complete_data);
 	}
 	return;
 }
@@ -938,7 +941,7 @@
 {
         unsigned long flags;
         struct hpsb_packet *packet;
-        struct list_head *lh;
+        struct list_head *lh, *tlh;
         LIST_HEAD(llist);
 
         host->driver->devctl(host, CANCEL_REQUESTS, 0);
@@ -948,8 +951,9 @@
         INIT_LIST_HEAD(&host->pending_packets);
         spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 
-        list_for_each(lh, &llist) {
+        list_for_each_safe(lh, tlh, &llist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
+                list_del(&packet->list);
                 packet->state = hpsb_complete;
                 packet->ack_code = ACKX_ABORTED;
                 up(&packet->state_change);
@@ -962,7 +966,7 @@
         unsigned long flags;
         struct hpsb_packet *packet;
         unsigned long expire;
-        struct list_head *lh, *next;
+        struct list_head *lh, *next, *tlh;
         LIST_HEAD(expiredlist);
 
         spin_lock_irqsave(&host->csr.lock, flags);
@@ -990,8 +994,9 @@
 
         spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
 
-        list_for_each(lh, &expiredlist) {
+        list_for_each_safe(lh, tlh, &expiredlist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
+                list_del(&packet->list);
                 packet->state = hpsb_complete;
                 packet->ack_code = ACKX_TIMEOUT;
                 up(&packet->state_change);
diff -Nru a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
--- a/drivers/ieee1394/ieee1394_transactions.c	Wed Mar  5 08:01:26 2003
+++ b/drivers/ieee1394/ieee1394_transactions.c	Mon May 19 19:56:22 2003
@@ -147,6 +147,8 @@
 	spin_lock_irqsave(&tp->lock, flags);
 	
 	packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
+	if(packet->tlabel > 63)
+		packet->tlabel = find_first_zero_bit(tp->pool, 64);
 	tp->next = (packet->tlabel + 1) % 64;
 	/* Should _never_ happen */
 	BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
@@ -573,10 +575,6 @@
 		   quadlet_t *buffer, size_t length, u32 specifier_id,
 		   unsigned int version)
 {
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-	int i;
-#endif
-
 	struct hpsb_packet *packet;
 	int retval = 0;
 	u16 specifier_id_hi = (specifier_id & 0x00ffff00) >> 8;
@@ -603,14 +601,6 @@
 	packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff));
 
 	memcpy(&(packet->data[2]), buffer, length - 4);
-
-#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
-	HPSB_DEBUG("GASP: packet->header_size = %d", packet->header_size);
-	HPSB_DEBUG("GASP: packet->data_size = %d", packet->data_size);
-
-	for(i=0; i<(packet->data_size/4); i++)
-		HPSB_DEBUG("GASP: data[%d]: 0x%08x", i*4, be32_to_cpu(packet->data[i]));
-#endif
 
 	packet->generation = generation;
 
diff -Nru a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
--- a/drivers/ieee1394/ohci1394.c	Mon May 19 07:50:25 2003
+++ b/drivers/ieee1394/ohci1394.c	Tue May 20 11:46:12 2003
@@ -164,7 +164,7 @@
 printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 931 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 938 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 static int phys_dma = 1;
@@ -3165,7 +3165,7 @@
 	struct config_rom_ptr cr;
 
 	memset(&cr, 0, sizeof(cr));
-	memset(ohci->csr_config_rom_cpu, 0, sizeof(*ohci->csr_config_rom_cpu));
+	memset(ohci->csr_config_rom_cpu, 0, OHCI_CONFIG_ROM_LEN);
 
 	cr.data = ohci->csr_config_rom_cpu;
 
@@ -3530,6 +3530,16 @@
 	}
 }
 
+
+#ifdef  CONFIG_PM
+static int ohci1394_pci_resume (struct pci_dev *dev)
+{
+	pci_enable_device(dev);
+	return 0;
+}
+#endif
+
+
 #define PCI_CLASS_FIREWIRE_OHCI     ((PCI_CLASS_SERIAL_FIREWIRE << 8) | 0x10)
 
 static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
@@ -3551,6 +3561,10 @@
 	.id_table =	ohci1394_pci_tbl,
 	.probe =	ohci1394_pci_probe,
 	.remove =	ohci1394_pci_remove,
+
+#ifdef  CONFIG_PM
+	.resume =	ohci1394_pci_resume,
+#endif  /* PM */
 };
 
 
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	Mon May 19 07:50:28 2003
+++ b/drivers/ieee1394/sbp2.c	Mon May 19 19:56:24 2003
@@ -79,7 +79,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-	"$Rev: 931 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 938 $ Ben Collins <bcollins@debian.org>";
 
 /*
  * Module load parameter definitions
@@ -2845,11 +2845,10 @@
 #define SPRINTF(args...) \
         do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
 
-static int sbp2scsi_proc_info(char *buffer, char **start, off_t offset,
-			      int length, int hostno, int inout)
+static int sbp2scsi_proc_info(struct Scsi_Host *scsi_host, char *buffer, char **start, off_t offset,
+			      int length, int inout)
 {
 	Scsi_Device *scd;
-	struct Scsi_Host *scsi_host;
 	struct hpsb_host *host;
 	char *pos = buffer;
 
@@ -2857,16 +2856,12 @@
 	if (inout)
 		return length;
 
-	scsi_host = scsi_host_hn_get(hostno);
-	if (!scsi_host)  /* if we couldn't find it, we return an error */
-		return -ESRCH;
-
 	host = hpsb_get_host_bykey(&sbp2_highlevel, (unsigned long)scsi_host);
 	if (!host) /* shouldn't happen, but... */
 		return -ESRCH;
 
-	SPRINTF("Host scsi%d             : SBP-2 IEEE-1394 (%s)\n", hostno,
-		host->driver->name);
+	SPRINTF("Host scsi%d             : SBP-2 IEEE-1394 (%s)\n",
+		scsi_host->host_no, host->driver->name);
 	SPRINTF("Driver version         : %s\n", version);
 
 	SPRINTF("\nModule options         :\n");
@@ -2899,8 +2894,6 @@
 
 	SPRINTF("\n");
 
-	/* release the reference count on this host */
-	scsi_host_put(scsi_host);
 	/* Calculate start of next buffer, and return value. */
 	*start = buffer + offset;
 
diff -Nru a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
--- a/drivers/isdn/i4l/isdn_tty.c	Mon Apr 21 20:58:42 2003
+++ b/drivers/isdn/i4l/isdn_tty.c	Mon May 26 15:29:23 2003
@@ -64,10 +64,8 @@
 
 #ifdef CONFIG_DEVFS_FS
 static char *isdn_ttyname_ttyI = "isdn/ttyI%d";
-static char *isdn_ttyname_cui = "isdn/cui%d";
 #else
 static char *isdn_ttyname_ttyI = "ttyI";
-static char *isdn_ttyname_cui = "cui";
 #endif
 
 struct isdn_modem isdn_mdm;
@@ -1652,41 +1650,16 @@
 #endif
 	}
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == ISDN_SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ISDN_ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-			return -EBUSY;
-		if ((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ISDN_ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-			return -EBUSY;
-		info->flags |= ISDN_ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	/*
 	 * If non-blocking mode is set, then make the check up front
 	 * and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
-	if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1720,8 +1693,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ISDN_ASYNC_CLOSING) &&
+		if (!(info->flags & ISDN_ASYNC_CLOSING) &&
 		    (do_clocal || (info->msr & UART_MSR_DCD))) {
 			break;
 		}
@@ -1797,14 +1769,9 @@
 		return retval;
 	}
 	if ((info->count == 1) && (info->flags & ISDN_ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == ISDN_SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		isdn_tty_change_speed(info);
 	}
-	info->session = current->session;
-	info->pgrp = current->pgrp;
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_open ttyi%d successful...\n", info->line);
 #endif
@@ -1865,8 +1832,6 @@
 	 */
 	if (info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 
 	tty->closing = 1;
 	/*
@@ -1904,8 +1869,7 @@
 		schedule_timeout(HZ/2);
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE |
-			 ISDN_ASYNC_CLOSING);
+	info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	restore_flags(flags);
 #ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1927,7 +1891,7 @@
 		return;
 	isdn_tty_shutdown(info);
 	info->count = 0;
-	info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ISDN_ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -2054,7 +2018,7 @@
 	m->tty_modem.minor_start = 0;
 	m->tty_modem.num = ISDN_MAX_CHANNELS;
 	m->tty_modem.type = TTY_DRIVER_TYPE_SERIAL;
-	m->tty_modem.subtype = ISDN_SERIAL_TYPE_NORMAL;
+	m->tty_modem.subtype = SERIAL_TYPE_NORMAL;
 	m->tty_modem.init_termios = tty_std_termios;
 	m->tty_modem.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 	m->tty_modem.flags = TTY_DRIVER_REAL_RAW;
@@ -2078,26 +2042,12 @@
 	m->tty_modem.start = NULL;
 	m->tty_modem.hangup = isdn_tty_hangup;
 	m->tty_modem.driver_name = "isdn_tty";
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	m->cua_modem = m->tty_modem;
-	m->cua_modem.name = isdn_ttyname_cui;
-	m->cua_modem.major = ISDN_TTYAUX_MAJOR;
-	m->tty_modem.minor_start = 0;
-	m->cua_modem.subtype = ISDN_SERIAL_TYPE_CALLOUT;
 
 	retval = tty_register_driver(&m->tty_modem);
 	if (retval) {
 		printk(KERN_WARNING "isdn_tty: Couldn't register modem-device\n");
 		goto err;
 	}
-	retval = tty_register_driver(&m->cua_modem);
-	if (retval) {
-		printk(KERN_WARNING "isdn_tty: Couldn't register modem-callout-device\n");
-		goto err_unregister_tty;
-	}
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		info = &m->info[i];
 #ifdef CONFIG_ISDN_TTY_FAX
@@ -2121,7 +2071,6 @@
 		info->x_char = 0;
 		info->count = 0;
 		info->blocked_open = 0;
-		info->callout_termios = m->cua_modem.init_termios;
 		info->normal_termios = m->tty_modem.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
@@ -2167,7 +2116,6 @@
 #endif
 		kfree(info->xmit_buf - 4);
 	}
-	tty_unregister_driver(&isdn_mdm.cua_modem);
  err_unregister_tty:
 	tty_unregister_driver(&isdn_mdm.tty_modem);
  err:
@@ -2189,7 +2137,6 @@
 #endif
 		kfree(info->xmit_buf - 4);
 	}
-	tty_unregister_driver(&isdn_mdm.cua_modem);
 	tty_unregister_driver(&isdn_mdm.tty_modem);
 }
 
@@ -2334,7 +2281,7 @@
 }
 
 #define TTY_IS_ACTIVE(info) \
-	(info->flags & (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE))
+	(info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
 
 static int
 isdn_tty_stat_callback(struct isdn_slot *slot, isdn_ctrl *c)
@@ -2833,9 +2780,7 @@
 		}
 		if (info->tty->ldisc.flush_buffer)
 			info->tty->ldisc.flush_buffer(info->tty);
-		if ((info->flags & ISDN_ASYNC_CHECK_CD) &&
-		    (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
-		       (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) {
+		if (info->flags & ISDN_ASYNC_CHECK_CD) {
 			tty_hangup(info->tty);
 		}
 		restore_flags(flags);
diff -Nru a/drivers/isdn/i4l/isdn_tty.h b/drivers/isdn/i4l/isdn_tty.h
--- a/drivers/isdn/i4l/isdn_tty.h	Tue Oct 29 19:01:05 2002
+++ b/drivers/isdn/i4l/isdn_tty.h	Mon May 26 15:29:24 2003
@@ -116,7 +116,6 @@
 struct isdn_modem {
   int                refcount;			   /* Number of opens        */
   struct tty_driver  tty_modem;			   /* tty-device             */
-  struct tty_driver  cua_modem;			   /* cua-device             */
   struct tty_struct  *modem_table[ISDN_MAX_CHANNELS]; /* ?? copied from Orig */
   struct termios     *modem_termios[ISDN_MAX_CHANNELS];
   struct termios     *modem_termios_locked[ISDN_MAX_CHANNELS];
diff -Nru a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c
--- a/drivers/macintosh/macserial.c	Wed May  7 07:11:08 2003
+++ b/drivers/macintosh/macserial.c	Mon May 26 15:29:14 2003
@@ -105,12 +105,11 @@
 #endif
 #define ZS_CLOCK         3686400 	/* Z8530 RTxC input clock rate */
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* serial subtype definitions */
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
@@ -492,7 +491,7 @@
 	    && info->tty && !C_CLOCAL(info->tty)) {
 		if (status & DCD) {
 			wake_up_interruptible(&info->open_wait);
-		} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
+		} else {
 			if (info->tty)
 				tty_hangup(info->tty);
 		}
@@ -1965,8 +1964,6 @@
 	 */
 	if (info->flags & ZILOG_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ZILOG_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -2021,8 +2018,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE|
-			 ZILOG_CLOSING);
+	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 }
 
@@ -2087,7 +2083,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE);
+	info->flags &= ~ZILOG_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -2119,43 +2115,17 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ZILOG_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ZILOG_CALLOUT_ACTIVE;
-		return 0;
-	}
-
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ZILOG_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ZILOG_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ZILOG_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 
 	/*
 	 * Block waiting for the carrier detect and the line to become
@@ -2175,8 +2145,7 @@
 	info->blocked_open++;
 	while (1) {
 		spin_lock_irq(&info->lock);
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD) &&
+		if ((tty->termios->c_cflag & CBAUD) &&
 		    !info->is_irda)
 			zs_rtsdtr(info, 1);
 		spin_unlock_irq(&info->lock);
@@ -2193,8 +2162,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    !(info->flags & ZILOG_CLOSING) &&
+		if (!(info->flags & ZILOG_CLOSING) &&
 		    (do_clocal || (read_zsreg(info->zs_channel, 0) & DCD)))
 			break;
 		if (signal_pending(current)) {
@@ -2291,10 +2259,7 @@
 	}
 
 	if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_speed(info, 0);
 	}
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -2305,9 +2270,6 @@
 	}
 #endif
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 	OPNDBG("rs_open %s successful...\n", tty->name);
 	return 0;
 }
@@ -2644,25 +2606,8 @@
 	serial_driver.wait_until_sent = rs_wait_until_sent;
 	serial_driver.read_proc = macserial_read_proc;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#ifdef CONFIG_DEVFS_FS
-	callout_driver.name = "cua/";
-#else
-	callout_driver.name = "cua";
-#endif /* CONFIG_DEVFS_FS */
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&serial_driver))
 		printk(KERN_ERR "Error: couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		printk(KERN_ERR "Error: couldn't register callout driver\n");
 
 	for (channel = 0; channel < zs_channels_found; ++channel) {
 #ifdef CONFIG_KGDB
@@ -2713,7 +2658,6 @@
 		info->blocked_open = 0;
 		INIT_WORK(&info->tqueue, do_softint, info);
 		spin_lock_init(&info->lock);
-		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
@@ -2758,7 +2702,6 @@
 		}
 	}
 	spin_unlock_irqrestore(&info->lock, flags);
-	tty_unregister_driver(&callout_driver);
 	tty_unregister_driver(&serial_driver);
 
 	if (tmp_buf) {
diff -Nru a/drivers/macintosh/macserial.h b/drivers/macintosh/macserial.h
--- a/drivers/macintosh/macserial.h	Sun Mar 16 15:21:50 2003
+++ b/drivers/macintosh/macserial.h	Mon May 26 15:29:14 2003
@@ -156,15 +156,12 @@
 	int			line;
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
 	int			xmit_cnt;
 	struct work_struct	tqueue;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 
diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c
--- a/drivers/md/linear.c	Thu Apr  3 17:21:33 2003
+++ b/drivers/md/linear.c	Mon May 26 19:01:37 2003
@@ -20,7 +20,6 @@
 
 #include <linux/raid/md.h>
 #include <linux/slab.h>
-#include <linux/bio.h>
 #include <linux/raid/linear.h>
 
 #define MAJOR_NR MD_MAJOR
@@ -67,7 +66,18 @@
 	dev0 = which_dev(mddev, bio->bi_sector);
 	maxsectors = (dev0->size << 1) - (bio->bi_sector - (dev0->offset<<1));
 
-	return (maxsectors - bio_sectors) << 9;
+	if (maxsectors < bio_sectors)
+		maxsectors = 0;
+	else
+		maxsectors -= bio_sectors;
+
+	if (maxsectors <= (PAGE_SIZE >> 9 ) && bio_sectors == 0)
+		return biovec->bv_len;
+	/* The bytes available at this offset could be really big,
+	 * so we cap at 2^31 to avoid overflow */
+	if (maxsectors > (1 << (31-9)))
+		return 1<<31;
+	return maxsectors << 9;
 }
 
 static int linear_run (mddev_t *mddev)
@@ -79,7 +89,8 @@
 	unsigned int curr_offset;
 	struct list_head *tmp;
 
-	conf = kmalloc (sizeof (*conf), GFP_KERNEL);
+	conf = kmalloc (sizeof (*conf) + mddev->raid_disks*sizeof(dev_info_t),
+			GFP_KERNEL);
 	if (!conf)
 		goto out;
 	memset(conf, 0, sizeof(*conf));
@@ -209,6 +220,23 @@
 		bio_io_error(bio, bio->bi_size);
 		return 0;
 	}
+	if (unlikely(bio->bi_sector + (bio->bi_size >> 9) >
+		     (tmp_dev->offset + tmp_dev->size)<<1)) {
+		/* This bio crosses a device boundary, so we have to
+		 * split it.
+		 */
+		struct bio_pair *bp;
+		bp = bio_split(bio, bio_split_pool, 
+			       (bio->bi_sector + (bio->bi_size >> 9) -
+				(tmp_dev->offset + tmp_dev->size))<<1);
+		if (linear_make_request(q, &bp->bio1))
+			generic_make_request(&bp->bio1);
+		if (linear_make_request(q, &bp->bio2))
+			generic_make_request(&bp->bio2);
+		bio_pair_release(bp);
+		return 0;
+	}
+		    
 	bio->bi_bdev = tmp_dev->rdev->bdev;
 	bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset;
 
@@ -226,12 +254,13 @@
 	seq_printf(seq, "      ");
 	for (j = 0; j < conf->nr_zones; j++)
 	{
+		char b[BDEVNAME_SIZE];
 		seq_printf(seq, "[%s",
-			bdev_partition_name(conf->hash_table[j].dev0->rdev->bdev));
+			   bdevname(conf->hash_table[j].dev0->rdev->bdev,b));
 
 		if (conf->hash_table[j].dev1)
 			seq_printf(seq, "/%s] ",
-			  bdev_partition_name(conf->hash_table[j].dev1->rdev->bdev));
+				   bdevname(conf->hash_table[j].dev1->rdev->bdev,b));
 		else
 			seq_printf(seq, "] ");
 	}
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Sun May 25 02:45:06 2003
+++ b/drivers/md/md.c	Mon May 26 19:01:37 2003
@@ -33,7 +33,6 @@
 #include <linux/linkage.h>
 #include <linux/raid/md.h>
 #include <linux/sysctl.h>
-#include <linux/bio.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/suspend.h>
@@ -350,7 +349,7 @@
 
 static int read_disk_sb(mdk_rdev_t * rdev)
 {
-
+	char b[BDEVNAME_SIZE];
 	if (!rdev->sb_page) {
 		MD_BUG();
 		return -EINVAL;
@@ -366,7 +365,7 @@
 
 fail:
 	printk(KERN_ERR "md: disabled device %s, could not read superblock.\n",
-		bdev_partition_name(rdev->bdev));
+		bdevname(rdev->bdev,b));
 	return -EINVAL;
 }
 
@@ -474,6 +473,7 @@
  */
 static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
 {
+	char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
 	mdp_super_t *sb;
 	int ret;
 	sector_t sb_offset;
@@ -492,11 +492,12 @@
 
 	ret = -EINVAL;
 
+	bdevname(rdev->bdev, b);
 	sb = (mdp_super_t*)page_address(rdev->sb_page);
 
 	if (sb->md_magic != MD_SB_MAGIC) {
 		printk(KERN_ERR "md: invalid raid superblock magic on %s\n",
-			bdev_partition_name(rdev->bdev));
+		       b);
 		goto abort;
 	}
 
@@ -504,13 +505,13 @@
 	    sb->minor_version != 90) {
 		printk(KERN_WARNING "Bad version number %d.%d on %s\n",
 			sb->major_version, sb->minor_version,
-			bdev_partition_name(rdev->bdev));
+			b);
 		goto abort;
 	}
 
 	if (sb->md_minor >= MAX_MD_DEVS) {
 		printk(KERN_ERR "md: %s: invalid raid minor (%x)\n",
-			bdev_partition_name(rdev->bdev), sb->md_minor);
+			b, sb->md_minor);
 		goto abort;
 	}
 	if (sb->raid_disks <= 0)
@@ -518,7 +519,7 @@
 
 	if (calc_sb_csum(sb) != sb->sb_csum) {
 		printk(KERN_WARNING "md: invalid superblock checksum on %s\n",
-			bdev_partition_name(rdev->bdev));
+			b);
 		goto abort;
 	}
 
@@ -537,15 +538,13 @@
 		mdp_super_t *refsb = (mdp_super_t*)page_address(refdev->sb_page);
 		if (!uuid_equal(refsb, sb)) {
 			printk(KERN_WARNING "md: %s has different UUID to %s\n",
-				bdev_partition_name(rdev->bdev),
-				bdev_partition_name(refdev->bdev));
+				b, bdevname(refdev->bdev,b2));
 			goto abort;
 		}
 		if (!sb_equal(refsb, sb)) {
 			printk(KERN_WARNING "md: %s has same UUID"
-				" but different superblock to %s\n",
-				bdev_partition_name(rdev->bdev),
-				bdev_partition_name(refdev->bdev));
+			       " but different superblock to %s\n",
+			       b, bdevname(refdev->bdev, b2));
 			goto abort;
 		}
 		ev1 = md_event(sb);
@@ -757,6 +756,7 @@
 	struct mdp_superblock_1 *sb;
 	int ret;
 	sector_t sb_offset;
+	char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
 
 	/*
 	 * Calculate the position of the superblock.
@@ -800,7 +800,7 @@
 
 	if (calc_sb_1_csum(sb) != sb->sb_csum) {
 		printk("md: invalid superblock checksum on %s\n",
-			bdev_partition_name(rdev->bdev));
+			bdevname(rdev->bdev,b));
 		return -EINVAL;
 	}
 	rdev->preferred_minor = 0xffff;
@@ -819,8 +819,8 @@
 		    sb->chunksize != refsb->chunksize) {
 			printk(KERN_WARNING "md: %s has strangely different"
 				" superblock to %s\n",
-				bdev_partition_name(rdev->bdev),
-				bdev_partition_name(refdev->bdev));
+				bdevname(rdev->bdev,b),
+				bdevname(refdev->bdev,b2));
 			return -EINVAL;
 		}
 		ev1 = le64_to_cpu(sb->events);
@@ -988,6 +988,7 @@
 static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 {
 	mdk_rdev_t *same_pdev;
+	char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
 
 	if (rdev->mddev) {
 		MD_BUG();
@@ -999,8 +1000,8 @@
 			"md%d: WARNING: %s appears to be on the same physical"
 	 		" disk as %s. True\n     protection against single-disk"
 			" failure might be compromised.\n",
-			mdidx(mddev), bdev_partition_name(rdev->bdev),
-			bdev_partition_name(same_pdev->bdev));
+			mdidx(mddev), bdevname(rdev->bdev,b),
+			bdevname(same_pdev->bdev,b2));
 
 	/* Verify rdev->desc_nr is unique.
 	 * If it is -1, assign a free number, else
@@ -1019,18 +1020,19 @@
 			
 	list_add(&rdev->same_set, &mddev->disks);
 	rdev->mddev = mddev;
-	printk(KERN_INFO "md: bind<%s>\n", bdev_partition_name(rdev->bdev));
+	printk(KERN_INFO "md: bind<%s>\n", bdevname(rdev->bdev,b));
 	return 0;
 }
 
 static void unbind_rdev_from_array(mdk_rdev_t * rdev)
 {
+	char b[BDEVNAME_SIZE];
 	if (!rdev->mddev) {
 		MD_BUG();
 		return;
 	}
 	list_del_init(&rdev->same_set);
-	printk(KERN_INFO "md: unbind<%s>\n", bdev_partition_name(rdev->bdev));
+	printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
 	rdev->mddev = NULL;
 }
 
@@ -1072,8 +1074,9 @@
 
 static void export_rdev(mdk_rdev_t * rdev)
 {
+	char b[BDEVNAME_SIZE];
 	printk(KERN_INFO "md: export_rdev(%s)\n",
-		bdev_partition_name(rdev->bdev));
+		bdevname(rdev->bdev,b));
 	if (rdev->mddev)
 		MD_BUG();
 	free_disk_sb(rdev);
@@ -1154,8 +1157,9 @@
 
 static void print_rdev(mdk_rdev_t *rdev)
 {
+	char b[BDEVNAME_SIZE];
 	printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
-		bdev_partition_name(rdev->bdev), (unsigned long long)rdev->size,
+		bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
 	       	rdev->faulty, rdev->in_sync, rdev->desc_nr);
 	if (rdev->sb_loaded) {
 		printk(KERN_INFO "md: rdev superblock:\n");
@@ -1169,6 +1173,7 @@
 	struct list_head *tmp, *tmp2;
 	mdk_rdev_t *rdev;
 	mddev_t *mddev;
+	char b[BDEVNAME_SIZE];
 
 	printk("\n");
 	printk("md:	**********************************\n");
@@ -1178,7 +1183,7 @@
 		printk("md%d: ", mdidx(mddev));
 
 		ITERATE_RDEV(mddev,rdev,tmp2)
-			printk("<%s>", bdev_partition_name(rdev->bdev));
+			printk("<%s>", bdevname(rdev->bdev,b));
 		printk("\n");
 
 		ITERATE_RDEV(mddev,rdev,tmp2)
@@ -1191,7 +1196,7 @@
 
 static int write_disk_sb(mdk_rdev_t * rdev)
 {
-
+	char b[BDEVNAME_SIZE];
 	if (!rdev->sb_loaded) {
 		MD_BUG();
 		return 1;
@@ -1202,14 +1207,14 @@
 	}
 
 	dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
-		bdev_partition_name(rdev->bdev),
+		bdevname(rdev->bdev,b),
 	       (unsigned long long)rdev->sb_offset);
   
 	if (sync_page_io(rdev->bdev, rdev->sb_offset<<1, MD_SB_BYTES, rdev->sb_page, WRITE))
 		return 0;
 
 	printk("md: write_disk_sb failed for device %s\n", 
-		bdev_partition_name(rdev->bdev));
+		bdevname(rdev->bdev,b));
 	return 1;
 }
 
@@ -1260,11 +1265,12 @@
 
 	err = 0;
 	ITERATE_RDEV(mddev,rdev,tmp) {
+		char b[BDEVNAME_SIZE];
 		dprintk(KERN_INFO "md: ");
 		if (rdev->faulty)
 			dprintk("(skipping faulty ");
 
-		dprintk("%s ", bdev_partition_name(rdev->bdev));
+		dprintk("%s ", bdevname(rdev->bdev,b));
 		if (!rdev->faulty) {
 			err += write_disk_sb(rdev);
 		} else
@@ -1328,7 +1334,7 @@
 	if (!size) {
 		printk(KERN_WARNING 
 			"md: %s has zero or unknown size, marking faulty!\n",
-			bdev_partition_name(rdev->bdev));
+			bdevname(rdev->bdev,b));
 		err = -EINVAL;
 		goto abort_free;
 	}
@@ -1339,13 +1345,13 @@
 		if (err == -EINVAL) {
 			printk(KERN_WARNING 
 				"md: %s has invalid sb, not importing!\n",
-				bdev_partition_name(rdev->bdev));
+				bdevname(rdev->bdev,b));
 			goto abort_free;
 		}
 		if (err < 0) {
 			printk(KERN_WARNING 
 				"md: could not read %s's sb, not importing!\n",
-				bdev_partition_name(rdev->bdev));
+				bdevname(rdev->bdev,b));
 			goto abort_free;
 		}
 	}
@@ -1373,6 +1379,7 @@
 	int i;
 	struct list_head *tmp;
 	mdk_rdev_t *rdev, *freshest;
+	char b[BDEVNAME_SIZE];
 
 	freshest = NULL;
 	ITERATE_RDEV(mddev,rdev,tmp)
@@ -1387,7 +1394,7 @@
 			printk( KERN_ERR \
 				"md: fatal superblock inconsistency in %s"
 				" -- removing from array\n", 
-				bdev_partition_name(rdev->bdev));
+				bdevname(rdev->bdev,b));
 			kick_rdev_from_array(rdev);
 		}
 
@@ -1402,7 +1409,7 @@
 			    validate_super(mddev, rdev)) {
 				printk(KERN_WARNING "md: kicking non-fresh %s"
 					" from array!\n",
-					bdev_partition_name(rdev->bdev));
+					bdevname(rdev->bdev,b));
 				kick_rdev_from_array(rdev);
 				continue;
 			}
@@ -1490,6 +1497,7 @@
 	struct list_head *tmp;
 	mdk_rdev_t *rdev;
 	struct gendisk *disk;
+	char b[BDEVNAME_SIZE];
 
 	if (list_empty(&mddev->disks)) {
 		MD_BUG();
@@ -1548,7 +1556,7 @@
 				printk(KERN_WARNING
 					"md: Dev %s smaller than chunk_size:"
 					" %lluk < %dk\n",
-					bdev_partition_name(rdev->bdev),
+					bdevname(rdev->bdev,b),
 					(unsigned long long)rdev->size,
 					chunk_size / 1024);
 				return -EINVAL;
@@ -1670,13 +1678,12 @@
 	int err = 0;
 	struct gendisk *disk = disks[mdidx(mddev)];
 
-	if (atomic_read(&mddev->active)>2) {
-		printk("md: md%d still in use.\n",mdidx(mddev));
-		err = -EBUSY;
-		goto out;
-	}
-
 	if (mddev->pers) {
+		if (atomic_read(&mddev->active)>2) {
+			printk("md: md%d still in use.\n",mdidx(mddev));
+			return -EBUSY;
+		}
+
 		if (mddev->sync_thread) {
 			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
 			md_unregister_thread(mddev->sync_thread);
@@ -1749,7 +1756,8 @@
 	printk(KERN_INFO "md: running: ");
 
 	ITERATE_RDEV(mddev,rdev,tmp) {
-		printk("<%s>", bdev_partition_name(rdev->bdev));
+		char b[BDEVNAME_SIZE];
+		printk("<%s>", bdevname(rdev->bdev,b));
 	}
 	printk("\n");
 
@@ -1778,6 +1786,7 @@
 	struct list_head *tmp;
 	mdk_rdev_t *rdev0, *rdev;
 	mddev_t *mddev;
+	char b[BDEVNAME_SIZE];
 
 	printk(KERN_INFO "md: autorun ...\n");
 	while (!list_empty(&pending_raid_disks)) {
@@ -1785,12 +1794,12 @@
 					 mdk_rdev_t, same_set);
 
 		printk(KERN_INFO "md: considering %s ...\n",
-			bdev_partition_name(rdev0->bdev));
+			bdevname(rdev0->bdev,b));
 		INIT_LIST_HEAD(&candidates);
 		ITERATE_RDEV_PENDING(rdev,tmp)
 			if (super_90_load(rdev, rdev0, 0) >= 0) {
 				printk(KERN_INFO "md:  adding %s ...\n",
-					bdev_partition_name(rdev->bdev));
+					bdevname(rdev->bdev,b));
 				list_move(&rdev->same_set, &candidates);
 			}
 		/*
@@ -1812,7 +1821,7 @@
 			 || !list_empty(&mddev->disks)) {
 			printk(KERN_WARNING 
 				"md: md%d already running, cannot run %s\n",
-				mdidx(mddev), bdev_partition_name(rdev0->bdev));
+				mdidx(mddev), bdevname(rdev0->bdev,b));
 			mddev_unlock(mddev);
 		} else {
 			printk(KERN_INFO "md: created md%d\n", mdidx(mddev));
@@ -1865,7 +1874,7 @@
 	if (start_rdev->faulty) {
 		printk(KERN_WARNING 
 			"md: can not autostart based on faulty %s!\n",
-			bdev_partition_name(start_rdev->bdev));
+			bdevname(start_rdev->bdev,b));
 		export_rdev(start_rdev);
 		return err;
 	}
@@ -2002,6 +2011,7 @@
 
 static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
 {
+	char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
 	mdk_rdev_t *rdev;
 	dev_t dev;
 	dev = MKDEV(info->major,info->minor);
@@ -2023,8 +2033,8 @@
 			if (err < 0) {
 				printk(KERN_WARNING 
 					"md: %s has different UUID to %s\n",
-					bdev_partition_name(rdev->bdev), 
-					bdev_partition_name(rdev0->bdev));
+					bdevname(rdev->bdev,b), 
+					bdevname(rdev0->bdev,b2));
 				export_rdev(rdev);
 				return -EINVAL;
 			}
@@ -2176,7 +2186,7 @@
 	return 0;
 busy:
 	printk(KERN_WARNING "md: cannot remove active disk %s from md%d ... \n",
-		bdev_partition_name(rdev->bdev), mdidx(mddev));
+		bdevname(rdev->bdev,b), mdidx(mddev));
 	return -EBUSY;
 }
 
@@ -2230,7 +2240,7 @@
 	if (rdev->faulty) {
 		printk(KERN_WARNING 
 			"md: can not hot-add faulty %s disk to md%d!\n",
-			bdev_partition_name(rdev->bdev), mdidx(mddev));
+			bdevname(rdev->bdev,b), mdidx(mddev));
 		err = -EINVAL;
 		goto abort_export;
 	}
@@ -2783,9 +2793,10 @@
 	seq_printf(seq, "unused devices: ");
 
 	ITERATE_RDEV_PENDING(rdev,tmp) {
+		char b[BDEVNAME_SIZE];
 		i++;
 		seq_printf(seq, "%s ",
-			      bdev_partition_name(rdev->bdev));
+			      bdevname(rdev->bdev,b));
 	}
 	if (!i)
 		seq_printf(seq, "<none>");
@@ -2940,8 +2951,9 @@
 
 		size = 0;
 		ITERATE_RDEV(mddev,rdev,tmp2) {
+			char b[BDEVNAME_SIZE];
 			seq_printf(seq, " %s[%d]",
-				bdev_partition_name(rdev->bdev), rdev->desc_nr);
+				bdevname(rdev->bdev,b), rdev->desc_nr);
 			if (rdev->faulty) {
 				seq_printf(seq, "(F)");
 				continue;
diff -Nru a/drivers/md/multipath.c b/drivers/md/multipath.c
--- a/drivers/md/multipath.c	Thu Apr  3 17:21:33 2003
+++ b/drivers/md/multipath.c	Mon May 26 19:01:37 2003
@@ -23,7 +23,6 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/raid/multipath.h>
-#include <linux/bio.h>
 #include <linux/buffer_head.h>
 #include <asm/atomic.h>
 
@@ -59,7 +58,7 @@
 static int multipath_map (mddev_t *mddev, mdk_rdev_t **rdevp)
 {
 	multipath_conf_t *conf = mddev_to_conf(mddev);
-	int i, disks = mddev->max_disks;
+	int i, disks = conf->raid_disks;
 
 	/*
 	 * Later we do read balancing on the read side 
@@ -128,9 +127,10 @@
 		/*
 		 * oops, IO error:
 		 */
+		char b[BDEVNAME_SIZE];
 		md_error (mp_bh->mddev, rdev);
 		printk(KERN_ERR "multipath: %s: rescheduling sector %llu\n", 
-		       bdev_partition_name(rdev->bdev), 
+		       bdevname(rdev->bdev,b), 
 		       (unsigned long long)bio->bi_sector);
 		multipath_reschedule_retry(mp_bh);
 	}
@@ -147,7 +147,7 @@
 {
 	int disk;
 
-	for (disk = 0; disk < conf->mddev->max_disks; disk++) {
+	for (disk = 0; disk < conf->raid_disks; disk++) {
 		mdk_rdev_t *rdev = conf->multipaths[disk].rdev;
 		if (rdev && rdev->in_sync)
 			return disk;
@@ -221,6 +221,7 @@
 		 * Mark disk as unusable
 		 */
 		if (!rdev->faulty) {
+			char b[BDEVNAME_SIZE];
 			rdev->in_sync = 0;
 			rdev->faulty = 1;
 			mddev->sb_dirty = 1;
@@ -228,7 +229,7 @@
 			printk(KERN_ALERT "multipath: IO failure on %s,"
 				" disabling IO path. \n	Operation continuing"
 				" on %d IO paths.\n",
-				bdev_partition_name (rdev->bdev),
+				bdevname (rdev->bdev,b),
 				conf->working_disks);
 		}
 	}
@@ -247,12 +248,13 @@
 	printk(" --- wd:%d rd:%d\n", conf->working_disks,
 			 conf->raid_disks);
 
-	for (i = 0; i < conf->mddev->max_disks; i++) {
+	for (i = 0; i < conf->raid_disks; i++) {
+		char b[BDEVNAME_SIZE];
 		tmp = conf->multipaths + i;
 		if (tmp->rdev)
 			printk(" disk%d, o:%d, dev:%s\n",
 				i,!tmp->rdev->faulty,
-			       bdev_partition_name(tmp->rdev->bdev));
+			       bdevname(tmp->rdev->bdev,b));
 	}
 }
 
@@ -327,6 +329,7 @@
 
 	md_check_recovery(mddev);
 	for (;;) {
+		char b[BDEVNAME_SIZE];
 		spin_lock_irqsave(&retry_list_lock, flags);
 		mp_bh = multipath_retry_list;
 		if (!mp_bh)
@@ -342,13 +345,13 @@
 		if (multipath_map (mddev, &rdev)<0) {
 			printk(KERN_ALERT "multipath: %s: unrecoverable IO read"
 				" error for block %llu\n",
-				bdev_partition_name(bio->bi_bdev), 
+				bdevname(bio->bi_bdev,b),
 				(unsigned long long)bio->bi_sector);
 			multipath_end_bh_io(mp_bh, 0);
 		} else {
 			printk(KERN_ERR "multipath: %s: redirecting sector %llu"
 				" to another IO path\n",
-				bdev_partition_name(bio->bi_bdev), 
+				bdevname(bio->bi_bdev,b),
 				(unsigned long long)bio->bi_sector);
 			bio->bi_bdev = rdev->bdev;
 			generic_make_request(bio);
@@ -386,6 +389,15 @@
 	}
 	memset(conf, 0, sizeof(*conf));
 
+	conf->multipaths = kmalloc(sizeof(struct multipath_info)*mddev->raid_disks,
+				   GFP_KERNEL);
+	if (!conf->multipaths) {
+		printk(KERN_ERR 
+			"multipath: couldn't allocate memory for md%d\n",
+			mdidx(mddev));
+		goto out_free_conf;
+	}
+
 	conf->working_disks = 0;
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		disk_idx = rdev->raid_disk;
@@ -444,6 +456,8 @@
 out_free_conf:
 	if (conf->pool)
 		mempool_destroy(conf->pool);
+	if (conf->multipaths)
+		kfree(conf->multipaths);
 	kfree(conf);
 	mddev->private = NULL;
 out:
@@ -457,6 +471,7 @@
 
 	md_unregister_thread(mddev->thread);
 	mempool_destroy(conf->pool);
+	kfree(conf->multipaths);
 	kfree(conf);
 	mddev->private = NULL;
 	return 0;
diff -Nru a/drivers/md/raid0.c b/drivers/md/raid0.c
--- a/drivers/md/raid0.c	Thu Apr  3 17:21:33 2003
+++ b/drivers/md/raid0.c	Mon May 26 19:01:37 2003
@@ -20,7 +20,6 @@
 
 #include <linux/module.h>
 #include <linux/raid/raid0.h>
-#include <linux/bio.h>
 
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
@@ -31,11 +30,13 @@
 {
 	int i, c, j;
 	sector_t current_offset, curr_zone_offset;
+	sector_t min_spacing;
 	raid0_conf_t *conf = mddev_to_conf(mddev);
 	mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev;
 	struct list_head *tmp1, *tmp2;
 	struct strip_zone *zone;
 	int cnt;
+	char b[BDEVNAME_SIZE];
  
 	/*
 	 * The number of 'same size groups'
@@ -44,14 +45,15 @@
  
 	ITERATE_RDEV(mddev,rdev1,tmp1) {
 		printk("raid0: looking at %s\n",
-			bdev_partition_name(rdev1->bdev));
+			bdevname(rdev1->bdev,b));
 		c = 0;
 		ITERATE_RDEV(mddev,rdev2,tmp2) {
-			printk("raid0:   comparing %s(%llu) with %s(%llu)\n",
-				bdev_partition_name(rdev1->bdev),
-				(unsigned long long)rdev1->size,
-				bdev_partition_name(rdev2->bdev),
-				(unsigned long long)rdev2->size);
+			printk("raid0:   comparing %s(%llu)",
+			       bdevname(rdev1->bdev,b),
+			       (unsigned long long)rdev1->size);
+			printk(" with %s(%llu)\n",
+			       bdevname(rdev2->bdev,b),
+			       (unsigned long long)rdev2->size);
 			if (rdev2 == rdev1) {
 				printk("raid0:   END\n");
 				break;
@@ -76,19 +78,27 @@
 	}
 	printk("raid0: FINAL %d zones\n", conf->nr_strip_zones);
 
-	conf->strip_zone = vmalloc(sizeof(struct strip_zone)*
-				conf->nr_strip_zones);
+	conf->strip_zone = kmalloc(sizeof(struct strip_zone)*
+				conf->nr_strip_zones, GFP_KERNEL);
 	if (!conf->strip_zone)
 		return 1;
+	conf->devlist = kmalloc(sizeof(mdk_rdev_t*)*
+				conf->nr_strip_zones*mddev->raid_disks,
+				GFP_KERNEL);
+	if (!conf->devlist) {
+		kfree(conf);
+		return 1;
+	}
 
 	memset(conf->strip_zone, 0,sizeof(struct strip_zone)*
 				   conf->nr_strip_zones);
 	/* The first zone must contain all devices, so here we check that
-	 * there is a properly alignment of slots to devices and find them all
+	 * there is a proper alignment of slots to devices and find them all
 	 */
 	zone = &conf->strip_zone[0];
 	cnt = 0;
 	smallest = NULL;
+	zone->dev = conf->devlist;
 	ITERATE_RDEV(mddev, rdev1, tmp1) {
 		int j = rdev1->raid_disk;
 
@@ -115,7 +125,6 @@
 	zone->size = smallest->size * cnt;
 	zone->zone_offset = 0;
 
-	conf->smallest = zone;
 	current_offset = smallest->size;
 	curr_zone_offset = zone->size;
 
@@ -123,6 +132,7 @@
 	for (i = 1; i < conf->nr_strip_zones; i++)
 	{
 		zone = conf->strip_zone + i;
+		zone->dev = conf->strip_zone[i-1].dev + mddev->raid_disks;
 
 		printk("raid0: zone %d\n", i);
 		zone->dev_offset = current_offset;
@@ -130,8 +140,9 @@
 		c = 0;
 
 		for (j=0; j<cnt; j++) {
+			char b[BDEVNAME_SIZE];
 			rdev = conf->strip_zone[0].dev[j];
-			printk("raid0: checking %s ...", bdev_partition_name(rdev->bdev));
+			printk("raid0: checking %s ...", bdevname(rdev->bdev,b));
 			if (rdev->size > current_offset)
 			{
 				printk(" contained as device %d\n", c);
@@ -151,9 +162,6 @@
 		printk("raid0: zone->nb_dev: %d, size: %llu\n",
 			zone->nb_dev, (unsigned long long)zone->size);
 
-		if (!conf->smallest || (zone->size < conf->smallest->size))
-			conf->smallest = zone;
-
 		zone->zone_offset = curr_zone_offset;
 		curr_zone_offset += zone->size;
 
@@ -161,10 +169,32 @@
 		printk("raid0: current zone offset: %llu\n",
 			(unsigned long long)current_offset);
 	}
+
+	/* Now find appropriate hash spacing.
+	 * We want a number which causes most hash entries to cover
+	 * at most two strips, but the hash table must be at most
+	 * 1 PAGE.  We choose the smallest strip, or contiguous collection
+	 * of strips, that has big enough size.  We never consider the last
+	 * strip though as it's size has no bearing on the efficacy of the hash
+	 * table.
+	 */
+	conf->hash_spacing = curr_zone_offset;
+	min_spacing = curr_zone_offset;
+	sector_div(min_spacing, PAGE_SIZE/sizeof(struct strip_zone*));
+	for (i=0; i < conf->nr_strip_zones-1; i++) {
+		sector_t sz = 0;
+		for (j=i; j<conf->nr_strip_zones-1 &&
+			     sz < min_spacing ; j++)
+			sz += conf->strip_zone[j].size;
+		if (sz >= min_spacing && sz < conf->hash_spacing)
+			conf->hash_spacing = sz;
+	}
+
 	printk("raid0: done.\n");
 	return 0;
  abort:
-	vfree(conf->strip_zone);
+	kfree(conf->devlist);
+	kfree(conf->strip_zone);
 	return 1;
 }
 
@@ -179,27 +209,28 @@
 static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec)
 {
 	mddev_t *mddev = q->queuedata;
-	sector_t sector;
-	unsigned int chunk_sectors;
-	unsigned int bio_sectors;
-
-	chunk_sectors = mddev->chunk_size >> 9;
-	sector = bio->bi_sector;
-	bio_sectors = bio->bi_size >> 9;
-
-	return (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
+	sector_t sector = bio->bi_sector;
+	int max;
+	unsigned int chunk_sectors = mddev->chunk_size >> 9;
+	unsigned int bio_sectors = bio->bi_size >> 9;
+
+	max =  (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
+	if (max < 0) max = 0; /* bio_add cannot handle a negative return */
+	if (max <= biovec->bv_len && bio_sectors == 0)
+		return biovec->bv_len;
+	else 
+		return max;
 }
 
 static int raid0_run (mddev_t *mddev)
 {
 	unsigned  cur=0, i=0, nb_zone;
-	sector_t zone0_size;
 	s64 size;
 	raid0_conf_t *conf;
 	mdk_rdev_t *rdev;
 	struct list_head *tmp;
 
-	conf = vmalloc(sizeof (raid0_conf_t));
+	conf = kmalloc(sizeof (raid0_conf_t), GFP_KERNEL);
 	if (!conf)
 		goto out;
 	mddev->private = (void *)conf;
@@ -214,70 +245,64 @@
 
 	printk("raid0 : md_size is %llu blocks.\n", 
 		(unsigned long long)mddev->array_size);
-	printk("raid0 : conf->smallest->size is %llu blocks.\n",
-		(unsigned long long)conf->smallest->size);
+	printk("raid0 : conf->hash_spacing is %llu blocks.\n",
+		(unsigned long long)conf->hash_spacing);
 	{
 #if __GNUC__ < 3
 		volatile
 #endif
 		sector_t s = mddev->array_size;
-		int round = sector_div(s, (unsigned long)conf->smallest->size) ? 1 : 0;
+		sector_t space = conf->hash_spacing;
+		int round;
+		conf->preshift = 0;
+		if (sizeof(sector_t) > sizeof(unsigned long)) {
+			/*shift down space and s so that sector_div will work */
+			while (space > (sector_t) (~(unsigned long)0)) {
+				s >>= 1;
+				space >>= 1;
+				s += 1; /* force round-up */
+				conf->preshift++;
+			}
+		}
+		round = sector_div(s, (unsigned long)space) ? 1 : 0;
 		nb_zone = s + round;
 	}
 	printk("raid0 : nb_zone is %d.\n", nb_zone);
-	conf->nr_zones = nb_zone;
 
 	printk("raid0 : Allocating %Zd bytes for hash.\n",
-				nb_zone*sizeof(struct raid0_hash));
-	conf->hash_table = vmalloc (sizeof (struct raid0_hash)*nb_zone);
+				nb_zone*sizeof(struct strip_zone*));
+	conf->hash_table = kmalloc (sizeof (struct strip_zone *)*nb_zone, GFP_KERNEL);
 	if (!conf->hash_table)
 		goto out_free_zone_conf;
 	size = conf->strip_zone[cur].size;
 
-	i = 0;
-	while (cur < conf->nr_strip_zones) {
-		conf->hash_table[i].zone0 = conf->strip_zone + cur;
-
-		/*
-		 * If we completely fill the slot
-		 */
-		if (size >= conf->smallest->size) {
-			conf->hash_table[i++].zone1 = NULL;
-			size -= conf->smallest->size;
-
-			if (!size) {
-				if (++cur == conf->nr_strip_zones)
-					continue;
-				size = conf->strip_zone[cur].size;
-			}
-			continue;
-		}
-		if (++cur == conf->nr_strip_zones) {
-			/*
-			 * Last dev, set unit1 as NULL
-			 */
-			conf->hash_table[i].zone1=NULL;
-			continue;
+	for (i=0; i< nb_zone; i++) {
+		conf->hash_table[i] = conf->strip_zone + cur;
+		while (size <= conf->hash_spacing) {
+			cur++;
+			size += conf->strip_zone[cur].size;
 		}
-
-		/*
-		 * Here we use a 2nd dev to fill the slot
+		size -= conf->hash_spacing;
+	}
+	if (conf->preshift) {
+		conf->hash_spacing >>= conf->preshift;
+		/* round hash_spacing up so when we divide by it, we
+		 * err on the side of too-low, which is safest
 		 */
-		zone0_size = size;
-		size = conf->strip_zone[cur].size;
-		conf->hash_table[i++].zone1 = conf->strip_zone + cur;
-		size -= (conf->smallest->size - zone0_size);
+		conf->hash_spacing++;
 	}
+
 	blk_queue_max_sectors(&mddev->queue, mddev->chunk_size >> 9);
 	blk_queue_merge_bvec(&mddev->queue, raid0_mergeable_bvec);
 	return 0;
 
 out_free_zone_conf:
-	vfree(conf->strip_zone);
+	kfree(conf->strip_zone);
 	conf->strip_zone = NULL;
 
 out_free_conf:
-	vfree(conf);
+	kfree (conf->devlist);
+	kfree(conf);
 	mddev->private = NULL;
 out:
 	return 1;
@@ -287,11 +312,11 @@
 {
 	raid0_conf_t *conf = mddev_to_conf(mddev);
 
-	vfree (conf->hash_table);
+	kfree (conf->hash_table);
 	conf->hash_table = NULL;
-	vfree (conf->strip_zone);
+	kfree (conf->strip_zone);
 	conf->strip_zone = NULL;
-	vfree (conf);
+	kfree (conf);
 	mddev->private = NULL;
 
 	return 0;
@@ -302,7 +327,6 @@
 	mddev_t *mddev = q->queuedata;
 	unsigned int sect_in_chunk, chunksize_bits,  chunk_size;
 	raid0_conf_t *conf = mddev_to_conf(mddev);
-	struct raid0_hash *hash;
 	struct strip_zone *zone;
 	mdk_rdev_t *tmp_dev;
 	unsigned long chunk;
@@ -313,39 +337,45 @@
 	block = bio->bi_sector >> 1;
 	
 
+	if (unlikely(chunk_size < (block & (chunk_size - 1)) + (bio->bi_size >> 10))) {
+		struct bio_pair *bp;
+		/* Sanity check -- queue functions should prevent this happening */
+		if (bio->bi_vcnt != 1 ||
+		    bio->bi_idx != 0)
+			goto bad_map;
+		/* This is a one page bio that upper layers
+		 * refuse to split for us, so we need to split it.
+		 */
+		bp = bio_split(bio, bio_split_pool, (chunk_size - (block & (chunk_size - 1)))<<1 );
+		if (raid0_make_request(q, &bp->bio1))
+			generic_make_request(&bp->bio1);
+		if (raid0_make_request(q, &bp->bio2))
+			generic_make_request(&bp->bio2);
+
+		bio_pair_release(bp);
+		return 0;
+	}
+ 
+
 	{
 #if __GNUC__ < 3
 		volatile
 #endif
-		sector_t x = block;
-		sector_div(x, (unsigned long)conf->smallest->size);
-		hash = conf->hash_table + x;
+		sector_t x = block >> conf->preshift;
+		sector_div(x, (unsigned long)conf->hash_spacing);
+		zone = conf->hash_table[x];
 	}
-
-	/* Sanity check -- queue functions should prevent this happening */
-	if (unlikely(chunk_size < (block & (chunk_size - 1)) + (bio->bi_size >> 10)))
-		goto bad_map;
  
-	if (!hash)
-		goto bad_hash;
-
-	if (!hash->zone0)
-		goto bad_zone0;
- 
-	if (block >= (hash->zone0->size + hash->zone0->zone_offset)) {
-		if (!hash->zone1)
-			goto bad_zone1;
-		zone = hash->zone1;
-	} else
-		zone = hash->zone0;
+	while (block >= (zone->zone_offset + zone->size)) 
+		zone++;
     
 	sect_in_chunk = bio->bi_sector & ((chunk_size<<1) -1);
 
 
 	{
-		sector_t x =  block - zone->zone_offset;
+		sector_t x =  (block - zone->zone_offset) >> chunksize_bits;
 
-		sector_div(x, (zone->nb_dev << chunksize_bits));
+		sector_div(x, zone->nb_dev);
 		chunk = x;
 		BUG_ON(x != (sector_t)chunk);
 
@@ -355,10 +385,6 @@
 	rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1)
 		+ sect_in_chunk;
  
-	/*
-	 * The new BH_Lock semantics in ll_rw_blk.c guarantee that this
-	 * is the only IO operation happening on this bh.
-	 */
 	bio->bi_bdev = tmp_dev->bdev;
 	bio->bi_sector = rsect + tmp_dev->data_offset;
 
@@ -371,19 +397,7 @@
 	printk("raid0_make_request bug: can't convert block across chunks"
 		" or bigger than %dk %llu %d\n", chunk_size, 
 		(unsigned long long)bio->bi_sector, bio->bi_size >> 10);
-	goto outerr;
-bad_hash:
-	printk("raid0_make_request bug: hash==NULL for block %llu\n",
-		(unsigned long long)block);
-	goto outerr;
-bad_zone0:
-	printk("raid0_make_request bug: hash->zone0==NULL for block %llu\n",
-		(unsigned long long)block);
-	goto outerr;
-bad_zone1:
-	printk("raid0_make_request bug: hash->zone1==NULL for block %llu\n",
-			(unsigned long long)block);
- outerr:
+
 	bio_io_error(bio, bio->bi_size);
 	return 0;
 }
@@ -392,27 +406,19 @@
 {
 #undef MD_DEBUG
 #ifdef MD_DEBUG
-	int j, k;
+	int j, k, h;
+	char b[BDEVNAME_SIZE];
 	raid0_conf_t *conf = mddev_to_conf(mddev);
   
-	seq_printf(seq, "      ");
-	for (j = 0; j < conf->nr_zones; j++) {
-		seq_printf(seq, "[z%d",
-				conf->hash_table[j].zone0 - conf->strip_zone);
-		if (conf->hash_table[j].zone1)
-			seq_printf(seq, "/z%d] ",
-				conf->hash_table[j].zone1 - conf->strip_zone);
-		else
-			seq_printf(seq, "] ");
-	}
-  
-	seq_printf(seq, "\n");
-  
+	h = 0;
 	for (j = 0; j < conf->nr_strip_zones; j++) {
-		seq_printf(seq, "      z%d=[", j);
+		seq_printf(seq, "      z%d", j);
+		if (conf->hash_table[h] == conf->strip_zone+j)
+			seq_printf("(h%d)", h++);
+		seq_printf(seq, "=[");
 		for (k = 0; k < conf->strip_zone[j].nb_dev; k++)
-			seq_printf (seq, "%s/", bdev_partition_name(
-				conf->strip_zone[j].dev[k]->bdev));
+			seq_printf (seq, "%s/", bdevname(
+				conf->strip_zone[j].dev[k]->bdev,b));
 
 		seq_printf (seq, "] zo=%d do=%d s=%d\n",
 				conf->strip_zone[j].zone_offset,
diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c
--- a/drivers/md/raid1.c	Sun Apr 20 09:24:36 2003
+++ b/drivers/md/raid1.c	Mon May 26 19:01:37 2003
@@ -23,7 +23,6 @@
  */
 
 #include <linux/raid/raid1.h>
-#include <linux/bio.h>
 
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
@@ -41,9 +40,12 @@
 
 static void * r1bio_pool_alloc(int gfp_flags, void *data)
 {
+	mddev_t *mddev = data;
 	r1bio_t *r1_bio;
 
-	r1_bio = kmalloc(sizeof(r1bio_t), gfp_flags);
+	/* allocate a r1bio with room for raid_disks entries in the write_bios array */
+	r1_bio = kmalloc(sizeof(r1bio_t) + sizeof(struct bio*)*mddev->raid_disks,
+			 gfp_flags);
 	if (r1_bio)
 		memset(r1_bio, 0, sizeof(*r1_bio));
 
@@ -68,8 +70,9 @@
 	struct bio *bio;
 	int i, j;
 
-	r1_bio = mempool_alloc(conf->r1bio_pool, gfp_flags);
-
+	r1_bio = r1bio_pool_alloc(gfp_flags, conf->mddev);
+	if (!r1_bio)
+		return NULL;
 	bio = bio_alloc(gfp_flags, RESYNC_PAGES);
 	if (!bio)
 		goto out_free_r1_bio;
@@ -102,7 +105,7 @@
 		__free_page(bio->bi_io_vec[j].bv_page);
 	bio_put(bio);
 out_free_r1_bio:
-	mempool_free(r1_bio, conf->r1bio_pool);
+	r1bio_pool_free(r1_bio, conf->mddev);
 	return NULL;
 }
 
@@ -122,7 +125,7 @@
 	if (atomic_read(&bio->bi_cnt) != 1)
 		BUG();
 	bio_put(bio);
-	mempool_free(r1bio, conf->r1bio_pool);
+	r1bio_pool_free(r1bio, conf->mddev);
 }
 
 static void put_all_bios(conf_t *conf, r1bio_t *r1_bio)
@@ -305,8 +308,9 @@
 			/*
 			 * oops, read error:
 			 */
+			char b[BDEVNAME_SIZE];
 			printk(KERN_ERR "raid1: %s: rescheduling sector %llu\n",
-				bdev_partition_name(conf->mirrors[mirror].rdev->bdev), (unsigned long long)r1_bio->sector);
+				bdevname(conf->mirrors[mirror].rdev->bdev,b), (unsigned long long)r1_bio->sector);
 			reschedule_retry(r1_bio);
 		}
 	} else {
@@ -594,6 +598,7 @@
 
 static void error(mddev_t *mddev, mdk_rdev_t *rdev)
 {
+	char b[BDEVNAME_SIZE];
 	conf_t *conf = mddev_to_conf(mddev);
 
 	/*
@@ -622,7 +627,7 @@
 	mddev->sb_dirty = 1;
 	printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
 		"	Operation continuing on %d devices\n",
-		bdev_partition_name(rdev->bdev), conf->working_disks);
+		bdevname(rdev->bdev,b), conf->working_disks);
 }
 
 static void print_conf(conf_t *conf)
@@ -639,11 +644,12 @@
 		conf->raid_disks);
 
 	for (i = 0; i < conf->raid_disks; i++) {
+		char b[BDEVNAME_SIZE];
 		tmp = conf->mirrors + i;
 		if (tmp->rdev)
 			printk(" disk %d, wo:%d, o:%d, dev:%s\n",
 				i, !tmp->rdev->in_sync, !tmp->rdev->faulty,
-				bdev_partition_name(tmp->rdev->bdev));
+				bdevname(tmp->rdev->bdev,b));
 	}
 }
 
@@ -811,9 +817,10 @@
 		 * There is no point trying a read-for-reconstruct as
 		 * reconstruct is about to be aborted
 		 */
+		char b[BDEVNAME_SIZE];
 		printk(KERN_ALERT "raid1: %s: unrecoverable I/O read error"
 			" for block %llu\n",
-			bdev_partition_name(bio->bi_bdev), 
+			bdevname(bio->bi_bdev,b), 
 			(unsigned long long)r1_bio->sector);
 		md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0);
 		put_buf(r1_bio);
@@ -826,7 +833,7 @@
 		if (!conf->mirrors[i].rdev || 
 		    conf->mirrors[i].rdev->faulty)
 			continue;
-		if (i == conf->last_used)
+		if (conf->mirrors[i].rdev->bdev == bio->bi_bdev)
 			/*
 			 * we read from here, no need to write
 			 */
@@ -903,6 +910,7 @@
 	md_handle_safemode(mddev);
 	
 	for (;;) {
+		char b[BDEVNAME_SIZE];
 		spin_lock_irqsave(&retry_list_lock, flags);
 		if (list_empty(head))
 			break;
@@ -922,14 +930,14 @@
 			if (map(mddev, &rdev) == -1) {
 				printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
 				" read error for block %llu\n",
-				bdev_partition_name(bio->bi_bdev), 
+				bdevname(bio->bi_bdev,b),
 				(unsigned long long)r1_bio->sector);
 				raid_end_bio_io(r1_bio);
 				break;
 			}
 			printk(KERN_ERR "raid1: %s: redirecting sector %llu to"
 				" another mirror\n",
-				bdev_partition_name(rdev->bdev), 
+				bdevname(rdev->bdev,b),
 				(unsigned long long)r1_bio->sector);
 			bio->bi_bdev = rdev->bdev;
 			bio->bi_sector = r1_bio->sector + rdev->data_offset;
@@ -1086,13 +1094,20 @@
 		goto out;
 	}
 	memset(conf, 0, sizeof(*conf));
+	conf->mirrors = kmalloc(sizeof(struct mirror_info)*mddev->raid_disks, 
+				 GFP_KERNEL);
+	if (!conf->mirrors) {
+		printk(KERN_ERR "raid1: couldn't allocate memory for md%d\n",
+		       mdidx(mddev));
+		goto out_free_conf;
+	}
 
 	conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
-						r1bio_pool_free, NULL);
+						r1bio_pool_free, mddev);
 	if (!conf->r1bio_pool) {
 		printk(KERN_ERR "raid1: couldn't allocate memory for md%d\n", 
 			mdidx(mddev));
-		goto out;
+		goto out_free_conf;
 	}
 
 
@@ -1170,6 +1185,8 @@
 out_free_conf:
 	if (conf->r1bio_pool)
 		mempool_destroy(conf->r1bio_pool);
+	if (conf->mirrors)
+		kfree(conf->mirrors);
 	kfree(conf);
 	mddev->private = NULL;
 out:
@@ -1184,6 +1201,8 @@
 	mddev->thread = NULL;
 	if (conf->r1bio_pool)
 		mempool_destroy(conf->r1bio_pool);
+	if (conf->mirrors)
+		kfree(conf->mirrors);
 	kfree(conf);
 	mddev->private = NULL;
 	return 0;
diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c
--- a/drivers/md/raid5.c	Thu Apr  3 17:21:33 2003
+++ b/drivers/md/raid5.c	Mon May 26 19:01:37 2003
@@ -20,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/raid/raid5.h>
-#include <linux/bio.h>
 #include <linux/highmem.h>
 #include <asm/bitops.h>
 #include <asm/atomic.h>
@@ -458,6 +457,7 @@
 
 static void error(mddev_t *mddev, mdk_rdev_t *rdev)
 {
+	char b[BDEVNAME_SIZE];
 	raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
 	PRINTK("raid5: error called\n");
 
@@ -477,7 +477,7 @@
 		printk (KERN_ALERT
 			"raid5: Disk failure on %s, disabling device."
 			" Operation continuing on %d devices\n",
-			bdev_partition_name(rdev->bdev), conf->working_disks);
+			bdevname(rdev->bdev,b), conf->working_disks);
 	}
 }	
 
@@ -919,7 +919,7 @@
 	/* check if the array has lost two devices and, if so, some requests might
 	 * need to be failed
 	 */
-	if (failed > 1 && to_read+to_write) {
+	if (failed > 1 && to_read+to_write+written) {
 		spin_lock_irq(&conf->device_lock);
 		for (i=disks; i--; ) {
 			/* fail all writes first */
@@ -937,6 +937,20 @@
 				}
 				bi = nextbi;
 			}
+			/* and fail all 'written' */
+			bi = sh->dev[i].written;
+			sh->dev[i].written = NULL;
+			while (bi && bi->bi_sector < dev->sector + STRIPE_SECTORS) {
+				struct bio *bi2 = bi->bi_next;
+				clear_bit(BIO_UPTODATE, &bi->bi_flags);
+				if (--bi->bi_phys_segments == 0) {
+					md_write_end(conf->mddev);
+					bi->bi_next = return_bi;
+					return_bi = bi;
+				}
+				bi = bi2;
+			}
+
 			/* fail any reads if this device is non-operational */
 			if (!test_bit(R5_Insync, &sh->dev[i].flags)) {
 				bi = sh->dev[i].toread;
@@ -1439,7 +1453,9 @@
 		return -EIO;
 	}
 
-	mddev->private = kmalloc (sizeof (raid5_conf_t), GFP_KERNEL);
+	mddev->private = kmalloc (sizeof (raid5_conf_t)
+				  + mddev->raid_disks * sizeof(struct disk_info),
+				  GFP_KERNEL);
 	if ((conf = mddev->private) == NULL)
 		goto abort;
 	memset (conf, 0, sizeof (*conf));
@@ -1463,7 +1479,7 @@
 
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		raid_disk = rdev->raid_disk;
-		if (raid_disk > mddev->raid_disks
+		if (raid_disk >= mddev->raid_disks
 		    || raid_disk < 0)
 			continue;
 		disk = conf->disks + raid_disk;
@@ -1471,8 +1487,9 @@
 		disk->rdev = rdev;
 
 		if (rdev->in_sync) {
+			char b[BDEVNAME_SIZE];
 			printk(KERN_INFO "raid5: device %s operational as raid"
-				" disk %d\n", bdev_partition_name(rdev->bdev),
+				" disk %d\n", bdevname(rdev->bdev,b),
 				raid_disk);
 			conf->working_disks++;
 		}
@@ -1648,11 +1665,12 @@
 		 conf->working_disks, conf->failed_disks);
 
 	for (i = 0; i < conf->raid_disks; i++) {
+		char b[BDEVNAME_SIZE];
 		tmp = conf->disks + i;
 		if (tmp->rdev)
 		printk(" disk %d, o:%d, dev:%s\n",
 			i, !tmp->rdev->faulty,
-			bdev_partition_name(tmp->rdev->bdev));
+			bdevname(tmp->rdev->bdev,b));
 	}
 }
 
diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
--- a/drivers/message/fusion/mptscsih.c	Sun May  4 02:56:42 2003
+++ b/drivers/message/fusion/mptscsih.c	Mon May 12 07:26:09 2003
@@ -2149,8 +2149,8 @@
  * 	hostno: scsi host number
  *	func:   if write = 1; if read = 0
  */
-int mptscsih_proc_info(char *buffer, char **start, off_t offset,
-			int length, int hostno, int func)
+int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			int length, int func)
 {
 	MPT_ADAPTER	*ioc = NULL;
 	MPT_SCSI_HOST	*hd = NULL;
@@ -2161,7 +2161,7 @@
 			buffer, start, *start, offset, length));
 
 	for (ioc = mpt_adapter_find_first(); ioc != NULL; ioc = mpt_adapter_find_next(ioc)) {
-		if ((ioc->sh) && (ioc->sh->host_no == hostno)) {
+		if ((ioc->sh) && (ioc->sh == host)) {
 			hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
 			break;
 		}
diff -Nru a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
--- a/drivers/message/fusion/mptscsih.h	Sun May  4 02:56:43 2003
+++ b/drivers/message/fusion/mptscsih.h	Mon May 12 07:26:10 2003
@@ -199,7 +199,7 @@
 extern	int		 x_scsi_slave_alloc(Scsi_Device *);
 extern	int		 x_scsi_slave_configure(Scsi_Device *);
 extern	void		 x_scsi_slave_destroy(Scsi_Device *);
-extern	int		 x_scsi_proc_info(char *, char **, off_t, int, int, int);
+extern	int		 x_scsi_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
diff -Nru a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
--- a/drivers/net/bonding/bond_3ad.c	Sun May 25 21:26:17 2003
+++ b/drivers/net/bonding/bond_3ad.c	Mon May 26 21:40:16 2003
@@ -721,7 +721,7 @@
 }
 
 /**
- * __detach_bond_to_agg
+ * __detach_bond_from_agg
  * @port: the port we're looking at
  *
  * Handle the detaching of the port's control parser/multiplexer from the
@@ -828,6 +828,55 @@
 	return retval;
 }
 
+/**
+ * __update_lacpdu_from_port - update a port's lacpdu fields
+ * @port: the port we're looking at
+ *
+ */
+static inline void __update_lacpdu_from_port(struct port *port)
+{
+	struct lacpdu *lacpdu = &port->lacpdu;
+
+	/* update current actual Actor parameters */
+	/* lacpdu->subtype                   initialized
+	 * lacpdu->version_number            initialized
+	 * lacpdu->tlv_type_actor_info       initialized
+	 * lacpdu->actor_information_length  initialized
+	 */
+
+	lacpdu->actor_system_priority = port->actor_system_priority;
+	lacpdu->actor_system = port->actor_system;
+	lacpdu->actor_key = port->actor_oper_port_key;
+	lacpdu->actor_port_priority = port->actor_port_priority;
+	lacpdu->actor_port = port->actor_port_number;
+	lacpdu->actor_state = port->actor_oper_port_state;
+
+	/* lacpdu->reserved_3_1              initialized
+	 * lacpdu->tlv_type_partner_info     initialized
+	 * lacpdu->partner_information_length initialized
+	 */
+
+	lacpdu->partner_system_priority = port->partner_oper_system_priority;
+	lacpdu->partner_system = port->partner_oper_system;
+	lacpdu->partner_key = port->partner_oper_key;
+	lacpdu->partner_port_priority = port->partner_oper_port_priority;
+	lacpdu->partner_port = port->partner_oper_port_number;
+	lacpdu->partner_state = port->partner_oper_port_state;
+
+	/* lacpdu->reserved_3_2              initialized
+	 * lacpdu->tlv_type_collector_info   initialized
+	 * lacpdu->collector_information_length initialized
+	 * collector_max_delay                initialized
+	 * reserved_12[12]                   initialized
+	 * tlv_type_terminator               initialized
+	 * terminator_length                 initialized
+	 * reserved_50[50]                   initialized
+	 */
+
+	/* Convert all non u8 parameters to Big Endian for transmit */
+	__ntohs_lacpdu(lacpdu);
+}
+
 //////////////////////////////////////////////////////////////////////////////////////
 // ================= main 802.3ad protocol code ======================================
 //////////////////////////////////////////////////////////////////////////////////////
@@ -1177,43 +1226,11 @@
  */
 static void ad_tx_machine(struct port *port)
 {
-	struct lacpdu *lacpdu = &port->lacpdu;
-
 	// check if tx timer expired, to verify that we do not send more than 3 packets per second
 	if (port->sm_tx_timer_counter && !(--port->sm_tx_timer_counter)) {
 		// check if there is something to send
 		if (port->ntt && (port->sm_vars & AD_PORT_LACP_ENABLED)) {
-			//update current actual Actor parameters
-			//lacpdu->subtype                   initialized
-			//lacpdu->version_number            initialized
-			//lacpdu->tlv_type_actor_info       initialized
-			//lacpdu->actor_information_length  initialized
-			lacpdu->actor_system_priority = port->actor_system_priority;
-			lacpdu->actor_system = port->actor_system;
-			lacpdu->actor_key = port->actor_oper_port_key;
-			lacpdu->actor_port_priority = port->actor_port_priority;
-			lacpdu->actor_port = port->actor_port_number;
-			lacpdu->actor_state = port->actor_oper_port_state;
-			//lacpdu->reserved_3_1              initialized
-			//lacpdu->tlv_type_partner_info     initialized
-			//lacpdu->partner_information_length initialized
-			lacpdu->partner_system_priority = port->partner_oper_system_priority;
-			lacpdu->partner_system = port->partner_oper_system;
-			lacpdu->partner_key = port->partner_oper_key;
-			lacpdu->partner_port_priority = port->partner_oper_port_priority;
-			lacpdu->partner_port = port->partner_oper_port_number;
-			lacpdu->partner_state = port->partner_oper_port_state;
-			//lacpdu->reserved_3_2              initialized
-			//lacpdu->tlv_type_collector_info   initialized
-			//lacpdu->collector_information_length initialized
-			//collector_max_delay                initialized
-			//reserved_12[12]                   initialized
-			//tlv_type_terminator               initialized
-			//terminator_length                 initialized
-			//reserved_50[50]                   initialized
-
-			// We need to convert all non u8 parameters to Big Endian for transmit
-			__ntohs_lacpdu(lacpdu);
+			__update_lacpdu_from_port(port);
 			// send the lacpdu
 			if (ad_lacpdu_send(port) >= 0) {
 				BOND_PRINT_DBG(("Sent LACPDU on port %d", port->actor_port_number));
@@ -1971,13 +1988,13 @@
 		return;
 	}
 
-	// disable the port
-	ad_disable_collecting_distributing(port);
+	BOND_PRINT_DBG(("Unbinding Link Aggregation Group %d", aggregator->aggregator_identifier));
 
-	// deinitialize port's locks if necessary(os-specific)
-	__deinitialize_port_locks(port);
+	/* Tell the partner that this port is not suitable for aggregation */
+	port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
+	__update_lacpdu_from_port(port);
+	ad_lacpdu_send(port);
 
-	BOND_PRINT_DBG(("Unbinding Link Aggregation Group %d", aggregator->aggregator_identifier));
 	// check if this aggregator is occupied
 	if (aggregator->lag_ports) {
 		// check if there are other ports related to this aggregator except
diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	Sun May 25 21:37:30 2003
+++ b/drivers/net/bonding/bond_main.c	Mon May 26 21:45:02 2003
@@ -2220,7 +2220,7 @@
 					}
 					printk(KERN_INFO
 						"%s: link status definitely down "
-						"for interface %s, disabling it\n",
+						"for interface %s, disabling it",
 						master->name,
 						dev->name);
 
@@ -2994,6 +2994,7 @@
 	struct ifbond *u_binfo = NULL, k_binfo;
 	struct ifslave *u_sinfo = NULL, k_sinfo;
 	struct mii_ioctl_data *mii = NULL;
+	int prev_abi_ver = orig_app_abi_ver;
 	int ret = 0;
 
 #ifdef BONDING_DEBUG
@@ -3112,6 +3113,15 @@
 		}
 		dev_put(slave_dev);
 	}
+
+	if (ret < 0) {
+		/* The ioctl failed, so there's no point in changing the
+		 * orig_app_abi_ver. We'll restore it's value just in case
+		 * we've changed it earlier in this function.
+		 */
+		orig_app_abi_ver = prev_abi_ver;
+	}
+
 	return ret;
 }
 
diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c	Sun Apr 20 23:39:11 2003
+++ b/drivers/net/eepro.c	Mon May 26 22:13:57 2003
@@ -1715,7 +1715,7 @@
 static int n_eepro;
 /* For linux 2.1.xx */
 
-MODULE_AUTHOR("Pascal Dupuis <dupuis@lei.ucl.ac.be> for the 2.1 stuff (locking,...)");
+MODULE_AUTHOR("Pascal Dupuis, and aris@cathedrallabs.org");
 MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/net/setup.c b/drivers/net/setup.c
--- a/drivers/net/setup.c	Fri May 23 00:50:54 2003
+++ b/drivers/net/setup.c	Mon May 26 16:32:22 2003
@@ -15,7 +15,6 @@
 extern int fec_enet_init(void); 
 extern int sdla_setup(void); 
 extern int sdla_c_setup(void); 
-extern int lmc_setup(void);
 
 /*
  *	Devices in this list must do new style probing. That is they must
@@ -44,9 +43,6 @@
 #endif
 #if defined(CONFIG_FEC_ENET)
         {fec_enet_init, 0},
-#endif
-#if defined(CONFIG_LANMEDIA)
-	{lmc_setup, 0},
 #endif
 	{NULL, 0},
 };
diff -Nru a/drivers/net/sundance.c b/drivers/net/sundance.c
--- a/drivers/net/sundance.c	Tue May 20 20:02:20 2003
+++ b/drivers/net/sundance.c	Mon May 26 22:05:38 2003
@@ -84,11 +84,14 @@
 	- Fix bug of custom mac address 
 	(StationAddr register only accept word write) 
 
+	Version LK1.09 (D-Link):
+	- Fix the flowctrl bug.	
+	- Set Pause bit in MII ANAR if flow control enabled.	
 */
 
 #define DRV_NAME	"sundance"
-#define DRV_VERSION	"1.01+LK1.08a"
-#define DRV_RELDATE	"23-Apr-2003"
+#define DRV_VERSION	"1.01+LK1.09a"
+#define DRV_RELDATE	"16-May-2003"
 
 
 /* The user-configurable values.
@@ -671,8 +674,8 @@
 				np->an_enable = 1;
 			}
 		}
-		if (flowctrl == 0)
-			np->flowctrl = 0;
+		if (flowctrl == 1)
+			np->flowctrl = 1;
 	}
 
 	/* Fibre PHY? */
@@ -687,6 +690,9 @@
 	/* Reset PHY */
 	mdio_write (dev, np->phys[0], MII_BMCR, BMCR_RESET);
 	mdelay (300);
+	/* If flow control enabled, we need to advertise it.*/
+	if (np->flowctrl)
+		mdio_write (dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising | 0x0400);
 	mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);
 	/* Force media type */
 	if (!np->an_enable) {
@@ -935,7 +941,7 @@
 			printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
 				   "negotiated capability %4.4x.\n", dev->name,
 				   duplex ? "full" : "half", np->phys[0], negotiated);
-		writew(duplex ? 0x20 : 0, ioaddr + MACCtrl0);
+		writew(readw(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0);
 	}
 }
 
@@ -1455,9 +1461,12 @@
 				"full" : "half");
 		}
 		check_duplex (dev);
-		if (np->flowctrl == 0)
-			writew(readw(ioaddr + MACCtrl0) & ~EnbFlowCtrl,
+		if (np->flowctrl && np->mii_if.full_duplex) {
+			writew(readw(ioaddr + MulticastFilter1+2) | 0x0200,
+				ioaddr + MulticastFilter1+2);
+			writew(readw(ioaddr + MACCtrl0) | EnbFlowCtrl,
 				ioaddr + MACCtrl0);
+		}
 	}
 	if (intr_status & StatsMax) {
 		get_stats(dev);
@@ -1500,6 +1509,7 @@
 static void set_rx_mode(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 	u16 mc_filter[4];			/* Multicast hash filter */
 	u32 rx_mode;
 	int i;
@@ -1532,6 +1542,9 @@
 		writeb(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
 		return;
 	}
+	if (np->mii_if.full_duplex && np->flowctrl)
+		mc_filter[3] |= 0x0200;
+
 	for (i = 0; i < 4; i++)
 		writew(mc_filter[i], ioaddr + MulticastFilter0 + i*2);
 	writeb(rx_mode, ioaddr + RxMode);
diff -Nru a/drivers/net/sunqe.c b/drivers/net/sunqe.c
--- a/drivers/net/sunqe.c	Sun May 11 19:48:01 2003
+++ b/drivers/net/sunqe.c	Tue May 27 00:50:01 2003
@@ -124,7 +124,6 @@
 		qb->qe_rxd[i].rx_flags =
 			(RXD_OWN | ((RXD_PKT_SZ) & RXD_LENGTH));
 	}
-	return IRQ_HANDLED;
 }
 
 static int qe_init(struct sunqe *qep, int from_irq)
diff -Nru a/drivers/net/wan/lmc/lmc_debug.c b/drivers/net/wan/lmc/lmc_debug.c
--- a/drivers/net/wan/lmc/lmc_debug.c	Thu Nov 21 14:45:10 2002
+++ b/drivers/net/wan/lmc/lmc_debug.c	Mon May 26 22:01:35 2003
@@ -2,9 +2,7 @@
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/interrupt.h>
-#include <linux/version.h>
 
-#include "lmc_ver.h"
 #include "lmc_debug.h"
 
 /*
diff -Nru a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
--- a/drivers/net/wan/lmc/lmc_main.c	Sun May 11 19:48:01 2003
+++ b/drivers/net/wan/lmc/lmc_main.c	Mon May 26 23:59:35 2003
@@ -11,7 +11,7 @@
   * With Help By:
   * David Boggs
   * Ron Crane
-  * Allan Cox
+  * Alan Cox
   *
   * This software may be used and distributed according to the terms
   * of the GNU General Public License version 2, incorporated herein by reference.
@@ -38,7 +38,6 @@
 
 /* $Id: lmc_main.c,v 1.36 2000/04/11 05:25:25 asj Exp $ */
 
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/string.h>
@@ -51,9 +50,6 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#if LINUX_VERSION_CODE < 0x20155
-#include <linux/bios32.h>
-#endif
 #include <linux/in.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
@@ -67,12 +63,8 @@
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#if LINUX_VERSION_CODE >= 0x20200
 #include <asm/uaccess.h>
 //#include <asm/spinlock.h>
-#else				/* 2.0 kernel */
-#define ARPHRD_HDLC 513
-#endif
 
 #define DRIVER_MAJOR_VERSION     1
 #define DRIVER_MINOR_VERSION    34
@@ -80,7 +72,6 @@
 
 #define DRIVER_VERSION  ((DRIVER_MAJOR_VERSION << 8) + DRIVER_MINOR_VERSION)
 
-#include "lmc_ver.h"
 #include "lmc.h"
 #include "lmc_var.h"
 #include "lmc_ioctl.h"
@@ -127,10 +118,8 @@
 static int lmc_init(struct net_device * const);
 static void lmc_reset(lmc_softc_t * const sc);
 static void lmc_dec_reset(lmc_softc_t * const sc);
-#if LINUX_VERSION_CODE >= 0x20363
 static void lmc_driver_timeout(struct net_device *dev);
 int lmc_setup(void);
-#endif
 
 
 /*
@@ -165,7 +154,8 @@
          * To date internally, just copy this out to the user.
          */
     case LMCIOCGINFO: /*fold01*/
-        LMC_COPY_TO_USER(ifr->ifr_data, &sc->ictl, sizeof (lmc_ctl_t));
+        if (copy_to_user(ifr->ifr_data, &sc->ictl, sizeof (lmc_ctl_t)))
+            return -EFAULT;
         ret = 0;
         break;
 
@@ -181,7 +171,8 @@
             break;
         }
 
-        LMC_COPY_FROM_USER(&ctl, ifr->ifr_data, sizeof (lmc_ctl_t));
+        if (copy_from_user(&ctl, ifr->ifr_data, sizeof (lmc_ctl_t)))
+            return -EFAULT;
 
         sc->lmc_media->set_status (sc, &ctl);
 
@@ -211,7 +202,8 @@
 		break;
 	    }
 
-	    LMC_COPY_FROM_USER(&new_type, ifr->ifr_data, sizeof(u_int16_t));
+	    if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u_int16_t)))
+                return -EFAULT;
 
             
 	    if (new_type == old_type)
@@ -248,8 +240,9 @@
 
         sc->lmc_xinfo.Magic1 = 0xDEADBEEF;
 
-        LMC_COPY_TO_USER(ifr->ifr_data, &sc->lmc_xinfo,
-                         sizeof (struct lmc_xinfo));
+        if (copy_to_user(ifr->ifr_data, &sc->lmc_xinfo,
+                         sizeof (struct lmc_xinfo)))
+            return -EFAULT;
         ret = 0;
 
         break;
@@ -279,8 +272,9 @@
                 regVal & T1FRAMER_SEF_MASK;
         }
 
-        LMC_COPY_TO_USER(ifr->ifr_data, &sc->stats,
-                         sizeof (struct lmc_statistics));
+        if (copy_to_user(ifr->ifr_data, &sc->stats,
+                         sizeof (struct lmc_statistics)))
+            return -EFAULT;
 
         ret = 0;
         break;
@@ -310,7 +304,8 @@
             break;
         }
 
-        LMC_COPY_FROM_USER(&ctl, ifr->ifr_data, sizeof (lmc_ctl_t));
+        if (copy_from_user(&ctl, ifr->ifr_data, sizeof (lmc_ctl_t)))
+            return -EFAULT;
         sc->lmc_media->set_circuit_type(sc, ctl.circuit_type);
         sc->ictl.circuit_type = ctl.circuit_type;
         ret = 0;
@@ -335,8 +330,10 @@
 
 #ifdef DEBUG
     case LMCIOCDUMPEVENTLOG:
-        LMC_COPY_TO_USER(ifr->ifr_data, &lmcEventLogIndex, sizeof (u32));
-        LMC_COPY_TO_USER(ifr->ifr_data + sizeof (u32), lmcEventLogBuf, sizeof (lmcEventLogBuf));
+        if (copy_to_user(ifr->ifr_data, &lmcEventLogIndex, sizeof (u32)))
+            return -EFAULT;
+        if (copy_to_user(ifr->ifr_data + sizeof (u32), lmcEventLogBuf, sizeof (lmcEventLogBuf)))
+            return -EFAULT;
 
         ret = 0;
         break;
@@ -359,9 +356,10 @@
             /*
              * Stop the xwitter whlie we restart the hardware
              */
-            LMC_XMITTER_BUSY(dev);
+            netif_stop_queue(dev);
 
-            LMC_COPY_FROM_USER(&xc, ifr->ifr_data, sizeof (struct lmc_xilinx_control));
+            if (copy_from_user(&xc, ifr->ifr_data, sizeof (struct lmc_xilinx_control)))
+                return -EFAULT;
             switch(xc.command){
             case lmc_xilinx_reset: /*fold02*/
                 {
@@ -620,7 +618,7 @@
                 break;
             }
 
-            LMC_XMITTER_FREE(dev);
+            netif_wake_queue(dev);
             sc->lmc_txfull = 0;
 
         }
@@ -646,7 +644,7 @@
     lmc_softc_t *sc;
     int link_status;
     u_int32_t ticks;
-    LMC_SPIN_FLAGS;
+    unsigned long flags;
 
     sc = dev->priv;
 
@@ -836,11 +834,7 @@
      * Allocate our own device structure
      */
 
-#if LINUX_VERSION_CODE < 0x20363
-    dev = kmalloc (sizeof (struct ppp_device)+8, GFP_KERNEL);
-#else
     dev = kmalloc (sizeof (struct net_device)+8, GFP_KERNEL);
-#endif
     if (dev == NULL){
         printk (KERN_ERR "lmc: kmalloc for device failed\n");
         return NULL;
@@ -909,10 +903,8 @@
     dev->get_stats = lmc_get_stats;
     dev->do_ioctl = lmc_ioctl;
     dev->set_config = lmc_set_config;
-#if LINUX_VERSION_CODE >= 0x20363
     dev->tx_timeout = lmc_driver_timeout;
     dev->watchdog_timeo = (HZ); /* 1 second */
-#endif
     
     /*
      * Why were we changing this???
@@ -923,8 +915,6 @@
 
     spin_lock_init(&sc->lmc_lock);
 
-    LMC_SETUP_20_DEV;
-
     printk ("%s: detected at %lx, irq %d\n", dev->name, ioaddr, dev->irq);
 
     if (register_netdev (dev) != 0) {
@@ -1048,7 +1038,7 @@
      * PCI bus, we are in trouble.
      */
 
-    if (!LMC_PCI_PRESENT()) {
+    if (!pci_present()) {
 /*        printk ("%s: We really want a pci bios!\n", dev->name);*/
         return -1;
     }
@@ -1124,11 +1114,7 @@
     if (cards_found < 1)
         return -1;
 
-#if LINUX_VERSION_CODE >= 0x20200
     return foundaddr;
-#else
-    return 0;
-#endif
 }
 
 /* After this is called, packets can be sent.
@@ -1199,11 +1185,7 @@
     dev->do_ioctl = lmc_ioctl;
 
 
-    LMC_XMITTER_INIT(dev);
-    
-#if LINUX_VERSION_CODE < 0x20363
-    dev->start = 1;
-#endif
+    netif_start_queue(dev);
     
     sc->stats.tx_tbusy0++ ;
 
@@ -1277,7 +1259,7 @@
 
     //dev->flags |= IFF_RUNNING;
     
-    LMC_XMITTER_FREE(dev);
+    netif_wake_queue(dev);
 
     sc->lmc_txfull = 0;
     sc->stats.tx_tbusy0++ ;
@@ -1327,7 +1309,7 @@
     
     /* Don't let anything else go on right now */
     //    dev->start = 0;
-    LMC_XMITTER_BUSY(dev);
+    netif_stop_queue(dev);
     sc->stats.tx_tbusy1++ ;
 
     /* stop interrupts */
@@ -1360,23 +1342,20 @@
         sc->lmc_rxring[i].length = 0;
         sc->lmc_rxring[i].buffer1 = 0xDEADBEEF;
         if (skb != NULL)
-        {
-            LMC_SKB_FREE(skb, 1);
-            LMC_DEV_KFREE_SKB (skb);
-        }
+            dev_kfree_skb(skb);
         sc->lmc_rxq[i] = NULL;
     }
 
     for (i = 0; i < LMC_TXDESCS; i++)
     {
         if (sc->lmc_txq[i] != NULL)
-            LMC_DEV_KFREE_SKB (sc->lmc_txq[i]);
+            dev_kfree_skb(sc->lmc_txq[i]);
         sc->lmc_txq[i] = NULL;
     }
 
     lmc_led_off (sc, LMC_MII16_LED_ALL);
 
-    LMC_XMITTER_FREE(dev);
+    netif_wake_queue(dev);
     sc->stats.tx_tbusy0++ ;
 
     lmc_trace(dev, "lmc_ifdown out");
@@ -1496,14 +1475,12 @@
                 }
                 else {
                     
-#if LINUX_VERSION_CODE >= 0x20200
                     sc->stats.tx_bytes += sc->lmc_txring[i].length & 0x7ff;
-#endif
                     
                     sc->stats.tx_packets++;
                 }
                 
-                //                LMC_DEV_KFREE_SKB (sc->lmc_txq[i]);
+                //                dev_kfree_skb(sc->lmc_txq[i]);
                 dev_kfree_skb_irq(sc->lmc_txq[i]);
                 sc->lmc_txq[i] = 0;
 
@@ -1518,20 +1495,14 @@
             }
             LMC_EVENT_LOG(LMC_EVENT_TBUSY0, n_compl, 0);
             sc->lmc_txfull = 0;
-            LMC_XMITTER_FREE(dev);
+            netif_wake_queue(dev);
             sc->stats.tx_tbusy0++ ;
-#if LINUX_VERSION_CODE < 0x20363
-            mark_bh (NET_BH);	/* Tell Linux to give me more packets */
-#endif
 
 
 #ifdef DEBUG
             sc->stats.dirtyTx = badtx;
             sc->stats.lmc_next_tx = sc->lmc_next_tx;
             sc->stats.lmc_txfull = sc->lmc_txfull;
-#if LINUX_VERSION_CODE < 0x20363
-            sc->stats.tbusy = dev->tbusy;
-#endif
 #endif
             sc->lmc_taint_tx = badtx;
 
@@ -1592,7 +1563,7 @@
     u32 flag;
     int entry;
     int ret = 0;
-    LMC_SPIN_FLAGS;
+    unsigned long flags;
 
     lmc_trace(dev, "lmc_start_xmit in");
 
@@ -1600,60 +1571,6 @@
 
     spin_lock_irqsave(&sc->lmc_lock, flags);
 
-    /*
-     * If the transmitter is busy
-     * this must be the 5 second polling
-     * from the kernel which called us.
-     * Poke the chip and try to get it running
-     *
-     */
-#if LINUX_VERSION_CODE < 0x20363
-    if(dev->tbusy != 0){
-        u32 csr6;
-
-        printk("%s: Xmitter busy|\n", dev->name);
-
-	sc->stats.tx_tbusy_calls++ ;
-        if (jiffies - dev->trans_start < TX_TIMEOUT) {
-            ret = 1;
-            goto lmc_start_xmit_bug_out;
-        }
-
-        /*
-         * Chip seems to have locked up
-         * Reset it
-         * This whips out all our decriptor
-         * table and starts from scartch
-         */
-
-        LMC_EVENT_LOG(LMC_EVENT_XMTPRCTMO,
-                      LMC_CSR_READ (sc, csr_status),
-                      sc->stats.tx_ProcTimeout);
-
-        lmc_running_reset (dev);
-
-        LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
-        LMC_EVENT_LOG(LMC_EVENT_RESET2,
-                      lmc_mii_readreg (sc, 0, 16),
-                      lmc_mii_readreg (sc, 0, 17));
-
-        /* restart the tx processes */
-        csr6 = LMC_CSR_READ (sc, csr_command);
-        LMC_CSR_WRITE (sc, csr_command, csr6 | 0x0002);
-        LMC_CSR_WRITE (sc, csr_command, csr6 | 0x2002);
-
-        /* immediate transmit */
-        LMC_CSR_WRITE (sc, csr_txpoll, 0);
-
-        sc->stats.tx_errors++;
-        sc->stats.tx_ProcTimeout++;	/* -baz */
-
-        dev->trans_start = jiffies;
-
-        ret = 1;
-        goto lmc_start_xmit_bug_out;
-    }
-#endif
     /* normal path, tbusy known to be zero */
 
     entry = sc->lmc_next_tx % LMC_TXDESCS;
@@ -1669,26 +1586,26 @@
     {
         /* Do not interrupt on completion of this packet */
         flag = 0x60000000;
-        LMC_XMITTER_FREE(dev);
+        netif_wake_queue(dev);
     }
     else if (sc->lmc_next_tx - sc->lmc_taint_tx == LMC_TXDESCS / 2)
     {
         /* This generates an interrupt on completion of this packet */
         flag = 0xe0000000;
-        LMC_XMITTER_FREE(dev);
+        netif_wake_queue(dev);
     }
     else if (sc->lmc_next_tx - sc->lmc_taint_tx < LMC_TXDESCS - 1)
     {
         /* Do not interrupt on completion of this packet */
         flag = 0x60000000;
-        LMC_XMITTER_FREE(dev);
+        netif_wake_queue(dev);
     }
     else
     {
         /* This generates an interrupt on completion of this packet */
         flag = 0xe0000000;
         sc->lmc_txfull = 1;
-        LMC_XMITTER_BUSY(dev);
+        netif_stop_queue(dev);
     }
 #else
     flag = LMC_TDES_INTERRUPT_ON_COMPLETION;
@@ -1696,7 +1613,7 @@
     if (sc->lmc_next_tx - sc->lmc_taint_tx >= LMC_TXDESCS - 1)
     {				/* ring full, go busy */
         sc->lmc_txfull = 1;
-        LMC_XMITTER_BUSY(dev);
+        netif_stop_queue(dev);
         sc->stats.tx_tbusy1++ ;
         LMC_EVENT_LOG(LMC_EVENT_TBUSY1, entry, 0);
     }
@@ -1726,10 +1643,6 @@
 
     dev->trans_start = jiffies;
 
-#if LINUX_VERSION_CODE < 0x20363
-lmc_start_xmit_bug_out:
-#endif
-
     spin_unlock_irqrestore(&sc->lmc_lock, flags);
 
     lmc_trace(dev, "lmc_start_xmit_out");
@@ -1815,7 +1728,6 @@
         if(skb == 0x0){
             nsb = dev_alloc_skb (LMC_PKT_BUF_SZ + 2);
             if (nsb) {
-                LMC_SKB_FREE(nsb, 1);
                 sc->lmc_rxq[i] = nsb;
                 nsb->dev = dev;
                 sc->lmc_rxring[i].buffer1 = virt_to_bus (nsb->tail);
@@ -1859,7 +1771,6 @@
              */
             nsb = dev_alloc_skb (LMC_PKT_BUF_SZ + 2);
             if (nsb) {
-                LMC_SKB_FREE(nsb, 1);
                 sc->lmc_rxq[i] = nsb;
                 nsb->dev = dev;
                 sc->lmc_rxring[i].buffer1 = virt_to_bus (nsb->tail);
@@ -1948,7 +1859,7 @@
 static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/
 {
     lmc_softc_t *sc;
-    LMC_SPIN_FLAGS;
+    unsigned long flags;
 
     lmc_trace(dev, "lmc_get_stats in");
 
@@ -1965,9 +1876,7 @@
     return (struct net_device_stats *) &sc->stats;
 }
 
-#ifdef MODULE
-
-int init_module (void) /*fold00*/
+static int __init init_lmc(void)
 {
     printk ("lmc: module loaded\n");
 
@@ -1978,7 +1887,7 @@
     return 0;
 }
 
-void cleanup_module (void) /*fold00*/
+static void __exit exit_lmc(void)
 {
     struct net_device *dev, *next;
     lmc_softc_t *sc;
@@ -2020,7 +1929,9 @@
     Lmc_root_dev = NULL;
     printk ("lmc module unloaded\n");
 }
-#endif
+
+module_init(init_lmc);
+module_exit(exit_lmc);
 
 unsigned lmc_mii_readreg (lmc_softc_t * const sc, unsigned devaddr, unsigned regno) /*fold00*/
 {
@@ -2148,7 +2059,6 @@
         }
 
         skb->dev = sc->lmc_device;
-        LMC_SKB_FREE(skb, 1);
 
         /* owned by 21140 */
         sc->lmc_rxring[i].status = 0x80000000;
@@ -2367,11 +2277,10 @@
     lmc_trace(sc->lmc_device, "lmc_initcsrs out");
 }
 
-#if LINUX_VERSION_CODE >= 0x20363
 static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/
     lmc_softc_t *sc;
     u32 csr6;
-    LMC_SPIN_FLAGS;
+    unsigned long flags;
 
     lmc_trace(dev, "lmc_driver_timeout in");
 
@@ -2430,4 +2339,3 @@
    return lmc_probe(NULL);
 }
 
-#endif
diff -Nru a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
--- a/drivers/net/wan/lmc/lmc_media.c	Thu Nov 21 14:45:10 2002
+++ b/drivers/net/wan/lmc/lmc_media.c	Mon May 26 22:01:35 2003
@@ -1,6 +1,5 @@
 /* $Id: lmc_media.c,v 1.13 2000/04/11 05:25:26 asj Exp $ */
 
-#include <linux/version.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -11,9 +10,6 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#if LINUX_VERSION_CODE < 0x20155
-#include <linux/bios32.h>
-#endif
 #include <linux/in.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
@@ -28,11 +24,8 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 
-#if LINUX_VERSION_CODE >= 0x20200
 #include <asm/uaccess.h>
-#endif
 
-#include "lmc_ver.h"
 #include "lmc.h"
 #include "lmc_var.h"
 #include "lmc_ioctl.h"
diff -Nru a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
--- a/drivers/net/wan/lmc/lmc_proto.c	Wed Nov 27 11:25:40 2002
+++ b/drivers/net/wan/lmc/lmc_proto.c	Mon May 26 22:01:35 2003
@@ -19,7 +19,6 @@
   * Driver for the LanMedia LMC5200, LMC5245, LMC1000, LMC1200 cards.
   */
 
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -46,7 +45,6 @@
 #include <asm/dma.h>
 #include <asm/smp.h>
 
-#include "lmc_ver.h"
 #include "lmc.h"
 #include "lmc_var.h"
 #include "lmc_debug.h"
@@ -66,14 +64,6 @@
 #define SPPP_attach(d)	(void)0
 #define SPPP_do_ioctl(d,i,c)	-EOPNOTSUPP
 #else
-#if LINUX_VERSION_CODE < 0x20363
-#define SPPP_attach(x)	sppp_attach((struct ppp_device *)(x)->lmc_device)
-#define SPPP_detach(x)	sppp_detach((x)->lmc_device)
-#define SPPP_open(x)	sppp_open((x)->lmc_device)
-#define SPPP_reopen(x)	sppp_reopen((x)->lmc_device)
-#define SPPP_close(x)	sppp_close((x)->lmc_device)
-#define SPPP_do_ioctl(x, y, z)	sppp_do_ioctl((x)->lmc_device, (y), (z))
-#else
 #define SPPP_attach(x)	sppp_attach((x)->pd)
 #define SPPP_detach(x)	sppp_detach((x)->pd->dev)
 #define SPPP_open(x)	sppp_open((x)->pd->dev)
@@ -81,7 +71,6 @@
 #define SPPP_close(x)	sppp_close((x)->pd->dev)
 #define SPPP_do_ioctl(x, y, z)	sppp_do_ioctl((x)->pd->dev, (y), (z))
 #endif
-#endif
 
 // init
 void lmc_proto_init(lmc_softc_t *sc) /*FOLD00*/
@@ -89,15 +78,12 @@
     lmc_trace(sc->lmc_device, "lmc_proto_init in");
     switch(sc->if_type){
     case LMC_PPP:
-        
-#if LINUX_VERSION_CODE >= 0x20363
         sc->pd = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
 	if (!sc->pd) {
 		printk("lmc_proto_init(): kmalloc failure!\n");
 		return;
 	}
         sc->pd->dev = sc->lmc_device;
-#endif
         sc->if_ptr = sc->pd;
         break;
     case LMC_RAW:
diff -Nru a/drivers/net/wan/lmc/lmc_var.h b/drivers/net/wan/lmc/lmc_var.h
--- a/drivers/net/wan/lmc/lmc_var.h	Sun Sep 29 15:26:50 2002
+++ b/drivers/net/wan/lmc/lmc_var.h	Mon May 26 22:01:35 2003
@@ -48,9 +48,6 @@
 #define u_int16_t	u16
 #define u_int8_t	u8
 #define tulip_uint32_t	u32
-#if LINUX_VERSION_CODE < 0x20155
-#define u_int32_t	u32
-#endif
 
 #define LMC_REG_RANGE 0x80
 
@@ -410,9 +407,7 @@
         u32                     last_int;
         u32                     num_int;
 
-#if LINUX_VERSION_CODE >= 0x20200
 	spinlock_t              lmc_lock;
-#endif
         u_int16_t               if_type;       /* PPP or NET */
         struct ppp_device       *pd;
 
@@ -549,10 +544,6 @@
 
 #define LMC_CRC_LEN_16 2  /* 16-bit CRC */
 #define LMC_CRC_LEN_32 4
-
-#if LINUX_VERSION_CODE < 0x20100
-#define test_and_set_bit(val, addr) set_bit(val, addr)
-#endif
 
 #ifdef LMC_HDLC
 /* definition of an hdlc header. */
diff -Nru a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
--- a/drivers/net/wan/pc300_tty.c	Mon Apr 21 20:58:42 2003
+++ b/drivers/net/wan/pc300_tty.c	Mon May 26 15:29:13 2003
@@ -113,7 +113,7 @@
 static struct tty_struct *cpc_tty_serial_table[CPC_TTY_NPORTS];
 static struct termios *cpc_tty_serial_termios[CPC_TTY_NPORTS];
 static struct termios *cpc_tty_serial_termios_locked[CPC_TTY_NPORTS];
-static struct tty_driver serial_drv, callout_drv;
+static struct tty_driver serial_drv;
 
 /* local variables */
 st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];
@@ -244,15 +244,6 @@
 		serial_drv.flush_buffer = cpc_tty_flush_buffer; 
 		serial_drv.hangup = cpc_tty_hangup;
 
-		/* the callout device is just like normal device except for major */
-	   	/* number and the subtype code */ 
-		callout_drv = serial_drv; 
-		callout_drv.name = "cucp"; 
-		callout_drv.major = CPC_TTY_MAJOR + 1;
-		callout_drv.subtype = SERIAL_TYPE_CALLOUT;
-		callout_drv.read_proc = 0;
-		callout_drv.proc_entry = 0; 
-		
 		/* register the TTY driver */
 		if (tty_register_driver(&serial_drv)) { 
 			printk("%s-tty: Failed to register serial driver! ",
@@ -260,11 +251,6 @@
 		   	return;
 		} 
 
-		if (tty_register_driver(&callout_drv)) {
-			CPC_TTY_DBG("%s-tty: Failed to register callout driver! ",
-				((struct net_device*)(pc300dev->hdlc))->name);
-			return;
-		}
 		memset((void *)cpc_tty_area, 0,
 								sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS);
 	}
@@ -436,10 +422,6 @@
 			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
 							cpc_tty->name,res);
 		}
-		if ((res=tty_unregister_driver(&callout_drv))) { 
-			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
-							cpc_tty->name,res);
-		}
 	}
 	return; 
 } 
@@ -688,10 +670,6 @@
 			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
 							cpc_tty->name,res);
 		}
-		if ((res=tty_unregister_driver(&callout_drv))) { 
-			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
-							cpc_tty->name,res);
-		}
 	}
 	cpc_tty_dtr_off(cpc_tty->pc300dev);
 }
@@ -1092,10 +1070,6 @@
 				CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
 								cpc_tty->name,res);
 			}
-			if ((res=tty_unregister_driver(&callout_drv))) { 
-				CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
-								cpc_tty->name,res);
-			}
 		}
 	}
 	CPC_TTY_LOCK(pc300dev->chan->card,flags);
@@ -1130,7 +1104,6 @@
 	CPC_TTY_DBG("hdlcX-tty: reset variables\n");
 	/* reset  the tty_driver structure - serial_drv */ 
 	memset(&serial_drv, 0, sizeof(struct tty_driver));
-	memset(&callout_drv, 0, sizeof(struct tty_driver));
 	for (i=0; i < CPC_TTY_NPORTS; i++){
 		memset(&cpc_tty_area[i],0, sizeof(st_cpc_tty_area)); 
 	}
diff -Nru a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c
--- a/drivers/net/wan/sdla_chdlc.c	Mon May 19 23:52:15 2003
+++ b/drivers/net/wan/sdla_chdlc.c	Mon May 26 15:29:13 2003
@@ -284,7 +284,7 @@
 static void wanpipe_tty_receive(sdla_t *, unsigned, unsigned int);
 static void wanpipe_tty_trigger_poll(sdla_t *card);
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount=1;
 static int tty_init_cnt=0;
 
@@ -1056,15 +1056,12 @@
 	if (card->tty_opt){
 		struct serial_state * state;
 		if (!(--tty_init_cnt)){
-			int e1,e2;
+			int e1;
 			*serial_driver.refcount=0;
 			
 			if ((e1 = tty_unregister_driver(&serial_driver)))
 				printk("SERIAL: failed to unregister serial driver (%d)\n",
 				       e1);
-			if ((e2 = tty_unregister_driver(&callout_driver)))
-				printk("SERIAL: failed to unregister callout driver (%d)\n", 
-				       e2);
 			printk(KERN_INFO "%s: Unregistering TTY Driver, Major %i\n",
 					card->devname,WAN_TTY_MAJOR);
 		}
@@ -4444,27 +4441,10 @@
 		serial_driver.wait_until_sent = wanpipe_tty_wait_until_sent;
 		serial_driver.read_proc = wanpipe_tty_read_proc;
 		
-		/*
-		 * The callout device is just like normal device except for
-		 * major number and the subtype code.
-		 */
-		callout_driver = serial_driver;
-		callout_driver.name = "cuw";
-		callout_driver.major = TTYAUX_MAJOR;
-		callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-		callout_driver.read_proc = 0;
-		callout_driver.proc_entry = 0;
-
 		if (tty_register_driver(&serial_driver)){
 			printk(KERN_INFO "%s: Failed to register serial driver!\n",
 					card->devname);
 		}
-
-		if (tty_register_driver(&callout_driver)){
-			printk(KERN_INFO "%s: Failed to register callout driver!\n",
-					card->devname);
-		}
-
 	}
 
 
@@ -4493,7 +4473,6 @@
 	state->custom_divisor = 0;
 	state->close_delay = 5*HZ/10;
 	state->closing_wait = 30*HZ;
-	state->callout_termios = callout_driver.init_termios;
 	state->normal_termios = serial_driver.init_termios;
 	state->icount.cts = state->icount.dsr = 
 		state->icount.rng = state->icount.dcd = 0;
diff -Nru a/drivers/net/wan/z85230.h b/drivers/net/wan/z85230.h
--- a/drivers/net/wan/z85230.h	Thu Apr 24 05:18:50 2003
+++ b/drivers/net/wan/z85230.h	Mon May 26 15:29:27 2003
@@ -334,14 +334,11 @@
 	struct tty_struct 	*tty;		/* Attached terminal */
 	int			line;		/* Minor number */
 	struct termios		normal_termios;	/* Terminal settings */
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;	/* Tasks waiting to open */
 	wait_queue_head_t	close_wait;	/* and for close to end */
 	unsigned long		event;		/* Pending events */
 	int			fdcount;    	/* # of fd on device */
 	int			blocked_open;	/* # of blocked opens */
-	long			session; 	/* Session of opening process */
-	long			pgrp; 		/* pgrp of opening process */
 	int			x_char;		/* XON/XOF char */
 	unsigned char 		*xmit_buf;	/* Transmit pointer */
 	int			xmit_head;	/* Transmit ring */
diff -Nru a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
--- a/drivers/s390/net/ctctty.c	Mon May 26 12:20:48 2003
+++ b/drivers/s390/net/ctctty.c	Mon May 26 15:29:27 2003
@@ -48,7 +48,6 @@
 #define CTC_ASYNC_SPLIT_TERMIOS      0x0008 /* Sep. termios for dialin/out  */
 #define CTC_TTY_XMIT_SIZE              1024 /* Default bufsize for write    */
 #define CTC_SERIAL_XMIT_MAX            4000 /* Maximum bufsize for write    */
-#define CTC_SERIAL_TYPE_NORMAL            1
 
 /* Private data (similar to async_struct in <linux/serial.h>) */
 typedef struct {
@@ -1176,7 +1175,7 @@
 	device->minor_start = 0;
 	device->num = CTC_TTY_MAX_DEVICES;
 	device->type = TTY_DRIVER_TYPE_SERIAL;
-	device->subtype = CTC_SERIAL_TYPE_NORMAL;
+	device->subtype = SERIAL_TYPE_NORMAL;
 	device->init_termios = tty_std_termios;
 	device->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 	device->flags = TTY_DRIVER_REAL_RAW;
diff -Nru a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
--- a/drivers/sbus/char/aurora.c	Mon Apr 21 20:58:42 2003
+++ b/drivers/sbus/char/aurora.c	Mon May 26 15:29:27 2003
@@ -85,8 +85,6 @@
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
 
-#define AURORA_TYPE_NORMAL	1
-
 static struct tty_driver aurora_driver;
 static struct Aurora_board aurora_board[AURORA_NBOARD] = {
 	{0,},
@@ -661,8 +659,7 @@
 	if (mcr & MCR_CDCHG)  {
 		if (sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD) 
 			wake_up_interruptible(&port->open_wait);
-		else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (port->flags & ASYNC_CALLOUT_NOHUP))) 
+		else
 			schedule_task(&port->tqueue_hangup);
 	}
 	
@@ -1334,19 +1331,12 @@
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (port->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		port->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (port->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (port->normal_termios.c_cflag & CLOCAL) 
-			do_clocal = 1;
-	} else {
-		if (C_CLOCAL(tty))  
-			do_clocal = 1;
-	}
+	if (C_CLOCAL(tty))  
+		do_clocal = 1;
 
 	/* Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1367,13 +1357,10 @@
 			    &bp->r[chip]->r[CD180_CAR]);
 		udelay(1);
 		CD = sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD;
-		if (!(port->flags & ASYNC_CALLOUT_ACTIVE))  {
-			port->MSVR=bp->RTS;
+		port->MSVR=bp->RTS;
 
-			/* auto drops DTR */
-			sbus_writeb(port->MSVR,
-				    &bp->r[chip]->r[CD180_MSVR]);
-		}
+		/* auto drops DTR */
+		sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -1384,8 +1371,7 @@
 				retval = -ERESTARTSYS;	
 			break;
 		}
-		if (/*!(port->flags & ASYNC_CALLOUT_ACTIVE) &&*/
-		    !(port->flags & ASYNC_CLOSING) &&
+		if (!(port->flags & ASYNC_CLOSING) &&
 		    (do_clocal || CD))
 			break;
 		if (signal_pending(current)) {
@@ -1465,8 +1451,6 @@
 		restore_flags(flags);
 	}
 
-	port->session = current->session;
-	port->pgrp = current->pgrp;
 #ifdef AURORA_DEBUG
 	printk("aurora_open: end\n");
 #endif
@@ -1520,8 +1504,6 @@
 	 */
 	if (port->flags & ASYNC_NORMAL_ACTIVE)
 		port->normal_termios = *tty->termios;
-/*	if (port->flags & ASYNC_CALLOUT_ACTIVE)
-		port->callout_termios = *tty->termios;*/
 
 	/* Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1578,8 +1560,7 @@
 		}
 		wake_up_interruptible(&port->open_wait);
 	}
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&port->close_wait);
 	restore_flags(flags);
 #ifdef AURORA_DEBUG
@@ -2223,7 +2204,7 @@
 	aurora_shutdown_port(bp, port);
 	port->event = 0;
 	port->count = 0;
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	port->flags &= ~ASYNC_NORMAL_ACTIVE;
 	port->tty = 0;
 	wake_up_interruptible(&port->open_wait);
 #ifdef AURORA_DEBUG
@@ -2310,7 +2291,7 @@
 	aurora_driver.major = AURORA_MAJOR;
 	aurora_driver.num = AURORA_TNPORTS;
 	aurora_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	aurora_driver.subtype = AURORA_TYPE_NORMAL;
+	aurora_driver.subtype = SERIAL_TYPE_NORMAL;
 	aurora_driver.init_termios = tty_std_termios;
 	aurora_driver.init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
diff -Nru a/drivers/sbus/char/aurora.h b/drivers/sbus/char/aurora.h
--- a/drivers/sbus/char/aurora.h	Mon Feb  4 23:41:06 2002
+++ b/drivers/sbus/char/aurora.h	Mon May 26 15:29:09 2003
@@ -247,8 +247,6 @@
 	long			event;
 	int			timeout;
 	int			close_delay;
-	long			session;
-	long			pgrp;
 	unsigned char 		* xmit_buf;
 	int			custom_divisor;
 	int			xmit_head;
diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/3w-xxxx.c	Mon May 12 08:14:01 2003
@@ -2497,7 +2497,8 @@
 } /* End tw_scsi_eh_reset() */
 
 /* This function handles input and output from /proc/scsi/3w-xxxx/x */
-int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout) 
+int tw_scsi_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
+		      off_t offset, int length, int inout) 
 {
 	TW_Device_Extension *tw_dev = NULL;
 	TW_Info info;
@@ -2508,7 +2509,7 @@
 
 	/* Find the correct device extension */
 	for (i=0;i<tw_device_extension_count;i++) 
-		if (tw_device_extension_list[i]->host->host_no == hostno) 
+		if (tw_device_extension_list[i]->host->host_no == shost->host_no) 
 			tw_dev = tw_device_extension_list[i];
 	if (tw_dev == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
@@ -2544,7 +2545,7 @@
 		if (start) {
 			*start = buffer;
 		}
-		tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", hostno);
+		tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", shost->host_no);
 		tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
 		tw_copy_info(&info, "Current commands posted:       %3d\n", tw_dev->posted_request_count);
 		tw_copy_info(&info, "Max commands posted:           %3d\n", tw_dev->max_posted_request_count);
diff -Nru a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
--- a/drivers/scsi/3w-xxxx.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/3w-xxxx.h	Mon May 12 07:26:10 2003
@@ -474,7 +474,6 @@
 int tw_scsi_detect(Scsi_Host_Template *tw_host);
 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt);
 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt);
-int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int inode, int inout);
 int tw_scsi_queue(Scsi_Cmnd *cmd, void (*done) (Scsi_Cmnd *));
 int tw_scsi_release(struct Scsi_Host *tw_host);
 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id);
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Sat Apr 26 07:41:50 2003
+++ b/drivers/scsi/53c700.c	Mon May 26 14:44:44 2003
@@ -124,6 +124,7 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/sched.h>
+#include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -167,12 +168,14 @@
 STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
 STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
 STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_proc_directory_info(char *, char **, off_t, int, int, int);
+STATIC int NCR_700_proc_directory_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
 STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
 STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt);
 
+static struct device_attribute **NCR_700_dev_attrs = NULL;
+
 static char *NCR_700_phase[] = {
 	"",
 	"after selection",
@@ -247,6 +250,9 @@
 	static int banner = 0;
 	int j;
 
+	if(tpnt->sdev_attrs == NULL)
+		tpnt->sdev_attrs = NCR_700_dev_attrs;
+
 	memory = dma_alloc_noncoherent(hostdata->dev, TOTAL_MEM_SIZE,
 				       &pScript, GFP_KERNEL);
 	if(memory == NULL) {
@@ -1703,23 +1709,15 @@
 	return IRQ_RETVAL(handled);
 }
 
-/* FIXME: Need to put some proc information in and plumb it
- * into the scsi proc system */
 STATIC int
-NCR_700_proc_directory_info(char *proc_buf, char **startp,
-			 off_t offset, int bytes_available,
-			 int host_no, int write)
+NCR_700_proc_directory_info(struct Scsi_Host *host, char *proc_buf, char **startp,
+			 off_t offset, int bytes_available, int write)
 {
 	static char buf[4096];	/* 1 page should be sufficient */
 	int len = 0;
-	struct Scsi_Host *host;
 	struct NCR_700_Host_Parameters *hostdata;
 	Scsi_Device *SDp;
 
-	host = scsi_host_hn_get(host_no);
-	if(host == NULL)
-		return 0;
-
 	if(write) {
 		/* FIXME: Clear internal statistics here */
 		return 0;
@@ -2023,6 +2021,56 @@
 	/* to do here: deallocate memory */
 }
 
+static ssize_t
+NCR_700_store_queue_depth(struct device *dev, const char *buf, size_t count)
+{
+	int depth;
+
+	struct scsi_device *SDp = to_scsi_device(dev);
+	depth = simple_strtoul(buf, NULL, 0);
+	if(depth > NCR_700_MAX_TAGS)
+		return -EINVAL;
+	scsi_adjust_queue_depth(SDp, MSG_ORDERED_TAG, depth);
+
+	return count;
+}
+
+static ssize_t
+NCR_700_show_active_tags(struct device *dev, char *buf)
+{
+	struct scsi_device *SDp = to_scsi_device(dev);
+
+	return snprintf(buf, 20, "%d\n", NCR_700_get_depth(SDp));
+}
+
+static struct device_attribute NCR_700_queue_depth_attr = {
+	.attr = {
+		.name = 	"queue_depth",
+		.mode =		S_IWUSR,
+	},
+	.store = NCR_700_store_queue_depth,
+};
+
+static struct device_attribute NCR_700_active_tags_attr = {
+	.attr = {
+		.name =		"active_tags",
+		.mode =		S_IRUGO,
+	},
+	.show = NCR_700_show_active_tags,
+};
+
+STATIC int __init
+NCR_700_init(void)
+{
+	scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs,
+					 &NCR_700_queue_depth_attr);
+	scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs,
+					 &NCR_700_active_tags_attr);
+	return 0;
+}
+
 EXPORT_SYMBOL(NCR_700_detect);
 EXPORT_SYMBOL(NCR_700_release);
 EXPORT_SYMBOL(NCR_700_intr);
+
+module_init(NCR_700_init);
diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
--- a/drivers/scsi/AM53C974.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/AM53C974.c	Tue May 13 03:59:32 2003
@@ -732,6 +732,12 @@
 	hostdata->disconnecting = 0;
 	hostdata->dma_busy = 0;
 
+	if (!request_region (instance->io_port, 128, "AM53C974")) {
+		printk ("AM53C974 (scsi%d): Could not get IO region %04lx.\n",
+			instance->host_no, instance->io_port);
+		scsi_unregister(instance);
+		return 0;
+	}
 /* Set up an interrupt handler if we aren't already sharing an IRQ with another board */
 	for (search = first_host;
 	     search && (((the_template != NULL) && (search->hostt != the_template)) ||
@@ -2442,6 +2448,7 @@
 static int AM53C974_release(struct Scsi_Host *shp)
 {
 	free_irq(shp->irq, shp);
+	release_region(shp->io_port, 128);
 	scsi_unregister(shp);
 	return 0;
 }
diff -Nru a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
--- a/drivers/scsi/BusLogic.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/BusLogic.c	Mon May 12 07:26:10 2003
@@ -4327,9 +4327,9 @@
   BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
 */
 
-int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
+int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer,
 			       off_t Offset, int BytesAvailable,
-			       int HostNumber, int WriteFlag)
+			       int WriteFlag)
 {
   BusLogic_HostAdapter_T *HostAdapter;
   BusLogic_TargetStatistics_T *TargetStatistics;
@@ -4338,11 +4338,11 @@
   for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
        HostAdapter != NULL;
        HostAdapter = HostAdapter->Next)
-    if (HostAdapter->HostNumber == HostNumber) break;
+    if (HostAdapter->HostNumber == shost->host_no) break;
   if (HostAdapter == NULL)
     {
       BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
-		     NULL, HostNumber);
+		     NULL, shost->host_no);
       return 0;
     }
   TargetStatistics = HostAdapter->TargetStatistics;
diff -Nru a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
--- a/drivers/scsi/BusLogic.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/BusLogic.h	Mon May 12 07:45:05 2003
@@ -56,7 +56,7 @@
 				 void (*CompletionRoutine)(SCSI_Command_T *));
 extern int BusLogic_BIOSDiskParameters(struct scsi_device *,
 		struct block_device *, sector_t, int *);
-extern int BusLogic_ProcDirectoryInfo(char *, char **, off_t, int, int, int);
+extern int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int);
 extern int BusLogic_SlaveConfigure(SCSI_Device_T *);
 
 #ifdef BusLogic_DriverVersion
diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
--- a/drivers/scsi/NCR5380.c	Thu May 15 18:42:51 2003
+++ b/drivers/scsi/NCR5380.c	Mon May 19 19:40:41 2003
@@ -824,7 +824,7 @@
 	NCR5380_dprint(NDEBUG_ANY, instance);
 	NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
-	len = NCR5380_proc_info(pr_bfr, &start, 0, sizeof(pr_bfr), instance->host_no, 0);
+	len = NCR5380_proc_info(instance, pr_bfr, &start, 0, sizeof(pr_bfr), 0);
 	pr_bfr[len] = 0;
 	printk("\n%s\n", pr_bfr);
 }
@@ -855,16 +855,12 @@
 #ifndef NCR5380_proc_info
 static
 #endif
-int NCR5380_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, char **start, off_t offset, int length, int inout)
 {
 	char *pos = buffer;
-	struct Scsi_Host *instance;
 	struct NCR5380_hostdata *hostdata;
 	Scsi_Cmnd *ptr;
 
-	instance = scsi_host_hn_get(hostno);
-	if (!instance)
-		return (-ESRCH);
 	hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
 	if (inout) {		/* Has data been written to the file ? */
diff -Nru a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
--- a/drivers/scsi/NCR5380.h	Sat Apr 26 07:28:14 2003
+++ b/drivers/scsi/NCR5380.h	Mon May 12 07:58:21 2003
@@ -310,7 +310,10 @@
 static int NCR5380_host_reset(Scsi_Cmnd * cmd);
 static int NCR5380_device_reset(Scsi_Cmnd * cmd);
 static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
-
+#ifdef NCR5380_proc_info
+int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
+off_t offset, int length, int inout);
+#endif
 
 static void NCR5380_reselect(struct Scsi_Host *instance);
 static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);
diff -Nru a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
--- a/drivers/scsi/NCR53C9x.c	Sat Apr 26 07:28:14 2003
+++ b/drivers/scsi/NCR53C9x.c	Mon May 12 07:26:10 2003
@@ -890,24 +890,15 @@
 }
 
 /* ESP proc filesystem code. */
-int esp_proc_info(char *buffer, char **start, off_t offset, int length,
-		  int hostno, int inout)
+int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length,
+		  int inout)
 {
-	struct NCR_ESP *esp;
+	struct NCR_ESP *esp = (struct NCR_ESP *) SCpnt->device->host->hostdata;
 
 	if(inout)
 		return -EINVAL; /* not yet */
-
-	for_each_esp(esp) {
-		if(esp->ehost->host_no == hostno)
-			break;
-	}
-	if(!esp)
-		return -EINVAL;
-
 	if(start)
 		*start = buffer;
-
 	return esp_host_info(esp, buffer, offset, length);
 }
 
diff -Nru a/drivers/scsi/NCR53C9x.h b/drivers/scsi/NCR53C9x.h
--- a/drivers/scsi/NCR53C9x.h	Sat Apr 26 07:28:14 2003
+++ b/drivers/scsi/NCR53C9x.h	Mon May 12 07:26:10 2003
@@ -664,6 +664,6 @@
 extern int esp_command(Scsi_Cmnd *);
 extern int esp_abort(Scsi_Cmnd *);
 extern int esp_reset(Scsi_Cmnd *);
-extern int esp_proc_info(char *buffer, char **start, off_t offset, int length,
-			 int hostno, int inout);
+extern int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length,
+			 int inout);
 #endif /* !(NCR53C9X_H) */
diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
--- a/drivers/scsi/NCR_D700.c	Sun May 25 17:00:00 2003
+++ b/drivers/scsi/NCR_D700.c	Mon May 26 18:54:33 2003
@@ -385,6 +385,7 @@
 static void __exit NCR_D700_exit(void)
 {
 	mca_unregister_driver(&NCR_D700_driver);
+	scsi_sysfs_release_attributes();
 }
 
 module_init(NCR_D700_init);
diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
--- a/drivers/scsi/aacraid/linit.c	Thu May  8 11:24:16 2003
+++ b/drivers/scsi/aacraid/linit.c	Mon May 12 08:14:20 2003
@@ -137,7 +137,6 @@
 static int aac_queuecommand(Scsi_Cmnd *, void (*CompletionRoutine)(Scsi_Cmnd *));
 static int aac_biosparm(struct scsi_device *, struct block_device *,
 			sector_t, int *);
-static int aac_procinfo(char *, char **, off_t, int, int, int);
 static int aac_ioctl(Scsi_Device *, int, void *);
 static int aac_eh_abort(Scsi_Cmnd * cmd);
 static int aac_eh_device_reset(Scsi_Cmnd* cmd);
@@ -616,7 +615,6 @@
 static Scsi_Host_Template driver_template = {
 	.module				= THIS_MODULE,
 	.name           		= "AAC",
-	.proc_info      		= aac_procinfo,
 	.detect         		= aac_detect,
 	.release        		= aac_release,
 	.info           		= aac_driverinfo,
@@ -682,35 +680,3 @@
 
 
 #include "scsi_module.c"
-
-/**
- *	aac_procinfo	-	Implement /proc/scsi/<drivername>/<n>
- *	@proc_buffer: memory buffer for I/O
- *	@start_ptr: pointer to first valid data
- *	@offset: offset into file
- *	@bytes_available: space left
- *	@host_no: scsi host ident
- *	@write: direction of I/O
- *
- *	Used to export driver statistics and other infos to the world outside 
- *	the kernel using the proc file system. Also provides an interface to
- *	feed the driver with information.
- *
- *		For reads
- *			- if offset > 0 return 0
- *			- if offset == 0 write data to proc_buffer and set the start_ptr to
- *			beginning of proc_buffer, return the number of characters written.
- *		For writes
- *			- writes currently not supported, return 0
- *
- *	Bugs:	Only offset zero is handled
- */
-
-static int aac_procinfo(char *proc_buffer, char **start_ptr,off_t offset,
-			int bytes_available, int host_no, int write)
-{
-	if(write || offset > 0)
-		return 0;
-	*start_ptr = proc_buffer;
-	return sprintf(proc_buffer, "%s  %d\n", "Raid Controller, scsi hba number", host_no);
-}
diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
--- a/drivers/scsi/advansys.c	Thu May  8 11:31:08 2003
+++ b/drivers/scsi/advansys.c	Mon May 12 07:41:38 2003
@@ -4290,14 +4290,14 @@
  * user just won't get all the available statistics.
  */
 int
-advansys_proc_info(char *buffer, char **start, off_t offset, int length,
-                   int hostno, int inout)
+advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
+		off_t offset, int length, int inout)
 {
     struct Scsi_Host    *shp;
     asc_board_t         *boardp;
     int                 i;
     char                *cp;
-    int                 cplen;
+    int			cplen;
     int                 cnt;
     int                 totcnt;
     int                 leftlen;
@@ -4322,7 +4322,7 @@
 
     /* Find the specified board. */
     for (i = 0; i < asc_board_count; i++) {
-        if (asc_host[i]->host_no == hostno) {
+        if (asc_host[i]->host_no == shost->host_no) {
             break;
         }
     }
@@ -4767,7 +4767,7 @@
 
 	    scsi_set_device(shp, &pci_devp->dev);
 
-            /* Save a pointer to the Scsi_host of each board found. */
+            /* Save a pointer to the Scsi_Host of each board found. */
             asc_host[asc_board_count++] = shp;
 
             /* Initialize private per board data */
diff -Nru a/drivers/scsi/advansys.h b/drivers/scsi/advansys.h
--- a/drivers/scsi/advansys.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/advansys.h	Mon May 12 07:26:10 2003
@@ -55,14 +55,6 @@
 int advansys_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int[]);
 static int advansys_slave_configure(Scsi_Device *);
-#ifdef CONFIG_PROC_FS
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28)
-extern struct proc_dir_entry proc_scsi_advansys;
-#endif /* version < v2.3.28 */
-int advansys_proc_info(char *, char **, off_t, int, int, int);
-#else /* !defined(CONFIG_PROC_FS) */
-#define advansys_proc_info      NULL
-#endif /* !defined(CONFIG_PROC_FS) */
 
 /* init/main.c setup function */
 void advansys_setup(char *, int *);
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	Sat Apr 26 07:28:18 2003
+++ b/drivers/scsi/aha152x.c	Mon May 12 07:26:11 2003
@@ -3734,26 +3734,18 @@
 #define SPRINTF(args...) \
 	do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
 
-static int aha152x_proc_info(char *buffer, char **start,
-		      off_t offset, int length, int hostno, int inout)
+static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
+		      off_t offset, int length, int inout)
 {
 	int i;
 	char *pos = buffer;
-	struct Scsi_Host *shpnt;
 	Scsi_Cmnd *ptr;
 	unsigned long flags;
 	int thislength;
 
-	for (i = 0, shpnt = (struct Scsi_Host *) NULL; i<ARRAY_SIZE(aha152x_host); i++)
-		if (aha152x_host[i] && aha152x_host[i]->host_no == hostno)
-			shpnt = aha152x_host[i];
-
-	if (!shpnt)
-		return -ESRCH;
-
 	DPRINTK(debug_procinfo, 
 	       KERN_DEBUG "aha152x_proc_info: buffer=%p offset=%ld length=%d hostno=%d inout=%d\n",
-	       buffer, offset, length, hostno, inout);
+	       buffer, offset, length, shpnt->host_no, inout);
 
 
 	if (inout)
diff -Nru a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
--- a/drivers/scsi/aha1740.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/aha1740.c	Mon May 12 07:26:11 2003
@@ -76,21 +76,15 @@
 /* One for each IRQ level (9-15) */
 static struct Scsi_Host * aha_host[8] = {NULL, };
 
-static int aha1740_proc_info(char *buffer, char **start, off_t offset,
-		      int length, int hostno, int inout)
+static int aha1740_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset,
+		      int length, int inout)
 {
     int len;
-    struct Scsi_Host * shpnt;
     struct aha1740_hostdata *host;
 
     if (inout)
 	return-ENOSYS;
 
-    for (len = 0; len < 8; len++) {
-	shpnt = aha_host[len];
-	if (shpnt && shpnt->host_no == hostno)
-	    break;
-    }
     host = HOSTDATA(shpnt);
 
     len = sprintf(buffer, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n"
@@ -108,7 +102,6 @@
     if (len > length)
 	len = length;
     return len;
-}
 
 
 static int aha1740_makecode(unchar *sense, unchar *status)
diff -Nru a/drivers/scsi/aha1740.h b/drivers/scsi/aha1740.h
--- a/drivers/scsi/aha1740.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/aha1740.h	Mon May 12 07:26:11 2003
@@ -156,7 +156,6 @@
 static int aha1740_command(Scsi_Cmnd *);
 static int aha1740_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 static int aha1740_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
-static int aha1740_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
 
 #define AHA1740_ECBS 32
 #define AHA1740_SCATTER 16
diff -Nru a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
--- a/drivers/scsi/aic7xxx/aic79xx.h	Thu Apr 24 11:15:39 2003
+++ b/drivers/scsi/aic7xxx/aic79xx.h	Wed May 14 15:03:47 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#89 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#90 $
  *
  * $FreeBSD$
  */
@@ -1225,20 +1225,20 @@
 	int			  seltime;
 
 	/*
-	 * Interrupt coalessing settings.
+	 * Interrupt coalescing settings.
 	 */
-#define	AHD_INT_COALESSING_TIMER_DEFAULT		250 /*us*/
-#define	AHD_INT_COALESSING_MAXCMDS_DEFAULT		10
-#define	AHD_INT_COALESSING_MAXCMDS_MAX			127
-#define	AHD_INT_COALESSING_MINCMDS_DEFAULT		5
-#define	AHD_INT_COALESSING_MINCMDS_MAX			127
-#define	AHD_INT_COALESSING_THRESHOLD_DEFAULT		2000
-#define	AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT	1000
-	u_int			  int_coalessing_timer;
-	u_int			  int_coalessing_maxcmds;
-	u_int			  int_coalessing_mincmds;
-	u_int			  int_coalessing_threshold;
-	u_int			  int_coalessing_stop_threshold;
+#define	AHD_INT_COALESCING_TIMER_DEFAULT		250 /*us*/
+#define	AHD_INT_COALESCING_MAXCMDS_DEFAULT		10
+#define	AHD_INT_COALESCING_MAXCMDS_MAX			127
+#define	AHD_INT_COALESCING_MINCMDS_DEFAULT		5
+#define	AHD_INT_COALESCING_MINCMDS_MAX			127
+#define	AHD_INT_COALESCING_THRESHOLD_DEFAULT		2000
+#define	AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT	1000
+	u_int			  int_coalescing_timer;
+	u_int			  int_coalescing_maxcmds;
+	u_int			  int_coalescing_mincmds;
+	u_int			  int_coalescing_threshold;
+	u_int			  int_coalescing_stop_threshold;
 
 	uint16_t	 	  user_discenable;/* Disconnection allowed  */
 	uint16_t		  user_tagenable;/* Tagged Queuing allowed */
@@ -1362,11 +1362,11 @@
 int			 ahd_parse_cfgdata(struct ahd_softc *ahd,
 					   struct seeprom_config *sc);
 void			 ahd_intr_enable(struct ahd_softc *ahd, int enable);
-void			 ahd_update_coalessing_values(struct ahd_softc *ahd,
+void			 ahd_update_coalescing_values(struct ahd_softc *ahd,
 						      u_int timer,
 						      u_int maxcmds,
 						      u_int mincmds);
-void			 ahd_enable_coalessing(struct ahd_softc *ahd,
+void			 ahd_enable_coalescing(struct ahd_softc *ahd,
 					       int enable);
 void			 ahd_pause_and_flushwork(struct ahd_softc *ahd);
 int			 ahd_suspend(struct ahd_softc *ahd); 
@@ -1514,7 +1514,7 @@
 #define AHD_SHOW_QUEUE		0x02000
 #define AHD_SHOW_TQIN		0x04000
 #define AHD_SHOW_SG		0x08000
-#define AHD_SHOW_INT_COALESSING	0x10000
+#define AHD_SHOW_INT_COALESCING	0x10000
 #define AHD_DEBUG_SEQUENCER	0x20000
 #endif
 void			ahd_print_scb(struct scb *scb);
diff -Nru a/drivers/scsi/aic7xxx/aic79xx.reg b/drivers/scsi/aic7xxx/aic79xx.reg
--- a/drivers/scsi/aic7xxx/aic79xx.reg	Thu Apr 24 11:46:35 2003
+++ b/drivers/scsi/aic7xxx/aic79xx.reg	Fri May 23 10:55:33 2003
@@ -39,7 +39,7 @@
  *
  * $FreeBSD$
  */
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $"
 
 /*
  * This file is processed by the aic7xxx_asm utility for use in assembling
@@ -286,7 +286,7 @@
 	address			0x00B
 	access_mode	RW
 	mask	HOST_TQINPOS	0x80	/* Boundary at either 0 or 128 */
-	mask	ENINT_COALESS	0x40	/* Perform interrupt coalessing */
+	mask	ENINT_COALESCE	0x40	/* Perform interrupt coalescing */
 }
 
 /*
@@ -3704,28 +3704,28 @@
 	}
 
 	/*
-	 * The maximum amount of time to wait, when interrupt coalessing
+	 * The maximum amount of time to wait, when interrupt coalescing
 	 * is enabled, before issueing a CMDCMPLT interrupt for a completed
 	 * command.
 	 */
-	INT_COALESSING_TIMER {
+	INT_COALESCING_TIMER {
 		size		2
 	}
 
 	/*
-	 * The maximum number of commands to coaless into a single interrupt.
+	 * The maximum number of commands to coalesce into a single interrupt.
 	 * Actually the 2's complement of that value to simplify sequencer
 	 * code.
 	 */
-	INT_COALESSING_MAXCMDS {
+	INT_COALESCING_MAXCMDS {
 		size		1
 	}
 
 	/*
 	 * The minimum number of commands still outstanding required
-	 * to continue coalessing (2's complement of value).
+	 * to continue coalescing (2's complement of value).
 	 */
-	INT_COALESSING_MINCMDS {
+	INT_COALESCING_MINCMDS {
 		size		1
 	}
 
@@ -3737,9 +3737,9 @@
 	}
 
 	/*
-	 * The count of commands that have been coalessed.
+	 * The count of commands that have been coalesced.
 	 */
-	INT_COALESSING_CMDCOUNT {
+	INT_COALESCING_CMDCOUNT {
 		size		1
 	}
 
@@ -3842,10 +3842,15 @@
 	}
 	SCB_LUN {
 		size	1
-		field	LID				0xff
+		field	LID	0xff
 	}
 	SCB_TASK_ATTRIBUTE {
 		size	1
+		/*
+		 * Overloaded field for non-packetized 
+		 * ignore wide residue message handling.
+		 */
+		field	SCB_XFERLEN_ODD	0x01
 	}
 	SCB_CDB_LEN {
 		size	1
diff -Nru a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq
--- a/drivers/scsi/aic7xxx/aic79xx.seq	Thu Apr 24 11:46:35 2003
+++ b/drivers/scsi/aic7xxx/aic79xx.seq	Fri May 23 10:55:34 2003
@@ -40,7 +40,7 @@
  * $FreeBSD$
  */
 
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $"
 PATCH_ARG_LIST = "struct ahd_softc *ahd"
 PREFIX = "ahd_"
 
@@ -212,44 +212,44 @@
 qoutfifo_updated:
 	/*
 	 * If there are more commands waiting to be dma'ed
-	 * to the host, always coaless.  Otherwise honor the
+	 * to the host, always coalesce.  Otherwise honor the
 	 * host's wishes.
 	 */
-	cmp	COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count;
-	cmp	COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coaless_by_count;
-	test	LOCAL_HS_MAILBOX, ENINT_COALESS jz issue_cmdcmplt;
+	cmp	COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;
+	cmp	COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;
+	test	LOCAL_HS_MAILBOX, ENINT_COALESCE jz issue_cmdcmplt;
 
 	/*
 	 * If we have relatively few commands outstanding, don't
 	 * bother waiting for another command to complete.
 	 */
-	test	CMDS_PENDING[1], 0xFF jnz coaless_by_count;
+	test	CMDS_PENDING[1], 0xFF jnz coalesce_by_count;
 	/* Add -1 so that jnc means <= not just < */
-	add	A, -1, INT_COALESSING_MINCMDS;
+	add	A, -1, INT_COALESCING_MINCMDS;
 	add	NONE, A, CMDS_PENDING;
 	jnc	issue_cmdcmplt;
 	
 	/*
-	 * If coalessing, only coaless up to the limit
+	 * If coalescing, only coalesce up to the limit
 	 * provided by the host driver.
 	 */
-coaless_by_count:
-	mov	A, INT_COALESSING_MAXCMDS;
-	add	NONE, A, INT_COALESSING_CMDCOUNT;
+coalesce_by_count:
+	mov	A, INT_COALESCING_MAXCMDS;
+	add	NONE, A, INT_COALESCING_CMDCOUNT;
 	jc	issue_cmdcmplt;
 	/*
 	 * If the timer is not currently active,
 	 * fire it up.
 	 */
 	test	INTCTL, SWTMINTMASK jz return;
-	bmov	SWTIMER, INT_COALESSING_TIMER, 2;
+	bmov	SWTIMER, INT_COALESCING_TIMER, 2;
 	mvi	CLRSEQINTSTAT, CLRSEQ_SWTMRTO;
 	or	INTCTL, SWTMINTEN|SWTIMER_START;
 	and	INTCTL, ~SWTMINTMASK ret;
 
 issue_cmdcmplt:
 	mvi	INTSTAT, CMDCMPLT;
-	clr	INT_COALESSING_CMDCOUNT;
+	clr	INT_COALESCING_CMDCOUNT;
 	or	INTCTL, SWTMINTMASK ret;
 
 BEGIN_CRITICAL;
@@ -261,6 +261,15 @@
 	clr	A;
 	add	CMDS_PENDING, 1;
 	adc	CMDS_PENDING[1], A;
+	if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
+		/*
+		 * "Short Luns" are not placed into outgoing LQ
+		 * packets in the correct byte order.  Use a full
+		 * sized lun field instead and fill it with the
+		 * one byte of lun information we support.
+		 */
+		mov	SCB_PKT_LUN[6], SCB_LUN;
+	}
 	/*
 	 * The FIFO use count field is shared with the
 	 * tag set by the host so that our SCB dma engine
@@ -324,7 +333,7 @@
 	mov	CCSCBRAM, SCBPTR;
 	or	CCSCBRAM, A, SCBPTR[1];
 	mov	NONE, SDSCB_QOFF;
-	inc	INT_COALESSING_CMDCOUNT;
+	inc	INT_COALESCING_CMDCOUNT;
 	add	CMDS_PENDING, -1;
 	adc	CMDS_PENDING[1], -1;
 	cmp	SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;
@@ -863,7 +872,8 @@
 	mvi	REG0	call inb_next;
 	cmp	REG0, 0x01 jne mesgin_reject;
 	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;
-	test	DATA_COUNT_ODD, 0x1	jz mesgin_done;
+	test	SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jnz mesgin_done;
+	SET_SEQINTCODE(IGN_WIDE_RES)
 	jmp	mesgin_done;
 
 mesgin_proto_violation:
@@ -1308,8 +1318,6 @@
 		bmov 	HADDR, CCSGRAM, 4;
 	}
 	bmov	HCNT, CCSGRAM, 3;
-	test	HCNT[0], 0x1 jz . + 2;
-	xor	DATA_COUNT_ODD, 0x1;
 	bmov	SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
 	if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
 		and	HADDR[4], SG_HIGH_ADDR_BITS, SCB_RESIDUAL_DATACNT[3];
@@ -1325,8 +1333,6 @@
 	adc	SCB_RESIDUAL_SGPTR[2],A;
 	adc	SCB_RESIDUAL_SGPTR[3],A;
 	mov	SINDEX, SCB_RESIDUAL_SGPTR[0];
-	test	DATA_COUNT_ODD, 0x1 jz . + 2;
-	or	SINDEX, ODD_SEG;
 	test	SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 3;
 	or	SINDEX, LAST_SEG;
 	clr	SG_STATE;
@@ -1352,12 +1358,9 @@
  */
 load_first_seg:
 	bmov	HADDR, SCB_DATAPTR, 11;
-	and	DATA_COUNT_ODD, 0x1, SCB_DATACNT[0];
 	and	REG_ISR, ~SG_FULL_RESID, SCB_SGPTR[0];
 	test	SCB_DATACNT[3], SG_LAST_SEG jz . + 2;
 	or	REG_ISR, LAST_SEG;
-	test	DATA_COUNT_ODD, 0x1 jz . + 2;
-	or	REG_ISR, ODD_SEG;
 	mov	SG_CACHE_PRE, REG_ISR;
 	mvi	DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);
 	/*
@@ -1507,7 +1510,7 @@
 		 * send Ignore Wide Residue messages for data-in phases.
 		test	DFCNTRL, DIRECTION jz target_ITloop;
 		test	SSTAT1, REQINIT	jnz .;
-		test	DATA_COUNT_ODD, 0x1 jz target_ITloop;
+		test	SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jz target_ITloop;
 		SET_MODE(M_SCSI, M_SCSI)
 		test	NEGCONOPTS, WIDEXFER jz target_ITloop;
 		 */
@@ -1577,9 +1580,6 @@
 	adc	SCB_RESIDUAL_SGPTR[3], -1;
 sgptr_fixup_done:
 	and	SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;
-	clr	DATA_COUNT_ODD;
-	test	SG_CACHE_SHADOW, ODD_SEG jz . + 2;
-	or	DATA_COUNT_ODD, 0x1;
 	clr	SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */
 	bmov	SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;
 
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
--- a/drivers/scsi/aic7xxx/aic79xx_core.c	Thu May  1 10:00:20 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c	Fri May 23 10:58:23 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#190 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#194 $
  *
  * $FreeBSD$
  */
@@ -4401,7 +4401,7 @@
 
 		sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
 		if ((sgptr & SG_LIST_NULL) != 0
-		 && ahd_inb(ahd, DATA_COUNT_ODD) == 1) {
+		 && (ahd_inb(ahd, SCB_TASK_ATTRIBUTE) & SCB_XFERLEN_ODD) != 0) {
 			/*
 			 * If the residual occurred on the last
 			 * transfer and the transfer request was
@@ -4414,29 +4414,20 @@
 			uint32_t sglen;
 
 			/* Pull in the rest of the sgptr */
-			sgptr |=
-			    (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24)
-			  | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16)
-			  | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8);
-			sgptr &= SG_PTR_MASK;
-			data_cnt =
-			    (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24)
-			  | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+2) << 16)
-			  | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+1) << 8)
-			  | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT));
-
-			data_addr = (((uint64_t)ahd_inb(ahd, SHADDR + 7)) << 56)
-				  | (((uint64_t)ahd_inb(ahd, SHADDR + 6)) << 48)
-				  | (((uint64_t)ahd_inb(ahd, SHADDR + 5)) << 40)
-				  | (((uint64_t)ahd_inb(ahd, SHADDR + 4)) << 32)
-				  | (ahd_inb(ahd, SHADDR + 3) << 24)
-				  | (ahd_inb(ahd, SHADDR + 2) << 16)
-				  | (ahd_inb(ahd, SHADDR + 1) << 8)
-				  | (ahd_inb(ahd, SHADDR));
-
+			sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
+			data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT);
+			if ((sgptr & SG_LIST_NULL) != 0) {
+				/*
+				 * The residual data count is not updated
+				 * for the command run to completion case.
+				 * Explicitly zero the count.
+				 */
+				data_cnt &= ~AHD_SG_LEN_MASK;
+			}
+			data_addr = ahd_inq(ahd, SHADDR);
 			data_cnt += 1;
 			data_addr -= 1;
-
+			sgptr &= SG_PTR_MASK;
 			if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
 				struct ahd_dma64_seg *sg;
 
@@ -4504,16 +4495,17 @@
 								  sg);
 				}
 			}
-			ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 3, sgptr >> 24);
-			ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 2, sgptr >> 16);
-			ahd_outb(ahd, SCB_RESIDUAL_SGPTR + 1, sgptr >> 8);
-			ahd_outb(ahd, SCB_RESIDUAL_SGPTR, sgptr);
-
-			ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24);
-			ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16);
-			ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8);
-			ahd_outb(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
+			/*
+			 * Toggle the "oddness" of the transfer length
+			 * to handle this mid-transfer ignore wide
+			 * residue.  This ensures that the oddness is
+			 * correct for subsequent data transfers.
+			 */
+			ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
+			    ahd_inb(ahd, SCB_TASK_ATTRIBUTE) ^ SCB_XFERLEN_ODD);
 
+			ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
+			ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
 			/*
 			 * The FIFO's pointers will be updated if/when the
 			 * sequencer re-enters a data phase.
@@ -4806,12 +4798,12 @@
 		   | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
 	ahd_timer_init(&ahd->reset_timer);
 	ahd_timer_init(&ahd->stat_timer);
-	ahd->int_coalessing_timer = AHD_INT_COALESSING_TIMER_DEFAULT;
-	ahd->int_coalessing_maxcmds = AHD_INT_COALESSING_MAXCMDS_DEFAULT;
-	ahd->int_coalessing_mincmds = AHD_INT_COALESSING_MINCMDS_DEFAULT;
-	ahd->int_coalessing_threshold = AHD_INT_COALESSING_THRESHOLD_DEFAULT;
-	ahd->int_coalessing_stop_threshold =
-	    AHD_INT_COALESSING_STOP_THRESHOLD_DEFAULT;
+	ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
+	ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
+	ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
+	ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT;
+	ahd->int_coalescing_stop_threshold =
+	    AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT;
 
 	if (ahd_platform_alloc(ahd, platform_arg) != 0) {
 		ahd_free(ahd);
@@ -5722,6 +5714,7 @@
 		next_scb->sg_list = segs;
 		next_scb->sense_data = sense_data;
 		next_scb->sense_busaddr = sense_busaddr;
+		memset(hscb, 0, sizeof(*hscb));
 		next_scb->hscb = hscb;
 		hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
 
@@ -6341,14 +6334,14 @@
 	ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
 
 	/*
-	 * Default to coalessing disabled.
+	 * Default to coalescing disabled.
 	 */
-	ahd_outw(ahd, INT_COALESSING_CMDCOUNT, 0);
+	ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0);
 	ahd_outw(ahd, CMDS_PENDING, 0);
-	ahd_update_coalessing_values(ahd, ahd->int_coalessing_timer,
-				     ahd->int_coalessing_maxcmds,
-				     ahd->int_coalessing_mincmds);
-	ahd_enable_coalessing(ahd, FALSE);
+	ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer,
+				     ahd->int_coalescing_maxcmds,
+				     ahd->int_coalescing_mincmds);
+	ahd_enable_coalescing(ahd, FALSE);
 
 	ahd_loadseq(ahd);
 	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
@@ -6601,30 +6594,30 @@
 }
 
 void
-ahd_update_coalessing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
+ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
 			     u_int mincmds)
 {
 	if (timer > AHD_TIMER_MAX_US)
 		timer = AHD_TIMER_MAX_US;
-	ahd->int_coalessing_timer = timer;
+	ahd->int_coalescing_timer = timer;
 
-	if (maxcmds > AHD_INT_COALESSING_MAXCMDS_MAX)
-		maxcmds = AHD_INT_COALESSING_MAXCMDS_MAX;
-	if (mincmds > AHD_INT_COALESSING_MINCMDS_MAX)
-		mincmds = AHD_INT_COALESSING_MINCMDS_MAX;
-	ahd->int_coalessing_maxcmds = maxcmds;
-	ahd_outw(ahd, INT_COALESSING_TIMER, timer / AHD_TIMER_US_PER_TICK);
-	ahd_outb(ahd, INT_COALESSING_MAXCMDS, -maxcmds);
-	ahd_outb(ahd, INT_COALESSING_MINCMDS, -mincmds);
+	if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX)
+		maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX;
+	if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX)
+		mincmds = AHD_INT_COALESCING_MINCMDS_MAX;
+	ahd->int_coalescing_maxcmds = maxcmds;
+	ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK);
+	ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds);
+	ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
 }
 
 void
-ahd_enable_coalessing(struct ahd_softc *ahd, int enable)
+ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
 {
 
-	ahd->hs_mailbox &= ~ENINT_COALESS;
+	ahd->hs_mailbox &= ~ENINT_COALESCE;
 	if (enable)
-		ahd->hs_mailbox |= ENINT_COALESS;
+		ahd->hs_mailbox |= ENINT_COALESCE;
 	ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox);
 	ahd_flush_device_writes(ahd);
 	ahd_run_qoutfifo(ahd);
@@ -7718,20 +7711,20 @@
 	}
 	ahd_lock(ahd, &s);
 
-	enint_coal = ahd->hs_mailbox & ENINT_COALESS;
-	if (ahd->cmdcmplt_total > ahd->int_coalessing_threshold)
-		enint_coal |= ENINT_COALESS;
-	else if (ahd->cmdcmplt_total < ahd->int_coalessing_stop_threshold)
-		enint_coal &= ~ENINT_COALESS;
+	enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
+	if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
+		enint_coal |= ENINT_COALESCE;
+	else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold)
+		enint_coal &= ~ENINT_COALESCE;
 
-	if (enint_coal != (ahd->hs_mailbox & ENINT_COALESS)) {
-		ahd_enable_coalessing(ahd, enint_coal);
+	if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) {
+		ahd_enable_coalescing(ahd, enint_coal);
 #ifdef AHD_DEBUG
-		if ((ahd_debug & AHD_SHOW_INT_COALESSING) != 0)
-			printf("%s: Interrupt coalessing "
+		if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
+			printf("%s: Interrupt coalescing "
 			       "now %sabled. Cmds %d\n",
 			       ahd_name(ahd),
-			       (enint_coal & ENINT_COALESS) ? "en" : "dis",
+			       (enint_coal & ENINT_COALESCE) ? "en" : "dis",
 			       ahd->cmdcmplt_total);
 #endif
 	}
@@ -8279,8 +8272,6 @@
 	download_consts[PKT_OVERRUN_BUFOFFSET] =
 		(ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;
 	download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;
-	if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0)
-		download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_FULL_LUN;
 	cur_patch = patches;
 	downloaded = 0;
 	skip_addr = 0;
@@ -8509,7 +8500,7 @@
 }
 
 void
-ahd_dump_all_cards_state()
+ahd_dump_all_cards_state(void)
 {
 	struct ahd_softc *list_ahd;
 
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h
--- a/drivers/scsi/aic7xxx/aic79xx_inline.h	Thu May  1 10:00:20 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_inline.h	Fri May 23 10:55:34 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#48 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $
  *
  * $FreeBSD$
  */
@@ -271,11 +271,12 @@
 	scb->crc_retry_count = 0;
 	if ((scb->flags & SCB_PACKETIZED) != 0) {
 		/* XXX what about ACA??  It is type 4, but TAG_TYPE == 0x3. */
-		scb->hscb->task_attribute= scb->hscb->control & SCB_TAG_TYPE;
-		/*
-		 * For Rev A short lun workaround.
-		 */
-		scb->hscb->pkt_long_lun[6] = scb->hscb->lun;
+		scb->hscb->task_attribute = scb->hscb->control & SCB_TAG_TYPE;
+	} else {
+		if (ahd_get_transfer_length(scb) & 0x01)
+			scb->hscb->task_attribute = SCB_XFERLEN_ODD;
+		else
+			scb->hscb->task_attribute = 0;
 	}
 
 	if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c	Thu May  8 11:24:16 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c	Fri May 23 10:58:23 2003
@@ -1,7 +1,7 @@
 /*
  * Adaptec AIC79xx device driver for Linux.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#160 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#169 $
  *
  * --------------------------------------------------------------------------
  * Copyright (c) 1994-2000 Justin T. Gibbs.
@@ -62,11 +62,6 @@
 
 #include <linux/mm.h>		/* For fetching system memory size */
 
-#define __KERNEL_SYSCALLS__
-
-#include <linux/unistd.h>
-static int errno;
-
 /*
  * Lock protecting manipulation of the ahd softc list.
  */
@@ -755,31 +750,11 @@
 	consumed = 1;
 	sg->addr = ahd_htole32(addr & 0xFFFFFFFF);
 	scb->platform_data->xfer_len += len;
+
 	if (sizeof(bus_addr_t) > 4
-	 && (ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
-		/*
-		 * Due to DAC restrictions, we can't
-		 * cross a 4GB boundary.
-		 */
-		if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) {
-			struct	 ahd_dma_seg *next_sg;
-			uint32_t next_len;
-
-			printf("Crossed Seg\n");
-			if ((scb->sg_count + 2) > AHD_NSEG)
-				panic("Too few segs for dma mapping.  "
-				      "Increase AHD_NSEG\n");
-
-			consumed++;
-			next_sg = sg + 1;
-			next_sg->addr = 0;
-			next_len = 0x100000000 - (addr & 0xFFFFFFFF);
-			len -= next_len;
-			next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000;
-			next_sg->len = ahd_htole32(next_len);
-		}
-		len |= (addr >> 8) & 0x7F000000;
-	}
+	 && (ahd->flags & AHD_39BIT_ADDRESSING) != 0)
+		len |= (addr >> 8) & AHD_SG_HIGH_ADDR_MASK;
+
 	sg->len = ahd_htole32(len);
 	return (consumed);
 }
@@ -796,14 +771,18 @@
 static int	   ahd_linux_slave_alloc(Scsi_Device *);
 static int	   ahd_linux_slave_configure(Scsi_Device *);
 static void	   ahd_linux_slave_destroy(Scsi_Device *);
+#if defined(__i386__)
 static int	   ahd_linux_biosparam(struct scsi_device*,
 				       struct block_device*, sector_t, int[]);
+#endif
 #else
 static int	   ahd_linux_release(struct Scsi_Host *);
 static void	   ahd_linux_select_queue_depth(struct Scsi_Host *host,
 						Scsi_Device *scsi_devs);
+#if defined(__i386__)
 static int	   ahd_linux_biosparam(Disk *, kdev_t, int[]);
 #endif
+#endif
 static int	   ahd_linux_bus_reset(Scsi_Cmnd *);
 static int	   ahd_linux_dev_reset(Scsi_Cmnd *);
 static int	   ahd_linux_abort(Scsi_Cmnd *);
@@ -1211,6 +1190,7 @@
 }
 #endif
 
+#if defined(__i386__)
 /*
  * Return the disk geometry for the given SCSI device.
  */
@@ -1273,6 +1253,7 @@
 	geom[2] = cylinders;
 	return (0);
 }
+#endif
 
 /*
  * Abort the current SCSI command(s).
@@ -2198,7 +2179,7 @@
 }
 
 uint64_t
-ahd_linux_get_memsize()
+ahd_linux_get_memsize(void)
 {
 	struct sysinfo si;
 
@@ -2213,7 +2194,7 @@
  * scenario.
  */
 static int
-ahd_linux_next_unit()
+ahd_linux_next_unit(void)
 {
 	struct ahd_softc *ahd;
 	int unit;
@@ -2955,13 +2936,11 @@
 			struct ahd_devinfo *devinfo,
 			struct ahd_linux_target *targ)
 {
-	cam_status cam_status;
 	u_int32_t status;
-	u_int scsi_status;
 
-	scsi_status = ahd_cmd_get_scsi_status(cmd);
-	cam_status = ahd_cmd_get_transaction_status(cmd);
-	status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status);
+	status = aic_error_action(cmd, targ->inq_data,
+				  ahd_cmd_get_transaction_status(cmd),
+				  ahd_cmd_get_scsi_status(cmd));
 
 	
 #ifdef AHD_DEBUG
@@ -4211,7 +4190,7 @@
 /*
  * SCSI controller interrupt handler.
  */
-AIC_LINUX_IRQRETURN_T
+irqreturn_t
 ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct	ahd_softc *ahd;
@@ -4225,7 +4204,7 @@
 		ahd_schedule_runq(ahd);
 	ahd_linux_run_complete_queue(ahd);
 	ahd_unlock(ahd, &flags);
-	AIC_LINUX_IRQRETURN(ours);
+	return IRQ_RETVAL(ours);
 }
 
 void
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h	Mon May 12 20:52:59 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h	Mon May 26 19:01:56 2003
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#130 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#133 $
  *
  */
 #ifndef _AIC79XX_LINUX_H_
@@ -293,7 +293,7 @@
 #define AHD_SCSI_HAS_HOST_LOCK 0
 #endif
 
-#define AIC79XX_DRIVER_VERSION "1.3.8"
+#define AIC79XX_DRIVER_VERSION "1.3.9"
 
 /**************************** Front End Queues ********************************/
 /*
@@ -1006,7 +1006,7 @@
 	(((dev_softc)->dma_mask = mask) && 0)
 #endif
 /**************************** Proc FS Support *********************************/
-int	ahd_linux_proc_info(char *, char **, off_t, int, int, int);
+int	ahd_linux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 
 /*************************** Domain Validation ********************************/
 #define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete)
@@ -1211,7 +1211,7 @@
 int	ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
 				char channel, int lun, u_int tag,
 				role_t role, uint32_t status);
-AIC_LINUX_IRQRETURN_T
+irqreturn_t
 	ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
 void	ahd_platform_flushwork(struct ahd_softc *ahd);
 int	ahd_softc_comp(struct ahd_softc *, struct ahd_softc *);
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c	Mon Mar 10 16:57:17 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c	Wed May 14 15:00:40 2003
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#21 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#23 $
  */
 
 #include "aic79xx_osm.h"
@@ -156,19 +156,21 @@
 	pci_set_master(pdev);
 
 	if (sizeof(bus_addr_t) > 4) {
-		uint64_t memsize;
+		uint64_t   memsize;
+		bus_addr_t mask_64bit;
+		bus_addr_t mask_39bit;
 
 		memsize = ahd_linux_get_memsize();
-		if (memsize >= 0x8000000000
-	 	 && ahd_pci_set_dma_mask(pdev, 0xFFFFFFFFFFFFFFFFULL) == 0) {
+		mask_64bit = (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0);
+		mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL&(bus_addr_t)~0);
+		if (memsize >= 0x8000000000ULL
+	 	 && ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) {
 			ahd->flags |= AHD_64BIT_ADDRESSING;
-			ahd->platform_data->hw_dma_mask =
-			    (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0);
+			ahd->platform_data->hw_dma_mask = mask_64bit;
 		} else if (memsize > 0x80000000
-			&& ahd_pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) {
+			&& ahd_pci_set_dma_mask(pdev, mask_39bit) == 0) {
 			ahd->flags |= AHD_39BIT_ADDRESSING;
-			ahd->platform_data->hw_dma_mask =
-			    (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
+			ahd->platform_data->hw_dma_mask = mask_39bit;
 		}
 	} else {
 		ahd_pci_set_dma_mask(pdev, 0xFFFFFFFF);
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c	Thu May  1 10:00:20 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c	Tue May 20 14:03:03 2003
@@ -38,7 +38,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#71 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#73 $
  *
  * $FreeBSD$
  */
@@ -65,28 +65,29 @@
 }
 
 #define ID_ALL_MASK			0xFFFFFFFFFFFFFFFFull
+#define ID_ALL_IROC_MASK		0xFFFFFF7FFFFFFFFFull
 #define ID_DEV_VENDOR_MASK		0xFFFFFFFF00000000ull
 #define ID_9005_GENERIC_MASK		0xFFF0FFFF00000000ull
+#define ID_9005_GENERIC_IROC_MASK	0xFFF0FF7F00000000ull
 
 #define ID_AIC7901			0x800F9005FFFF9005ull
-#define ID_AIC7901A			0x801E9005FFFF9005ull
-#define ID_AIC7901A_IROC		0x809E9005FFFF9005ull
 #define ID_AHA_29320A			0x8000900500609005ull
+#define ID_AHA_29320ALP			0x8017900500449005ull
+
+#define ID_AIC7901A			0x801E9005FFFF9005ull
+#define ID_AHA_29320			0x8012900500429005ull
+#define ID_AHA_29320B			0x8013900500439005ull
 #define ID_AHA_29320LP			0x8014900500449005ull
-#define ID_AHA_29320LP_IROC		0x8094900500449005ull
 
 #define ID_AIC7902			0x801F9005FFFF9005ull
-#define ID_AIC7902_IROC			0x809F9005FFFF9005ull
 #define ID_AIC7902_B			0x801D9005FFFF9005ull
-#define ID_AIC7902_B_IROC		0x809D9005FFFF9005ull
 #define ID_AHA_39320			0x8010900500409005ull
+#define ID_AHA_39320_B			0x8015900500409005ull
 #define ID_AHA_39320A			0x8016900500409005ull
 #define ID_AHA_39320D			0x8011900500419005ull
 #define ID_AHA_39320D_B			0x801C900500419005ull
 #define ID_AHA_39320D_HP		0x8011900500AC0E11ull
 #define ID_AHA_39320D_B_HP		0x801C900500AC0E11ull
-#define ID_AHA_29320			0x8012900500429005ull
-#define ID_AHA_29320B			0x8013900500439005ull
 #define ID_AIC7902_PCI_REV_A4		0x3
 #define ID_AIC7902_PCI_REV_B0		0x10
 #define SUBID_HP			0x0E11
@@ -113,22 +114,42 @@
 #define		SUBID_9005_SEEPTYPE_NONE	0x0
 #define		SUBID_9005_SEEPTYPE_4K		0x1
 
+static ahd_device_setup_t ahd_aic7901_setup;
 static ahd_device_setup_t ahd_aic7901A_setup;
 static ahd_device_setup_t ahd_aic7902_setup;
 
 struct ahd_pci_identity ahd_pci_ident_table [] =
 {
+	/* aic7901 based controllers */
+	{
+		ID_AHA_29320A,
+		ID_ALL_MASK,
+		"Adaptec 29320A Ultra320 SCSI adapter",
+		ahd_aic7901_setup
+	},
+	{
+		ID_AHA_29320ALP,
+		ID_ALL_MASK,
+		"Adaptec 29320ALP Ultra320 SCSI adapter",
+		ahd_aic7901_setup
+	},
 	/* aic7901A based controllers */
 	{
-		ID_AHA_29320LP,
+		ID_AHA_29320,
 		ID_ALL_MASK,
-		"Adaptec 29320LP Ultra320 SCSI adapter",
+		"Adaptec 29320 Ultra320 SCSI adapter",
 		ahd_aic7901A_setup
 	},
 	{
-		ID_AHA_29320A,
+		ID_AHA_29320B,
 		ID_ALL_MASK,
-		"Adaptec 29320A Ultra320 SCSI adapter",
+		"Adaptec 29320B Ultra320 SCSI adapter",
+		ahd_aic7901A_setup
+	},
+	{
+		ID_AHA_29320LP,
+		ID_ALL_MASK,
+		"Adaptec 29320LP Ultra320 SCSI adapter",
 		ahd_aic7901A_setup
 	},
 	/* aic7902 based controllers */	
@@ -139,6 +160,12 @@
 		ahd_aic7902_setup
 	},
 	{
+		ID_AHA_39320_B,
+		ID_ALL_MASK,
+		"Adaptec 39320 Ultra320 SCSI adapter",
+		ahd_aic7902_setup
+	},
+	{
 		ID_AHA_39320A,
 		ID_ALL_MASK,
 		"Adaptec 39320A Ultra320 SCSI adapter",
@@ -182,6 +209,12 @@
 	},
 	/* Generic chip probes for devices we don't know 'exactly' */
 	{
+		ID_AIC7901 & ID_DEV_VENDOR_MASK,
+		ID_DEV_VENDOR_MASK,
+		"Adaptec AIC7901 Ultra320 SCSI adapter",
+		ahd_aic7901_setup
+	},
+	{
 		ID_AIC7901A & ID_DEV_VENDOR_MASK,
 		ID_DEV_VENDOR_MASK,
 		"Adaptec AIC7901A Ultra320 SCSI adapter",
@@ -332,9 +365,9 @@
 	}
 	
 	/* Ensure busmastering is enabled */
-	command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/1);
+	command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
 	command |= PCIM_CMD_BUSMASTEREN;
-	ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
+	ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
 
 	error = ahd_softc_init(ahd);
 	if (error != 0)
@@ -868,6 +901,18 @@
 }
 
 static int
+ahd_aic7901_setup(struct ahd_softc *ahd)
+{
+	int error;
+
+	error = ahd_aic7902_setup(ahd);
+	if (error != 0)
+		return (error);
+	ahd->chip = AHD_AIC7901;
+	return (0);
+}
+
+static int
 ahd_aic7901A_setup(struct ahd_softc *ahd)
 {
 	int error;
@@ -890,7 +935,7 @@
 	if (rev < ID_AIC7902_PCI_REV_A4) {
 		printf("%s: Unable to attach to unsupported chip revision %d\n",
 		       ahd_name(ahd), rev);
-		ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/1);
+		ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
 		return (ENXIO);
 	}
 	ahd->channel = ahd_get_pci_function(pci) + 'A';
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c
--- a/drivers/scsi/aic7xxx/aic79xx_proc.c	Thu Apr 24 14:10:07 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_proc.c	Mon May 12 08:30:19 2003
@@ -278,8 +278,8 @@
  * Return information to handle /proc support for the driver.
  */
 int
-ahd_linux_proc_info(char *buffer, char **start, off_t offset,
-		  int length, int hostno, int inout)
+ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
+		  int length, int inout)
 {
 	struct	ahd_softc *ahd;
 	struct	info_str info;
@@ -292,7 +292,7 @@
 	retval = -EINVAL;
 	ahd_list_lock(&l);
 	TAILQ_FOREACH(ahd, &ahd_tailq, links) {
-		if (ahd->platform_data->host->host_no == hostno)
+		if (ahd->platform_data->host == shost)
 			break;
 	}
 
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
--- a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped	Thu Apr 24 11:46:35 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped	Fri May 23 10:55:34 2003
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $
  */
 typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
 typedef struct ahd_reg_parse_entry {
@@ -2134,24 +2134,24 @@
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_int_coalessing_timer_print;
+ahd_reg_print_t ahd_int_coalescing_timer_print;
 #else
-#define ahd_int_coalessing_timer_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "INT_COALESSING_TIMER", 0x14a, regvalue, cur_col, wrap)
+#define ahd_int_coalescing_timer_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "INT_COALESCING_TIMER", 0x14a, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_int_coalessing_maxcmds_print;
+ahd_reg_print_t ahd_int_coalescing_maxcmds_print;
 #else
-#define ahd_int_coalessing_maxcmds_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS", 0x14c, regvalue, cur_col, wrap)
+#define ahd_int_coalescing_maxcmds_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS", 0x14c, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_int_coalessing_mincmds_print;
+ahd_reg_print_t ahd_int_coalescing_mincmds_print;
 #else
-#define ahd_int_coalessing_mincmds_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS", 0x14d, regvalue, cur_col, wrap)
+#define ahd_int_coalescing_mincmds_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS", 0x14d, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -2162,10 +2162,10 @@
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahd_reg_print_t ahd_int_coalessing_cmdcount_print;
+ahd_reg_print_t ahd_int_coalescing_cmdcount_print;
 #else
-#define ahd_int_coalessing_cmdcount_print(regvalue, cur_col, wrap) \
-    ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT", 0x150, regvalue, cur_col, wrap)
+#define ahd_int_coalescing_cmdcount_print(regvalue, cur_col, wrap) \
+    ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT", 0x150, regvalue, cur_col, wrap)
 #endif
 
 #if AIC_DEBUG_REGISTERS
@@ -2432,7 +2432,7 @@
 
 #define	HS_MAILBOX      		0x0b
 #define		HOST_TQINPOS    	0x80
-#define		ENINT_COALESS   	0x40
+#define		ENINT_COALESCE  	0x40
 
 #define	CLRSEQINTSTAT   		0x0c
 #define		CLRSEQ_SWTMRTO  	0x10
@@ -3612,15 +3612,15 @@
 
 #define	ALLOCFIFO_SCBPTR		0x148
 
-#define	INT_COALESSING_TIMER		0x14a
+#define	INT_COALESCING_TIMER		0x14a
 
-#define	INT_COALESSING_MAXCMDS		0x14c
+#define	INT_COALESCING_MAXCMDS		0x14c
 
-#define	INT_COALESSING_MINCMDS		0x14d
+#define	INT_COALESCING_MINCMDS		0x14d
 
 #define	CMDS_PENDING    		0x14e
 
-#define	INT_COALESSING_CMDCOUNT		0x150
+#define	INT_COALESCING_CMDCOUNT		0x150
 
 #define	LOCAL_HS_MAILBOX		0x151
 
@@ -3683,6 +3683,7 @@
 #define		LID             	0xff
 
 #define	SCB_TASK_ATTRIBUTE		0x1ab
+#define		SCB_XFERLEN_ODD 	0x01
 
 #define	SCB_CDB_LEN     		0x1ac
 #define		SCB_CDB_LEN_PTR 	0x80
@@ -3768,5 +3769,5 @@
 
 
 /* Exported Labels */
-#define	LABEL_seq_isr 	0x270
-#define	LABEL_timer_isr	0x26c
+#define	LABEL_seq_isr 	0x269
+#define	LABEL_timer_isr	0x265
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
--- a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped	Thu Apr 24 11:46:35 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped	Tue May 20 14:05:24 2003
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $
  */
 
 #include "aic79xx_osm.h"
@@ -161,7 +161,7 @@
 }
 
 static ahd_reg_parse_entry_t HS_MAILBOX_parse_table[] = {
-	{ "ENINT_COALESS",	0x40, 0x40 },
+	{ "ENINT_COALESCE",	0x40, 0x40 },
 	{ "HOST_TQINPOS",	0x80, 0x80 }
 };
 
@@ -3375,23 +3375,23 @@
 }
 
 int
-ahd_int_coalessing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-	return (ahd_print_register(NULL, 0, "INT_COALESSING_TIMER",
+	return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER",
 	    0x14a, regvalue, cur_col, wrap));
 }
 
 int
-ahd_int_coalessing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-	return (ahd_print_register(NULL, 0, "INT_COALESSING_MAXCMDS",
+	return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS",
 	    0x14c, regvalue, cur_col, wrap));
 }
 
 int
-ahd_int_coalessing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-	return (ahd_print_register(NULL, 0, "INT_COALESSING_MINCMDS",
+	return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS",
 	    0x14d, regvalue, cur_col, wrap));
 }
 
@@ -3403,9 +3403,9 @@
 }
 
 int
-ahd_int_coalessing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-	return (ahd_print_register(NULL, 0, "INT_COALESSING_CMDCOUNT",
+	return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT",
 	    0x150, regvalue, cur_col, wrap));
 }
 
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
--- a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped	Thu Apr 24 11:46:35 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped	Fri May 23 10:55:34 2003
@@ -2,30 +2,30 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#91 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#67 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $
  */
 static uint8_t seqprog[] = {
 	0xff, 0x02, 0x06, 0x78,
-	0x00, 0xea, 0x4e, 0x59,
+	0x00, 0xea, 0x50, 0x59,
 	0x01, 0xea, 0x04, 0x30,
 	0xff, 0x04, 0x0c, 0x78,
-	0x19, 0xea, 0x4e, 0x59,
+	0x19, 0xea, 0x50, 0x59,
 	0x19, 0xea, 0x04, 0x00,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x60, 0x3a, 0x1a, 0x68,
 	0x04, 0x47, 0x1b, 0x68,
 	0xff, 0x21, 0x1b, 0x70,
-	0x40, 0x4b, 0x90, 0x69,
-	0x00, 0xe2, 0x52, 0x59,
-	0x40, 0x4b, 0x90, 0x69,
-	0x20, 0x4b, 0x80, 0x69,
+	0x40, 0x4b, 0x92, 0x69,
+	0x00, 0xe2, 0x54, 0x59,
+	0x40, 0x4b, 0x92, 0x69,
+	0x20, 0x4b, 0x82, 0x69,
 	0xfc, 0x42, 0x24, 0x78,
 	0x10, 0x40, 0x24, 0x78,
-	0x00, 0xe2, 0xd2, 0x5d,
+	0x00, 0xe2, 0xc4, 0x5d,
 	0x20, 0x4d, 0x28, 0x78,
-	0x00, 0xe2, 0xd2, 0x5d,
+	0x00, 0xe2, 0xc4, 0x5d,
 	0x30, 0x3f, 0xc0, 0x09,
 	0x30, 0xe0, 0x30, 0x60,
 	0x7f, 0x4a, 0x94, 0x08,
@@ -35,7 +35,7 @@
 	0x00, 0xe2, 0x56, 0x58,
 	0x00, 0xe2, 0x66, 0x58,
 	0x00, 0xe2, 0x06, 0x40,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x01, 0x52, 0x64, 0x78,
 	0x02, 0x58, 0x50, 0x31,
@@ -43,26 +43,26 @@
 	0xff, 0xad, 0x4f, 0x78,
 	0x50, 0x4b, 0x4a, 0x68,
 	0xbf, 0x3a, 0x74, 0x08,
-	0x14, 0xea, 0x4e, 0x59,
+	0x14, 0xea, 0x50, 0x59,
 	0x14, 0xea, 0x04, 0x00,
 	0x08, 0xa8, 0x51, 0x03,
 	0xff, 0xae, 0x3f, 0x68,
-	0x00, 0xe2, 0x50, 0x5b,
+	0x00, 0xe2, 0x56, 0x5b,
 	0x00, 0xe2, 0x3e, 0x40,
-	0x00, 0xea, 0x42, 0x59,
+	0x00, 0xea, 0x44, 0x59,
 	0x01, 0xea, 0x00, 0x30,
 	0x80, 0xf9, 0x5e, 0x68,
-	0x00, 0xe2, 0x40, 0x59,
-	0x11, 0xea, 0x42, 0x59,
+	0x00, 0xe2, 0x42, 0x59,
+	0x11, 0xea, 0x44, 0x59,
 	0x11, 0xea, 0x00, 0x00,
-	0x80, 0xf9, 0x40, 0x79,
+	0x80, 0xf9, 0x42, 0x79,
 	0xff, 0xea, 0xd4, 0x0d,
-	0x22, 0xea, 0x42, 0x59,
+	0x22, 0xea, 0x44, 0x59,
 	0x22, 0xea, 0x00, 0x00,
 	0x10, 0x16, 0x70, 0x78,
 	0x01, 0x0b, 0xa2, 0x32,
 	0x10, 0x16, 0x2c, 0x00,
-	0x18, 0xad, 0xfe, 0x78,
+	0x18, 0xad, 0x00, 0x79,
 	0x04, 0xad, 0xca, 0x68,
 	0x80, 0xad, 0x64, 0x78,
 	0x10, 0xad, 0x98, 0x78,
@@ -71,15 +71,15 @@
 	0x02, 0x8c, 0x59, 0x32,
 	0x02, 0x28, 0x19, 0x33,
 	0x02, 0xa8, 0x50, 0x36,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x40, 0x3a, 0x64, 0x68,
 	0x50, 0x4b, 0x64, 0x68,
-	0x22, 0xea, 0x42, 0x59,
+	0x22, 0xea, 0x44, 0x59,
 	0x22, 0xea, 0x00, 0x00,
 	0xe7, 0xad, 0x5a, 0x09,
 	0x02, 0x8c, 0x59, 0x32,
-	0x1a, 0xea, 0x4e, 0x59,
+	0x1a, 0xea, 0x50, 0x59,
 	0x1a, 0xea, 0x04, 0x00,
 	0xff, 0xea, 0xd4, 0x0d,
 	0xe7, 0xad, 0x5a, 0x09,
@@ -113,29 +113,30 @@
 	0xff, 0xea, 0xc0, 0x09,
 	0x01, 0x4e, 0x9d, 0x1a,
 	0x00, 0x4f, 0x9f, 0x22,
+	0x01, 0xaa, 0x6d, 0x33,
 	0x01, 0xea, 0x5c, 0x33,
 	0x04, 0xa4, 0x49, 0x32,
 	0xff, 0xea, 0x4a, 0x03,
 	0xff, 0xea, 0x4e, 0x03,
 	0x01, 0x10, 0xd4, 0x31,
-	0x10, 0xa8, 0xf3, 0x68,
+	0x10, 0xa8, 0xf5, 0x68,
 	0x3d, 0xa9, 0xc5, 0x29,
 	0xfe, 0xe2, 0xc4, 0x09,
 	0x01, 0xea, 0xc6, 0x01,
 	0x02, 0xe2, 0xc8, 0x31,
 	0x02, 0xec, 0x50, 0x31,
 	0x02, 0xa0, 0xda, 0x31,
-	0xff, 0xa9, 0xf2, 0x70,
+	0xff, 0xa9, 0xf4, 0x70,
 	0x02, 0xa0, 0x48, 0x37,
-	0xff, 0x21, 0xfb, 0x70,
+	0xff, 0x21, 0xfd, 0x70,
 	0x02, 0x22, 0x51, 0x31,
 	0x02, 0xa0, 0x4c, 0x33,
 	0x02, 0xa0, 0x44, 0x36,
 	0x02, 0xa0, 0x40, 0x32,
 	0x02, 0xa0, 0x44, 0x36,
-	0x04, 0x47, 0x03, 0x69,
-	0x40, 0x16, 0x2e, 0x69,
-	0xff, 0x2d, 0x33, 0x61,
+	0x04, 0x47, 0x05, 0x69,
+	0x40, 0x16, 0x30, 0x69,
+	0xff, 0x2d, 0x35, 0x61,
 	0xff, 0x29, 0x65, 0x70,
 	0x01, 0x37, 0xc1, 0x31,
 	0x02, 0x28, 0x55, 0x32,
@@ -148,20 +149,20 @@
 	0x01, 0x50, 0xa1, 0x1a,
 	0xff, 0x4e, 0x9d, 0x1a,
 	0xff, 0x4f, 0x9f, 0x22,
-	0xff, 0x8d, 0x27, 0x71,
-	0x80, 0xac, 0x26, 0x71,
-	0x20, 0x16, 0x26, 0x69,
+	0xff, 0x8d, 0x29, 0x71,
+	0x80, 0xac, 0x28, 0x71,
+	0x20, 0x16, 0x28, 0x69,
 	0x02, 0x8c, 0x51, 0x31,
-	0x00, 0xe2, 0x10, 0x41,
+	0x00, 0xe2, 0x12, 0x41,
 	0x01, 0xac, 0x08, 0x31,
 	0x09, 0xea, 0x5a, 0x01,
 	0x02, 0x8c, 0x51, 0x32,
 	0xff, 0xea, 0x1a, 0x07,
 	0x04, 0x24, 0xf9, 0x30,
-	0x1d, 0xea, 0x38, 0x41,
+	0x1d, 0xea, 0x3a, 0x41,
 	0x02, 0x2c, 0x51, 0x31,
 	0x04, 0xa0, 0xf9, 0x30,
-	0x19, 0xea, 0x38, 0x41,
+	0x19, 0xea, 0x3a, 0x41,
 	0x06, 0xea, 0x08, 0x81,
 	0x01, 0xe2, 0x5a, 0x35,
 	0x02, 0xf2, 0xf0, 0x35,
@@ -179,23 +180,23 @@
 	0x02, 0x20, 0xb9, 0x30,
 	0x02, 0x20, 0x51, 0x31,
 	0x4c, 0xa9, 0xd7, 0x28,
-	0x10, 0xa8, 0x61, 0x79,
+	0x10, 0xa8, 0x63, 0x79,
 	0x01, 0x6b, 0xc0, 0x30,
 	0x02, 0x64, 0xc8, 0x00,
 	0x40, 0x3a, 0x74, 0x04,
 	0x00, 0xe2, 0x56, 0x58,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x30, 0x3f, 0xc0, 0x09,
-	0x30, 0xe0, 0x62, 0x61,
-	0x20, 0x3f, 0x78, 0x69,
-	0x10, 0x3f, 0x62, 0x79,
+	0x30, 0xe0, 0x64, 0x61,
+	0x20, 0x3f, 0x7a, 0x69,
+	0x10, 0x3f, 0x64, 0x79,
 	0x02, 0xea, 0x7e, 0x00,
-	0x00, 0xea, 0x42, 0x59,
+	0x00, 0xea, 0x44, 0x59,
 	0x01, 0xea, 0x00, 0x30,
 	0x02, 0x48, 0x51, 0x35,
 	0x01, 0xea, 0x7e, 0x00,
-	0x11, 0xea, 0x42, 0x59,
+	0x11, 0xea, 0x44, 0x59,
 	0x11, 0xea, 0x00, 0x00,
 	0x02, 0x48, 0x51, 0x35,
 	0x08, 0xea, 0x98, 0x00,
@@ -205,11 +206,11 @@
 	0x0f, 0x67, 0xc0, 0x09,
 	0x00, 0x34, 0x69, 0x02,
 	0x20, 0xea, 0x96, 0x00,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x40, 0x3a, 0xac, 0x69,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x40, 0x3a, 0xae, 0x69,
 	0x02, 0x55, 0x06, 0x68,
-	0x02, 0x56, 0xac, 0x69,
-	0xff, 0x5b, 0xac, 0x61,
+	0x02, 0x56, 0xae, 0x69,
+	0xff, 0x5b, 0xae, 0x61,
 	0x02, 0x20, 0x51, 0x31,
 	0x80, 0xea, 0xb2, 0x01,
 	0x44, 0xea, 0x00, 0x00,
@@ -217,36 +218,36 @@
 	0x33, 0xea, 0x00, 0x00,
 	0xff, 0xea, 0xb2, 0x09,
 	0xff, 0xe0, 0xc0, 0x19,
-	0xff, 0xe0, 0xae, 0x79,
+	0xff, 0xe0, 0xb0, 0x79,
 	0x02, 0xa4, 0x51, 0x31,
-	0x00, 0xe2, 0xa4, 0x41,
+	0x00, 0xe2, 0xa6, 0x41,
 	0x02, 0x5e, 0x50, 0x31,
 	0x02, 0xa8, 0xb8, 0x30,
 	0x02, 0x5c, 0x50, 0x31,
-	0xff, 0xa5, 0xbf, 0x71,
+	0xff, 0xa5, 0xc1, 0x71,
 	0x02, 0xa4, 0x41, 0x31,
 	0x02, 0x22, 0x51, 0x31,
 	0x02, 0xa0, 0x4c, 0x33,
 	0x02, 0xa0, 0x44, 0x32,
-	0x00, 0xe2, 0xc8, 0x41,
-	0x10, 0xa8, 0xc9, 0x69,
+	0x00, 0xe2, 0xca, 0x41,
+	0x10, 0xa8, 0xcb, 0x69,
 	0x3d, 0xa9, 0xc9, 0x29,
 	0x01, 0xe4, 0xc8, 0x01,
 	0x01, 0xea, 0xca, 0x01,
 	0xff, 0xea, 0xda, 0x01,
 	0x02, 0x20, 0x51, 0x31,
 	0x02, 0xa6, 0x41, 0x32,
-	0xff, 0x21, 0xd1, 0x61,
+	0xff, 0x21, 0xd3, 0x61,
 	0xff, 0xea, 0x46, 0x02,
 	0x02, 0x5c, 0x50, 0x31,
 	0x40, 0xea, 0x96, 0x00,
-	0x02, 0x56, 0xda, 0x6d,
-	0x01, 0x55, 0xda, 0x6d,
-	0x10, 0xa8, 0xdd, 0x79,
-	0x10, 0x40, 0xe6, 0x69,
-	0x01, 0x56, 0xe6, 0x79,
+	0x02, 0x56, 0xcc, 0x6d,
+	0x01, 0x55, 0xcc, 0x6d,
+	0x10, 0xa8, 0xdf, 0x79,
+	0x10, 0x40, 0xe8, 0x69,
+	0x01, 0x56, 0xe8, 0x79,
 	0xff, 0xad, 0x07, 0x78,
-	0x13, 0xea, 0x4e, 0x59,
+	0x13, 0xea, 0x50, 0x59,
 	0x13, 0xea, 0x04, 0x00,
 	0x00, 0xe2, 0x06, 0x40,
 	0xbf, 0x3a, 0x74, 0x08,
@@ -257,104 +258,106 @@
 	0x40, 0xea, 0x66, 0x02,
 	0x08, 0x3c, 0x78, 0x00,
 	0x80, 0xea, 0x62, 0x02,
-	0x00, 0xe2, 0xb2, 0x5b,
+	0x00, 0xe2, 0xb8, 0x5b,
 	0x01, 0x36, 0xc1, 0x31,
-	0x9f, 0xe0, 0x54, 0x7c,
-	0x80, 0xe0, 0x0a, 0x72,
-	0xa0, 0xe0, 0x42, 0x72,
-	0xc0, 0xe0, 0x38, 0x72,
-	0xe0, 0xe0, 0x72, 0x72,
-	0x01, 0xea, 0x4e, 0x59,
+	0x9f, 0xe0, 0x4c, 0x7c,
+	0x80, 0xe0, 0x0c, 0x72,
+	0xa0, 0xe0, 0x44, 0x72,
+	0xc0, 0xe0, 0x3a, 0x72,
+	0xe0, 0xe0, 0x74, 0x72,
+	0x01, 0xea, 0x50, 0x59,
 	0x01, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x80, 0x33, 0x11, 0x7a,
-	0x03, 0xea, 0x4e, 0x59,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x80, 0x33, 0x13, 0x7a,
+	0x03, 0xea, 0x50, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0xee, 0x00, 0x18, 0x6a,
+	0xee, 0x00, 0x1a, 0x6a,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x02, 0xa8, 0x90, 0x32,
-	0x00, 0xe2, 0x68, 0x59,
+	0x00, 0xe2, 0x6a, 0x59,
 	0xef, 0xac, 0xd5, 0x19,
-	0x00, 0xe2, 0x28, 0x52,
+	0x00, 0xe2, 0x2a, 0x52,
 	0x09, 0x80, 0xe1, 0x30,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x2e, 0x42,
+	0x00, 0xe2, 0x30, 0x42,
 	0x01, 0xac, 0xd1, 0x30,
 	0x10, 0x80, 0x89, 0x31,
 	0x20, 0xea, 0x32, 0x00,
 	0xbf, 0x33, 0x67, 0x0a,
-	0x20, 0x19, 0x30, 0x6a,
-	0x02, 0x4d, 0xf6, 0x69,
+	0x20, 0x19, 0x32, 0x6a,
+	0x02, 0x4d, 0xf8, 0x69,
 	0x40, 0x33, 0x67, 0x02,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x80, 0x33, 0xaf, 0x6a,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x80, 0x33, 0xb5, 0x6a,
 	0x01, 0x44, 0x10, 0x33,
 	0x08, 0xa8, 0x51, 0x03,
-	0x00, 0xe2, 0xf6, 0x41,
+	0x00, 0xe2, 0xf8, 0x41,
 	0x10, 0xea, 0x80, 0x00,
 	0x01, 0x31, 0xc5, 0x31,
-	0x80, 0xe2, 0x5e, 0x62,
-	0x10, 0xa8, 0x83, 0x6a,
+	0x80, 0xe2, 0x60, 0x62,
+	0x10, 0xa8, 0x85, 0x6a,
 	0xc0, 0xaa, 0xc5, 0x01,
-	0x40, 0xa8, 0x4f, 0x6a,
+	0x40, 0xa8, 0x51, 0x6a,
 	0xbf, 0xe2, 0xc4, 0x09,
-	0x20, 0xa8, 0x63, 0x7a,
+	0x20, 0xa8, 0x65, 0x7a,
 	0x01, 0xe2, 0x88, 0x30,
-	0x00, 0xe2, 0xb2, 0x5b,
-	0xa0, 0x36, 0x6b, 0x62,
+	0x00, 0xe2, 0xb8, 0x5b,
+	0xa0, 0x36, 0x6d, 0x62,
 	0x23, 0xa8, 0x89, 0x08,
-	0x00, 0xe2, 0xb2, 0x5b,
-	0xa0, 0x36, 0x6b, 0x62,
-	0x00, 0xa8, 0x62, 0x42,
-	0xff, 0xe2, 0x62, 0x62,
-	0x00, 0xe2, 0x82, 0x42,
+	0x00, 0xe2, 0xb8, 0x5b,
+	0xa0, 0x36, 0x6d, 0x62,
+	0x00, 0xa8, 0x64, 0x42,
+	0xff, 0xe2, 0x64, 0x62,
+	0x00, 0xe2, 0x84, 0x42,
 	0x40, 0xea, 0x98, 0x00,
 	0x01, 0xe2, 0x88, 0x30,
-	0x00, 0xe2, 0xb2, 0x5b,
-	0xa0, 0x36, 0x41, 0x72,
+	0x00, 0xe2, 0xb8, 0x5b,
+	0xa0, 0x36, 0x43, 0x72,
 	0x40, 0xea, 0x98, 0x00,
 	0x01, 0x31, 0x89, 0x32,
 	0x08, 0xea, 0x62, 0x02,
-	0x00, 0xe2, 0xf6, 0x41,
-	0xe0, 0xea, 0xce, 0x5b,
-	0x80, 0xe0, 0xba, 0x6a,
-	0x04, 0xe0, 0x60, 0x73,
-	0x02, 0xe0, 0x90, 0x73,
-	0x00, 0xea, 0x18, 0x73,
-	0x03, 0xe0, 0xa0, 0x73,
-	0x23, 0xe0, 0x94, 0x72,
-	0x08, 0xe0, 0xb6, 0x72,
-	0x00, 0xe2, 0xb2, 0x5b,
-	0x07, 0xea, 0x4e, 0x59,
+	0x00, 0xe2, 0xf8, 0x41,
+	0xe0, 0xea, 0xd4, 0x5b,
+	0x80, 0xe0, 0xc0, 0x6a,
+	0x04, 0xe0, 0x66, 0x73,
+	0x02, 0xe0, 0x96, 0x73,
+	0x00, 0xea, 0x1e, 0x73,
+	0x03, 0xe0, 0xa6, 0x73,
+	0x23, 0xe0, 0x96, 0x72,
+	0x08, 0xe0, 0xbc, 0x72,
+	0x00, 0xe2, 0xb8, 0x5b,
+	0x07, 0xea, 0x50, 0x59,
 	0x07, 0xea, 0x04, 0x00,
-	0x08, 0x42, 0xf7, 0x71,
-	0x04, 0x42, 0x91, 0x62,
+	0x08, 0x42, 0xf9, 0x71,
+	0x04, 0x42, 0x93, 0x62,
 	0x01, 0x43, 0x89, 0x30,
-	0x00, 0xe2, 0x82, 0x42,
+	0x00, 0xe2, 0x84, 0x42,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0x82, 0x42,
+	0x00, 0xe2, 0x84, 0x42,
 	0x01, 0x00, 0x60, 0x32,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x4c, 0x34, 0xc1, 0x28,
 	0x01, 0x64, 0xc0, 0x31,
-	0x00, 0x30, 0x43, 0x59,
+	0x00, 0x30, 0x45, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x01, 0xe0, 0xb4, 0x7a,
-	0xa0, 0xea, 0xc4, 0x5b,
-	0x01, 0xa0, 0xb4, 0x62,
-	0x01, 0x84, 0xad, 0x7a,
-	0x01, 0xa7, 0xb6, 0x7a,
-	0x00, 0xe2, 0xb6, 0x42,
-	0x03, 0xea, 0x4e, 0x59,
+	0x01, 0xe0, 0xba, 0x7a,
+	0xa0, 0xea, 0xca, 0x5b,
+	0x01, 0xa0, 0xba, 0x62,
+	0x01, 0x84, 0xaf, 0x7a,
+	0x01, 0xab, 0xbd, 0x6a,
+	0x05, 0xea, 0x50, 0x59,
+	0x05, 0xea, 0x04, 0x00,
+	0x00, 0xe2, 0xbc, 0x42,
+	0x03, 0xea, 0x50, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xb6, 0x42,
-	0x07, 0xea, 0xd6, 0x5b,
+	0x00, 0xe2, 0xbc, 0x42,
+	0x07, 0xea, 0xdc, 0x5b,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0xf6, 0x41,
+	0x00, 0xe2, 0xf8, 0x41,
 	0x3f, 0xe0, 0x6a, 0x0a,
 	0xc0, 0x34, 0xc1, 0x09,
 	0x00, 0x35, 0x51, 0x01,
@@ -365,54 +368,54 @@
 	0x01, 0xea, 0xc6, 0x01,
 	0x02, 0xe2, 0xc8, 0x31,
 	0x02, 0xec, 0x40, 0x31,
-	0xff, 0xa1, 0xd6, 0x72,
+	0xff, 0xa1, 0xdc, 0x72,
 	0x02, 0xe8, 0xda, 0x31,
 	0x02, 0xa0, 0x50, 0x31,
-	0x00, 0xe2, 0xf8, 0x42,
+	0x00, 0xe2, 0xfe, 0x42,
 	0x80, 0x33, 0x67, 0x02,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0xb2, 0x5b,
+	0x00, 0xe2, 0xb8, 0x5b,
 	0x01, 0x33, 0x67, 0x02,
-	0xe0, 0x36, 0x13, 0x63,
+	0xe0, 0x36, 0x19, 0x63,
 	0x02, 0x33, 0x67, 0x02,
-	0x20, 0x46, 0x0c, 0x63,
+	0x20, 0x46, 0x12, 0x63,
 	0xff, 0xea, 0x52, 0x09,
-	0xa8, 0xea, 0xc4, 0x5b,
-	0x04, 0xa8, 0xf3, 0x7a,
+	0xa8, 0xea, 0xca, 0x5b,
+	0x04, 0xa8, 0xf9, 0x7a,
 	0x01, 0x34, 0xc1, 0x31,
-	0x00, 0xa9, 0xf3, 0x62,
+	0x00, 0xa9, 0xf9, 0x62,
 	0x01, 0x35, 0xc1, 0x31,
-	0x00, 0xaa, 0xfd, 0x72,
+	0x00, 0xaa, 0x03, 0x73,
 	0x01, 0xa9, 0x52, 0x11,
-	0xff, 0xa9, 0xe8, 0x6a,
-	0x00, 0xe2, 0x0c, 0x43,
+	0xff, 0xa9, 0xee, 0x6a,
+	0x00, 0xe2, 0x12, 0x43,
 	0x10, 0x33, 0x67, 0x02,
-	0x04, 0xa8, 0x0d, 0x7b,
+	0x04, 0xa8, 0x13, 0x7b,
 	0xfb, 0xa8, 0x51, 0x0b,
 	0xff, 0xea, 0x66, 0x0a,
-	0x01, 0x9c, 0x07, 0x6b,
+	0x01, 0x9c, 0x0d, 0x6b,
 	0x02, 0xa8, 0x90, 0x32,
-	0x00, 0xe2, 0x68, 0x59,
-	0x10, 0xa8, 0xb7, 0x7a,
-	0xff, 0xea, 0xd6, 0x5b,
-	0x00, 0xe2, 0xb6, 0x42,
-	0x04, 0xea, 0x4e, 0x59,
+	0x00, 0xe2, 0x6a, 0x59,
+	0x10, 0xa8, 0xbd, 0x7a,
+	0xff, 0xea, 0xdc, 0x5b,
+	0x00, 0xe2, 0xbc, 0x42,
+	0x04, 0xea, 0x50, 0x59,
 	0x04, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xb6, 0x42,
-	0x04, 0xea, 0x4e, 0x59,
+	0x00, 0xe2, 0xbc, 0x42,
+	0x04, 0xea, 0x50, 0x59,
 	0x04, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x08, 0xa8, 0xaf, 0x7a,
-	0xc0, 0x33, 0x23, 0x7b,
-	0x80, 0x33, 0xaf, 0x6a,
-	0xff, 0x88, 0x23, 0x6b,
-	0x40, 0x33, 0xaf, 0x6a,
-	0x10, 0xa8, 0x29, 0x7b,
-	0x0a, 0xea, 0x4e, 0x59,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x08, 0xa8, 0xb5, 0x7a,
+	0xc0, 0x33, 0x29, 0x7b,
+	0x80, 0x33, 0xb5, 0x6a,
+	0xff, 0x88, 0x29, 0x6b,
+	0x40, 0x33, 0xb5, 0x6a,
+	0x10, 0xa8, 0x2f, 0x7b,
+	0x0a, 0xea, 0x50, 0x59,
 	0x0a, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x48, 0x5b,
-	0x00, 0xe2, 0x7c, 0x43,
-	0x50, 0x4b, 0x30, 0x6b,
+	0x00, 0xe2, 0x4e, 0x5b,
+	0x00, 0xe2, 0x82, 0x43,
+	0x50, 0x4b, 0x36, 0x6b,
 	0xbf, 0x3a, 0x74, 0x08,
 	0x01, 0xe0, 0xf4, 0x31,
 	0xff, 0xea, 0xc0, 0x09,
@@ -422,25 +425,25 @@
 	0x01, 0xfa, 0xc0, 0x35,
 	0x02, 0xa8, 0x84, 0x32,
 	0x02, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x02, 0x42, 0x51, 0x31,
 	0xff, 0xae, 0x65, 0x68,
-	0xff, 0x88, 0x55, 0x6b,
-	0x01, 0x9c, 0x51, 0x6b,
-	0x02, 0x9c, 0x59, 0x6b,
-	0x01, 0x84, 0x59, 0x7b,
+	0xff, 0x88, 0x5b, 0x6b,
+	0x01, 0x9c, 0x57, 0x6b,
+	0x02, 0x9c, 0x5f, 0x6b,
+	0x01, 0x84, 0x5f, 0x7b,
 	0x02, 0x28, 0x19, 0x33,
 	0x02, 0xa8, 0x50, 0x36,
-	0xff, 0x88, 0x59, 0x73,
-	0x00, 0xe2, 0x2c, 0x5b,
+	0xff, 0x88, 0x5f, 0x73,
+	0x00, 0xe2, 0x32, 0x5b,
 	0x02, 0xa8, 0x5c, 0x33,
 	0x02, 0x2c, 0x19, 0x33,
 	0x02, 0xa8, 0x58, 0x32,
 	0x04, 0x9c, 0x39, 0x07,
-	0xc0, 0x33, 0xaf, 0x6a,
+	0xc0, 0x33, 0xb5, 0x6a,
 	0x04, 0xa8, 0x51, 0x03,
-	0x20, 0xa8, 0x7d, 0x6b,
+	0x20, 0xa8, 0x83, 0x6b,
 	0x02, 0xa8, 0x40, 0x31,
 	0xc0, 0x34, 0xc1, 0x09,
 	0x00, 0x35, 0x51, 0x01,
@@ -455,56 +458,56 @@
 	0xf7, 0x57, 0xae, 0x08,
 	0x08, 0xea, 0x98, 0x00,
 	0x01, 0x44, 0xd4, 0x31,
-	0xee, 0x00, 0x86, 0x6b,
+	0xee, 0x00, 0x8c, 0x6b,
 	0x02, 0xea, 0xb4, 0x00,
-	0x00, 0xe2, 0xae, 0x5b,
-	0x09, 0x4c, 0x88, 0x7b,
+	0x00, 0xe2, 0xb4, 0x5b,
+	0x09, 0x4c, 0x8e, 0x7b,
 	0x08, 0x4c, 0x06, 0x68,
-	0x0b, 0xea, 0x4e, 0x59,
+	0x0b, 0xea, 0x50, 0x59,
 	0x0b, 0xea, 0x04, 0x00,
 	0x01, 0x44, 0xd4, 0x31,
-	0x20, 0x33, 0xf7, 0x79,
-	0x00, 0xe2, 0x98, 0x5b,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x01, 0x84, 0x9d, 0x7b,
+	0x20, 0x33, 0xf9, 0x79,
+	0x00, 0xe2, 0x9e, 0x5b,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x01, 0x84, 0xa3, 0x7b,
 	0x01, 0x9c, 0x39, 0x07,
 	0x08, 0x60, 0x20, 0x33,
 	0x08, 0x80, 0x31, 0x37,
 	0xdf, 0x33, 0x67, 0x0a,
-	0xee, 0x00, 0xaa, 0x6b,
+	0xee, 0x00, 0xb0, 0x6b,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
-	0x00, 0xe2, 0x68, 0x59,
-	0x00, 0xe2, 0xb6, 0x42,
+	0x00, 0xe2, 0x6a, 0x59,
+	0x00, 0xe2, 0xbc, 0x42,
 	0x01, 0xea, 0x6c, 0x02,
 	0xc0, 0xea, 0x66, 0x06,
-	0xff, 0x42, 0xbe, 0x6b,
-	0x01, 0x41, 0xb2, 0x6b,
-	0x02, 0x41, 0xb2, 0x7b,
-	0xff, 0x42, 0xbe, 0x6b,
-	0x01, 0x41, 0xb2, 0x6b,
-	0x02, 0x41, 0xb2, 0x7b,
-	0xff, 0x42, 0xbe, 0x7b,
-	0x04, 0x4c, 0xb2, 0x6b,
+	0xff, 0x42, 0xc4, 0x6b,
+	0x01, 0x41, 0xb8, 0x6b,
+	0x02, 0x41, 0xb8, 0x7b,
+	0xff, 0x42, 0xc4, 0x6b,
+	0x01, 0x41, 0xb8, 0x6b,
+	0x02, 0x41, 0xb8, 0x7b,
+	0xff, 0x42, 0xc4, 0x7b,
+	0x04, 0x4c, 0xb8, 0x6b,
 	0xe0, 0x41, 0x6c, 0x0e,
 	0x01, 0x44, 0xd4, 0x31,
-	0xff, 0x42, 0xc6, 0x7b,
-	0x04, 0x4c, 0xc6, 0x6b,
+	0xff, 0x42, 0xcc, 0x7b,
+	0x04, 0x4c, 0xcc, 0x6b,
 	0xe0, 0x41, 0x6c, 0x0a,
-	0xe0, 0x36, 0xf7, 0x61,
+	0xe0, 0x36, 0xf9, 0x61,
 	0xff, 0xea, 0xca, 0x09,
 	0x01, 0xe2, 0xc8, 0x31,
 	0x01, 0x46, 0xda, 0x35,
 	0x01, 0x44, 0xd4, 0x35,
 	0x10, 0xea, 0x80, 0x00,
 	0x01, 0xe2, 0x62, 0x36,
-	0x04, 0xa6, 0xde, 0x7b,
+	0x04, 0xa6, 0xe4, 0x7b,
 	0xff, 0xea, 0x5a, 0x09,
 	0xff, 0xea, 0x4c, 0x0d,
-	0x01, 0xa6, 0xfc, 0x6b,
+	0x01, 0xa6, 0x02, 0x6c,
 	0x10, 0xad, 0x64, 0x78,
-	0x80, 0xad, 0xf4, 0x6b,
+	0x80, 0xad, 0xfa, 0x6b,
 	0x08, 0xad, 0x64, 0x68,
 	0x04, 0x84, 0xf9, 0x30,
 	0x00, 0xea, 0x08, 0x81,
@@ -521,8 +524,6 @@
 	0x08, 0xb0, 0xe0, 0x30,
 	0x04, 0xb0, 0xe0, 0x30,
 	0x03, 0xb0, 0xf0, 0x30,
-	0x01, 0x78, 0x0a, 0x7c,
-	0x01, 0xa7, 0x4e, 0x11,
 	0x01, 0xb0, 0x06, 0x33,
 	0x7f, 0x83, 0xe9, 0x08,
 	0x04, 0xac, 0x58, 0x19,
@@ -532,9 +533,7 @@
 	0x00, 0x86, 0x0d, 0x23,
 	0x00, 0x87, 0x0f, 0x23,
 	0x01, 0x84, 0xc5, 0x31,
-	0x01, 0xa7, 0x20, 0x7c,
-	0x04, 0xe2, 0xc4, 0x01,
-	0x80, 0x83, 0x27, 0x7c,
+	0x80, 0x83, 0x25, 0x7c,
 	0x02, 0xe2, 0xc4, 0x01,
 	0xff, 0xea, 0x4c, 0x09,
 	0x01, 0xe2, 0x36, 0x30,
@@ -544,86 +543,80 @@
 	0x00, 0xe2, 0x64, 0x50,
 	0xfe, 0xa6, 0x4c, 0x0d,
 	0x0b, 0x90, 0xe1, 0x30,
-	0x01, 0x98, 0x4f, 0x09,
 	0xfd, 0x9c, 0x49, 0x09,
-	0x80, 0x9b, 0x3d, 0x7c,
+	0x80, 0x9b, 0x39, 0x7c,
 	0x02, 0xa4, 0x48, 0x01,
-	0x01, 0xa7, 0x40, 0x7c,
-	0x04, 0xa4, 0x48, 0x01,
 	0x01, 0xa4, 0x36, 0x30,
 	0xa8, 0xea, 0x32, 0x00,
 	0xfd, 0x9c, 0x39, 0x0b,
 	0x05, 0x9b, 0x07, 0x33,
-	0x80, 0x83, 0x4d, 0x6c,
+	0x80, 0x83, 0x45, 0x6c,
 	0x02, 0xea, 0x4c, 0x05,
 	0xff, 0xea, 0x4c, 0x0d,
-	0x00, 0xe2, 0x3c, 0x59,
-	0x02, 0xa6, 0xe0, 0x6b,
+	0x00, 0xe2, 0x3e, 0x59,
+	0x02, 0xa6, 0xe6, 0x6b,
 	0x80, 0xf9, 0xf2, 0x05,
-	0xc0, 0x33, 0x5b, 0x7c,
-	0x03, 0xea, 0x4e, 0x59,
+	0xc0, 0x33, 0x53, 0x7c,
+	0x03, 0xea, 0x50, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0x20, 0x33, 0x7f, 0x7c,
-	0x01, 0x84, 0x65, 0x6c,
-	0x06, 0xea, 0x4e, 0x59,
+	0x20, 0x33, 0x77, 0x7c,
+	0x01, 0x84, 0x5d, 0x6c,
+	0x06, 0xea, 0x50, 0x59,
 	0x06, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x82, 0x44,
+	0x00, 0xe2, 0x7a, 0x44,
 	0x01, 0x00, 0x60, 0x32,
-	0xee, 0x00, 0x6e, 0x6c,
+	0xee, 0x00, 0x66, 0x6c,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x42, 0x59,
+	0x33, 0xea, 0x44, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x80, 0x3d, 0x7a, 0x00,
-	0xfc, 0x42, 0x70, 0x7c,
+	0xfc, 0x42, 0x68, 0x7c,
 	0x7f, 0x3d, 0x7a, 0x08,
-	0x00, 0x30, 0x43, 0x59,
+	0x00, 0x30, 0x45, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x09, 0xea, 0x4e, 0x59,
+	0x09, 0xea, 0x50, 0x59,
 	0x09, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x01, 0x9c, 0x65, 0x6c,
-	0x00, 0xe2, 0x32, 0x5c,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x01, 0x9c, 0x5d, 0x6c,
+	0x00, 0xe2, 0x30, 0x5c,
 	0x20, 0x33, 0x67, 0x02,
 	0x01, 0x00, 0x60, 0x32,
-	0x02, 0xa6, 0x8a, 0x7c,
-	0x00, 0xe2, 0x4e, 0x5c,
+	0x02, 0xa6, 0x82, 0x7c,
+	0x00, 0xe2, 0x46, 0x5c,
 	0x00, 0xe2, 0x56, 0x58,
 	0x00, 0xe2, 0x66, 0x58,
 	0x00, 0xe2, 0x3a, 0x58,
-	0x00, 0x30, 0x43, 0x59,
+	0x00, 0x30, 0x45, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x20, 0x19, 0x8a, 0x6c,
-	0x00, 0xe2, 0xba, 0x5c,
-	0x04, 0x19, 0xa4, 0x6c,
+	0x20, 0x19, 0x82, 0x6c,
+	0x00, 0xe2, 0xb2, 0x5c,
+	0x04, 0x19, 0x9c, 0x6c,
 	0x02, 0x19, 0x32, 0x00,
-	0x01, 0x84, 0xa5, 0x7c,
-	0x01, 0x1b, 0x9e, 0x7c,
-	0x01, 0x1a, 0xa4, 0x6c,
-	0x00, 0xe2, 0x54, 0x44,
-	0x80, 0x4b, 0xaa, 0x6c,
-	0x01, 0x4c, 0xa6, 0x7c,
-	0x03, 0x42, 0x54, 0x6c,
-	0x00, 0xe2, 0xda, 0x5b,
+	0x01, 0x84, 0x9d, 0x7c,
+	0x01, 0x1b, 0x96, 0x7c,
+	0x01, 0x1a, 0x9c, 0x6c,
+	0x00, 0xe2, 0x4c, 0x44,
+	0x80, 0x4b, 0xa2, 0x6c,
+	0x01, 0x4c, 0x9e, 0x7c,
+	0x03, 0x42, 0x4c, 0x6c,
+	0x00, 0xe2, 0xe0, 0x5b,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x04, 0x33, 0xf7, 0x79,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x08, 0x5d, 0xc2, 0x6c,
+	0x04, 0x33, 0xf9, 0x79,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x08, 0x5d, 0xba, 0x6c,
 	0x00, 0xe2, 0x56, 0x58,
-	0x00, 0x30, 0x43, 0x59,
+	0x00, 0x30, 0x45, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x02, 0x1b, 0xb2, 0x7c,
-	0x08, 0x5d, 0xc0, 0x7c,
+	0x02, 0x1b, 0xaa, 0x7c,
+	0x08, 0x5d, 0xb8, 0x7c,
 	0x03, 0x68, 0x00, 0x37,
 	0x01, 0x84, 0x09, 0x07,
-	0x80, 0x1b, 0xcc, 0x7c,
-	0x80, 0x84, 0xcd, 0x6c,
+	0x80, 0x1b, 0xc4, 0x7c,
+	0x80, 0x84, 0xc5, 0x6c,
 	0xff, 0x85, 0x0b, 0x1b,
 	0xff, 0x86, 0x0d, 0x23,
 	0xff, 0x87, 0x0f, 0x23,
 	0xf8, 0x1b, 0x08, 0x0b,
-	0xff, 0xea, 0x4e, 0x09,
-	0x04, 0x1b, 0xd4, 0x7c,
-	0x01, 0xa7, 0x4e, 0x01,
 	0xff, 0xea, 0x06, 0x0b,
 	0x03, 0x68, 0x00, 0x37,
 	0x00, 0xe2, 0xc4, 0x58,
@@ -631,161 +624,161 @@
 	0xf9, 0xd9, 0xb2, 0x0d,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x01, 0x52, 0x48, 0x31,
-	0x20, 0xa4, 0xfc, 0x7c,
-	0x20, 0x5b, 0xfc, 0x7c,
-	0x80, 0xf9, 0x0a, 0x7d,
+	0x20, 0xa4, 0xee, 0x7c,
+	0x20, 0x5b, 0xee, 0x7c,
+	0x80, 0xf9, 0xfc, 0x7c,
 	0x02, 0xea, 0xb4, 0x00,
 	0x11, 0x00, 0x00, 0x10,
-	0x04, 0x19, 0x16, 0x7d,
+	0x04, 0x19, 0x08, 0x7d,
 	0xdf, 0x19, 0x32, 0x08,
-	0x60, 0x5b, 0xf4, 0x6c,
-	0x01, 0x4c, 0xf0, 0x7c,
+	0x60, 0x5b, 0xe6, 0x6c,
+	0x01, 0x4c, 0xe2, 0x7c,
 	0x20, 0x19, 0x32, 0x00,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x02, 0xea, 0xb4, 0x00,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x10, 0x5b, 0x0e, 0x6d,
-	0x08, 0x5b, 0x18, 0x6d,
-	0x20, 0x5b, 0x08, 0x6d,
-	0x02, 0x5b, 0x38, 0x6d,
-	0x0e, 0xea, 0x4e, 0x59,
+	0x10, 0x5b, 0x00, 0x6d,
+	0x08, 0x5b, 0x0a, 0x6d,
+	0x20, 0x5b, 0xfa, 0x6c,
+	0x02, 0x5b, 0x2a, 0x6d,
+	0x0e, 0xea, 0x50, 0x59,
 	0x0e, 0xea, 0x04, 0x00,
-	0x80, 0xf9, 0xf8, 0x6c,
+	0x80, 0xf9, 0xea, 0x6c,
 	0xdf, 0x5c, 0xb8, 0x08,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x01, 0x9c, 0xf3, 0x6d,
-	0x00, 0xe2, 0x32, 0x5c,
-	0x00, 0xe2, 0x42, 0x5d,
+	0x01, 0x9c, 0xe5, 0x6d,
+	0x00, 0xe2, 0x30, 0x5c,
+	0x00, 0xe2, 0x34, 0x5d,
 	0x01, 0xae, 0x5d, 0x1b,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x00, 0xe2, 0x2c, 0x5b,
+	0x00, 0xe2, 0x32, 0x5b,
 	0xf3, 0xac, 0xd5, 0x19,
-	0x00, 0xe2, 0x26, 0x55,
-	0x80, 0xac, 0x27, 0x6d,
-	0x0f, 0xea, 0x4e, 0x59,
+	0x00, 0xe2, 0x18, 0x55,
+	0x80, 0xac, 0x19, 0x6d,
+	0x0f, 0xea, 0x50, 0x59,
 	0x0f, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x2e, 0x45,
+	0x00, 0xe2, 0x20, 0x45,
 	0x04, 0x8c, 0xe1, 0x30,
 	0x01, 0xea, 0xf2, 0x00,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0xff, 0xad, 0x35, 0x7d,
-	0x14, 0xea, 0x4e, 0x59,
+	0xff, 0xad, 0x27, 0x7d,
+	0x14, 0xea, 0x50, 0x59,
 	0x14, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xa4, 0x5d,
+	0x00, 0xe2, 0x96, 0x5d,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x09, 0x80, 0xe1, 0x30,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x9c, 0x5d,
+	0x00, 0xe2, 0x8e, 0x5d,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x02, 0xa6, 0x52, 0x7d,
-	0x00, 0xe2, 0x3c, 0x59,
-	0x20, 0x5b, 0x60, 0x6d,
-	0xfc, 0x42, 0x4c, 0x7d,
-	0x10, 0x40, 0x4e, 0x6d,
-	0x20, 0x4d, 0x50, 0x7d,
-	0x08, 0x5d, 0x60, 0x6d,
-	0x02, 0xa6, 0xe0, 0x6b,
-	0x00, 0xe2, 0x3c, 0x59,
-	0x20, 0x5b, 0x60, 0x6d,
-	0x01, 0x1b, 0x80, 0x6d,
-	0xfc, 0x42, 0x5c, 0x7d,
-	0x10, 0x40, 0x5e, 0x6d,
+	0x02, 0xa6, 0x44, 0x7d,
+	0x00, 0xe2, 0x3e, 0x59,
+	0x20, 0x5b, 0x52, 0x6d,
+	0xfc, 0x42, 0x3e, 0x7d,
+	0x10, 0x40, 0x40, 0x6d,
+	0x20, 0x4d, 0x42, 0x7d,
+	0x08, 0x5d, 0x52, 0x6d,
+	0x02, 0xa6, 0xe6, 0x6b,
+	0x00, 0xe2, 0x3e, 0x59,
+	0x20, 0x5b, 0x52, 0x6d,
+	0x01, 0x1b, 0x72, 0x6d,
+	0xfc, 0x42, 0x4e, 0x7d,
+	0x10, 0x40, 0x50, 0x6d,
 	0x20, 0x4d, 0x64, 0x78,
 	0x08, 0x5d, 0x64, 0x78,
 	0x02, 0x19, 0x32, 0x00,
 	0x01, 0x5b, 0x40, 0x31,
-	0x00, 0xe2, 0xba, 0x5c,
-	0x00, 0xe2, 0x98, 0x5b,
+	0x00, 0xe2, 0xb2, 0x5c,
+	0x00, 0xe2, 0x9e, 0x5b,
 	0x20, 0xea, 0xb6, 0x00,
-	0x00, 0xe2, 0xda, 0x5b,
+	0x00, 0xe2, 0xe0, 0x5b,
 	0x20, 0x5c, 0xb8, 0x00,
-	0x04, 0x19, 0x76, 0x6d,
-	0x01, 0x1a, 0x76, 0x6d,
-	0x00, 0xe2, 0x3c, 0x59,
+	0x04, 0x19, 0x68, 0x6d,
+	0x01, 0x1a, 0x68, 0x6d,
+	0x00, 0xe2, 0x3e, 0x59,
 	0x01, 0x1a, 0x64, 0x78,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x20, 0xa0, 0xda, 0x7d,
+	0x20, 0xa0, 0xcc, 0x7d,
 	0xff, 0xae, 0x5d, 0x1b,
-	0x08, 0xa8, 0x3d, 0x6b,
+	0x08, 0xa8, 0x43, 0x6b,
 	0x02, 0xea, 0xb4, 0x04,
 	0x01, 0x9c, 0x39, 0x03,
-	0x40, 0x5b, 0x90, 0x6d,
-	0x00, 0xe2, 0x3c, 0x59,
-	0x40, 0x5b, 0x90, 0x6d,
-	0x04, 0x5d, 0xf4, 0x7d,
-	0x01, 0x1a, 0xf4, 0x7d,
+	0x40, 0x5b, 0x82, 0x6d,
+	0x00, 0xe2, 0x3e, 0x59,
+	0x40, 0x5b, 0x82, 0x6d,
+	0x04, 0x5d, 0xe6, 0x7d,
+	0x01, 0x1a, 0xe6, 0x7d,
 	0x20, 0x4d, 0x64, 0x78,
-	0x40, 0x5b, 0xda, 0x7d,
-	0x04, 0x5d, 0xf4, 0x7d,
-	0x01, 0x1a, 0xf4, 0x7d,
+	0x40, 0x5b, 0xcc, 0x7d,
+	0x04, 0x5d, 0xe6, 0x7d,
+	0x01, 0x1a, 0xe6, 0x7d,
 	0x80, 0xf9, 0xf2, 0x01,
 	0xff, 0xae, 0x5d, 0x1b,
-	0x08, 0xa8, 0x3d, 0x6b,
+	0x08, 0xa8, 0x43, 0x6b,
 	0x02, 0xea, 0xb4, 0x04,
-	0x00, 0xe2, 0x3c, 0x59,
+	0x00, 0xe2, 0x3e, 0x59,
 	0x01, 0x1b, 0x64, 0x78,
 	0x80, 0xf9, 0xf2, 0x01,
 	0x02, 0xea, 0xb4, 0x04,
-	0x00, 0xe2, 0x3c, 0x59,
-	0x01, 0x1b, 0xb8, 0x6d,
-	0x40, 0x5b, 0xc6, 0x7d,
-	0x01, 0x1b, 0xb8, 0x6d,
+	0x00, 0xe2, 0x3e, 0x59,
+	0x01, 0x1b, 0xaa, 0x6d,
+	0x40, 0x5b, 0xb8, 0x7d,
+	0x01, 0x1b, 0xaa, 0x6d,
 	0x02, 0x19, 0x32, 0x00,
 	0x01, 0x1a, 0x64, 0x78,
 	0x80, 0xf9, 0xf2, 0x01,
 	0xff, 0xea, 0x10, 0x03,
 	0x08, 0xa8, 0x51, 0x03,
-	0x00, 0xe2, 0x3c, 0x43,
-	0x01, 0x1a, 0xc2, 0x7d,
-	0x40, 0x5b, 0xbe, 0x7d,
-	0x01, 0x1a, 0xac, 0x6d,
+	0x00, 0xe2, 0x42, 0x43,
+	0x01, 0x1a, 0xb4, 0x7d,
+	0x40, 0x5b, 0xb0, 0x7d,
+	0x01, 0x1a, 0x9e, 0x6d,
 	0xfc, 0x42, 0x64, 0x78,
-	0x01, 0x1a, 0xc6, 0x6d,
-	0x10, 0xea, 0x4e, 0x59,
+	0x01, 0x1a, 0xb8, 0x6d,
+	0x10, 0xea, 0x50, 0x59,
 	0x10, 0xea, 0x04, 0x00,
 	0xfc, 0x42, 0x64, 0x78,
-	0x10, 0x40, 0xcc, 0x6d,
+	0x10, 0x40, 0xbe, 0x6d,
 	0x20, 0x4d, 0x64, 0x78,
-	0x40, 0x5b, 0xac, 0x6d,
+	0x40, 0x5b, 0x9e, 0x6d,
 	0x01, 0x1a, 0x64, 0x78,
 	0x01, 0xae, 0x5d, 0x1b,
 	0x30, 0x3f, 0xc0, 0x09,
 	0x30, 0xe0, 0x64, 0x60,
 	0x40, 0x4b, 0x64, 0x68,
 	0xff, 0xea, 0x52, 0x01,
-	0xee, 0x00, 0xe0, 0x6d,
+	0xee, 0x00, 0xd2, 0x6d,
 	0x80, 0xf9, 0xf2, 0x01,
 	0xff, 0xae, 0x5d, 0x1b,
 	0x02, 0xea, 0xb4, 0x00,
 	0x20, 0xea, 0x9a, 0x00,
-	0xf3, 0x42, 0xec, 0x6d,
-	0x12, 0xea, 0x4e, 0x59,
+	0xf3, 0x42, 0xde, 0x6d,
+	0x12, 0xea, 0x50, 0x59,
 	0x12, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xf6, 0x41,
-	0x0d, 0xea, 0x4e, 0x59,
+	0x00, 0xe2, 0xf8, 0x41,
+	0x0d, 0xea, 0x50, 0x59,
 	0x0d, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xf6, 0x41,
+	0x00, 0xe2, 0xf8, 0x41,
 	0x01, 0xae, 0x5d, 0x1b,
-	0x11, 0xea, 0x4e, 0x59,
+	0x11, 0xea, 0x50, 0x59,
 	0x11, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x2c, 0x5b,
+	0x00, 0xe2, 0x32, 0x5b,
 	0x08, 0x5a, 0xb4, 0x00,
-	0x00, 0xe2, 0x1a, 0x5e,
+	0x00, 0xe2, 0x0c, 0x5e,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x3c, 0x59,
-	0x80, 0x1a, 0x08, 0x7e,
-	0x00, 0xe2, 0x1a, 0x5e,
+	0x00, 0xe2, 0x3e, 0x59,
+	0x80, 0x1a, 0xfa, 0x7d,
+	0x00, 0xe2, 0x0c, 0x5e,
 	0x80, 0x19, 0x32, 0x00,
-	0x40, 0x5b, 0x0e, 0x6e,
-	0x08, 0x5a, 0x0e, 0x7e,
+	0x40, 0x5b, 0x00, 0x6e,
+	0x08, 0x5a, 0x00, 0x7e,
 	0x20, 0x4d, 0x64, 0x78,
 	0x02, 0x84, 0x09, 0x03,
-	0x40, 0x5b, 0xda, 0x7d,
+	0x40, 0x5b, 0xcc, 0x7d,
 	0xff, 0xae, 0x5d, 0x1b,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x08, 0xa8, 0x3d, 0x6b,
+	0x08, 0xa8, 0x43, 0x6b,
 	0x02, 0xea, 0xb4, 0x04,
 	0x01, 0x38, 0xe1, 0x30,
 	0x05, 0x39, 0xe3, 0x98,
@@ -801,12 +794,20 @@
 };
 
 typedef int ahd_patch_func_t (struct ahd_softc *ahd);
+static ahd_patch_func_t ahd_patch22_func;
+
+static int
+ahd_patch22_func(struct ahd_softc *ahd)
+{
+	return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0);
+}
+
 static ahd_patch_func_t ahd_patch21_func;
 
 static int
 ahd_patch21_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0);
+	return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0);
 }
 
 static ahd_patch_func_t ahd_patch20_func;
@@ -814,7 +815,7 @@
 static int
 ahd_patch20_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0);
+	return ((ahd->features & AHD_RTI) == 0);
 }
 
 static ahd_patch_func_t ahd_patch19_func;
@@ -822,7 +823,7 @@
 static int
 ahd_patch19_func(struct ahd_softc *ahd)
 {
-	return ((ahd->features & AHD_RTI) == 0);
+	return ((ahd->flags & AHD_INITIATORROLE) != 0);
 }
 
 static ahd_patch_func_t ahd_patch18_func;
@@ -830,7 +831,7 @@
 static int
 ahd_patch18_func(struct ahd_softc *ahd)
 {
-	return ((ahd->flags & AHD_INITIATORROLE) != 0);
+	return ((ahd->flags & AHD_TARGETROLE) != 0);
 }
 
 static ahd_patch_func_t ahd_patch17_func;
@@ -838,7 +839,7 @@
 static int
 ahd_patch17_func(struct ahd_softc *ahd)
 {
-	return ((ahd->flags & AHD_TARGETROLE) != 0);
+	return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch16_func;
@@ -846,7 +847,7 @@
 static int
 ahd_patch16_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0);
+	return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0);
 }
 
 static ahd_patch_func_t ahd_patch15_func;
@@ -854,7 +855,7 @@
 static int
 ahd_patch15_func(struct ahd_softc *ahd)
 {
-	return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0);
+	return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0);
 }
 
 static ahd_patch_func_t ahd_patch14_func;
@@ -862,7 +863,7 @@
 static int
 ahd_patch14_func(struct ahd_softc *ahd)
 {
-	return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0);
+	return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0);
 }
 
 static ahd_patch_func_t ahd_patch13_func;
@@ -870,7 +871,7 @@
 static int
 ahd_patch13_func(struct ahd_softc *ahd)
 {
-	return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0);
+	return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0);
 }
 
 static ahd_patch_func_t ahd_patch12_func;
@@ -878,7 +879,7 @@
 static int
 ahd_patch12_func(struct ahd_softc *ahd)
 {
-	return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0);
+	return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch11_func;
@@ -886,7 +887,7 @@
 static int
 ahd_patch11_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0);
+	return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch10_func;
@@ -894,7 +895,7 @@
 static int
 ahd_patch10_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0);
+	return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0);
 }
 
 static ahd_patch_func_t ahd_patch9_func;
@@ -902,7 +903,7 @@
 static int
 ahd_patch9_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0);
+	return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch8_func;
@@ -910,7 +911,7 @@
 static int
 ahd_patch8_func(struct ahd_softc *ahd)
 {
-	return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0);
+	return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch7_func;
@@ -918,7 +919,7 @@
 static int
 ahd_patch7_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0);
+	return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch6_func;
@@ -926,7 +927,7 @@
 static int
 ahd_patch6_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0);
+	return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch5_func;
@@ -934,7 +935,7 @@
 static int
 ahd_patch5_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0);
+	return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch4_func;
@@ -942,7 +943,7 @@
 static int
 ahd_patch4_func(struct ahd_softc *ahd)
 {
-	return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0);
+	return ((ahd->bugs & AHD_PKT_LUN_BUG) != 0);
 }
 
 static ahd_patch_func_t ahd_patch3_func;
@@ -1008,109 +1009,112 @@
 	{ ahd_patch0_func, 70, 1, 1 },
 	{ ahd_patch1_func, 73, 1, 2 },
 	{ ahd_patch0_func, 74, 1, 1 },
-	{ ahd_patch2_func, 161, 6, 1 },
-	{ ahd_patch1_func, 167, 2, 1 },
-	{ ahd_patch4_func, 169, 1, 1 },
-	{ ahd_patch2_func, 178, 1, 2 },
-	{ ahd_patch0_func, 179, 1, 1 },
-	{ ahd_patch5_func, 180, 2, 2 },
-	{ ahd_patch0_func, 182, 6, 3 },
-	{ ahd_patch2_func, 185, 1, 2 },
-	{ ahd_patch0_func, 186, 1, 1 },
-	{ ahd_patch2_func, 189, 1, 2 },
-	{ ahd_patch0_func, 190, 1, 1 },
-	{ ahd_patch6_func, 192, 2, 1 },
-	{ ahd_patch4_func, 200, 16, 2 },
-	{ ahd_patch0_func, 216, 1, 1 },
-	{ ahd_patch7_func, 236, 2, 1 },
-	{ ahd_patch1_func, 240, 1, 2 },
-	{ ahd_patch0_func, 241, 1, 1 },
-	{ ahd_patch6_func, 244, 2, 1 },
-	{ ahd_patch1_func, 258, 1, 2 },
-	{ ahd_patch0_func, 259, 1, 1 },
-	{ ahd_patch1_func, 262, 1, 2 },
-	{ ahd_patch0_func, 263, 1, 1 },
-	{ ahd_patch2_func, 266, 1, 2 },
-	{ ahd_patch0_func, 267, 1, 1 },
-	{ ahd_patch1_func, 322, 1, 2 },
-	{ ahd_patch0_func, 323, 1, 1 },
-	{ ahd_patch2_func, 331, 1, 2 },
-	{ ahd_patch0_func, 332, 1, 1 },
-	{ ahd_patch2_func, 335, 1, 2 },
-	{ ahd_patch0_func, 336, 1, 1 },
+	{ ahd_patch4_func, 107, 1, 1 },
+	{ ahd_patch2_func, 162, 6, 1 },
+	{ ahd_patch1_func, 168, 2, 1 },
+	{ ahd_patch5_func, 170, 1, 1 },
+	{ ahd_patch2_func, 179, 1, 2 },
+	{ ahd_patch0_func, 180, 1, 1 },
+	{ ahd_patch6_func, 181, 2, 2 },
+	{ ahd_patch0_func, 183, 6, 3 },
+	{ ahd_patch2_func, 186, 1, 2 },
+	{ ahd_patch0_func, 187, 1, 1 },
+	{ ahd_patch2_func, 190, 1, 2 },
+	{ ahd_patch0_func, 191, 1, 1 },
+	{ ahd_patch7_func, 193, 2, 1 },
+	{ ahd_patch5_func, 201, 16, 2 },
+	{ ahd_patch0_func, 217, 1, 1 },
+	{ ahd_patch8_func, 237, 2, 1 },
+	{ ahd_patch1_func, 241, 1, 2 },
+	{ ahd_patch0_func, 242, 1, 1 },
+	{ ahd_patch7_func, 245, 2, 1 },
+	{ ahd_patch1_func, 259, 1, 2 },
+	{ ahd_patch0_func, 260, 1, 1 },
+	{ ahd_patch1_func, 263, 1, 2 },
+	{ ahd_patch0_func, 264, 1, 1 },
+	{ ahd_patch2_func, 267, 1, 2 },
+	{ ahd_patch0_func, 268, 1, 1 },
+	{ ahd_patch1_func, 323, 1, 2 },
+	{ ahd_patch0_func, 324, 1, 1 },
+	{ ahd_patch2_func, 332, 1, 2 },
+	{ ahd_patch0_func, 333, 1, 1 },
+	{ ahd_patch2_func, 336, 1, 2 },
+	{ ahd_patch0_func, 337, 1, 1 },
 	{ ahd_patch1_func, 343, 1, 2 },
 	{ ahd_patch0_func, 344, 1, 1 },
-	{ ahd_patch8_func, 363, 1, 1 },
-	{ ahd_patch8_func, 366, 1, 1 },
-	{ ahd_patch8_func, 368, 1, 1 },
-	{ ahd_patch8_func, 380, 1, 1 },
-	{ ahd_patch1_func, 390, 1, 2 },
-	{ ahd_patch0_func, 391, 1, 1 },
+	{ ahd_patch1_func, 346, 1, 2 },
+	{ ahd_patch0_func, 347, 1, 1 },
+	{ ahd_patch9_func, 366, 1, 1 },
+	{ ahd_patch9_func, 369, 1, 1 },
+	{ ahd_patch9_func, 371, 1, 1 },
+	{ ahd_patch9_func, 383, 1, 1 },
 	{ ahd_patch1_func, 393, 1, 2 },
 	{ ahd_patch0_func, 394, 1, 1 },
-	{ ahd_patch1_func, 402, 1, 2 },
-	{ ahd_patch0_func, 403, 1, 1 },
-	{ ahd_patch2_func, 416, 1, 2 },
-	{ ahd_patch0_func, 417, 1, 1 },
-	{ ahd_patch9_func, 447, 1, 1 },
-	{ ahd_patch1_func, 454, 1, 2 },
-	{ ahd_patch0_func, 455, 1, 1 },
-	{ ahd_patch2_func, 467, 1, 2 },
-	{ ahd_patch0_func, 468, 1, 1 },
-	{ ahd_patch10_func, 473, 6, 2 },
-	{ ahd_patch0_func, 479, 1, 1 },
-	{ ahd_patch11_func, 502, 1, 1 },
-	{ ahd_patch12_func, 511, 1, 1 },
-	{ ahd_patch13_func, 512, 1, 2 },
-	{ ahd_patch0_func, 513, 1, 1 },
-	{ ahd_patch14_func, 518, 1, 1 },
-	{ ahd_patch13_func, 519, 1, 1 },
-	{ ahd_patch15_func, 532, 1, 2 },
-	{ ahd_patch0_func, 533, 1, 1 },
+	{ ahd_patch1_func, 396, 1, 2 },
+	{ ahd_patch0_func, 397, 1, 1 },
+	{ ahd_patch1_func, 405, 1, 2 },
+	{ ahd_patch0_func, 406, 1, 1 },
+	{ ahd_patch2_func, 419, 1, 2 },
+	{ ahd_patch0_func, 420, 1, 1 },
+	{ ahd_patch10_func, 450, 1, 1 },
+	{ ahd_patch1_func, 457, 1, 2 },
+	{ ahd_patch0_func, 458, 1, 1 },
+	{ ahd_patch2_func, 470, 1, 2 },
+	{ ahd_patch0_func, 471, 1, 1 },
+	{ ahd_patch11_func, 476, 6, 2 },
+	{ ahd_patch0_func, 482, 1, 1 },
+	{ ahd_patch12_func, 505, 1, 1 },
+	{ ahd_patch13_func, 514, 1, 1 },
+	{ ahd_patch14_func, 515, 1, 2 },
+	{ ahd_patch0_func, 516, 1, 1 },
+	{ ahd_patch15_func, 519, 1, 1 },
+	{ ahd_patch14_func, 520, 1, 1 },
+	{ ahd_patch16_func, 531, 1, 2 },
+	{ ahd_patch0_func, 532, 1, 1 },
+	{ ahd_patch1_func, 551, 1, 2 },
+	{ ahd_patch0_func, 552, 1, 1 },
 	{ ahd_patch1_func, 555, 1, 2 },
 	{ ahd_patch0_func, 556, 1, 1 },
-	{ ahd_patch1_func, 559, 1, 2 },
-	{ ahd_patch0_func, 560, 1, 1 },
-	{ ahd_patch2_func, 565, 1, 2 },
-	{ ahd_patch0_func, 566, 1, 1 },
-	{ ahd_patch2_func, 570, 1, 2 },
-	{ ahd_patch0_func, 571, 1, 1 },
-	{ ahd_patch1_func, 572, 1, 2 },
-	{ ahd_patch0_func, 573, 1, 1 },
-	{ ahd_patch2_func, 584, 1, 2 },
-	{ ahd_patch0_func, 585, 1, 1 },
-	{ ahd_patch16_func, 589, 1, 1 },
-	{ ahd_patch17_func, 594, 1, 1 },
-	{ ahd_patch18_func, 595, 2, 1 },
-	{ ahd_patch17_func, 599, 1, 2 },
+	{ ahd_patch2_func, 561, 1, 2 },
+	{ ahd_patch0_func, 562, 1, 1 },
+	{ ahd_patch2_func, 566, 1, 2 },
+	{ ahd_patch0_func, 567, 1, 1 },
+	{ ahd_patch1_func, 568, 1, 2 },
+	{ ahd_patch0_func, 569, 1, 1 },
+	{ ahd_patch2_func, 580, 1, 2 },
+	{ ahd_patch0_func, 581, 1, 1 },
+	{ ahd_patch17_func, 585, 1, 1 },
+	{ ahd_patch18_func, 590, 1, 1 },
+	{ ahd_patch19_func, 591, 2, 1 },
+	{ ahd_patch18_func, 595, 1, 2 },
+	{ ahd_patch0_func, 596, 1, 1 },
+	{ ahd_patch2_func, 599, 1, 2 },
 	{ ahd_patch0_func, 600, 1, 1 },
-	{ ahd_patch2_func, 603, 1, 2 },
-	{ ahd_patch0_func, 604, 1, 1 },
-	{ ahd_patch2_func, 622, 1, 2 },
-	{ ahd_patch0_func, 623, 1, 1 },
-	{ ahd_patch19_func, 624, 14, 1 },
-	{ ahd_patch1_func, 642, 1, 2 },
-	{ ahd_patch0_func, 643, 1, 1 },
-	{ ahd_patch19_func, 644, 1, 1 },
-	{ ahd_patch1_func, 656, 1, 2 },
-	{ ahd_patch0_func, 657, 1, 1 },
-	{ ahd_patch1_func, 664, 1, 2 },
-	{ ahd_patch0_func, 665, 1, 1 },
-	{ ahd_patch16_func, 688, 1, 1 },
-	{ ahd_patch16_func, 726, 1, 1 },
-	{ ahd_patch1_func, 737, 1, 2 },
-	{ ahd_patch0_func, 738, 1, 1 },
+	{ ahd_patch2_func, 615, 1, 2 },
+	{ ahd_patch0_func, 616, 1, 1 },
+	{ ahd_patch20_func, 617, 14, 1 },
+	{ ahd_patch1_func, 635, 1, 2 },
+	{ ahd_patch0_func, 636, 1, 1 },
+	{ ahd_patch20_func, 637, 1, 1 },
+	{ ahd_patch1_func, 649, 1, 2 },
+	{ ahd_patch0_func, 650, 1, 1 },
+	{ ahd_patch1_func, 657, 1, 2 },
+	{ ahd_patch0_func, 658, 1, 1 },
+	{ ahd_patch17_func, 681, 1, 1 },
+	{ ahd_patch17_func, 719, 1, 1 },
+	{ ahd_patch1_func, 730, 1, 2 },
+	{ ahd_patch0_func, 731, 1, 1 },
+	{ ahd_patch1_func, 748, 1, 2 },
+	{ ahd_patch0_func, 749, 1, 1 },
+	{ ahd_patch1_func, 751, 1, 2 },
+	{ ahd_patch0_func, 752, 1, 1 },
 	{ ahd_patch1_func, 755, 1, 2 },
 	{ ahd_patch0_func, 756, 1, 1 },
-	{ ahd_patch1_func, 758, 1, 2 },
-	{ ahd_patch0_func, 759, 1, 1 },
-	{ ahd_patch1_func, 762, 1, 2 },
-	{ ahd_patch0_func, 763, 1, 1 },
-	{ ahd_patch20_func, 765, 1, 2 },
-	{ ahd_patch0_func, 766, 2, 1 },
-	{ ahd_patch21_func, 769, 4, 2 },
-	{ ahd_patch0_func, 773, 1, 1 },
-	{ ahd_patch21_func, 781, 11, 1 }
+	{ ahd_patch21_func, 758, 1, 2 },
+	{ ahd_patch0_func, 759, 2, 1 },
+	{ ahd_patch22_func, 762, 4, 2 },
+	{ ahd_patch0_func, 766, 1, 1 },
+	{ ahd_patch22_func, 774, 11, 1 }
 };
 
 static struct cs {
@@ -1121,14 +1125,14 @@
 	{ 13, 14 },
 	{ 29, 42 },
 	{ 56, 59 },
-	{ 101, 127 },
-	{ 128, 156 },
-	{ 158, 161 },
-	{ 169, 177 },
-	{ 200, 249 },
-	{ 688, 704 },
-	{ 704, 718 },
-	{ 728, 732 }
+	{ 101, 128 },
+	{ 129, 157 },
+	{ 159, 162 },
+	{ 170, 178 },
+	{ 201, 250 },
+	{ 681, 697 },
+	{ 697, 711 },
+	{ 721, 725 }
 };
 
 static const int num_critical_sections = sizeof(critical_sections)
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h
--- a/drivers/scsi/aic7xxx/aic7xxx.h	Thu Apr 24 11:10:32 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx.h	Fri May 23 10:40:46 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#75 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#77 $
  *
  * $FreeBSD$
  */
@@ -93,7 +93,7 @@
 #define	SCB_GET_CHANNEL(ahc, scb) \
 	SCSIID_CHANNEL(ahc, (scb)->hscb->scsiid)
 #define	SCB_GET_LUN(scb) \
-	((scb)->hscb->lun)
+	((scb)->hscb->lun & LID)
 #define SCB_GET_TARGET_OFFSET(ahc, scb)	\
 	(SCB_GET_TARGET(ahc, scb) + (SCB_IS_SCSIBUS_B(ahc, scb) ? 8 : 0))
 #define SCB_GET_TARGET_MASK(ahc, scb) \
@@ -1045,6 +1045,11 @@
 	 */
 	struct target_cmd	 *targetcmds;
 	uint8_t			  tqinfifonext;
+
+	/*
+	 * Cached copy of the sequencer control register.
+	 */
+	uint8_t			  seqctl;
 
 	/*
 	 * Incoming and outgoing message handling.
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.reg b/drivers/scsi/aic7xxx/aic7xxx.reg
--- a/drivers/scsi/aic7xxx/aic7xxx.reg	Fri Feb 21 15:50:42 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx.reg	Fri May 23 10:40:47 2003
@@ -39,7 +39,7 @@
  *
  * $FreeBSD$
  */
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $"
 
 /*
  * This file is processed by the aic7xxx_asm utility for use in assembling
@@ -1080,7 +1080,8 @@
 		mask	OID				0x0f
 	}
 	SCB_LUN {
-		mask	LID				0xff
+		field	SCB_XFERLEN_ODD			0x80
+		mask	LID				0x3f
 		size	1
 	}
 	SCB_TAG {
@@ -1239,7 +1240,6 @@
 	access_mode WO
 	address			0x0fc
 	mask	SG_ADDR_MASK	0xf8
-	field	ODD_SEG		0x04
 	field	LAST_SEG	0x02
 	field	LAST_SEG_DONE	0x01
 }
@@ -1248,7 +1248,6 @@
 	access_mode RO
 	address			0x0fc
 	mask	SG_ADDR_MASK	0xf8
-	field	ODD_SEG		0x04
 	field	LAST_SEG	0x02
 	field	LAST_SEG_DONE	0x01
 }
@@ -1477,14 +1476,6 @@
 		field	ENAUTOATNO	0x08
 		field	ENAUTOATNI	0x04
 		field	ENAUTOATNP	0x02
-	}
-
-	/*
-	 * Track whether the transfer byte count for
-	 * the current data phase is odd.
-	 */
-	DATA_COUNT_ODD {
-		size		1
 	}
 }
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq
--- a/drivers/scsi/aic7xxx/aic7xxx.seq	Fri Jan 17 12:17:42 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx.seq	Fri May 23 10:50:58 2003
@@ -40,7 +40,7 @@
  * $FreeBSD$
  */
 
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $"
 PATCH_ARG_LIST = "struct ahc_softc *ahc"
 PREFIX = "ahc_"
 
@@ -437,7 +437,7 @@
 	mov	SCBPTR, WAITING_SCBH;
 	mov	WAITING_SCBH,SCB_NEXT;
 	mov	SAVED_SCSIID, SCB_SCSIID;
-	mov	SAVED_LUN, SCB_LUN;
+	and	SAVED_LUN, LID, SCB_LUN;
 	call	set_transfer_settings;
 	if ((ahc->flags & AHC_TARGETROLE) != 0) {
 		test	SSTAT0, TARGET	jz initiator_select;
@@ -461,7 +461,7 @@
 		/*
 		 * Start out with a simple identify message.
 		 */
-		or	SCB_LUN, MSG_IDENTIFYFLAG call target_outb;
+		or	SAVED_LUN, MSG_IDENTIFYFLAG call target_outb;
 
 		/*
 		 * If we are the result of a tagged command, send
@@ -768,16 +768,12 @@
 		/* Does the hardware have space for another SG entry? */
 		test	DFSTATUS, PRELOAD_AVAIL jz return;
 		bmov 	HADDR, CCSGRAM, 7;
-		test	HCNT[0], 0x1 jz . + 2;
-		xor	DATA_COUNT_ODD, 0x1;
 		bmov	SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;
 		if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
 			mov	SCB_RESIDUAL_DATACNT[3] call set_hhaddr;
 		}
 		call	sg_advance;
 		mov	SINDEX, SCB_RESIDUAL_SGPTR[0];
-		test	DATA_COUNT_ODD, 0x1 jz . + 2;
-		or	SINDEX, ODD_SEG;
 		test	SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
 		or	SINDEX, LAST_SEG;
 		mov	SG_CACHE_PRE, SINDEX;
@@ -875,7 +871,6 @@
 		call	calc_mwi_residual;
 	}
 	and	SCB_RESIDUAL_SGPTR[0], ~SG_FULL_RESID;
-	and	DATA_COUNT_ODD, 0x1, HCNT[0];
 
 	if ((ahc->features & AHC_ULTRA2) == 0) {
 		if ((ahc->features & AHC_CMD_CHAN) != 0) {
@@ -910,8 +905,6 @@
 		mov	SINDEX, SCB_RESIDUAL_SGPTR[0];
 		test	SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;
 		or	SINDEX, LAST_SEG;
-		test	DATA_COUNT_ODD, 0x1 jz . + 2;
-		or	SINDEX, ODD_SEG;
 		mov	SG_CACHE_PRE, SINDEX;
 		mov	DFCNTRL, DMAPARAMS;
 ultra2_dma_loop:
@@ -1006,10 +999,8 @@
 		adc	SCB_RESIDUAL_SGPTR[3], -1;
 sgptr_fixup_done:
 		and	SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;
-		clr	DATA_COUNT_ODD;
-		test	SG_CACHE_SHADOW, ODD_SEG jz . + 2;
-		or	DATA_COUNT_ODD, 0x1;
-		clr	SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */
+		/* We are not the last seg */
+		and	SCB_RESIDUAL_DATACNT[3], ~SG_LAST_SEG;
 residuals_correct:
 		/*
 		 * Go ahead and shut down the DMA engine now.
@@ -1053,11 +1044,19 @@
 			 * LAST_SEG_DONE to come true on a completed transfer
 			 * and then test to see if the data FIFO is non-empty.
 			 */
-			test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 4;
+			test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL
+				jz ultra2_wait_fifoemp;
 			test	SG_CACHE_SHADOW, LAST_SEG_DONE jz .;
+			/*
+			 * FIFOEMP can lag LAST_SEG_DONE.  Wait a few
+			 * clocks before calling this an overrun.
+			 */
+			test	DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
+			test	DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
 			test	DFSTATUS, FIFOEMP jnz ultra2_fifoempty;
 			/* Overrun */
 			jmp	data_phase_loop;
+ultra2_wait_fifoemp:
 			test	DFSTATUS, FIFOEMP jz .;
 		}
 ultra2_fifoempty:
@@ -1246,9 +1245,6 @@
 		} else {
 			call	set_stcnt_from_hcnt;
 		}
-		/* Track odd'ness */
-		test	HCNT[0], 0x1 jz . + 2;
-		xor	DATA_COUNT_ODD, 0x1;
 
 		if ((ahc->flags & AHC_TARGETROLE) != 0) {
 			test	SSTAT0, TARGET jnz data_phase_loop;
@@ -1350,7 +1346,7 @@
 		 */
 		test	DFCNTRL, DIRECTION jz target_ITloop;
 		test	SSTAT1, REQINIT	jnz .;
-		test	DATA_COUNT_ODD, 0x1 jz target_ITloop;
+		test	SCB_LUN, SCB_XFERLEN_ODD jz target_ITloop;
 		test	SCSIRATE, WIDEXFER jz target_ITloop;
 		/*
 		 * Issue an Ignore Wide Residue Message.
@@ -1510,7 +1506,7 @@
 	cmp	SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;
 	test	SCB_CONTROL,MK_MESSAGE	jnz host_message_loop;
 p_mesgout_identify:
-	or	SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN;
+	or	SINDEX, MSG_IDENTIFYFLAG|DISCENB, SAVED_LUN;
 	test	SCB_CONTROL, DISCENB jnz . + 2;
 	and	SINDEX, ~DISCENB;
 /*
@@ -1587,7 +1583,7 @@
 	mvi	ARG_1	call inb_next;
 	cmp	ARG_1, 0x01 jne mesgin_reject;
 	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;
-	test	DATA_COUNT_ODD, 0x1	jz mesgin_done;
+	test	SCB_LUN, SCB_XFERLEN_ODD jnz mesgin_done;
 	mvi	IGN_WIDE_RES call set_seqint;
 	jmp	mesgin_done;
 }
@@ -1716,7 +1712,7 @@
 	}
 	test	SCB_CONTROL, TAG_ENB jnz await_busfree;
 	mov	ARG_1, SCB_TAG;
-	mov	SAVED_LUN, SCB_LUN;
+	and	SAVED_LUN, LID, SCB_LUN;
 	mov	SCB_SCSIID	call set_busy_target;
 	jmp	await_busfree;
 
@@ -1859,7 +1855,7 @@
 		 * at a time.  So, if the lun doesn't match, look
 		 * for a tag message.
 		 */
-		mov	A, SCB_LUN;
+		and	A, LID, SCB_LUN;
 		cmp	SAVED_LUN, A	je setup_SCB_id_lun_okay;
 		if ((ahc->flags & AHC_PAGESCBS) != 0) {
 			/*
@@ -1917,7 +1913,7 @@
 		or	SEQ_FLAGS, 0x8;
 	}
 setup_SCB_id_okay:
-	mov	A, SCB_LUN;
+	and	A, LID, SCB_LUN;
 	cmp	SAVED_LUN, A	jne not_found_cleanup_scb;
 setup_SCB_id_lun_okay:
 	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c	Wed Apr  9 12:01:02 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c	Fri May 23 10:58:24 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#128 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#131 $
  *
  * $FreeBSD$
  */
@@ -202,7 +202,7 @@
 					    struct ahc_devinfo *devinfo,
 					    cam_status status, char *message,
 					    int verbose_level);
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 static void		ahc_setup_target_msgin(struct ahc_softc *ahc,
 					       struct ahc_devinfo *devinfo,
 					       struct scb *scb);
@@ -291,7 +291,7 @@
 			 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
 	}
 	ahc_outb(ahc, MWI_RESIDUAL, 0);
-	ahc_outb(ahc, SEQCTL, FASTMODE);
+	ahc_outb(ahc, SEQCTL, ahc->seqctl);
 	ahc_outb(ahc, SEQADDR0, 0);
 	ahc_outb(ahc, SEQADDR1, 0);
 	ahc_unpause(ahc);
@@ -705,7 +705,7 @@
 					ahc->msgin_index = 0;
 				}
 			}
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 			else {
 				if (bus_phase == P_MESGOUT) {
 					ahc->msg_type =
@@ -1467,7 +1467,7 @@
 			else
 				ahc_outb(ahc, SIMODE1, 0);
 			ahc_outb(ahc, CLRINT, CLRSCSIINT);
-			ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) | STEP);
+			ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP);
 			stepping = TRUE;
 		}
 		if ((ahc->features & AHC_DT) != 0) {
@@ -1481,7 +1481,7 @@
 	if (stepping) {
 		ahc_outb(ahc, SIMODE0, simode0);
 		ahc_outb(ahc, SIMODE1, simode1);
-		ahc_outb(ahc, SEQCTL, ahc_inb(ahc, SEQCTL) & ~STEP);
+		ahc_outb(ahc, SEQCTL, ahc->seqctl);
 	}
 }
 
@@ -3573,7 +3573,7 @@
 
 		sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
 		if ((sgptr & SG_LIST_NULL) != 0
-		 && ahc_inb(ahc, DATA_COUNT_ODD) == 1) {
+		 && (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) {
 			/*
 			 * If the residual occurred on the last
 			 * transfer and the transfer request was
@@ -3586,25 +3586,27 @@
 			uint32_t data_addr;
 			uint32_t sglen;
 
-			/* Pull in the rest of the sgptr */
-			sgptr |= (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
-			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
-			      | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8);
-			sgptr &= SG_PTR_MASK;
-			data_cnt = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+3) << 24)
-				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+2) << 16)
-				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT+1) << 8)
-				 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT));
-
-			data_addr = (ahc_inb(ahc, SHADDR + 3) << 24)
-				  | (ahc_inb(ahc, SHADDR + 2) << 16)
-				  | (ahc_inb(ahc, SHADDR + 1) << 8)
-				  | (ahc_inb(ahc, SHADDR));
+			/* Pull in all of the sgptr */
+			sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR);
+			data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT);
+
+			if ((sgptr & SG_LIST_NULL) != 0) {
+				/*
+				 * The residual data count is not updated
+				 * for the command run to completion case.
+				 * Explicitly zero the count.
+				 */
+				data_cnt &= ~AHC_SG_LEN_MASK;
+			}
+
+			data_addr = ahc_inl(ahc, SHADDR);
 
 			data_cnt += 1;
 			data_addr -= 1;
+			sgptr &= SG_PTR_MASK;
 
 			sg = ahc_sg_bus_to_virt(scb, sgptr);
+
 			/*
 			 * The residual sg ptr points to the next S/G
 			 * to load so we must go back one.
@@ -3630,19 +3632,17 @@
 				 */
 				sg++;
 				sgptr = ahc_sg_virt_to_bus(scb, sg);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 3,
-					 sgptr >> 24);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 2,
-					 sgptr >> 16);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR + 1,
-					 sgptr >> 8);
-				ahc_outb(ahc, SCB_RESIDUAL_SGPTR, sgptr);
 			}
-
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 3, data_cnt >> 24);
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 2, data_cnt >> 16);
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT + 1, data_cnt >> 8);
-			ahc_outb(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
+			ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr);
+			ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
+			/*
+			 * Toggle the "oddness" of the transfer length
+			 * to handle this mid-transfer ignore wide
+			 * residue.  This ensures that the oddness is
+			 * correct for subsequent data transfers.
+			 */
+			ahc_outb(ahc, SCB_LUN,
+				 ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD);
 		}
 	}
 }
@@ -3826,6 +3826,12 @@
 	ahc->features = AHC_FENONE;
 	ahc->bugs = AHC_BUGNONE;
 	ahc->flags = AHC_FNONE;
+	/*
+	 * Default to all error reporting enabled with the
+	 * sequencer operating at its fastest speed.
+	 * The bus attach code may modify this.
+	 */
+	ahc->seqctl = FASTMODE;
 
 	for (i = 0; i < AHC_NUM_TARGETS; i++)
 		TAILQ_INIT(&ahc->untagged_queues[i]);
@@ -3986,7 +3992,7 @@
 
 		tstate = ahc->enabled_targets[i];
 		if (tstate != NULL) {
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 			int j;
 
 			for (j = 0; j < AHC_NUM_LUNS; j++) {
@@ -4002,7 +4008,7 @@
 			free(tstate, M_DEVBUF);
 		}
 	}
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 	if (ahc->black_hole != NULL) {
 		xpt_free_path(ahc->black_hole->path);
 		free(ahc->black_hole, M_DEVBUF);
@@ -5120,7 +5126,7 @@
 		return (EBUSY);
 	}
 
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 	/*
 	 * XXX What about ATIOs that have not yet been serviced?
 	 * Perhaps we should just refuse to be suspended if we
@@ -5221,7 +5227,7 @@
 	if (match != 0)
 		match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
 	if (match != 0) {
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 		int group;
 
 		group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
@@ -5964,7 +5970,7 @@
 	 * before the reset occurred.
 	 */
 	ahc_run_qoutfifo(ahc);
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 	/*
 	 * XXX - In Twin mode, the tqinfifo may have commands
 	 *	 for an unaffected channel in it.  However, if
@@ -5996,7 +6002,7 @@
 		 */
 		ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
 		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 		/*
 		 * Bus resets clear ENSELI, so we cannot
 		 * defer re-enabling bus reset interrupts
@@ -6015,7 +6021,7 @@
 	} else {
 		/* Case 2: A command from this bus is active or we're idle */
 		simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
-#if AHC_TARGET_MODE
+#ifdef AHC_TARGET_MODE
 		/*
 		 * Bus resets clear ENSELI, so we cannot
 		 * defer re-enabling bus reset interrupts
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_inline.h b/drivers/scsi/aic7xxx/aic7xxx_inline.h
--- a/drivers/scsi/aic7xxx/aic7xxx_inline.h	Thu May  1 10:06:05 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_inline.h	Fri May 23 10:40:47 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#42 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#43 $
  *
  * $FreeBSD$
  */
@@ -453,6 +453,13 @@
 	 || scb->hscb->next == SCB_LIST_NULL)
 		panic("Attempt to queue invalid SCB tag %x:%x\n",
 		      scb->hscb->tag, scb->hscb->next);
+
+	/*
+	 * Setup data "oddness".
+	 */
+	scb->hscb->lun &= LID;
+	if (ahc_get_transfer_length(scb) & 0x1)
+		scb->hscb->lun |= SCB_XFERLEN_ODD;
 
 	/*
 	 * Keep a history of SCBs we've downloaded in the qinfifo.
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c	Thu May 22 09:44:33 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c	Fri May 23 12:29:22 2003
@@ -1,7 +1,7 @@
 /*
  * Adaptec AIC7xxx device driver for Linux.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#221 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#232 $
  *
  * Copyright (c) 1994 John Aycock
  *   The University of Calgary Department of Computer Science.
@@ -141,11 +141,6 @@
 #include <linux/mm.h>		/* For fetching system memory size */
 #include <linux/blk.h>		/* For block_size() */
 
-#define __KERNEL_SYSCALLS__
- 
-#include <linux/unistd.h>
-static int errno;
-
 /*
  * Lock protecting manipulation of the ahc softc list.
  */
@@ -746,31 +741,11 @@
 	consumed = 1;
 	sg->addr = ahc_htole32(addr & 0xFFFFFFFF);
 	scb->platform_data->xfer_len += len;
+
 	if (sizeof(bus_addr_t) > 4
-	 && (ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
-		/*
-		 * Due to DAC restrictions, we can't
-		 * cross a 4GB boundary.
-		 */
-		if ((addr ^ (addr + len - 1)) & ~0xFFFFFFFF) {
-			struct	 ahc_dma_seg *next_sg;
-			uint32_t next_len;
-
-			printf("Crossed Seg\n");
-			if ((scb->sg_count + 2) > AHC_NSEG)
-				panic("Too few segs for dma mapping.  "
-				      "Increase AHC_NSEG\n");
-
-			consumed++;
-			next_sg = sg + 1;
-			next_sg->addr = 0;
-			next_len = 0x100000000 - (addr & 0xFFFFFFFF);
-			len -= next_len;
-			next_len |= ((addr >> 8) + 0x1000000) & 0x7F000000;
-			next_sg->len = ahc_htole32(next_len);
-		}
-		len |= (addr >> 8) & 0x7F000000;
-	}
+	 && (ahc->flags & AHC_39BIT_ADDRESSING) != 0)
+		len |= (addr >> 8) & AHC_SG_HIGH_ADDR_MASK;
+
 	sg->len = ahc_htole32(len);
 	return (consumed);
 }
@@ -1195,10 +1170,10 @@
 }
 #endif
 
+#if defined(__i386__)
 /*
  * Return the disk geometry for the given SCSI device.
  */
-#if defined(__i386__)
 static int
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
@@ -1747,7 +1722,7 @@
 	struct	 Scsi_Host *host;
 	char	*new_name;
 	u_long	 s;
-	u_int	 target;
+	u_int	 targ_offset;
 
 	template->name = ahc->description;
 	host = scsi_register(template, sizeof(struct ahc_softc *));
@@ -1802,14 +1777,19 @@
 	 * negotiation will occur for the first command, and DV
 	 * will comence should that first command be successful.
 	 */
-	for (target = 0;
-	     target < host->max_id * (host->max_channel + 1); target++) {
+	for (targ_offset = 0;
+	     targ_offset < host->max_id * (host->max_channel + 1);
+	     targ_offset++) {
 		u_int channel;
+		u_int target;
 
 		channel = 0;
+		target = targ_offset;
 		if (target > 7
-		 && (ahc->features & AHC_TWIN) != 0)
+		 && (ahc->features & AHC_TWIN) != 0) {
 			channel = 1;
+			target &= 0x7;
+		}
 		/*
 		 * Skip our own ID.  Some Compaq/HP storage devices
 		 * have enclosure management devices that respond to
@@ -2443,8 +2423,10 @@
 		ahc_unlock(ahc, &s);
 		return;
 	}
-	ahc_compile_devinfo(&devinfo, ahc->our_id, targ->target, /*lun*/0,
-			    targ->channel + 'A', ROLE_INITIATOR);
+	ahc_compile_devinfo(&devinfo,
+			    targ->channel == 0 ? ahc->our_id : ahc->our_id_b,
+			    targ->target, /*lun*/0, targ->channel + 'A',
+			    ROLE_INITIATOR);
 #ifdef AHC_DEBUG
 	if (ahc_debug & AHC_SHOW_DV) {
 		ahc_print_devinfo(ahc, &devinfo);
@@ -2616,14 +2598,11 @@
 			struct ahc_devinfo *devinfo,
 			struct ahc_linux_target *targ)
 {
-	cam_status cam_status;
 	u_int32_t status;
-	u_int scsi_status;
-
-	scsi_status = ahc_cmd_get_scsi_status(cmd);
-	cam_status = ahc_cmd_get_transaction_status(cmd);
-	status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status);
 
+	status = aic_error_action(cmd, targ->inq_data,
+				  ahc_cmd_get_transaction_status(cmd),
+				  ahc_cmd_get_scsi_status(cmd));
 	
 #ifdef AHC_DEBUG
 	if (ahc_debug & AHC_SHOW_DV) {
@@ -3777,7 +3756,7 @@
 
 			cur_seg = (struct scatterlist *)cmd->request_buffer;
 			nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
-				 scsi_to_pci_dma_dir(cmd ->sc_data_direction));
+			    scsi_to_pci_dma_dir(cmd->sc_data_direction));
 			end_seg = cur_seg + nseg;
 			/* Copy the segments into the SG list. */
 			sg = scb->sg_list;
@@ -3881,7 +3860,7 @@
 /*
  * SCSI controller interrupt handler.
  */
-AIC_LINUX_IRQRETURN_T
+irqreturn_t
 ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct	ahc_softc *ahc;
@@ -3895,7 +3874,7 @@
 		ahc_schedule_runq(ahc);
 	ahc_linux_run_complete_queue(ahc);
 	ahc_unlock(ahc, &flags);
-	AIC_LINUX_IRQRETURN(ours);
+	return IRQ_RETVAL(ours);
 }
 
 void
@@ -4910,7 +4889,7 @@
 			disconnected = FALSE;
 		else if (flag != SCB_ABORT
 		      && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
-		      && ahc_inb(ahc, SAVED_LUN) == pending_scb->hscb->lun)
+		      && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
 			disconnected = FALSE;
 	}
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h	Mon May 12 20:52:59 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h	Mon May 26 19:01:56 2003
@@ -53,7 +53,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#142 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#147 $
  *
  */
 #ifndef _AIC7XXX_LINUX_H_
@@ -305,7 +305,7 @@
 #define AHC_SCSI_HAS_HOST_LOCK 0
 #endif
 
-#define AIC7XXX_DRIVER_VERSION "6.2.33"
+#define AIC7XXX_DRIVER_VERSION "6.2.35"
 
 /**************************** Front End Queues ********************************/
 /*
@@ -963,7 +963,7 @@
 	(((dev_softc)->dma_mask = mask) && 0)
 #endif
 /**************************** Proc FS Support *********************************/
-int	ahc_linux_proc_info(char *, char **, off_t, int, int, int);
+int	ahc_linux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 
 /*************************** Domain Validation ********************************/
 #define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete)
@@ -1165,7 +1165,7 @@
 int	ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
 				char channel, int lun, u_int tag,
 				role_t role, uint32_t status);
-AIC_LINUX_IRQRETURN_T
+irqreturn_t
 	ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
 void	ahc_platform_flushwork(struct ahc_softc *ahc);
 int	ahc_softc_comp(struct ahc_softc *, struct ahc_softc *);
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	Mon Mar 10 16:57:17 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	Wed May 14 15:00:40 2003
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#44 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#45 $
  */
 
 #include "aic7xxx_osm.h"
@@ -110,6 +110,7 @@
 ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	char		 buf[80];
+	bus_addr_t	 mask_39bit;
 	struct		 ahc_softc *ahc;
 	ahc_dev_softc_t	 pci;
 	struct		 ahc_pci_identity *entry;
@@ -160,12 +161,12 @@
 	}
 	pci_set_master(pdev);
 
+	mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
 	if (sizeof(bus_addr_t) > 4
 	 && ahc_linux_get_memsize() > 0x80000000
-	 && ahc_pci_set_dma_mask(pdev, 0x7FFFFFFFFFULL) == 0) {
+	 && ahc_pci_set_dma_mask(pdev, mask_39bit) == 0) {
 		ahc->flags |= AHC_39BIT_ADDRESSING;
-		ahc->platform_data->hw_dma_mask =
-		    (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
+		ahc->platform_data->hw_dma_mask = mask_39bit;
 	} else {
 		ahc_pci_set_dma_mask(pdev, 0xFFFFFFFF);
 		ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c	Mon May 12 20:53:00 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c	Fri May 23 10:31:47 2003
@@ -39,7 +39,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#63 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#66 $
  *
  * $FreeBSD$
  */
@@ -834,10 +834,10 @@
 	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
 
 	/* Ensure busmastering is enabled */
-	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
+	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
 	command |= PCIM_CMD_BUSMASTEREN;
 
-	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
+	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
 
 	/* On all PCI adapters, we allow SCB paging */
 	ahc->flags |= AHC_PAGESCBS;
@@ -854,10 +854,8 @@
 	 * error reporting when doing this, so CIO bus, scb ram, and
 	 * scratch ram parity errors will be ignored too.
 	 */
-	if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) {
-		ahc->pause |= FAILDIS;
-		ahc->unpause |= FAILDIS;
-	}
+	if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
+		ahc->seqctl |= FAILDIS;
 
 	ahc->bus_intr = ahc_pci_intr;
 	ahc->bus_chip_init = ahc_pci_chip_init;
@@ -2044,8 +2042,8 @@
 "%s: WARNING WARNING WARNING WARNING\n",
 		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),
 		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));
-		ahc->pause |= FAILDIS;
-		ahc->unpause |= FAILDIS;
+		ahc->seqctl |= FAILDIS;
+		ahc_outb(ahc, SEQCTL, ahc->seqctl);
 	}
 	ahc_unpause(ahc);
 }
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c
--- a/drivers/scsi/aic7xxx/aic7xxx_proc.c	Thu Apr 24 14:10:07 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c	Mon May 12 08:30:15 2003
@@ -289,8 +289,8 @@
  * Return information to handle /proc support for the driver.
  */
 int
-ahc_linux_proc_info(char *buffer, char **start, off_t offset,
-		  int length, int hostno, int inout)
+ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
+		  int length, int inout)
 {
 	struct	ahc_softc *ahc;
 	struct	info_str info;
@@ -303,7 +303,7 @@
 	retval = -EINVAL;
 	ahc_list_lock(&s);
 	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-		if (ahc->platform_data->host->host_no == hostno)
+		if (ahc->platform_data->host == shost)
 			break;
 	}
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped
--- a/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped	Fri Feb 21 15:50:42 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped	Fri May 23 10:50:58 2003
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
  */
 typedef int (ahc_reg_print_t)(u_int, u_int *, u_int);
 typedef struct ahc_reg_parse_entry {
@@ -433,13 +433,6 @@
 #endif
 
 #if AIC_DEBUG_REGISTERS
-ahc_reg_print_t ahc_data_count_odd_print;
-#else
-#define ahc_data_count_odd_print(regvalue, cur_col, wrap) \
-    ahc_print_register(NULL, 0, "DATA_COUNT_ODD", 0x55, regvalue, cur_col, wrap)
-#endif
-
-#if AIC_DEBUG_REGISTERS
 ahc_reg_print_t ahc_ha_274_biosglobal_print;
 #else
 #define ahc_ha_274_biosglobal_print(regvalue, cur_col, wrap) \
@@ -1396,8 +1389,6 @@
 #define		ENAUTOATNI      	0x04
 #define		ENAUTOATNP      	0x02
 
-#define	DATA_COUNT_ODD  		0x55
-
 #define	HA_274_BIOSGLOBAL		0x56
 #define	INITIATOR_TAG   		0x56
 #define		HA_274_EXTENDED_TRANS	0x01
@@ -1655,7 +1646,8 @@
 #define		TWIN_CHNLB      	0x80
 
 #define	SCB_LUN         		0xba
-#define		LID             	0xff
+#define		LID             	0x3f
+#define		SCB_XFERLEN_ODD 	0x80
 
 #define	SCB_TAG         		0xbb
 
@@ -1749,7 +1741,6 @@
 
 #define	SG_CACHE_SHADOW 		0xfc
 #define		SG_ADDR_MASK    	0xf8
-#define		ODD_SEG         	0x04
 #define		LAST_SEG        	0x02
 #define		LAST_SEG_DONE   	0x01
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
--- a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped	Fri Feb 21 15:50:42 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped	Fri May 23 10:50:58 2003
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
  */
 static uint8_t seqprog[] = {
 	0xb2, 0x00, 0x00, 0x08,
@@ -21,15 +21,15 @@
 	0x01, 0x4d, 0xc8, 0x30,
 	0x00, 0x4c, 0x12, 0x70,
 	0x01, 0x39, 0xa2, 0x30,
-	0x00, 0x6a, 0xd4, 0x5e,
+	0x00, 0x6a, 0xc0, 0x5e,
 	0x01, 0x51, 0x20, 0x31,
 	0x01, 0x57, 0xae, 0x00,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x51, 0x26, 0x5e,
+	0x00, 0x51, 0x12, 0x5e,
 	0x01, 0x51, 0xc8, 0x30,
 	0x00, 0x39, 0xc8, 0x60,
 	0x00, 0xbb, 0x30, 0x70,
-	0xc1, 0x6a, 0xec, 0x5e,
+	0xc1, 0x6a, 0xd8, 0x5e,
 	0x01, 0xbf, 0x72, 0x30,
 	0x01, 0x40, 0x7e, 0x31,
 	0x01, 0x90, 0x80, 0x30,
@@ -49,10 +49,10 @@
 	0x08, 0x6a, 0x78, 0x00,
 	0x01, 0x50, 0xc8, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x10, 0x5e,
+	0x48, 0x6a, 0xfc, 0x5d,
 	0x01, 0x6a, 0xdc, 0x01,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x10, 0x5e,
+	0x48, 0x6a, 0xfc, 0x5d,
 	0x01, 0x6a, 0x26, 0x01,
 	0xf0, 0x19, 0x7a, 0x08,
 	0x0f, 0x18, 0xc8, 0x08,
@@ -93,7 +93,7 @@
 	0x00, 0x65, 0x20, 0x41,
 	0x02, 0x57, 0xae, 0x00,
 	0x00, 0x65, 0x9e, 0x40,
-	0x61, 0x6a, 0xec, 0x5e,
+	0x61, 0x6a, 0xd8, 0x5e,
 	0x08, 0x51, 0x20, 0x71,
 	0x02, 0x0b, 0xb2, 0x78,
 	0x00, 0x65, 0xae, 0x40,
@@ -106,7 +106,7 @@
 	0x80, 0x3d, 0x7a, 0x00,
 	0x20, 0x6a, 0x16, 0x00,
 	0x00, 0x65, 0xcc, 0x41,
-	0x00, 0x65, 0xc6, 0x5e,
+	0x00, 0x65, 0xb2, 0x5e,
 	0x00, 0x65, 0x12, 0x40,
 	0x20, 0x11, 0xd2, 0x68,
 	0x20, 0x6a, 0x18, 0x00,
@@ -135,20 +135,20 @@
 	0x01, 0x40, 0x20, 0x31,
 	0x01, 0xbf, 0x80, 0x30,
 	0x01, 0xb9, 0x7a, 0x30,
-	0x01, 0xba, 0x7c, 0x30,
+	0x3f, 0xba, 0x7c, 0x08,
 	0x00, 0x65, 0xea, 0x58,
 	0x80, 0x0b, 0xc4, 0x79,
 	0x12, 0x01, 0x02, 0x00,
 	0x01, 0xab, 0xac, 0x30,
-	0xe4, 0x6a, 0x82, 0x5d,
+	0xe4, 0x6a, 0x6e, 0x5d,
 	0x40, 0x6a, 0x16, 0x00,
-	0x80, 0xba, 0x98, 0x5d,
+	0x80, 0x3e, 0x84, 0x5d,
 	0x20, 0xb8, 0x18, 0x79,
-	0x20, 0x6a, 0x98, 0x5d,
-	0x00, 0xab, 0x98, 0x5d,
+	0x20, 0x6a, 0x84, 0x5d,
+	0x00, 0xab, 0x84, 0x5d,
 	0x01, 0xa9, 0x78, 0x30,
 	0x10, 0xb8, 0x20, 0x79,
-	0xe4, 0x6a, 0x82, 0x5d,
+	0xe4, 0x6a, 0x6e, 0x5d,
 	0x00, 0x65, 0xae, 0x40,
 	0x10, 0x03, 0x3c, 0x69,
 	0x08, 0x3c, 0x5a, 0x69,
@@ -157,10 +157,10 @@
 	0x01, 0x3c, 0x44, 0x79,
 	0xff, 0x6a, 0x70, 0x00,
 	0x00, 0x65, 0xa4, 0x59,
-	0x00, 0x6a, 0xd4, 0x5e,
+	0x00, 0x6a, 0xc0, 0x5e,
 	0xff, 0x38, 0x30, 0x71,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x38, 0x26, 0x5e,
+	0x00, 0x38, 0x12, 0x5e,
 	0x00, 0x65, 0xea, 0x58,
 	0x12, 0x01, 0x02, 0x00,
 	0x00, 0x65, 0x18, 0x41,
@@ -168,10 +168,10 @@
 	0x00, 0x65, 0xf2, 0x58,
 	0xfd, 0x57, 0xae, 0x08,
 	0x00, 0x65, 0xae, 0x40,
-	0xe4, 0x6a, 0x82, 0x5d,
+	0xe4, 0x6a, 0x6e, 0x5d,
 	0x20, 0x3c, 0x4a, 0x79,
-	0x02, 0x6a, 0x98, 0x5d,
-	0x04, 0x6a, 0x98, 0x5d,
+	0x02, 0x6a, 0x84, 0x5d,
+	0x04, 0x6a, 0x84, 0x5d,
 	0x01, 0x03, 0x4c, 0x69,
 	0xf7, 0x11, 0x22, 0x08,
 	0xff, 0x6a, 0x24, 0x08,
@@ -182,13 +182,13 @@
 	0x80, 0x86, 0xc8, 0x08,
 	0x01, 0x4f, 0xc8, 0x30,
 	0x00, 0x50, 0x6c, 0x61,
-	0xc4, 0x6a, 0x82, 0x5d,
+	0xc4, 0x6a, 0x6e, 0x5d,
 	0x40, 0x3c, 0x68, 0x79,
-	0x28, 0x6a, 0x98, 0x5d,
+	0x28, 0x6a, 0x84, 0x5d,
 	0x00, 0x65, 0x4c, 0x41,
-	0x08, 0x6a, 0x98, 0x5d,
+	0x08, 0x6a, 0x84, 0x5d,
 	0x00, 0x65, 0x4c, 0x41,
-	0x84, 0x6a, 0x82, 0x5d,
+	0x84, 0x6a, 0x6e, 0x5d,
 	0x00, 0x65, 0xf2, 0x58,
 	0x01, 0x66, 0xc8, 0x30,
 	0x01, 0x64, 0xd8, 0x31,
@@ -208,16 +208,16 @@
 	0xf7, 0x3c, 0x78, 0x08,
 	0x00, 0x65, 0x20, 0x41,
 	0x40, 0xaa, 0x7e, 0x10,
-	0x04, 0xaa, 0x82, 0x5d,
-	0x00, 0x65, 0x5e, 0x42,
-	0xc4, 0x6a, 0x82, 0x5d,
+	0x04, 0xaa, 0x6e, 0x5d,
+	0x00, 0x65, 0x56, 0x42,
+	0xc4, 0x6a, 0x6e, 0x5d,
 	0xc0, 0x6a, 0x7e, 0x00,
-	0x00, 0xa8, 0x98, 0x5d,
+	0x00, 0xa8, 0x84, 0x5d,
 	0xe4, 0x6a, 0x06, 0x00,
-	0x00, 0x6a, 0x98, 0x5d,
+	0x00, 0x6a, 0x84, 0x5d,
 	0x00, 0x65, 0x4c, 0x41,
 	0x10, 0x3c, 0xa8, 0x69,
-	0x00, 0xbb, 0x9e, 0x44,
+	0x00, 0xbb, 0x8a, 0x44,
 	0x18, 0x6a, 0xda, 0x01,
 	0x01, 0x69, 0xd8, 0x31,
 	0x1c, 0x6a, 0xd0, 0x01,
@@ -227,23 +227,23 @@
 	0x01, 0x93, 0x26, 0x01,
 	0x03, 0x6a, 0x2a, 0x01,
 	0x01, 0x69, 0x32, 0x31,
-	0x1c, 0x6a, 0xf4, 0x5d,
+	0x1c, 0x6a, 0xe0, 0x5d,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xbc, 0x5e,
+	0x00, 0x65, 0xa8, 0x5e,
 	0x01, 0x50, 0xa0, 0x18,
 	0x02, 0x6a, 0x22, 0x05,
 	0x1a, 0x01, 0x02, 0x00,
 	0x80, 0x6a, 0x74, 0x00,
 	0x40, 0x6a, 0x78, 0x00,
 	0x40, 0x6a, 0x16, 0x00,
-	0x00, 0x65, 0xec, 0x5d,
+	0x00, 0x65, 0xd8, 0x5d,
 	0x01, 0x3f, 0xc8, 0x30,
-	0xbf, 0x64, 0x5e, 0x7a,
-	0x80, 0x64, 0xb2, 0x73,
-	0xa0, 0x64, 0x14, 0x74,
-	0xc0, 0x64, 0x08, 0x74,
-	0xe0, 0x64, 0x44, 0x74,
-	0x01, 0x6a, 0xec, 0x5e,
+	0xbf, 0x64, 0x56, 0x7a,
+	0x80, 0x64, 0x9e, 0x73,
+	0xa0, 0x64, 0x00, 0x74,
+	0xc0, 0x64, 0xf4, 0x73,
+	0xe0, 0x64, 0x30, 0x74,
+	0x01, 0x6a, 0xd8, 0x5e,
 	0x00, 0x65, 0xcc, 0x41,
 	0xf7, 0x11, 0x22, 0x08,
 	0x01, 0x06, 0xd4, 0x30,
@@ -251,7 +251,7 @@
 	0xf7, 0x01, 0x02, 0x08,
 	0x09, 0x0c, 0xe6, 0x79,
 	0x08, 0x0c, 0x04, 0x68,
-	0xb1, 0x6a, 0xec, 0x5e,
+	0xb1, 0x6a, 0xd8, 0x5e,
 	0xff, 0x6a, 0x26, 0x09,
 	0x12, 0x01, 0x02, 0x00,
 	0x02, 0x6a, 0x08, 0x30,
@@ -264,33 +264,29 @@
 	0x00, 0xa5, 0x4a, 0x21,
 	0x00, 0xa6, 0x4c, 0x21,
 	0x00, 0xa7, 0x4e, 0x25,
-	0x08, 0xeb, 0xf0, 0x7e,
+	0x08, 0xeb, 0xdc, 0x7e,
 	0x80, 0xeb, 0x06, 0x7a,
 	0xff, 0x6a, 0xd6, 0x09,
 	0x08, 0xeb, 0x0a, 0x6a,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x80, 0xa3, 0xf0, 0x6e,
+	0x80, 0xa3, 0xdc, 0x6e,
 	0x88, 0xeb, 0x20, 0x72,
-	0x08, 0xeb, 0xf0, 0x6e,
+	0x08, 0xeb, 0xdc, 0x6e,
 	0x04, 0xea, 0x24, 0xe2,
-	0x08, 0xee, 0xf0, 0x6e,
+	0x08, 0xee, 0xdc, 0x6e,
 	0x04, 0x6a, 0xd0, 0x81,
 	0x05, 0xa4, 0xc0, 0x89,
 	0x03, 0xa5, 0xc2, 0x31,
 	0x09, 0x6a, 0xd6, 0x05,
 	0x00, 0x65, 0x08, 0x5a,
 	0x06, 0xa4, 0xd4, 0x89,
-	0x80, 0x94, 0xf0, 0x7e,
+	0x80, 0x94, 0xdc, 0x7e,
 	0x07, 0xe9, 0x10, 0x31,
-	0x01, 0x8c, 0x2c, 0x7a,
-	0x01, 0x55, 0xaa, 0x10,
 	0x01, 0xe9, 0x46, 0x31,
-	0x00, 0xa3, 0xce, 0x5e,
+	0x00, 0xa3, 0xba, 0x5e,
 	0x00, 0x65, 0xfa, 0x59,
 	0x01, 0xa4, 0xca, 0x30,
-	0x01, 0x55, 0x38, 0x7a,
-	0x04, 0x65, 0xca, 0x00,
-	0x80, 0xa3, 0x3c, 0x7a,
+	0x80, 0xa3, 0x34, 0x7a,
 	0x02, 0x65, 0xca, 0x00,
 	0x01, 0x65, 0xf8, 0x31,
 	0x80, 0x93, 0x26, 0x01,
@@ -298,168 +294,162 @@
 	0x01, 0x8c, 0xc8, 0x30,
 	0x00, 0x88, 0xc8, 0x18,
 	0x02, 0x64, 0xc8, 0x88,
-	0xff, 0x64, 0xf0, 0x7e,
-	0xff, 0x8d, 0x52, 0x6a,
-	0xff, 0x8e, 0x52, 0x6a,
+	0xff, 0x64, 0xdc, 0x7e,
+	0xff, 0x8d, 0x4a, 0x6a,
+	0xff, 0x8e, 0x4a, 0x6a,
 	0x03, 0x8c, 0xd4, 0x98,
-	0x00, 0x65, 0xf0, 0x56,
+	0x00, 0x65, 0xdc, 0x56,
 	0x01, 0x64, 0x70, 0x30,
 	0xff, 0x64, 0xc8, 0x10,
 	0x01, 0x64, 0xc8, 0x18,
 	0x00, 0x8c, 0x18, 0x19,
 	0xff, 0x8d, 0x1a, 0x21,
 	0xff, 0x8e, 0x1c, 0x25,
-	0xc0, 0x3c, 0x62, 0x7a,
-	0x21, 0x6a, 0xec, 0x5e,
+	0xc0, 0x3c, 0x5a, 0x7a,
+	0x21, 0x6a, 0xd8, 0x5e,
 	0xa8, 0x6a, 0x76, 0x00,
 	0x79, 0x6a, 0x76, 0x00,
-	0x40, 0x3f, 0x6a, 0x6a,
+	0x40, 0x3f, 0x62, 0x6a,
 	0x04, 0x3b, 0x76, 0x00,
 	0x04, 0x6a, 0xd4, 0x81,
-	0x20, 0x3c, 0x72, 0x7a,
-	0x51, 0x6a, 0xec, 0x5e,
-	0x00, 0x65, 0x8c, 0x42,
+	0x20, 0x3c, 0x6a, 0x7a,
+	0x51, 0x6a, 0xd8, 0x5e,
+	0x00, 0x65, 0x82, 0x42,
 	0x20, 0x3c, 0x78, 0x00,
-	0x00, 0xb3, 0xce, 0x5e,
+	0x00, 0xb3, 0xba, 0x5e,
 	0x07, 0xac, 0x10, 0x31,
 	0x05, 0xb3, 0x46, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xac, 0x6a, 0x02, 0x5e,
+	0xac, 0x6a, 0xee, 0x5d,
 	0xa3, 0x6a, 0xcc, 0x00,
-	0xb3, 0x6a, 0x06, 0x5e,
-	0x00, 0x65, 0x42, 0x5a,
+	0xb3, 0x6a, 0xf2, 0x5d,
+	0x00, 0x65, 0x3a, 0x5a,
 	0xfd, 0xa4, 0x48, 0x09,
-	0x01, 0x8c, 0xaa, 0x08,
 	0x03, 0x8c, 0x10, 0x30,
-	0x00, 0x65, 0xfa, 0x5d,
-	0x01, 0xa4, 0x9e, 0x7a,
+	0x00, 0x65, 0xe6, 0x5d,
+	0x01, 0xa4, 0x94, 0x7a,
 	0x04, 0x3b, 0x76, 0x08,
 	0x01, 0x3b, 0x26, 0x31,
 	0x80, 0x02, 0x04, 0x00,
-	0x10, 0x0c, 0x94, 0x7a,
-	0x03, 0x9e, 0x96, 0x6a,
+	0x10, 0x0c, 0x8a, 0x7a,
+	0x03, 0x9e, 0x8c, 0x6a,
 	0x7f, 0x02, 0x04, 0x08,
-	0x91, 0x6a, 0xec, 0x5e,
+	0x91, 0x6a, 0xd8, 0x5e,
 	0x00, 0x65, 0xcc, 0x41,
 	0x01, 0xa4, 0xca, 0x30,
-	0x80, 0xa3, 0xa4, 0x7a,
+	0x80, 0xa3, 0x9a, 0x7a,
 	0x02, 0x65, 0xca, 0x00,
-	0x01, 0x55, 0xa8, 0x7a,
-	0x04, 0x65, 0xca, 0x00,
 	0x01, 0x65, 0xf8, 0x31,
 	0x01, 0x3b, 0x26, 0x31,
 	0x00, 0x65, 0x0e, 0x5a,
-	0x01, 0xfc, 0xb6, 0x6a,
-	0x80, 0x0b, 0xac, 0x6a,
-	0x10, 0x0c, 0xac, 0x7a,
-	0x20, 0x93, 0xac, 0x6a,
+	0x01, 0xfc, 0xa8, 0x6a,
+	0x80, 0x0b, 0x9e, 0x6a,
+	0x10, 0x0c, 0x9e, 0x7a,
+	0x20, 0x93, 0x9e, 0x6a,
 	0x02, 0x93, 0x26, 0x01,
-	0x02, 0xfc, 0xc0, 0x7a,
-	0x40, 0x0d, 0xda, 0x6a,
-	0x01, 0xa4, 0x48, 0x01,
-	0x00, 0x65, 0xda, 0x42,
+	0x02, 0xfc, 0xb2, 0x7a,
 	0x40, 0x0d, 0xc6, 0x6a,
+	0x01, 0xa4, 0x48, 0x01,
+	0x00, 0x65, 0xc6, 0x42,
+	0x40, 0x0d, 0xb8, 0x6a,
 	0x00, 0x65, 0x0e, 0x5a,
-	0x00, 0x65, 0xb8, 0x42,
-	0x80, 0xfc, 0xd0, 0x7a,
-	0x80, 0xa4, 0xd0, 0x6a,
+	0x00, 0x65, 0xaa, 0x42,
+	0x80, 0xfc, 0xc2, 0x7a,
+	0x80, 0xa4, 0xc2, 0x6a,
 	0xff, 0xa5, 0x4a, 0x19,
 	0xff, 0xa6, 0x4c, 0x21,
 	0xff, 0xa7, 0x4e, 0x21,
 	0xf8, 0xfc, 0x48, 0x09,
-	0xff, 0x6a, 0xaa, 0x08,
-	0x04, 0xfc, 0xd8, 0x7a,
-	0x01, 0x55, 0xaa, 0x00,
-	0xff, 0x6a, 0x46, 0x09,
-	0x04, 0x3b, 0xf2, 0x6a,
+	0x7f, 0xa3, 0x46, 0x09,
+	0x04, 0x3b, 0xe2, 0x6a,
 	0x02, 0x93, 0x26, 0x01,
-	0x01, 0x94, 0xdc, 0x7a,
-	0x01, 0x94, 0xdc, 0x7a,
-	0x01, 0x94, 0xdc, 0x7a,
-	0x01, 0x94, 0xdc, 0x7a,
-	0x01, 0x94, 0xdc, 0x7a,
-	0x01, 0xa4, 0xf0, 0x7a,
-	0x01, 0xfc, 0xea, 0x7a,
-	0x01, 0x94, 0xf2, 0x6a,
-	0x00, 0x65, 0x8c, 0x42,
-	0x01, 0x94, 0xf0, 0x7a,
-	0x10, 0x94, 0xf2, 0x6a,
+	0x01, 0x94, 0xc8, 0x7a,
+	0x01, 0x94, 0xc8, 0x7a,
+	0x01, 0x94, 0xc8, 0x7a,
+	0x01, 0x94, 0xc8, 0x7a,
+	0x01, 0x94, 0xc8, 0x7a,
+	0x01, 0xa4, 0xe0, 0x7a,
+	0x01, 0xfc, 0xd6, 0x7a,
+	0x01, 0x94, 0xe2, 0x6a,
+	0x01, 0x94, 0xe2, 0x6a,
+	0x01, 0x94, 0xe2, 0x6a,
+	0x00, 0x65, 0x82, 0x42,
+	0x01, 0x94, 0xe0, 0x7a,
+	0x10, 0x94, 0xe2, 0x6a,
 	0xd7, 0x93, 0x26, 0x09,
-	0x28, 0x93, 0xf6, 0x6a,
+	0x28, 0x93, 0xe6, 0x6a,
 	0x01, 0x85, 0x0a, 0x01,
-	0x02, 0xfc, 0xfe, 0x6a,
+	0x02, 0xfc, 0xee, 0x6a,
 	0x01, 0x14, 0x46, 0x31,
 	0xff, 0x6a, 0x10, 0x09,
 	0xfe, 0x85, 0x0a, 0x09,
-	0xff, 0x38, 0x0c, 0x6b,
-	0x80, 0xa3, 0x0c, 0x7b,
-	0x80, 0x0b, 0x0a, 0x7b,
-	0x04, 0x3b, 0x0c, 0x7b,
+	0xff, 0x38, 0xfc, 0x6a,
+	0x80, 0xa3, 0xfc, 0x7a,
+	0x80, 0x0b, 0xfa, 0x7a,
+	0x04, 0x3b, 0xfc, 0x7a,
 	0xbf, 0x3b, 0x76, 0x08,
 	0x01, 0x3b, 0x26, 0x31,
 	0x00, 0x65, 0x0e, 0x5a,
-	0x01, 0x0b, 0x1a, 0x6b,
-	0x10, 0x0c, 0x0e, 0x7b,
-	0x04, 0x93, 0x18, 0x6b,
-	0x01, 0x94, 0x16, 0x7b,
-	0x10, 0x94, 0x18, 0x6b,
+	0x01, 0x0b, 0x0a, 0x6b,
+	0x10, 0x0c, 0xfe, 0x7a,
+	0x04, 0x93, 0x08, 0x6b,
+	0x01, 0x94, 0x06, 0x7b,
+	0x10, 0x94, 0x08, 0x6b,
 	0xc7, 0x93, 0x26, 0x09,
 	0x01, 0x99, 0xd4, 0x30,
-	0x38, 0x93, 0x1c, 0x6b,
-	0xff, 0x08, 0x6e, 0x6b,
-	0xff, 0x09, 0x6e, 0x6b,
-	0xff, 0x0a, 0x6e, 0x6b,
-	0xff, 0x38, 0x38, 0x7b,
+	0x38, 0x93, 0x0c, 0x6b,
+	0xff, 0x08, 0x5a, 0x6b,
+	0xff, 0x09, 0x5a, 0x6b,
+	0xff, 0x0a, 0x5a, 0x6b,
+	0xff, 0x38, 0x28, 0x7b,
 	0x04, 0x14, 0x10, 0x31,
 	0x01, 0x38, 0x18, 0x31,
 	0x02, 0x6a, 0x1a, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x14, 0x6a, 0x08, 0x5e,
-	0x00, 0x38, 0xf4, 0x5d,
+	0x14, 0x6a, 0xf4, 0x5d,
+	0x00, 0x38, 0xe0, 0x5d,
 	0xff, 0x6a, 0x70, 0x08,
-	0x00, 0x65, 0x64, 0x43,
-	0x80, 0xa3, 0x3e, 0x7b,
+	0x00, 0x65, 0x54, 0x43,
+	0x80, 0xa3, 0x2e, 0x7b,
 	0x01, 0xa4, 0x48, 0x01,
-	0x00, 0x65, 0x6e, 0x43,
-	0x08, 0xeb, 0x44, 0x7b,
+	0x00, 0x65, 0x5a, 0x43,
+	0x08, 0xeb, 0x34, 0x7b,
 	0x00, 0x65, 0x0e, 0x5a,
-	0x08, 0xeb, 0x40, 0x6b,
+	0x08, 0xeb, 0x30, 0x6b,
 	0x07, 0xe9, 0x10, 0x31,
 	0x01, 0xe9, 0xca, 0x30,
 	0x01, 0x65, 0x46, 0x31,
-	0x00, 0x6a, 0xce, 0x5e,
+	0x00, 0x6a, 0xba, 0x5e,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xa4, 0x6a, 0x08, 0x5e,
-	0x08, 0x6a, 0xf4, 0x5d,
+	0xa4, 0x6a, 0xf4, 0x5d,
+	0x08, 0x6a, 0xe0, 0x5d,
 	0x0d, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xbc, 0x5e,
+	0x00, 0x65, 0xa8, 0x5e,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x00, 0x65, 0x9e, 0x5e,
+	0x00, 0x65, 0x8a, 0x5e,
 	0x01, 0x99, 0x46, 0x31,
-	0x00, 0xa3, 0xce, 0x5e,
+	0x00, 0xa3, 0xba, 0x5e,
 	0x01, 0x88, 0x10, 0x31,
-	0x00, 0x65, 0x42, 0x5a,
+	0x00, 0x65, 0x3a, 0x5a,
 	0x00, 0x65, 0xfa, 0x59,
 	0x03, 0x8c, 0x10, 0x30,
-	0x00, 0x65, 0xfa, 0x5d,
-	0x01, 0x8c, 0x6c, 0x7b,
-	0x01, 0x55, 0xaa, 0x10,
-	0x80, 0x0b, 0x8c, 0x6a,
-	0x80, 0x0b, 0x76, 0x6b,
-	0x01, 0x0c, 0x70, 0x7b,
-	0x10, 0x0c, 0x8c, 0x7a,
-	0x03, 0x9e, 0x8c, 0x6a,
+	0x00, 0x65, 0xe6, 0x5d,
+	0x80, 0x0b, 0x82, 0x6a,
+	0x80, 0x0b, 0x62, 0x6b,
+	0x01, 0x0c, 0x5c, 0x7b,
+	0x10, 0x0c, 0x82, 0x7a,
+	0x03, 0x9e, 0x82, 0x6a,
 	0x00, 0x65, 0x04, 0x5a,
-	0x00, 0x6a, 0xce, 0x5e,
-	0x01, 0xa4, 0x96, 0x6b,
-	0xff, 0x38, 0x8c, 0x7b,
+	0x00, 0x6a, 0xba, 0x5e,
+	0x01, 0xa4, 0x82, 0x6b,
+	0xff, 0x38, 0x78, 0x7b,
 	0x01, 0x38, 0xc8, 0x30,
 	0x00, 0x08, 0x40, 0x19,
 	0xff, 0x6a, 0xc8, 0x08,
 	0x00, 0x09, 0x42, 0x21,
 	0x00, 0x0a, 0x44, 0x21,
 	0xff, 0x6a, 0x70, 0x08,
-	0x00, 0x65, 0x8e, 0x43,
+	0x00, 0x65, 0x7a, 0x43,
 	0x03, 0x08, 0x40, 0x31,
 	0x03, 0x08, 0x40, 0x31,
 	0x01, 0x08, 0x40, 0x31,
@@ -471,16 +461,16 @@
 	0x04, 0x3c, 0xcc, 0x79,
 	0xfb, 0x3c, 0x78, 0x08,
 	0x04, 0x93, 0x20, 0x79,
-	0x01, 0x0c, 0xa2, 0x6b,
-	0x01, 0x55, 0x20, 0x79,
+	0x01, 0x0c, 0x8e, 0x6b,
+	0x80, 0xba, 0x20, 0x79,
 	0x80, 0x04, 0x20, 0x79,
-	0xe4, 0x6a, 0x82, 0x5d,
-	0x23, 0x6a, 0x98, 0x5d,
-	0x01, 0x6a, 0x98, 0x5d,
+	0xe4, 0x6a, 0x6e, 0x5d,
+	0x23, 0x6a, 0x84, 0x5d,
+	0x01, 0x6a, 0x84, 0x5d,
 	0x00, 0x65, 0x20, 0x41,
 	0x00, 0x65, 0xcc, 0x41,
-	0x80, 0x3c, 0xb6, 0x7b,
-	0x21, 0x6a, 0xec, 0x5e,
+	0x80, 0x3c, 0xa2, 0x7b,
+	0x21, 0x6a, 0xd8, 0x5e,
 	0x01, 0xbc, 0x18, 0x31,
 	0x02, 0x6a, 0x1a, 0x31,
 	0x02, 0x6a, 0xf8, 0x01,
@@ -490,16 +480,16 @@
 	0xff, 0x6a, 0x12, 0x08,
 	0xff, 0x6a, 0x14, 0x08,
 	0xf3, 0xbc, 0xd4, 0x18,
-	0xa0, 0x6a, 0xdc, 0x53,
+	0xa0, 0x6a, 0xc8, 0x53,
 	0x04, 0xa0, 0x10, 0x31,
 	0xac, 0x6a, 0x26, 0x01,
 	0x04, 0xa0, 0x10, 0x31,
 	0x03, 0x08, 0x18, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xa0, 0x6a, 0x08, 0x5e,
-	0x00, 0xbc, 0xf4, 0x5d,
+	0xa0, 0x6a, 0xf4, 0x5d,
+	0x00, 0xbc, 0xe0, 0x5d,
 	0x3d, 0x6a, 0x26, 0x01,
-	0x00, 0x65, 0xf4, 0x43,
+	0x00, 0x65, 0xe0, 0x43,
 	0xff, 0x6a, 0x10, 0x09,
 	0xa4, 0x6a, 0x26, 0x01,
 	0x0c, 0xa0, 0x32, 0x31,
@@ -509,128 +499,128 @@
 	0x36, 0x6a, 0x26, 0x01,
 	0x02, 0x93, 0x26, 0x01,
 	0x35, 0x6a, 0x26, 0x01,
-	0x00, 0x65, 0xb0, 0x5e,
-	0x00, 0x65, 0xb0, 0x5e,
+	0x00, 0x65, 0x9c, 0x5e,
+	0x00, 0x65, 0x9c, 0x5e,
 	0x02, 0x93, 0x26, 0x01,
 	0xbf, 0x3c, 0x78, 0x08,
-	0x04, 0x0b, 0xfa, 0x6b,
-	0x10, 0x0c, 0xf6, 0x7b,
-	0x01, 0x03, 0xfa, 0x6b,
-	0x20, 0x93, 0xfc, 0x6b,
-	0x04, 0x0b, 0x02, 0x6c,
+	0x04, 0x0b, 0xe6, 0x6b,
+	0x10, 0x0c, 0xe2, 0x7b,
+	0x01, 0x03, 0xe6, 0x6b,
+	0x20, 0x93, 0xe8, 0x6b,
+	0x04, 0x0b, 0xee, 0x6b,
 	0x40, 0x3c, 0x78, 0x00,
 	0xc7, 0x93, 0x26, 0x09,
-	0x38, 0x93, 0x04, 0x6c,
+	0x38, 0x93, 0xf0, 0x6b,
 	0x00, 0x65, 0xcc, 0x41,
-	0x80, 0x3c, 0x6a, 0x6c,
+	0x80, 0x3c, 0x56, 0x6c,
 	0x01, 0x06, 0x50, 0x31,
 	0x80, 0xb8, 0x70, 0x01,
 	0x00, 0x65, 0xcc, 0x41,
 	0x10, 0x3f, 0x06, 0x00,
 	0x10, 0x6a, 0x06, 0x00,
 	0x01, 0x3a, 0xca, 0x30,
-	0x80, 0x65, 0x30, 0x64,
-	0x10, 0xb8, 0x54, 0x6c,
-	0xc0, 0xba, 0xca, 0x00,
-	0x40, 0xb8, 0x20, 0x6c,
+	0x80, 0x65, 0x1c, 0x64,
+	0x10, 0xb8, 0x40, 0x6c,
+	0xc0, 0x3e, 0xca, 0x00,
+	0x40, 0xb8, 0x0c, 0x6c,
 	0xbf, 0x65, 0xca, 0x08,
-	0x20, 0xb8, 0x34, 0x7c,
+	0x20, 0xb8, 0x20, 0x7c,
 	0x01, 0x65, 0x0c, 0x30,
-	0x00, 0x65, 0xec, 0x5d,
-	0xa0, 0x3f, 0x3c, 0x64,
+	0x00, 0x65, 0xd8, 0x5d,
+	0xa0, 0x3f, 0x28, 0x64,
 	0x23, 0xb8, 0x0c, 0x08,
-	0x00, 0x65, 0xec, 0x5d,
-	0xa0, 0x3f, 0x3c, 0x64,
-	0x00, 0xbb, 0x34, 0x44,
-	0xff, 0x65, 0x34, 0x64,
-	0x00, 0x65, 0x54, 0x44,
+	0x00, 0x65, 0xd8, 0x5d,
+	0xa0, 0x3f, 0x28, 0x64,
+	0x00, 0xbb, 0x20, 0x44,
+	0xff, 0x65, 0x20, 0x64,
+	0x00, 0x65, 0x40, 0x44,
 	0x40, 0x6a, 0x18, 0x00,
 	0x01, 0x65, 0x0c, 0x30,
-	0x00, 0x65, 0xec, 0x5d,
-	0xa0, 0x3f, 0x10, 0x74,
+	0x00, 0x65, 0xd8, 0x5d,
+	0xa0, 0x3f, 0xfc, 0x73,
 	0x40, 0x6a, 0x18, 0x00,
 	0x01, 0x3a, 0xa6, 0x30,
 	0x08, 0x6a, 0x74, 0x00,
 	0x00, 0x65, 0xcc, 0x41,
-	0x64, 0x6a, 0x7c, 0x5d,
-	0x80, 0x64, 0xec, 0x6c,
-	0x04, 0x64, 0xae, 0x74,
-	0x02, 0x64, 0xbe, 0x74,
-	0x00, 0x6a, 0x74, 0x74,
-	0x03, 0x64, 0xdc, 0x74,
-	0x23, 0x64, 0x5c, 0x74,
-	0x08, 0x64, 0x70, 0x74,
-	0x61, 0x6a, 0xec, 0x5e,
-	0x00, 0x65, 0xec, 0x5d,
+	0x64, 0x6a, 0x68, 0x5d,
+	0x80, 0x64, 0xd8, 0x6c,
+	0x04, 0x64, 0x9a, 0x74,
+	0x02, 0x64, 0xaa, 0x74,
+	0x00, 0x6a, 0x60, 0x74,
+	0x03, 0x64, 0xc8, 0x74,
+	0x23, 0x64, 0x48, 0x74,
+	0x08, 0x64, 0x5c, 0x74,
+	0x61, 0x6a, 0xd8, 0x5e,
+	0x00, 0x65, 0xd8, 0x5d,
 	0x08, 0x51, 0xce, 0x71,
-	0x00, 0x65, 0x54, 0x44,
-	0x80, 0x04, 0x6e, 0x7c,
-	0x51, 0x6a, 0x72, 0x5d,
-	0x01, 0x51, 0x6e, 0x64,
-	0x01, 0xa4, 0x66, 0x7c,
-	0x01, 0x55, 0x70, 0x7c,
-	0x41, 0x6a, 0xec, 0x5e,
-	0x00, 0x65, 0x70, 0x44,
-	0x21, 0x6a, 0xec, 0x5e,
-	0x00, 0x65, 0x70, 0x44,
-	0x07, 0x6a, 0x68, 0x5d,
+	0x00, 0x65, 0x40, 0x44,
+	0x80, 0x04, 0x5a, 0x7c,
+	0x51, 0x6a, 0x5e, 0x5d,
+	0x01, 0x51, 0x5a, 0x64,
+	0x01, 0xa4, 0x52, 0x7c,
+	0x80, 0xba, 0x5c, 0x6c,
+	0x41, 0x6a, 0xd8, 0x5e,
+	0x00, 0x65, 0x5c, 0x44,
+	0x21, 0x6a, 0xd8, 0x5e,
+	0x00, 0x65, 0x5c, 0x44,
+	0x07, 0x6a, 0x54, 0x5d,
 	0x01, 0x06, 0xd4, 0x30,
 	0x00, 0x65, 0xcc, 0x41,
-	0x80, 0xb8, 0x6a, 0x7c,
-	0xc0, 0x3c, 0x7e, 0x7c,
-	0x80, 0x3c, 0x6a, 0x6c,
-	0xff, 0xa8, 0x7e, 0x6c,
-	0x40, 0x3c, 0x6a, 0x6c,
-	0x10, 0xb8, 0x82, 0x7c,
-	0xa1, 0x6a, 0xec, 0x5e,
-	0x01, 0xb4, 0x88, 0x6c,
-	0x02, 0xb4, 0x8a, 0x6c,
-	0x01, 0xa4, 0x8a, 0x7c,
-	0xff, 0xa8, 0x9a, 0x7c,
+	0x80, 0xb8, 0x56, 0x7c,
+	0xc0, 0x3c, 0x6a, 0x7c,
+	0x80, 0x3c, 0x56, 0x6c,
+	0xff, 0xa8, 0x6a, 0x6c,
+	0x40, 0x3c, 0x56, 0x6c,
+	0x10, 0xb8, 0x6e, 0x7c,
+	0xa1, 0x6a, 0xd8, 0x5e,
+	0x01, 0xb4, 0x74, 0x6c,
+	0x02, 0xb4, 0x76, 0x6c,
+	0x01, 0xa4, 0x76, 0x7c,
+	0xff, 0xa8, 0x86, 0x7c,
 	0x04, 0xb4, 0x68, 0x01,
 	0x01, 0x6a, 0x76, 0x00,
-	0x00, 0xbb, 0x26, 0x5e,
-	0xff, 0xa8, 0x9a, 0x7c,
-	0x71, 0x6a, 0xec, 0x5e,
-	0x40, 0x51, 0x9a, 0x64,
-	0x00, 0x65, 0xc6, 0x5e,
+	0x00, 0xbb, 0x12, 0x5e,
+	0xff, 0xa8, 0x86, 0x7c,
+	0x71, 0x6a, 0xd8, 0x5e,
+	0x40, 0x51, 0x86, 0x64,
+	0x00, 0x65, 0xb2, 0x5e,
 	0x00, 0x65, 0xde, 0x41,
-	0x00, 0xbb, 0x9e, 0x5c,
+	0x00, 0xbb, 0x8a, 0x5c,
 	0x00, 0x65, 0xde, 0x41,
-	0x00, 0x65, 0xc6, 0x5e,
+	0x00, 0x65, 0xb2, 0x5e,
 	0x01, 0x65, 0xa2, 0x30,
 	0x01, 0xf8, 0xc8, 0x30,
 	0x01, 0x4e, 0xc8, 0x30,
-	0x00, 0x6a, 0xca, 0xdd,
-	0x00, 0x51, 0xdc, 0x5d,
+	0x00, 0x6a, 0xb6, 0xdd,
+	0x00, 0x51, 0xc8, 0x5d,
 	0x01, 0x4e, 0x9c, 0x18,
 	0x02, 0x6a, 0x22, 0x05,
-	0xc0, 0x3c, 0x6a, 0x6c,
+	0xc0, 0x3c, 0x56, 0x6c,
 	0x04, 0xb8, 0x70, 0x01,
-	0x00, 0x65, 0xe8, 0x5e,
+	0x00, 0x65, 0xd4, 0x5e,
 	0x20, 0xb8, 0xde, 0x69,
 	0x01, 0xbb, 0xa2, 0x30,
-	0x01, 0xba, 0x7c, 0x30,
-	0x00, 0xb9, 0xe2, 0x5c,
+	0x3f, 0xba, 0x7c, 0x08,
+	0x00, 0xb9, 0xce, 0x5c,
 	0x00, 0x65, 0xde, 0x41,
 	0x01, 0x06, 0xd4, 0x30,
 	0x20, 0x3c, 0xcc, 0x79,
-	0x20, 0x3c, 0x70, 0x7c,
-	0x01, 0xa4, 0xcc, 0x7c,
+	0x20, 0x3c, 0x5c, 0x7c,
+	0x01, 0xa4, 0xb8, 0x7c,
 	0x01, 0xb4, 0x68, 0x01,
 	0x00, 0x65, 0xcc, 0x41,
-	0x00, 0x65, 0x70, 0x44,
+	0x00, 0x65, 0x5c, 0x44,
 	0x04, 0x14, 0x58, 0x31,
 	0x01, 0x06, 0xd4, 0x30,
 	0x08, 0xa0, 0x60, 0x31,
 	0xac, 0x6a, 0xcc, 0x00,
-	0x14, 0x6a, 0x08, 0x5e,
+	0x14, 0x6a, 0xf4, 0x5d,
 	0x01, 0x06, 0xd4, 0x30,
-	0xa0, 0x6a, 0x00, 0x5e,
+	0xa0, 0x6a, 0xec, 0x5d,
 	0x00, 0x65, 0xcc, 0x41,
 	0xdf, 0x3c, 0x78, 0x08,
 	0x12, 0x01, 0x02, 0x00,
-	0x00, 0x65, 0x70, 0x44,
+	0x00, 0x65, 0x5c, 0x44,
 	0x4c, 0x65, 0xcc, 0x28,
 	0x01, 0x3e, 0x20, 0x31,
 	0xd0, 0x66, 0xcc, 0x18,
@@ -641,102 +631,102 @@
 	0xd0, 0x65, 0xca, 0x18,
 	0x01, 0x3e, 0x20, 0x31,
 	0x30, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0xfa, 0x4c,
+	0x00, 0x65, 0xe6, 0x4c,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x20, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0x02, 0x55,
+	0x00, 0x65, 0xee, 0x54,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x20, 0x65, 0xca, 0x18,
 	0xe0, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0x0c, 0x4d,
+	0x00, 0x65, 0xf8, 0x4c,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xd0, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0x14, 0x55,
+	0x00, 0x65, 0x00, 0x55,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x01, 0x6c, 0xa2, 0x30,
-	0xff, 0x51, 0x26, 0x75,
-	0x00, 0x51, 0xa2, 0x5d,
+	0xff, 0x51, 0x12, 0x75,
+	0x00, 0x51, 0x8e, 0x5d,
 	0x01, 0x51, 0x20, 0x31,
-	0x00, 0x65, 0x48, 0x45,
-	0x01, 0xba, 0xc8, 0x30,
-	0x00, 0x3e, 0x48, 0x75,
-	0x00, 0x65, 0xc4, 0x5e,
+	0x00, 0x65, 0x34, 0x45,
+	0x3f, 0xba, 0xc8, 0x08,
+	0x00, 0x3e, 0x34, 0x75,
+	0x00, 0x65, 0xb0, 0x5e,
 	0x80, 0x3c, 0x78, 0x00,
 	0x01, 0x06, 0xd4, 0x30,
-	0x00, 0x65, 0xec, 0x5d,
+	0x00, 0x65, 0xd8, 0x5d,
 	0x01, 0x3c, 0x78, 0x00,
-	0xe0, 0x3f, 0x64, 0x65,
+	0xe0, 0x3f, 0x50, 0x65,
 	0x02, 0x3c, 0x78, 0x00,
-	0x20, 0x12, 0x64, 0x65,
-	0x51, 0x6a, 0x72, 0x5d,
-	0x00, 0x51, 0xa2, 0x5d,
-	0x51, 0x6a, 0x72, 0x5d,
+	0x20, 0x12, 0x50, 0x65,
+	0x51, 0x6a, 0x5e, 0x5d,
+	0x00, 0x51, 0x8e, 0x5d,
+	0x51, 0x6a, 0x5e, 0x5d,
 	0x01, 0x51, 0x20, 0x31,
 	0x04, 0x3c, 0x78, 0x00,
 	0x01, 0xb9, 0xc8, 0x30,
-	0x00, 0x3d, 0x62, 0x65,
+	0x00, 0x3d, 0x4e, 0x65,
 	0x08, 0x3c, 0x78, 0x00,
-	0x01, 0xba, 0xc8, 0x30,
-	0x00, 0x3e, 0x62, 0x65,
+	0x3f, 0xba, 0xc8, 0x08,
+	0x00, 0x3e, 0x4e, 0x65,
 	0x10, 0x3c, 0x78, 0x00,
-	0x04, 0xb8, 0x62, 0x7d,
+	0x04, 0xb8, 0x4e, 0x7d,
 	0xfb, 0xb8, 0x70, 0x09,
-	0x20, 0xb8, 0x58, 0x6d,
+	0x20, 0xb8, 0x44, 0x6d,
 	0x01, 0x90, 0xc8, 0x30,
 	0xff, 0x6a, 0xa2, 0x00,
-	0x00, 0x3d, 0xe2, 0x5c,
+	0x00, 0x3d, 0xce, 0x5c,
 	0x01, 0x64, 0x20, 0x31,
 	0xff, 0x6a, 0x78, 0x08,
 	0x00, 0x65, 0xea, 0x58,
-	0x10, 0xb8, 0x70, 0x7c,
-	0xff, 0x6a, 0x68, 0x5d,
-	0x00, 0x65, 0x70, 0x44,
-	0x00, 0x65, 0xc4, 0x5e,
-	0x31, 0x6a, 0xec, 0x5e,
-	0x00, 0x65, 0x70, 0x44,
+	0x10, 0xb8, 0x5c, 0x7c,
+	0xff, 0x6a, 0x54, 0x5d,
+	0x00, 0x65, 0x5c, 0x44,
+	0x00, 0x65, 0xb0, 0x5e,
+	0x31, 0x6a, 0xd8, 0x5e,
+	0x00, 0x65, 0x5c, 0x44,
 	0x10, 0x3f, 0x06, 0x00,
 	0x10, 0x6a, 0x06, 0x00,
 	0x01, 0x65, 0x74, 0x34,
-	0x81, 0x6a, 0xec, 0x5e,
-	0x00, 0x65, 0x74, 0x45,
+	0x81, 0x6a, 0xd8, 0x5e,
+	0x00, 0x65, 0x60, 0x45,
 	0x01, 0x06, 0xd4, 0x30,
-	0x01, 0x0c, 0x74, 0x7d,
-	0x04, 0x0c, 0x6e, 0x6d,
+	0x01, 0x0c, 0x60, 0x7d,
+	0x04, 0x0c, 0x5a, 0x6d,
 	0xe0, 0x03, 0x7e, 0x08,
 	0xe0, 0x3f, 0xcc, 0x61,
 	0x01, 0x65, 0xcc, 0x30,
 	0x01, 0x12, 0xda, 0x34,
 	0x01, 0x06, 0xd4, 0x34,
-	0x01, 0x03, 0x82, 0x6d,
+	0x01, 0x03, 0x6e, 0x6d,
 	0x40, 0x03, 0xcc, 0x08,
 	0x01, 0x65, 0x06, 0x30,
 	0x40, 0x65, 0xc8, 0x08,
-	0x00, 0x66, 0x90, 0x75,
-	0x40, 0x65, 0x90, 0x7d,
-	0x00, 0x65, 0x90, 0x5d,
+	0x00, 0x66, 0x7c, 0x75,
+	0x40, 0x65, 0x7c, 0x7d,
+	0x00, 0x65, 0x7c, 0x5d,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0x08, 0x01, 0x02, 0x00,
-	0x02, 0x0b, 0x9a, 0x7d,
+	0x02, 0x0b, 0x86, 0x7d,
 	0x01, 0x65, 0x0c, 0x30,
-	0x02, 0x0b, 0x9e, 0x7d,
+	0x02, 0x0b, 0x8a, 0x7d,
 	0xf7, 0x01, 0x02, 0x0c,
 	0x01, 0x65, 0xc8, 0x30,
-	0xff, 0x41, 0xc2, 0x75,
+	0xff, 0x41, 0xae, 0x75,
 	0x01, 0x41, 0x20, 0x31,
 	0xff, 0x6a, 0xa4, 0x00,
-	0x00, 0x65, 0xb2, 0x45,
-	0xff, 0xbf, 0xc2, 0x75,
+	0x00, 0x65, 0x9e, 0x45,
+	0xff, 0xbf, 0xae, 0x75,
 	0x01, 0x90, 0xa4, 0x30,
 	0x01, 0xbf, 0x20, 0x31,
-	0x00, 0xbb, 0xac, 0x65,
-	0xff, 0x52, 0xc0, 0x75,
+	0x00, 0xbb, 0x98, 0x65,
+	0xff, 0x52, 0xac, 0x75,
 	0x01, 0xbf, 0xcc, 0x30,
 	0x01, 0x90, 0xca, 0x30,
 	0x01, 0x52, 0x20, 0x31,
@@ -744,28 +734,28 @@
 	0x01, 0x65, 0x20, 0x35,
 	0x01, 0xbf, 0x82, 0x34,
 	0x01, 0x64, 0xa2, 0x30,
-	0x00, 0x6a, 0xd4, 0x5e,
+	0x00, 0x6a, 0xc0, 0x5e,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x51, 0x26, 0x46,
+	0x00, 0x51, 0x12, 0x46,
 	0x01, 0x65, 0xa4, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x1a, 0x5e,
+	0x48, 0x6a, 0x06, 0x5e,
 	0x01, 0x6a, 0xd0, 0x01,
 	0x01, 0x6a, 0xdc, 0x05,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x1a, 0x5e,
-	0x01, 0x6a, 0xf4, 0x5d,
+	0x48, 0x6a, 0x06, 0x5e,
+	0x01, 0x6a, 0xe0, 0x5d,
 	0x01, 0x6a, 0x26, 0x05,
 	0x01, 0x65, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0xe0, 0x7d,
+	0x80, 0xee, 0xcc, 0x7d,
 	0xff, 0x6a, 0xdc, 0x0d,
 	0x01, 0x65, 0x32, 0x31,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xbc, 0x46,
-	0x81, 0x6a, 0xec, 0x5e,
-	0x01, 0x0c, 0xec, 0x7d,
-	0x04, 0x0c, 0xea, 0x6d,
+	0x00, 0x65, 0xa8, 0x46,
+	0x81, 0x6a, 0xd8, 0x5e,
+	0x01, 0x0c, 0xd8, 0x7d,
+	0x04, 0x0c, 0xd6, 0x6d,
 	0xe0, 0x03, 0x06, 0x08,
 	0xe0, 0x03, 0x7e, 0x0c,
 	0x01, 0x65, 0x18, 0x31,
@@ -784,7 +774,7 @@
 	0x01, 0x6c, 0xda, 0x34,
 	0x3d, 0x64, 0xa4, 0x28,
 	0x55, 0x64, 0xc8, 0x28,
-	0x00, 0x65, 0x1a, 0x46,
+	0x00, 0x65, 0x06, 0x46,
 	0x2e, 0x64, 0xa4, 0x28,
 	0x66, 0x64, 0xc8, 0x28,
 	0x00, 0x6c, 0xda, 0x18,
@@ -795,63 +785,63 @@
 	0x00, 0x6c, 0xda, 0x24,
 	0x01, 0x65, 0xc8, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x44, 0x6a, 0x16, 0x5e,
+	0x44, 0x6a, 0x02, 0x5e,
 	0x01, 0x90, 0xe2, 0x31,
-	0x04, 0x3b, 0x3a, 0x7e,
+	0x04, 0x3b, 0x26, 0x7e,
 	0x30, 0x6a, 0xd0, 0x01,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x1d, 0x6a, 0xdc, 0x01,
-	0xdc, 0xee, 0x36, 0x66,
-	0x00, 0x65, 0x52, 0x46,
+	0xdc, 0xee, 0x22, 0x66,
+	0x00, 0x65, 0x3e, 0x46,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x01, 0x6a, 0xdc, 0x01,
 	0x20, 0xa0, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0x42, 0x7e,
+	0x80, 0xee, 0x2e, 0x7e,
 	0x11, 0x6a, 0xdc, 0x01,
-	0x50, 0xee, 0x46, 0x66,
+	0x50, 0xee, 0x32, 0x66,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x09, 0x6a, 0xdc, 0x01,
-	0x88, 0xee, 0x4c, 0x66,
+	0x88, 0xee, 0x38, 0x66,
 	0x19, 0x6a, 0xdc, 0x01,
-	0xd8, 0xee, 0x50, 0x66,
+	0xd8, 0xee, 0x3c, 0x66,
 	0xff, 0x6a, 0xdc, 0x09,
-	0x18, 0xee, 0x54, 0x6e,
+	0x18, 0xee, 0x40, 0x6e,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x44, 0x6a, 0x16, 0x5e,
-	0x20, 0x6a, 0xf4, 0x5d,
+	0x44, 0x6a, 0x02, 0x5e,
+	0x20, 0x6a, 0xe0, 0x5d,
 	0x01, 0x3b, 0x26, 0x31,
-	0x04, 0x3b, 0x6e, 0x6e,
+	0x04, 0x3b, 0x5a, 0x6e,
 	0xa0, 0x6a, 0xca, 0x00,
 	0x20, 0x65, 0xc8, 0x18,
-	0x00, 0x65, 0xac, 0x5e,
-	0x00, 0x65, 0x66, 0x66,
+	0x00, 0x65, 0x98, 0x5e,
+	0x00, 0x65, 0x52, 0x66,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xbc, 0x46,
+	0x00, 0x65, 0xa8, 0x46,
 	0xa0, 0x6a, 0xcc, 0x00,
 	0xff, 0x6a, 0xc8, 0x08,
-	0x20, 0x94, 0x72, 0x6e,
-	0x10, 0x94, 0x74, 0x6e,
-	0x08, 0x94, 0x8e, 0x6e,
-	0x08, 0x94, 0x8e, 0x6e,
-	0x08, 0x94, 0x8e, 0x6e,
+	0x20, 0x94, 0x5e, 0x6e,
+	0x10, 0x94, 0x60, 0x6e,
+	0x08, 0x94, 0x7a, 0x6e,
+	0x08, 0x94, 0x7a, 0x6e,
+	0x08, 0x94, 0x7a, 0x6e,
 	0xff, 0x8c, 0xc8, 0x10,
 	0xc1, 0x64, 0xc8, 0x18,
 	0xf8, 0x64, 0xc8, 0x08,
 	0x01, 0x99, 0xda, 0x30,
-	0x00, 0x66, 0x82, 0x66,
-	0xc0, 0x66, 0xbe, 0x76,
+	0x00, 0x66, 0x6e, 0x66,
+	0xc0, 0x66, 0xaa, 0x76,
 	0x60, 0x66, 0xc8, 0x18,
 	0x3d, 0x64, 0xc8, 0x28,
-	0x00, 0x65, 0x72, 0x46,
+	0x00, 0x65, 0x5e, 0x46,
 	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0x90, 0x6e,
+	0x08, 0x93, 0x7c, 0x6e,
 	0x00, 0x62, 0xc4, 0x18,
-	0x00, 0x65, 0xbc, 0x5e,
-	0x00, 0x65, 0x9c, 0x5e,
-	0x00, 0x65, 0x9c, 0x5e,
-	0x00, 0x65, 0x9c, 0x5e,
+	0x00, 0x65, 0xa8, 0x5e,
+	0x00, 0x65, 0x88, 0x5e,
+	0x00, 0x65, 0x88, 0x5e,
+	0x00, 0x65, 0x88, 0x5e,
 	0x01, 0x99, 0xda, 0x30,
 	0x01, 0x99, 0xda, 0x30,
 	0x01, 0x99, 0xda, 0x30,
@@ -868,11 +858,11 @@
 	0x01, 0x6c, 0x32, 0x31,
 	0x01, 0x6c, 0x32, 0x31,
 	0x01, 0x6c, 0x32, 0x35,
-	0x08, 0x94, 0xbc, 0x7e,
+	0x08, 0x94, 0xa8, 0x7e,
 	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0xc0, 0x6e,
+	0x08, 0x93, 0xac, 0x6e,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x04, 0xb8, 0xe8, 0x6e,
+	0x04, 0xb8, 0xd4, 0x6e,
 	0x01, 0x42, 0x7e, 0x31,
 	0xff, 0x6a, 0x76, 0x01,
 	0x01, 0x90, 0x84, 0x34,
@@ -880,14 +870,14 @@
 	0x01, 0x85, 0x0a, 0x01,
 	0x7f, 0x65, 0x10, 0x09,
 	0xfe, 0x85, 0x0a, 0x0d,
-	0xff, 0x42, 0xe4, 0x66,
-	0xff, 0x41, 0xdc, 0x66,
-	0xd1, 0x6a, 0xec, 0x5e,
+	0xff, 0x42, 0xd0, 0x66,
+	0xff, 0x41, 0xc8, 0x66,
+	0xd1, 0x6a, 0xd8, 0x5e,
 	0xff, 0x6a, 0xca, 0x04,
 	0x01, 0x41, 0x20, 0x31,
 	0x01, 0xbf, 0x82, 0x30,
 	0x01, 0x6a, 0x76, 0x00,
-	0x00, 0xbb, 0x26, 0x46,
+	0x00, 0xbb, 0x12, 0x46,
 	0x01, 0x42, 0x20, 0x31,
 	0x01, 0xbf, 0x84, 0x34,
 	0x01, 0x41, 0x7e, 0x31,
@@ -1157,147 +1147,147 @@
 	{ ahc_patch1_func, 248, 1, 2 },
 	{ ahc_patch0_func, 249, 2, 2 },
 	{ ahc_patch11_func, 250, 1, 1 },
-	{ ahc_patch9_func, 258, 31, 3 },
-	{ ahc_patch1_func, 274, 14, 2 },
-	{ ahc_patch13_func, 279, 1, 1 },
-	{ ahc_patch14_func, 289, 14, 1 },
-	{ ahc_patch1_func, 305, 1, 2 },
-	{ ahc_patch0_func, 306, 1, 1 },
-	{ ahc_patch9_func, 309, 1, 1 },
-	{ ahc_patch13_func, 314, 1, 1 },
-	{ ahc_patch9_func, 315, 2, 2 },
-	{ ahc_patch0_func, 317, 4, 1 },
-	{ ahc_patch14_func, 321, 1, 1 },
-	{ ahc_patch15_func, 324, 2, 3 },
-	{ ahc_patch9_func, 324, 1, 2 },
-	{ ahc_patch0_func, 325, 1, 1 },
-	{ ahc_patch6_func, 330, 1, 2 },
-	{ ahc_patch0_func, 331, 1, 1 },
-	{ ahc_patch1_func, 335, 50, 11 },
-	{ ahc_patch6_func, 344, 2, 4 },
-	{ ahc_patch7_func, 344, 1, 1 },
-	{ ahc_patch8_func, 345, 1, 1 },
-	{ ahc_patch0_func, 346, 1, 1 },
-	{ ahc_patch16_func, 347, 1, 1 },
-	{ ahc_patch6_func, 366, 6, 3 },
-	{ ahc_patch16_func, 366, 5, 1 },
-	{ ahc_patch0_func, 372, 5, 1 },
-	{ ahc_patch13_func, 380, 5, 1 },
-	{ ahc_patch0_func, 385, 54, 17 },
-	{ ahc_patch14_func, 385, 1, 1 },
-	{ ahc_patch7_func, 387, 2, 2 },
-	{ ahc_patch17_func, 388, 1, 1 },
-	{ ahc_patch9_func, 391, 1, 1 },
-	{ ahc_patch18_func, 398, 1, 1 },
-	{ ahc_patch14_func, 403, 9, 3 },
-	{ ahc_patch9_func, 404, 3, 2 },
-	{ ahc_patch0_func, 407, 3, 1 },
-	{ ahc_patch9_func, 415, 6, 2 },
-	{ ahc_patch0_func, 421, 9, 2 },
-	{ ahc_patch13_func, 421, 1, 1 },
-	{ ahc_patch13_func, 430, 2, 1 },
-	{ ahc_patch14_func, 432, 1, 1 },
-	{ ahc_patch9_func, 434, 1, 2 },
-	{ ahc_patch0_func, 435, 1, 1 },
-	{ ahc_patch7_func, 438, 1, 1 },
-	{ ahc_patch7_func, 439, 1, 1 },
-	{ ahc_patch8_func, 440, 3, 3 },
-	{ ahc_patch6_func, 441, 1, 2 },
-	{ ahc_patch0_func, 442, 1, 1 },
-	{ ahc_patch9_func, 443, 1, 1 },
-	{ ahc_patch15_func, 444, 1, 2 },
-	{ ahc_patch13_func, 444, 1, 1 },
-	{ ahc_patch14_func, 446, 9, 4 },
-	{ ahc_patch9_func, 446, 1, 1 },
-	{ ahc_patch9_func, 453, 2, 1 },
-	{ ahc_patch0_func, 455, 4, 3 },
-	{ ahc_patch9_func, 455, 1, 2 },
-	{ ahc_patch0_func, 456, 3, 1 },
-	{ ahc_patch1_func, 460, 2, 1 },
-	{ ahc_patch7_func, 462, 10, 2 },
-	{ ahc_patch0_func, 472, 1, 1 },
-	{ ahc_patch8_func, 473, 118, 22 },
-	{ ahc_patch1_func, 475, 3, 2 },
-	{ ahc_patch0_func, 478, 5, 3 },
-	{ ahc_patch9_func, 478, 2, 2 },
-	{ ahc_patch0_func, 480, 3, 1 },
+	{ ahc_patch9_func, 258, 27, 3 },
+	{ ahc_patch1_func, 274, 10, 2 },
+	{ ahc_patch13_func, 277, 1, 1 },
+	{ ahc_patch14_func, 285, 14, 1 },
+	{ ahc_patch1_func, 301, 1, 2 },
+	{ ahc_patch0_func, 302, 1, 1 },
+	{ ahc_patch9_func, 305, 1, 1 },
+	{ ahc_patch13_func, 310, 1, 1 },
+	{ ahc_patch9_func, 311, 2, 2 },
+	{ ahc_patch0_func, 313, 4, 1 },
+	{ ahc_patch14_func, 317, 1, 1 },
+	{ ahc_patch15_func, 319, 2, 3 },
+	{ ahc_patch9_func, 319, 1, 2 },
+	{ ahc_patch0_func, 320, 1, 1 },
+	{ ahc_patch6_func, 325, 1, 2 },
+	{ ahc_patch0_func, 326, 1, 1 },
+	{ ahc_patch1_func, 330, 47, 11 },
+	{ ahc_patch6_func, 337, 2, 4 },
+	{ ahc_patch7_func, 337, 1, 1 },
+	{ ahc_patch8_func, 338, 1, 1 },
+	{ ahc_patch0_func, 339, 1, 1 },
+	{ ahc_patch16_func, 340, 1, 1 },
+	{ ahc_patch6_func, 356, 6, 3 },
+	{ ahc_patch16_func, 356, 5, 1 },
+	{ ahc_patch0_func, 362, 7, 1 },
+	{ ahc_patch13_func, 372, 5, 1 },
+	{ ahc_patch0_func, 377, 52, 17 },
+	{ ahc_patch14_func, 377, 1, 1 },
+	{ ahc_patch7_func, 379, 2, 2 },
+	{ ahc_patch17_func, 380, 1, 1 },
+	{ ahc_patch9_func, 383, 1, 1 },
+	{ ahc_patch18_func, 390, 1, 1 },
+	{ ahc_patch14_func, 395, 9, 3 },
+	{ ahc_patch9_func, 396, 3, 2 },
+	{ ahc_patch0_func, 399, 3, 1 },
+	{ ahc_patch9_func, 407, 6, 2 },
+	{ ahc_patch0_func, 413, 9, 2 },
+	{ ahc_patch13_func, 413, 1, 1 },
+	{ ahc_patch13_func, 422, 2, 1 },
+	{ ahc_patch14_func, 424, 1, 1 },
+	{ ahc_patch9_func, 426, 1, 2 },
+	{ ahc_patch0_func, 427, 1, 1 },
+	{ ahc_patch7_func, 428, 1, 1 },
+	{ ahc_patch7_func, 429, 1, 1 },
+	{ ahc_patch8_func, 430, 3, 3 },
+	{ ahc_patch6_func, 431, 1, 2 },
+	{ ahc_patch0_func, 432, 1, 1 },
+	{ ahc_patch9_func, 433, 1, 1 },
+	{ ahc_patch15_func, 434, 1, 2 },
+	{ ahc_patch13_func, 434, 1, 1 },
+	{ ahc_patch14_func, 436, 9, 4 },
+	{ ahc_patch9_func, 436, 1, 1 },
+	{ ahc_patch9_func, 443, 2, 1 },
+	{ ahc_patch0_func, 445, 4, 3 },
+	{ ahc_patch9_func, 445, 1, 2 },
+	{ ahc_patch0_func, 446, 3, 1 },
+	{ ahc_patch1_func, 450, 2, 1 },
+	{ ahc_patch7_func, 452, 10, 2 },
+	{ ahc_patch0_func, 462, 1, 1 },
+	{ ahc_patch8_func, 463, 118, 22 },
+	{ ahc_patch1_func, 465, 3, 2 },
+	{ ahc_patch0_func, 468, 5, 3 },
+	{ ahc_patch9_func, 468, 2, 2 },
+	{ ahc_patch0_func, 470, 3, 1 },
+	{ ahc_patch1_func, 475, 2, 2 },
+	{ ahc_patch0_func, 477, 6, 3 },
+	{ ahc_patch9_func, 477, 2, 2 },
+	{ ahc_patch0_func, 479, 3, 1 },
 	{ ahc_patch1_func, 485, 2, 2 },
-	{ ahc_patch0_func, 487, 6, 3 },
-	{ ahc_patch9_func, 487, 2, 2 },
-	{ ahc_patch0_func, 489, 3, 1 },
-	{ ahc_patch1_func, 495, 2, 2 },
-	{ ahc_patch0_func, 497, 9, 7 },
-	{ ahc_patch9_func, 497, 5, 6 },
-	{ ahc_patch19_func, 497, 1, 2 },
-	{ ahc_patch0_func, 498, 1, 1 },
-	{ ahc_patch19_func, 500, 1, 2 },
-	{ ahc_patch0_func, 501, 1, 1 },
-	{ ahc_patch0_func, 502, 4, 1 },
-	{ ahc_patch6_func, 507, 3, 2 },
-	{ ahc_patch0_func, 510, 1, 1 },
-	{ ahc_patch6_func, 520, 1, 2 },
-	{ ahc_patch0_func, 521, 1, 1 },
-	{ ahc_patch20_func, 558, 7, 1 },
-	{ ahc_patch3_func, 593, 1, 2 },
-	{ ahc_patch0_func, 594, 1, 1 },
-	{ ahc_patch21_func, 597, 1, 1 },
-	{ ahc_patch8_func, 599, 106, 33 },
-	{ ahc_patch4_func, 601, 1, 1 },
-	{ ahc_patch1_func, 607, 2, 2 },
-	{ ahc_patch0_func, 609, 1, 1 },
-	{ ahc_patch1_func, 612, 1, 2 },
-	{ ahc_patch0_func, 613, 1, 1 },
-	{ ahc_patch9_func, 614, 3, 3 },
-	{ ahc_patch15_func, 615, 1, 1 },
-	{ ahc_patch0_func, 617, 4, 1 },
-	{ ahc_patch19_func, 626, 2, 2 },
-	{ ahc_patch0_func, 628, 1, 1 },
-	{ ahc_patch19_func, 632, 10, 3 },
-	{ ahc_patch5_func, 634, 8, 1 },
-	{ ahc_patch0_func, 642, 9, 2 },
-	{ ahc_patch5_func, 643, 8, 1 },
-	{ ahc_patch4_func, 653, 1, 2 },
-	{ ahc_patch0_func, 654, 1, 1 },
-	{ ahc_patch19_func, 655, 1, 2 },
-	{ ahc_patch0_func, 656, 3, 2 },
-	{ ahc_patch4_func, 658, 1, 1 },
-	{ ahc_patch5_func, 659, 1, 1 },
-	{ ahc_patch5_func, 662, 1, 1 },
-	{ ahc_patch5_func, 664, 1, 1 },
-	{ ahc_patch4_func, 666, 2, 2 },
-	{ ahc_patch0_func, 668, 2, 1 },
-	{ ahc_patch5_func, 670, 1, 1 },
-	{ ahc_patch5_func, 673, 1, 1 },
-	{ ahc_patch5_func, 676, 1, 1 },
-	{ ahc_patch19_func, 680, 1, 1 },
-	{ ahc_patch19_func, 683, 1, 1 },
-	{ ahc_patch4_func, 689, 1, 1 },
-	{ ahc_patch6_func, 692, 1, 2 },
-	{ ahc_patch0_func, 693, 1, 1 },
-	{ ahc_patch7_func, 705, 16, 1 },
-	{ ahc_patch4_func, 721, 20, 1 },
-	{ ahc_patch9_func, 742, 4, 2 },
-	{ ahc_patch0_func, 746, 4, 1 },
-	{ ahc_patch9_func, 750, 4, 2 },
-	{ ahc_patch0_func, 754, 3, 1 },
-	{ ahc_patch6_func, 760, 1, 1 },
-	{ ahc_patch22_func, 762, 14, 1 },
-	{ ahc_patch7_func, 776, 3, 1 },
-	{ ahc_patch9_func, 788, 24, 8 },
-	{ ahc_patch19_func, 792, 1, 2 },
-	{ ahc_patch0_func, 793, 1, 1 },
-	{ ahc_patch15_func, 798, 4, 2 },
-	{ ahc_patch0_func, 802, 7, 3 },
-	{ ahc_patch23_func, 802, 5, 2 },
-	{ ahc_patch0_func, 807, 2, 1 },
-	{ ahc_patch0_func, 812, 42, 3 },
-	{ ahc_patch18_func, 824, 18, 2 },
-	{ ahc_patch0_func, 842, 1, 1 },
-	{ ahc_patch4_func, 866, 1, 1 },
-	{ ahc_patch4_func, 867, 3, 2 },
-	{ ahc_patch0_func, 870, 1, 1 },
-	{ ahc_patch13_func, 871, 3, 1 },
-	{ ahc_patch4_func, 874, 12, 1 }
+	{ ahc_patch0_func, 487, 9, 7 },
+	{ ahc_patch9_func, 487, 5, 6 },
+	{ ahc_patch19_func, 487, 1, 2 },
+	{ ahc_patch0_func, 488, 1, 1 },
+	{ ahc_patch19_func, 490, 1, 2 },
+	{ ahc_patch0_func, 491, 1, 1 },
+	{ ahc_patch0_func, 492, 4, 1 },
+	{ ahc_patch6_func, 497, 3, 2 },
+	{ ahc_patch0_func, 500, 1, 1 },
+	{ ahc_patch6_func, 510, 1, 2 },
+	{ ahc_patch0_func, 511, 1, 1 },
+	{ ahc_patch20_func, 548, 7, 1 },
+	{ ahc_patch3_func, 583, 1, 2 },
+	{ ahc_patch0_func, 584, 1, 1 },
+	{ ahc_patch21_func, 587, 1, 1 },
+	{ ahc_patch8_func, 589, 106, 33 },
+	{ ahc_patch4_func, 591, 1, 1 },
+	{ ahc_patch1_func, 597, 2, 2 },
+	{ ahc_patch0_func, 599, 1, 1 },
+	{ ahc_patch1_func, 602, 1, 2 },
+	{ ahc_patch0_func, 603, 1, 1 },
+	{ ahc_patch9_func, 604, 3, 3 },
+	{ ahc_patch15_func, 605, 1, 1 },
+	{ ahc_patch0_func, 607, 4, 1 },
+	{ ahc_patch19_func, 616, 2, 2 },
+	{ ahc_patch0_func, 618, 1, 1 },
+	{ ahc_patch19_func, 622, 10, 3 },
+	{ ahc_patch5_func, 624, 8, 1 },
+	{ ahc_patch0_func, 632, 9, 2 },
+	{ ahc_patch5_func, 633, 8, 1 },
+	{ ahc_patch4_func, 643, 1, 2 },
+	{ ahc_patch0_func, 644, 1, 1 },
+	{ ahc_patch19_func, 645, 1, 2 },
+	{ ahc_patch0_func, 646, 3, 2 },
+	{ ahc_patch4_func, 648, 1, 1 },
+	{ ahc_patch5_func, 649, 1, 1 },
+	{ ahc_patch5_func, 652, 1, 1 },
+	{ ahc_patch5_func, 654, 1, 1 },
+	{ ahc_patch4_func, 656, 2, 2 },
+	{ ahc_patch0_func, 658, 2, 1 },
+	{ ahc_patch5_func, 660, 1, 1 },
+	{ ahc_patch5_func, 663, 1, 1 },
+	{ ahc_patch5_func, 666, 1, 1 },
+	{ ahc_patch19_func, 670, 1, 1 },
+	{ ahc_patch19_func, 673, 1, 1 },
+	{ ahc_patch4_func, 679, 1, 1 },
+	{ ahc_patch6_func, 682, 1, 2 },
+	{ ahc_patch0_func, 683, 1, 1 },
+	{ ahc_patch7_func, 695, 16, 1 },
+	{ ahc_patch4_func, 711, 20, 1 },
+	{ ahc_patch9_func, 732, 4, 2 },
+	{ ahc_patch0_func, 736, 4, 1 },
+	{ ahc_patch9_func, 740, 4, 2 },
+	{ ahc_patch0_func, 744, 3, 1 },
+	{ ahc_patch6_func, 750, 1, 1 },
+	{ ahc_patch22_func, 752, 14, 1 },
+	{ ahc_patch7_func, 766, 3, 1 },
+	{ ahc_patch9_func, 778, 24, 8 },
+	{ ahc_patch19_func, 782, 1, 2 },
+	{ ahc_patch0_func, 783, 1, 1 },
+	{ ahc_patch15_func, 788, 4, 2 },
+	{ ahc_patch0_func, 792, 7, 3 },
+	{ ahc_patch23_func, 792, 5, 2 },
+	{ ahc_patch0_func, 797, 2, 1 },
+	{ ahc_patch0_func, 802, 42, 3 },
+	{ ahc_patch18_func, 814, 18, 2 },
+	{ ahc_patch0_func, 832, 1, 1 },
+	{ ahc_patch4_func, 856, 1, 1 },
+	{ ahc_patch4_func, 857, 3, 2 },
+	{ ahc_patch0_func, 860, 1, 1 },
+	{ ahc_patch13_func, 861, 3, 1 },
+	{ ahc_patch4_func, 864, 12, 1 }
 };
 
 static struct cs {
@@ -1306,11 +1296,11 @@
 } critical_sections[] = {
 	{ 11, 18 },
 	{ 21, 30 },
-	{ 721, 737 },
-	{ 867, 870 },
-	{ 874, 880 },
-	{ 882, 884 },
-	{ 884, 886 }
+	{ 711, 727 },
+	{ 857, 860 },
+	{ 864, 870 },
+	{ 872, 874 },
+	{ 874, 876 }
 };
 
 static const int num_critical_sections = sizeof(critical_sections)
diff -Nru a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h
--- a/drivers/scsi/aic7xxx/aiclib.h	Thu Apr 24 14:12:34 2003
+++ b/drivers/scsi/aic7xxx/aiclib.h	Wed May 14 15:00:40 2003
@@ -60,12 +60,9 @@
 /*
  * Linux Interrupt Support.
  */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#define	AIC_LINUX_IRQRETURN_T irqreturn_t
-#define	AIC_LINUX_IRQRETURN(ours) return (IRQ_RETVAL(ours))
-#else
-#define	AIC_LINUX_IRQRETURN_T void
-#define	AIC_LINUX_IRQRETURN(ours)  return
+#ifndef IRQ_RETVAL
+typedef void irqreturn_t;
+#define	IRQ_RETVAL(x)
 #endif
 
 /*
diff -Nru a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c
--- a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	Tue Feb  4 11:14:05 2003
+++ b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	Mon May 12 07:40:10 2003
@@ -80,10 +80,9 @@
  *   Return information to handle /proc support for the driver.
  *-F*************************************************************************/
 int
-aic7xxx_proc_info ( char *buffer, char **start, off_t offset, int length, 
-                    int hostno, int inout)
+aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, 
+                    int inout)
 {
-  struct Scsi_Host *HBAptr;
   struct aic7xxx_host *p;
   struct aic_dev_data *aic_dev;
   struct scsi_device *sdptr;
@@ -93,12 +92,12 @@
 
   HBAptr = NULL;
 
-  for(p=first_aic7xxx; p->host->host_no != hostno; p=p->next)
+  for(p=first_aic7xxx; p->host != HBAptr; p=p->next)
     ;
 
   if (!p)
   {
-    size += sprintf(buffer, "Can't find adapter for host number %d\n", hostno);
+    size += sprintf(buffer, "Can't find adapter for host number %d\n", HBAptr->host_no);
     if (size > length)
     {
       return (size);
@@ -108,8 +107,6 @@
       return (length);
     }
   }
-
-  HBAptr = p->host;
 
   if (inout == TRUE) /* Has data been written to the file? */ 
   {
diff -Nru a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
--- a/drivers/scsi/arm/acornscsi.c	Sat May 17 11:00:48 2003
+++ b/drivers/scsi/arm/acornscsi.c	Mon May 19 19:40:43 2003
@@ -2857,18 +2857,15 @@
     return string;
 }
 
-int acornscsi_proc_info(char *buffer, char **start, off_t offset,
-			int length, int host_no, int inout)
+int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, off_t offset,
+			int length, int inout)
 {
     int pos, begin = 0, devidx;
-    struct Scsi_Host *instance;
     Scsi_Device *scd;
     AS_Host *host;
     char *p = buffer;
 
-    instance = scsi_host_hn_get(host_no);
-
-    if (inout == 1 || !instance)
+    if (inout == 1)
 	return -EINVAL;
 
     host  = (AS_Host *)instance->hostdata;
diff -Nru a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c
--- a/drivers/scsi/arm/arxescsi.c	Sat May 17 08:48:41 2003
+++ b/drivers/scsi/arm/arxescsi.c	Mon May 19 19:40:44 2003
@@ -236,17 +236,12 @@
  * Returns : length of data written to buffer.
  */
 static int
-arxescsi_proc_info(char *buffer, char **start, off_t offset, int length,
+arxescsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
 		   int host_no, int inout)
 {
-	struct Scsi_Host *host;
 	struct arxescsi_info *info;
 	char *p = buffer;
 	int pos;
-
-	host = scsi_host_hn_get(host_no);
-	if (!host)
-		return 0;
 
 	info = (struct arxescsi_info *)host->hostdata;
 	if (inout == 1)
diff -Nru a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
--- a/drivers/scsi/arm/cumana_1.c	Sat May 17 08:48:41 2003
+++ b/drivers/scsi/arm/cumana_1.c	Mon May 19 19:40:44 2003
@@ -35,9 +35,6 @@
 #define NCR5380_queue_command		cumanascsi_queue_command
 #define NCR5380_proc_info		cumanascsi_proc_info
 
-int NCR5380_proc_info(char *buffer, char **start, off_t offset,
-		      int length, int hostno, int inout);
-
 #define BOARD_NORMAL	0
 #define BOARD_NCR53C400	1
 
diff -Nru a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
--- a/drivers/scsi/arm/cumana_2.c	Sat May 17 11:02:30 2003
+++ b/drivers/scsi/arm/cumana_2.c	Mon May 19 19:40:45 2003
@@ -353,17 +353,12 @@
  *	      inout  - 0 for reading, 1 for writing.
  * Returns  : length of data written to buffer.
  */
-int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset,
-			    int length, int host_no, int inout)
+int cumanascsi_2_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			    int length, int inout)
 {
-	struct Scsi_Host *host;
 	struct cumanascsi2_info *info;
 	char *p = buffer;
 	int pos;
-
-	host = scsi_host_hn_get(host_no);
-	if (!host)
-		return 0;
 
 	if (inout == 1)
 		return cumanascsi_2_set_proc_info(host, buffer, length);
diff -Nru a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c
--- a/drivers/scsi/arm/ecoscsi.c	Sat May 17 06:52:32 2003
+++ b/drivers/scsi/arm/ecoscsi.c	Mon May 19 19:40:45 2003
@@ -233,9 +233,6 @@
 #endif
 #undef STAT
 
-int NCR5380_proc_info(char *buffer, char **start, off_t offset,
-		      int length, int hostno, int inout);
-
 #define BOARD_NORMAL	0
 #define BOARD_NCR53C400	1
 
diff -Nru a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
--- a/drivers/scsi/arm/eesox.c	Sat May 17 11:00:49 2003
+++ b/drivers/scsi/arm/eesox.c	Mon May 19 19:40:46 2003
@@ -427,17 +427,12 @@
  *	      inout  - 0 for reading, 1 for writing.
  * Returns  : length of data written to buffer.
  */
-int eesoxscsi_proc_info(char *buffer, char **start, off_t offset,
-			    int length, int host_no, int inout)
+int eesoxscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			    int length, int inout)
 {
-	struct Scsi_Host *host;
 	struct eesoxscsi_info *info;
 	char *p = buffer;
 	int pos;
-
-	host = scsi_host_hn_get(host_no);
-	if (!host)
-		return 0;
 
 	if (inout == 1)
 		return eesoxscsi_set_proc_info(host, buffer, length);
diff -Nru a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
--- a/drivers/scsi/arm/oak.c	Sat May 17 08:48:42 2003
+++ b/drivers/scsi/arm/oak.c	Mon May 19 19:40:46 2003
@@ -30,9 +30,6 @@
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_proc_info		oakscsi_proc_info
 
-int NCR5380_proc_info(char *buffer, char **start, off_t offset,
-		      int length, int hostno, int inout);
-
 #define NCR5380_implementation_fields	int port, ctrl
 #define NCR5380_local_declare()		struct Scsi_Host *_instance
 #define NCR5380_setup(instance)		_instance = instance
diff -Nru a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
--- a/drivers/scsi/arm/powertec.c	Sat May 17 08:48:43 2003
+++ b/drivers/scsi/arm/powertec.c	Mon May 19 19:40:47 2003
@@ -239,19 +239,14 @@
  *	      inout   - 0 for reading, 1 for writing.
  * Returns  : length of data written to buffer.
  */
-int powertecscsi_proc_info(char *buffer, char **start, off_t offset,
+int powertecscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
 			    int length, int host_no, int inout)
 {
-	struct Scsi_Host *host;
 	struct powertec_info *info;
 	char *p = buffer;
 	int pos;
 
-	host = scsi_host_hn_get(host_no);
-	if (!host)
-		return 0;
-
-	if (inout == 1)
+	If (inout == 1)
 		return powertecscsi_set_proc_info(host, buffer, length);
 
 	info = (struct powertec_info *)host->hostdata;
diff -Nru a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
--- a/drivers/scsi/atari_NCR5380.c	Fri May  9 03:21:34 2003
+++ b/drivers/scsi/atari_NCR5380.c	Mon May 26 18:54:33 2003
@@ -746,11 +746,10 @@
 #ifndef NCR5380_proc_info
 static
 #endif
-int NCR5380_proc_info (char *buffer, char **start, off_t offset,
-		       int length, int hostno, int inout)
+int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start, off_t offset,
+		       int length, int inout)
 {
     char *pos = buffer;
-    struct Scsi_Host *instance;
     struct NCR5380_hostdata *hostdata;
     Scsi_Cmnd *ptr;
     unsigned long flags;
@@ -763,9 +762,6 @@
 	}					\
     } while (0)
 
-    instance = scsi_host_hn_get(hostno);
-    if (!instance)
-	return(-ESRCH);
     hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
     if (inout) { /* Has data been written to the file ? */
diff -Nru a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h
--- a/drivers/scsi/atari_scsi.h	Sun Feb  9 11:14:51 2003
+++ b/drivers/scsi/atari_scsi.h	Mon May 12 07:26:11 2003
@@ -21,7 +21,6 @@
 int atari_scsi_detect (Scsi_Host_Template *);
 const char *atari_scsi_info (struct Scsi_Host *);
 int atari_scsi_reset (Scsi_Cmnd *, unsigned int);
-int atari_scsi_proc_info (char *, char **, off_t, int, int, int);
 #ifdef MODULE
 int atari_scsi_release (struct Scsi_Host *);
 #else
diff -Nru a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/atp870u.c	Mon May 12 08:07:29 2003
@@ -2657,33 +2657,14 @@
 }
 
 #define BLS buffer + len + size
-int atp870u_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, int inout)
 {
-	struct Scsi_Host *HBAptr;
 	static u8 buff[512];
-	int i;
 	int size = 0;
 	int len = 0;
 	off_t begin = 0;
 	off_t pos = 0;
 
-	HBAptr = NULL;
-	for (i = 0; i < MAX_ATP; i++) {
-		if ((HBAptr = atp_host[i]) != NULL) {
-			if (HBAptr->host_no == hostno) {
-				break;
-			}
-			HBAptr = NULL;
-		}
-	}
-
-	if (HBAptr == NULL) {
-		size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno);
-		len += size;
-		pos = begin + len;
-		size = 0;
-		goto stop_output;
-	}
 	if (inout == TRUE) {	/* Has data been written to the file? */
 		return (atp870u_set_info(buffer, length, HBAptr));
 	}
@@ -2701,9 +2682,7 @@
 	size += sprintf(BLS, "                   IRQ: %d\n", HBAptr->irq);
 	len += size;
 	pos = begin + len;
-	size = 0;
 
-stop_output:
 	*start = buffer + (offset - begin);	/* Start of wanted data */
 	len -= (offset - begin);	/* Start slop */
 	if (len > length) {
diff -Nru a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h
--- a/drivers/scsi/atp870u.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/atp870u.h	Mon May 12 07:26:11 2003
@@ -35,6 +35,4 @@
 
 extern const char *atp870u_info(struct Scsi_Host *);
 
-extern int atp870u_proc_info(char *, char **, off_t, int, int, int);
-
 #endif
diff -Nru a/drivers/scsi/cpqfcTS.h b/drivers/scsi/cpqfcTS.h
--- a/drivers/scsi/cpqfcTS.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/cpqfcTS.h	Mon May 12 07:26:11 2003
@@ -6,7 +6,7 @@
 extern int cpqfcTS_detect(Scsi_Host_Template *);
 extern int cpqfcTS_release(struct Scsi_Host *);
 extern const char * cpqfcTS_info(struct Scsi_Host *);
-extern int cpqfcTS_proc_info(char *, char **, off_t, int, int, int);
+extern int cpqfcTS_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 extern int cpqfcTS_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 extern int cpqfcTS_abort(Scsi_Cmnd *);
 extern int cpqfcTS_reset(Scsi_Cmnd *, unsigned int);
diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/cpqfcTSinit.c	Mon May 12 07:26:11 2003
@@ -921,10 +921,9 @@
 
 // Routine to get data for /proc RAM filesystem
 //
-int cpqfcTS_proc_info (char *buffer, char **start, off_t offset, int length, 
-		       int hostno, int inout)
+int cpqfcTS_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, 
+		       int inout)
 {
-  struct Scsi_Host *host;
   Scsi_Cmnd DumCmnd;
   int Chan, Targ, i;
   struct info_str info;
@@ -933,11 +932,6 @@
   PFC_LOGGEDIN_PORT pLoggedInPort;
   char buf[81];
 
-  // Search the Scsi host list for our controller
-  host = scsi_host_hn_get(hostno);
-
-  if (!host) return -ESRCH;
-
   if (inout) return -EINVAL;
 
   // get the pointer to our Scsi layer HBA buffer  
@@ -969,7 +963,7 @@
     				NULL,     // DON'T search list for FC WWN
     				NULL))){   // DON'T care about end of list
 	copy_info(&info, "Host: scsi%d Channel: %02d TargetId: %02d -> WWN: ",
-			   hostno, Chan, Targ);
+			   host->host_no, Chan, Targ);
         for( i=3; i>=0; i--)        // copy the LOGIN port's WWN
           copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]);
         for( i=7; i>3; i--)             // copy the LOGIN port's WWN
diff -Nru a/drivers/scsi/dc390.h b/drivers/scsi/dc390.h
--- a/drivers/scsi/dc390.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/dc390.h	Mon May 12 08:06:40 2003
@@ -33,8 +33,6 @@
 # define USE_NEW_EH
 #endif
 
-#if defined(HOSTS_C) || defined(MODULE) || LINUX_VERSION_CODE > KERNEL_VERSION(2,3,99)
-
 extern int DC390_detect(Scsi_Host_Template *psht);
 extern int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
 extern int DC390_abort(Scsi_Cmnd *cmd);
@@ -47,7 +45,5 @@
 #else
 # define DC390_release NULL
 #endif
-
-extern int DC390_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
 
 #endif /* DC390_H */
diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c	Tue May  6 13:16:34 2003
+++ b/drivers/scsi/dc395x.c	Mon May 19 19:40:42 2003
@@ -5364,7 +5364,7 @@
 	eeprom = &dc395x_trm_eepromBuf[index];
 	pTempACB = DC395x_pACB_start;
 	if (pTempACB != NULL) {
-		for (; (pTempACB != (struct AdapterCtlBlk *) -1);) {
+		while (pTempACB) {
 			if (pTempACB->IRQLevel == irq) {
 				used_irq = 1;
 				break;
@@ -5842,11 +5842,11 @@
 		if (!DC395x_pACB_start) {
 			DC395x_pACB_start = pACB;
 			DC395x_pACB_current = pACB;
-			pACB->pNextACB = (struct AdapterCtlBlk *) -1;
+			pACB->pNextACB = NULL;
 		} else {
 			DC395x_pACB_current->pNextACB = pACB;
 			DC395x_pACB_current = pACB;
-			pACB->pNextACB = (struct AdapterCtlBlk *) -1;
+			pACB->pNextACB = NULL;
 		}
 		/*DC395x_ACB_UNLOCK(pACB,acb_flags); */
 		return host;
@@ -6062,12 +6062,11 @@
  else SPRINTF(" No  ")
 
 static int
-DC395x_proc_info(char *buffer, char **start, off_t offset, int length,
-		 int hostno, int inout)
+DC395x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length,
+		 int inout)
 {
 	int dev, spd, spd1;
 	char *pos = buffer;
-	struct Scsi_Host *shpnt = NULL;
 	struct AdapterCtlBlk *pACB;
 	struct DeviceCtlBlk *pDCB;
 	unsigned long flags;
@@ -6077,16 +6076,12 @@
 
 	pACB = DC395x_pACB_start;
 
-	while (pACB != (struct AdapterCtlBlk *) -1) {
-		shpnt = pACB->pScsiHost;
-		if (shpnt->host_no == hostno)
+	while (pACB) {
+		if (pACB->pScsiHost == shpnt)
 			break;
 		pACB = pACB->pNextACB;
 	}
-	if (pACB == (struct AdapterCtlBlk *) -1)
-		return -ESRCH;
-
-	if (!shpnt)
+	if (!pACB)
 		return -ESRCH;
 
 	if (inout)		/* Has data been written to the file ? */
@@ -6306,7 +6301,7 @@
 		 */
 		int irq_count;
 		for (irq_count = 0, pACB = DC395x_pACB_start;
-		     pACB != (struct AdapterCtlBlk *) -1;
+		     pACB;
 		     pACB = pACB->pNextACB) {
 			if (pACB->IRQLevel == host->irq)
 				++irq_count;
diff -Nru a/drivers/scsi/dmx3191d.h b/drivers/scsi/dmx3191d.h
--- a/drivers/scsi/dmx3191d.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/dmx3191d.h	Mon May 12 08:01:09 2003
@@ -1,4 +1,3 @@
-
 /*
     dmx3191d.h - defines for the Domex DMX3191D SCSI card.
     Copyright (C) 2000 by Massimo Piccioni <dafastidio@libero.it>
@@ -23,7 +22,6 @@
 static int dmx3191d_abort(Scsi_Cmnd *);
 static int dmx3191d_detect(Scsi_Host_Template *);
 static const char* dmx3191d_info(struct Scsi_Host *);
-static int dmx3191d_proc_info(char *, char **, off_t, int, int, int);
 static int dmx3191d_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 static int dmx3191d_release_resources(struct Scsi_Host *);
 static int dmx3191d_bus_reset(Scsi_Cmnd *);
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/dpt_i2o.c	Mon May 12 07:26:11 2003
@@ -505,8 +505,8 @@
 	return (char *) (pHba->detail);
 }
 
-static int adpt_proc_info(char *buffer, char **start, off_t offset,
-		  int length, int hostno, int inout)
+static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+		  int length, int inout)
 {
 	struct adpt_device* d;
 	int id;
@@ -515,7 +515,6 @@
 	int begin = 0;
 	int pos = 0;
 	adpt_hba* pHba;
-	struct Scsi_Host *host;
 	int unit;
 
 	*start = buffer;
@@ -539,7 +538,7 @@
 	// Find HBA (host bus adapter) we are looking for
 	down(&adpt_configuration_lock);
 	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		if (pHba->host->host_no == hostno) {
+		if (pHba->host == host) {
 			break;	/* found adapter */
 		}
 	}
diff -Nru a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
--- a/drivers/scsi/dpti.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/dpti.h	Mon May 12 07:26:11 2003
@@ -37,8 +37,6 @@
  * SCSI interface function Prototypes
  */
 
-static int adpt_proc_info(char *buffer, char **start, off_t offset,
-		  int length, int inode, int inout);
 static int adpt_detect(Scsi_Host_Template * sht);
 static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
 static int adpt_abort(Scsi_Cmnd * cmd);
diff -Nru a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h
--- a/drivers/scsi/dtc.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/dtc.h	Mon May 12 07:26:11 2003
@@ -36,8 +36,6 @@
 static int dtc_bus_reset(Scsi_Cmnd *);
 static int dtc_device_reset(Scsi_Cmnd *);
 static int dtc_host_reset(Scsi_Cmnd *);
-static int dtc_proc_info (char *buffer, char **start, off_t offset,
-		   int length, int hostno, int inout);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
diff -Nru a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
--- a/drivers/scsi/eata_pio.c	Sun May 25 17:00:00 2003
+++ b/drivers/scsi/eata_pio.c	Mon May 26 18:54:34 2003
@@ -102,20 +102,15 @@
  * length: If inout==FALSE max number of bytes to be written into the buffer 
  *         else number of bytes in the buffer
  */
-static int eata_pio_proc_info(char *buffer, char **start, off_t offset,
-			      int length, int hostno, int rw)
+static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
+			      int length, int rw)
 {
-    struct Scsi_Host *shost;
     static u8 buff[512];
     int size, len = 0;
     off_t begin = 0, pos = 0;
 
     if (rw)
     	return -ENOSYS;
-    shost = scsi_host_hn_get(hostno);
-    if (!shost)
-    	return -EINVAL;
-
     if (offset == 0)
 	memset(buff, 0, sizeof(buff));
 
diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c
--- a/drivers/scsi/esp.c	Sun May 18 03:04:59 2003
+++ b/drivers/scsi/esp.c	Mon May 26 18:54:35 2003
@@ -1408,8 +1408,8 @@
 }
 
 /* ESP proc filesystem code. */
-static int esp_proc_info(char *buffer, char **start, off_t offset,
-			 int length, int hostno, int inout)
+static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			 int length, int inout)
 {
 	struct esp *esp;
 
@@ -1417,7 +1417,7 @@
 		return -EINVAL; /* not yet */
 
 	for_each_esp(esp) {
-		if (esp->ehost->host_no == hostno)
+		if (esp->ehost == host)
 			break;
 	}
 	if (!esp)
diff -Nru a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c
--- a/drivers/scsi/fcal.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/fcal.c	Mon May 12 07:26:12 2003
@@ -209,17 +209,12 @@
 #undef SPRINTF
 #define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); }
 
-int fcal_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+int fcal_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout)
 {
-	struct Scsi_Host *host = NULL;
 	struct fcal *fcal;
 	fc_channel *fc;
 	char *pos = buffer;
 	int i, j;
-
-	host = scsi_host_hn_get(hostno);
-
-	if (!host) return -ESRCH;
 
 	if (inout) return length;
     
diff -Nru a/drivers/scsi/fcal.h b/drivers/scsi/fcal.h
--- a/drivers/scsi/fcal.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/fcal.h	Mon May 12 07:26:12 2003
@@ -22,7 +22,6 @@
 
 int fcal_detect(Scsi_Host_Template *);
 int fcal_release(struct Scsi_Host *);
-int fcal_proc_info (char *, char **, off_t, int, int, int);
 int fcal_slave_configure(Scsi_Device *);
 
 #endif /* !(_FCAL_H) */
diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	Thu May  8 11:24:14 2003
+++ b/drivers/scsi/fd_mcs.c	Mon May 12 07:26:12 2003
@@ -586,9 +586,8 @@
  * length: If inout==FALSE max number of bytes to be written into the buffer 
  *         else number of bytes in the buffer
  */
-static int fd_mcs_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+static int fd_mcs_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
 {
-	struct Scsi_Host *shpnt;
 	int len = 0;
 	int i;
 
@@ -597,20 +596,10 @@
 
 	*start = buffer + offset;
 
-	for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
-	shpnt = hosts[i];
-
-	if (!shpnt) {
-		return (-ENOENT);
-	} else {
-		len += sprintf(buffer + len, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION);
-
-		len += sprintf(buffer + len, "HOST #%d: %s\n", hostno, adapter_name);
-
-		len += sprintf(buffer + len, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size, FIFO_COUNT);
-
-		len += sprintf(buffer + len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);
-	}
+	len += sprintf(buffer + len, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION);
+	len += sprintf(buffer + len, "HOST #%d: %s\n", shpnt->host_no, adapter_name);
+	len += sprintf(buffer + len, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size, FIFO_COUNT);
+	len += sprintf(buffer + len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);
 
 	if ((len -= offset) <= 0)
 		return 0;
diff -Nru a/drivers/scsi/fd_mcs.h b/drivers/scsi/fd_mcs.h
--- a/drivers/scsi/fd_mcs.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/fd_mcs.h	Mon May 12 07:26:12 2003
@@ -32,7 +32,6 @@
 static int fd_mcs_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 static int fd_mcs_biosparam(struct scsi_device *, struct block_device *,
 			    sector_t, int *);
-static int fd_mcs_proc_info(char *, char **, off_t, int, int, int);
 static const char *fd_mcs_info(struct Scsi_Host *);
 
 #endif				/* _FD_MCS_H */
diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c	Sat Apr 26 07:28:20 2003
+++ b/drivers/scsi/fdomain.c	Mon May 12 07:26:12 2003
@@ -1068,45 +1068,6 @@
    return buffer;
 }
 
-				/* First pass at /proc information routine. */
-/*
- * inout : decides on the direction of the dataflow and the meaning of the 
- *         variables
- * buffer: If inout==FALSE data is being written to it else read from it
- * *start: If inout==FALSE start of the valid data in the buffer
- * offset: If inout==FALSE offset from the beginning of the imaginary file 
- *         from which we start writing into the buffer
- * length: If inout==FALSE max number of bytes to be written into the buffer 
- *         else number of bytes in the buffer
- */
-static int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset,
-			    int length, int hostno, int inout )
-{
-   const char *info = fdomain_16x0_info( NULL );
-   int        len;
-   int        pos;
-   int        begin;
-
-   if (inout) return(-EINVAL);
-    
-   begin = 0;
-   strcpy( buffer, info );
-   strcat( buffer, "\n" );
-
-   pos = len = strlen( buffer );
-
-   if(pos < offset) {
-      len = 0;
-      begin = pos;
-   }
-    
-   *start = buffer + (offset - begin);   /* Start of wanted data */
-   len -= (offset - begin);
-   if(len > length) len = length;
-   
-   return(len);
-}
-   
 #if 0
 static int fdomain_arbitrate( void )
 {
@@ -1870,7 +1831,6 @@
 	.module			= THIS_MODULE,
 	.name			= "fdomain",
 	.proc_name		= "fdomain",
-	.proc_info		= fdomain_16x0_proc_info,
 	.detect			= fdomain_16x0_detect,
 	.info			= fdomain_16x0_info,
 	.command		= fdomain_16x0_command,
diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
--- a/drivers/scsi/g_NCR5380.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/g_NCR5380.c	Mon May 12 07:26:12 2003
@@ -770,14 +770,13 @@
  *	Locks: global cli/lock for queue walk
  */
  
-int generic_NCR5380_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, char **start, off_t offset, int length, int inout)
 {
 	int len = 0;
 	NCR5380_local_declare();
 	unsigned long flags;
 	unsigned char status;
 	int i;
-	struct Scsi_Host *scsi_ptr;
 	Scsi_Cmnd *ptr;
 	struct NCR5380_hostdata *hostdata;
 #ifdef NCR5380_STATS
@@ -785,9 +784,6 @@
 	extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
 #endif
 
-	/* For now this is constant so we may walk it */
-	scsi_ptr = scsi_host_hn_get(hostno);
-	
 	NCR5380_setup(scsi_ptr);
 	hostdata = (struct NCR5380_hostdata *) scsi_ptr->hostdata;
 
diff -Nru a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
--- a/drivers/scsi/g_NCR5380.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/g_NCR5380.h	Thu May 22 18:23:21 2003
@@ -51,11 +51,8 @@
 static int generic_NCR5380_bus_reset(Scsi_Cmnd *);
 static int generic_NCR5380_host_reset(Scsi_Cmnd *);
 static int generic_NCR5380_device_reset(Scsi_Cmnd *);
-static int notyet_generic_proc_info (char *buffer ,char **start, off_t offset,
-                     int length, int hostno, int inout);
 static const char* generic_NCR5380_info(struct Scsi_Host *);
 static int generic_NCR5380_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
-static int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
@@ -102,7 +99,7 @@
 #define NCR5380_region_size 0x3a00
 
 #define NCR5380_read(reg) isa_readb(NCR5380_map_name + NCR53C400_mem_base + (reg))
-#define NCR5380_write(reg, value) isa_writeb(NCR5380_map_name + NCR53C400_mem_base + (reg), value)
+#define NCR5380_write(reg, value) isa_writeb(value, NCR5380_map_name + NCR53C400_mem_base + (reg))
 #endif
 
 #define NCR5380_implementation_fields \
diff -Nru a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
--- a/drivers/scsi/gdth.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/gdth.h	Mon May 12 07:26:12 2003
@@ -978,7 +978,7 @@
 
 #if LINUX_VERSION_CODE >= 0x020501
 int gdth_bios_param(struct scsi_device *,struct block_device *,sector_t,int *);
-int gdth_proc_info(char *,char **,off_t,int,int,int);
+int gdth_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int);
 int gdth_eh_abort(Scsi_Cmnd *scp);
 int gdth_eh_device_reset(Scsi_Cmnd *scp);
 int gdth_eh_bus_reset(Scsi_Cmnd *scp);
diff -Nru a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
--- a/drivers/scsi/gdth_proc.c	Thu Apr 17 15:01:39 2003
+++ b/drivers/scsi/gdth_proc.c	Mon May 12 08:08:27 2003
@@ -6,31 +6,24 @@
 #include <linux/completion.h>
 #endif
 
-int gdth_proc_info(char *buffer,char **start,off_t offset,int length,   
-                   int hostno,int inout)
+int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,   
+                   int inout)
 {
-    int hanum,busnum,i;
+    int hanum,busnum;
 
     TRACE2(("gdth_proc_info() length %d ha %d offs %d inout %d\n",
             length,hostno,(int)offset,inout));
 
-    for (i=0; i<gdth_ctr_vcount; ++i) {
-        if (gdth_ctr_vtab[i]->host_no == hostno)
-            break;
-    }
-    if (i==gdth_ctr_vcount)
-        return(-EINVAL);
-
-    hanum = NUMDATA(gdth_ctr_vtab[i])->hanum;
-    busnum= NUMDATA(gdth_ctr_vtab[i])->busnum;
+    hanum = NUMDATA(host)->hanum;
+    busnum= NUMDATA(host)->busnum;
 
     if (inout)
-        return(gdth_set_info(buffer,length,i,hanum,busnum));
+        return(gdth_set_info(buffer,length,hanum,busnum));
     else
-        return(gdth_get_info(buffer,start,offset,length,i,hanum,busnum));
+        return(gdth_get_info(buffer,start,offset,length,hanum,busnum));
 }
 
-static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
+static int gdth_set_info(char *buffer,int length,int hanum,int busnum)
 {
     int             ret_val = -EINVAL;
 #if LINUX_VERSION_CODE >= 0x020503
@@ -763,7 +756,7 @@
 #endif
 
 static int gdth_get_info(char *buffer,char **start,off_t offset,
-                         int length,int vh,int hanum,int busnum)
+                         int length,int hanum,int busnum)
 {
     int size = 0,len = 0;
     off_t begin = 0,pos = 0;
diff -Nru a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h
--- a/drivers/scsi/gdth_proc.h	Thu Mar  6 15:10:14 2003
+++ b/drivers/scsi/gdth_proc.h	Mon May 12 08:13:36 2003
@@ -5,9 +5,9 @@
  * $Id: gdth_proc.h,v 1.13 2003/02/27 14:59:25 achim Exp $
  */
 
-static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum);
+static int gdth_set_info(char *buffer,int length,int hanum,int busnum);
 static int gdth_get_info(char *buffer,char **start,off_t offset,
-                         int length,int vh,int hanum,int busnum);
+                         int length,int hanum,int busnum);
 
 #if LINUX_VERSION_CODE >= 0x020503
 static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd, 
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Sun Apr 20 05:51:54 2003
+++ b/drivers/scsi/hosts.c	Mon May 26 18:54:35 2003
@@ -216,6 +216,10 @@
 	scsi_proc_host_rm(shost);
 	scsi_forget_host(shost);
 	scsi_sysfs_remove_host(shost);
+
+	if (shost->hostt->release)
+		(*shost->hostt->release)(shost);
+
 	return 0;
 }
 
@@ -318,7 +322,12 @@
            shost_tp->eh_host_reset_handler == NULL) {
 		printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\nERROR: This is not a safe way to run your SCSI host\nERROR: The error handling must be added to this driver\n", shost_tp->proc_name);
 		dump_stack();
-        } 
+        }
+	if(shost_tp->shost_attrs == NULL)
+		/* if its not set in the template, use the default */
+		 shost_tp->shost_attrs = scsi_sysfs_shost_attrs;
+	if(shost_tp->sdev_attrs == NULL)
+		 shost_tp->sdev_attrs = scsi_sysfs_sdev_attrs;
 	gfp_mask = GFP_KERNEL;
 	if (shost_tp->unchecked_isa_dma && xtr_bytes)
 		gfp_mask |= __GFP_DMA;
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Thu May  8 11:24:14 2003
+++ b/drivers/scsi/hosts.h	Mon May 26 14:47:09 2003
@@ -68,7 +68,7 @@
      * outside the kernel ie. userspace and it also provides an interface
      * to feed the driver with information. Check eata_dma_proc.c for reference
      */
-    int (*proc_info)(char *, char **, off_t, int, int, int);
+    int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
 
     /*
      * The name pointer is a pointer to the name of the SCSI
@@ -356,6 +356,16 @@
      * FIXME: This should probably be a value in the template */
     #define SCSI_DEFAULT_HOST_BLOCKED	7
 
+    /*
+     * pointer to the sysfs class properties for this host
+     */
+    struct class_device_attribute **shost_attrs;
+
+    /*
+     * Pointer to the SCSI device properties for this host
+     */
+    struct device_attribute **sdev_attrs;
+
 } Scsi_Host_Template;
 
 /*
@@ -570,9 +580,6 @@
 extern int scsi_register_host(Scsi_Host_Template *);
 extern int scsi_unregister_host(Scsi_Host_Template *);
 
-extern struct Scsi_Host *scsi_host_hn_get(unsigned short);
-extern void scsi_host_put(struct Scsi_Host *);
-
 /**
  * scsi_find_device - find a device given the host
  * @shost:	SCSI host pointer
@@ -590,5 +597,7 @@
                         return sdev;
         return NULL;
 }
+
+extern void scsi_sysfs_release_attributes(struct SHT *hostt);
 
 #endif
diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/ibmmca.c	Mon May 12 07:26:12 2003
@@ -2384,7 +2384,7 @@
 }
 
 /* routine to display info in the proc-fs-structure (a deluxe feature) */
-static int ibmmca_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
 {
 	int len = 0;
 	int i, id, lun, host_index;
@@ -2392,13 +2392,13 @@
 	unsigned long flags;
 	int max_pun;
 
-	for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
+	for (i = 0; hosts[i] && hosts[i] != shpnt; i++);
 	
 	spin_lock_irqsave(hosts[i]->host_lock, flags);	/* Check it */
-	shpnt = hosts[i];
 	host_index = i;
 	if (!shpnt) {
-		len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n", hostno);
+		len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n",
+				shpnt->host_no);
 		return len;
 	}
 	max_pun = subsystem_maxid(host_index);
@@ -2411,7 +2411,7 @@
 #else
 	len += sprintf(buffer + len, "               Multiple LUN probing.....: No\n");
 #endif
-	len += sprintf(buffer + len, "               This Hostnumber..........: %d\n", hostno);
+	len += sprintf(buffer + len, "               This Hostnumber..........: %d\n", shpnt->host_no);
 	len += sprintf(buffer + len, "               Base I/O-Port............: 0x%x\n", (unsigned int) (IM_CMD_REG(host_index)));
 	len += sprintf(buffer + len, "               (Shared) IRQ.............: %d\n", IM_IRQ);
 	len += sprintf(buffer + len, "               Total Interrupts.........: %d\n", IBM_DS(host_index).total_interrupts);
diff -Nru a/drivers/scsi/ibmmca.h b/drivers/scsi/ibmmca.h
--- a/drivers/scsi/ibmmca.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/ibmmca.h	Mon May 12 07:26:12 2003
@@ -11,7 +11,6 @@
 /* Common forward declarations for all Linux-versions: */
 
 /* Interfaces to the midlevel Linux SCSI driver */
-static int ibmmca_proc_info (char *, char **, off_t, int, int, int);
 static int ibmmca_detect (Scsi_Host_Template *);
 static int ibmmca_release (struct Scsi_Host *);
 static int ibmmca_command (Scsi_Cmnd *);
diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c
--- a/drivers/scsi/imm.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/imm.c	Mon May 12 07:26:12 2003
@@ -253,14 +253,14 @@
     return (-EINVAL);
 }
 
-int imm_proc_info(char *buffer, char **start, off_t offset,
+int imm_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
 		  int length, int hostno, int inout)
 {
     int i;
     int len = 0;
 
     for (i = 0; i < 4; i++)
-	if (imm_hosts[i].host == hostno)
+	if (imm_hosts[i].host == host->host_no)
 	    break;
 
     if (inout)
diff -Nru a/drivers/scsi/imm.h b/drivers/scsi/imm.h
--- a/drivers/scsi/imm.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/imm.h	Mon May 12 07:26:13 2003
@@ -159,7 +159,6 @@
 int imm_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 int imm_abort(Scsi_Cmnd *);
 int imm_reset(Scsi_Cmnd *);
-int imm_proc_info(char *, char **, off_t, int, int, int);
 int imm_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int *);
 
diff -Nru a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
--- a/drivers/scsi/in2000.c	Sun May 25 17:00:00 2003
+++ b/drivers/scsi/in2000.c	Mon May 26 18:54:36 2003
@@ -2154,7 +2154,7 @@
 }
 
 
-static int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
+static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off, int len, int in)
 {
 
 #ifdef PROC_INTERFACE
@@ -2162,17 +2162,11 @@
 	char *bp;
 	char tbuf[128];
 	unsigned long flags;
-	struct Scsi_Host *instance;
 	struct IN2000_hostdata *hd;
 	Scsi_Cmnd *cmd;
 	int x, i;
 	static int stop = 0;
 
-	instance = scsi_host_hn_get(hn);
-	if (!instance) {
-		printk("*** Hmm... Can't find host #%d!\n", hn);
-		return (-ESRCH);
-	}
 	hd = (struct IN2000_hostdata *) instance->hostdata;
 
 /* If 'in' is TRUE we need to _read_ the proc file. We accept the following
diff -Nru a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h
--- a/drivers/scsi/in2000.h	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/in2000.h	Mon May 12 07:26:13 2003
@@ -401,7 +401,6 @@
 static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 static int in2000_abort(Scsi_Cmnd *);
 static void in2000_setup(char *, int *) in2000__INIT;
-static int in2000_proc_info(char *, char **, off_t, int, int, int);
 static int in2000_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int *);
 static int in2000_host_reset(Scsi_Cmnd *);
diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c	Tue May  6 10:19:58 2003
+++ b/drivers/scsi/ips.c	Mon May 12 07:26:13 2003
@@ -488,7 +488,7 @@
 static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned int count);
 static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned int count);
 
-int  ips_proc_info(char *, char **, off_t, int, int, int);
+int  ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
 static void copy_mem_info(IPS_INFOSTR *, char *, int);
 static int copy_info(IPS_INFOSTR *, char *, ...);
@@ -1496,8 +1496,8 @@
 /*                                                                          */
 /****************************************************************************/
 int
-ips_proc_info(char *buffer, char **start, off_t offset,
-              int length, int hostno, int func) {
+ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+              int length, int func) {
    int           i;
    int           ret;
    ips_ha_t     *ha = NULL;
@@ -1507,7 +1507,7 @@
    /* Find our host structure */
    for (i = 0; i < ips_next_controller; i++) {
       if (ips_sh[i]) {
-         if (ips_sh[i]->host_no == hostno) {
+         if (ips_sh[i] == host) {
             ha = (ips_ha_t *) ips_sh[i]->hostdata;
             break;
          }
diff -Nru a/drivers/scsi/mac_NCR5380.c b/drivers/scsi/mac_NCR5380.c
--- a/drivers/scsi/mac_NCR5380.c	Fri May  9 03:21:35 2003
+++ b/drivers/scsi/mac_NCR5380.c	Mon May 26 18:54:37 2003
@@ -740,7 +740,7 @@
 	printk("NCR5380_print_status: no memory for print buffer\n");
 	return;
     }
-    len = NCR5380_proc_info(pr_bfr, &start, 0, PAGE_SIZE, HOSTNO, 0);
+    len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0);
     pr_bfr[len] = 0;
     printk("\n%s\n", pr_bfr);
     free_page((unsigned long) pr_bfr);
@@ -771,11 +771,10 @@
 #ifndef NCR5380_proc_info
 static
 #endif
-int NCR5380_proc_info (char *buffer, char **start, off_t offset,
-		       int length, int hostno, int inout)
+int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start, off_t offset,
+		       int length, int inout)
 {
     char *pos = buffer;
-    struct Scsi_Host *instance;
     struct NCR5380_hostdata *hostdata;
     Scsi_Cmnd *ptr;
     unsigned long flags;
@@ -787,13 +786,6 @@
 	    pos = buffer;			\
 	}					\
     } while (0)
-
-    for (instance = first_instance; instance && HOSTNO != hostno;
-	 instance = instance->next)
-	;
-    if (!instance)
-	return(-ESRCH);
-    hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
     if (inout) { /* Has data been written to the file ? */
 	return(-ENOSYS);  /* Currently this is a no-op */
diff -Nru a/drivers/scsi/mac_scsi.h b/drivers/scsi/mac_scsi.h
--- a/drivers/scsi/mac_scsi.h	Fri Dec 20 06:37:31 2002
+++ b/drivers/scsi/mac_scsi.h	Mon May 12 07:26:13 2003
@@ -32,9 +32,6 @@
 #define MACSCSI_PUBLIC_RELEASE 2
 
 #ifndef ASM
-int macscsi_proc_info (char *buffer, char **start, off_t offset,
-			int length, int hostno, int inout);
-
 #ifndef NULL
 #define NULL 0
 #endif
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	Sat May 17 14:09:51 2003
+++ b/drivers/scsi/megaraid.c	Mon May 19 19:40:43 2003
@@ -2392,21 +2392,6 @@
 		enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];
 }
 
-
-/*
- * megaraid_proc_info()
- *
- * Returns data to be displayed in /proc/scsi/megaraid/X
- */
-static int
-megaraid_proc_info(char *buffer, char **start, off_t offset, int length,
-		int host_no, int inout)
-{
-	*start = buffer;
-	return 0;
-}
-
-
 /*
  * Release the controller's resources
  */
@@ -5379,7 +5364,6 @@
 
 static Scsi_Host_Template driver_template = {
 	.name =				"MegaRAID",
-	.proc_info =			megaraid_proc_info,
 	.detect =			megaraid_detect,
 	.release =			megaraid_release,
 	.info =				megaraid_info,
diff -Nru a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
--- a/drivers/scsi/megaraid.h	Sun May  4 02:56:44 2003
+++ b/drivers/scsi/megaraid.h	Mon May 12 07:26:13 2003
@@ -1007,7 +1007,6 @@
 static int megaraid_abort_and_reset(adapter_t *, Scsi_Cmnd *, int);
 static int megaraid_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int []);
-static int megaraid_proc_info (char *, char **, off_t, int, int, int);
 static int mega_print_inquiry(char *, char *);
 
 static int mega_build_sglist (adapter_t *adapter, scb_t *scb,
diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
--- a/drivers/scsi/ncr53c8xx.c	Sun May 25 17:00:00 2003
+++ b/drivers/scsi/ncr53c8xx.c	Mon May 26 18:54:38 2003
@@ -399,8 +399,8 @@
 
 static irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
 static void ncr53c8xx_timeout(unsigned long np);
-static int ncr53c8xx_proc_info(char *buffer, char **start, off_t offset,
-			int length, int hostno, int func);
+static int ncr53c8xx_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			int length, int func);
 
 #define initverbose (driver_setup.verbose)
 #define bootverbose (np->verbose)
@@ -9249,21 +9249,17 @@
 **	- func = 1 means write (parse user control command)
 */
 
-static int ncr53c8xx_proc_info(char *buffer, char **start, off_t offset,
-			int length, int hostno, int func)
+static int ncr53c8xx_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			int length, int func)
 {
-	struct Scsi_Host *host;
 	struct host_data *host_data;
 	ncb_p ncb = 0;
 	int retv;
 
 #ifdef DEBUG_PROC_INFO
-printk("ncr53c8xx_proc_info: hostno=%d, func=%d\n", hostno, func);
+printk("ncr53c8xx_proc_info: hostno=%d, func=%d\n", host->host_no, func);
 #endif
 
-	if((host = scsi_host_hn_get(hostno))==NULL)
-		return -EINVAL;
-		
 	host_data = (struct host_data *) host->hostdata;
 	ncb = host_data->ncb;
 
diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c	Thu May  8 11:24:14 2003
+++ b/drivers/scsi/nsp32.c	Mon May 12 07:26:14 2003
@@ -286,7 +286,7 @@
 static int nsp32_eh_host_reset(Scsi_Cmnd *);
 static int nsp32_reset(Scsi_Cmnd *, unsigned int);
 static int nsp32_release(struct Scsi_Host *);
-static int nsp32_proc_info(char *, char **, off_t, int, int, int);
+static int nsp32_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *);
 static void __devexit nsp32_remove(struct pci_dev *);
 static int __init init_nsp32(void);
@@ -1555,18 +1555,16 @@
 #undef SPRINTF
 #define SPRINTF(args...) \
         do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
-static int nsp32_proc_info(char  *buffer,
+static int nsp32_proc_info(struct Scsi_Host *host, char  *buffer,
 			   char **start,
 			   off_t  offset,
 			   int    length,
-			   int    hostno,
 			   int    inout)
 {
 	char *pos = buffer;
 	int thislength;
 	unsigned long flags;
 	nsp32_hw_data *data;
-	struct Scsi_Host *host = NULL;
 	unsigned int base;
 	unsigned char mode_reg;
 
@@ -1575,19 +1573,12 @@
 		return -EINVAL;
 	}
 
-	/* search this HBA host */
-	
-	host = scsi_host_hn_get(hostno);
-	
-	if (host == NULL) {
-		return -ESRCH;
-	}
 	data = (nsp32_hw_data *)host->hostdata;
 	base = host->io_port;
 
 	SPRINTF("NinjaSCSI-32 status\n\n");
 	SPRINTF("Driver version:        %s\n",		nsp32_release_version);
-	SPRINTF("SCSI host No.:         %d\n",		hostno);
+	SPRINTF("SCSI host No.:         %d\n",		host->host_no);
 	SPRINTF("IRQ:                   %d\n",		host->irq);
 	SPRINTF("IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
 	SPRINTF("MMIO(virtual address): 0x%lx\n",	host->base);
diff -Nru a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h
--- a/drivers/scsi/pas16.h	Sun May  4 02:56:44 2003
+++ b/drivers/scsi/pas16.h	Mon May 12 07:26:14 2003
@@ -122,8 +122,6 @@
 static int pas16_bus_reset(Scsi_Cmnd *);
 static int pas16_host_reset(Scsi_Cmnd *);
 static int pas16_device_reset(Scsi_Cmnd *);
-static int pas16_proc_info (char *buffer ,char **start, off_t offset,
-		     int length, int hostno, int inout);
 
 #ifndef NULL
 #define NULL 0
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	Thu May  1 09:44:53 2003
+++ b/drivers/scsi/pcmcia/nsp_cs.c	Mon May 12 08:14:55 2003
@@ -1291,11 +1291,10 @@
 #undef SPRINTF
 #define SPRINTF(args...) \
         do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
-static int nsp_proc_info(char  *buffer,
+static int nsp_proc_info(struct Scsi_Host *host, char  *buffer,
 			 char **start,
 			 off_t  offset,
 			 int    length,
-			 int    hostno,
 			 int    inout)
 {
 	int id;
@@ -1304,29 +1303,14 @@
 	int speed;
 	unsigned long flags;
 	nsp_hw_data *data = &nsp_data;
-	struct Scsi_Host *host = NULL;
 
 	if (inout) {
 		return -EINVAL;
 	}
 
-	/* search this HBA host */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45))
-	host = scsi_host_hn_get(hostno);
-#else
-	for (host=scsi_hostlist; host; host=host->next) {
-                if (host->host_no == hostno) {
-                        break;
-                }
-        }
-#endif
-	if (host == NULL) {
-		return -ESRCH;
-	}
-
 	SPRINTF("NinjaSCSI status\n\n");
 	SPRINTF("Driver version:        $Revision: 1.5 $\n");
-	SPRINTF("SCSI host No.:         %d\n",          hostno);
+	SPRINTF("SCSI host No.:         %d\n",          host->host_no);
 	SPRINTF("IRQ:                   %d\n",          host->irq);
 	SPRINTF("IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
 	SPRINTF("MMIO(virtual address): 0x%lx\n",       host->base);
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
--- a/drivers/scsi/pcmcia/nsp_cs.h	Sun Mar  2 23:32:33 2003
+++ b/drivers/scsi/pcmcia/nsp_cs.h	Mon May 12 07:26:17 2003
@@ -281,8 +281,8 @@
 static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
 
 static const char *nsp_info(struct Scsi_Host *shpnt);
-static int nsp_proc_info(char *buffer, char **start, off_t offset,
-			 int length, int hostno, int inout);
+static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			 int length, int inout);
 static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 
 /*static int nsp_eh_abort(Scsi_Cmnd * SCpnt);*/
diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c	Sun May  4 02:56:44 2003
+++ b/drivers/scsi/ppa.c	Mon May 12 07:26:14 2003
@@ -270,14 +270,14 @@
     return (-EINVAL);
 }
 
-int ppa_proc_info(char *buffer, char **start, off_t offset,
-		  int length, int hostno, int inout)
+int ppa_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+		  int length, int inout)
 {
     int i;
     int len = 0;
 
     for (i = 0; i < 4; i++)
-	if (ppa_hosts[i].host == hostno)
+	if (ppa_hosts[i] == host)
 	    break;
 
     if (inout)
diff -Nru a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h
--- a/drivers/scsi/ppa.h	Sun May  4 02:56:44 2003
+++ b/drivers/scsi/ppa.h	Mon May 12 07:26:14 2003
@@ -167,7 +167,7 @@
 int ppa_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 int ppa_abort(Scsi_Cmnd *);
 int ppa_reset(Scsi_Cmnd *);
-int ppa_proc_info(char *, char **, off_t, int, int, int);
+int ppa_proc_info(struct Scsi_Host *host, char *, char **, off_t, int, int);
 int ppa_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int *);
 
diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c	Sun May  4 02:56:45 2003
+++ b/drivers/scsi/qla1280.c	Mon May 26 16:33:44 2003
@@ -332,6 +332,23 @@
 #define pci_dma_lo32(a)		(a & 0xffffffff)
 #define pci_dma_hi32(a)		0
 #endif
+/* MACROS for managing the endian addresses */
+static inline uint16_t qla1280_addr0_15(dma_addr_t dma)
+{
+	return ((uint16_t)(dma & 0xffff));
+}
+static inline uint16_t qla1280_addr16_31(dma_addr_t dma)
+{
+	return ((uint16_t)((dma >> 16) & 0xffff));
+}
+static inline uint16_t qla1280_addr32_47(dma_addr_t dma)
+{
+	return ((uint16_t)(pci_dma_hi32(dma) & 0xffff));
+}
+static inline uint16_t qla1280_addr48_63(dma_addr_t dma)
+{
+	return ((uint16_t)((pci_dma_hi32(dma) >> 16) & 0xffff));
+}
 
 #define NVRAM_DELAY()		udelay(500)	/* 2 microsecond delay */
 
@@ -442,6 +459,35 @@
 static void qla12160_get_target_parameters(struct scsi_qla_host *,
 					   uint32_t, uint32_t, uint32_t);
 
+/* convert scsi data direction to request_t control flags
+ */
+static inline uint16_t
+qla1280_data_direction(struct scsi_cmnd *cmnd)
+{
+	uint16_t flags = 0;
+
+	switch(cmnd->sc_data_direction) {
+
+	case SCSI_DATA_NONE:
+		flags = 0;
+		break;
+
+	case SCSI_DATA_READ:
+		flags = BIT_5;
+		break;
+
+	case SCSI_DATA_WRITE:
+		flags = BIT_6;
+		break;
+
+	case SCSI_DATA_UNKNOWN:
+	default:
+		flags = BIT_5 | BIT_6;
+		break;
+	}
+	return flags;
+}
+		
 #if QL1280_LUN_SUPPORT
 static void qla1280_enable_lun(struct scsi_qla_host *, int, int);
 #endif
@@ -623,11 +669,10 @@
 #define	PROC_BUF	&qla1280_buffer[len]
 
 int
-qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
-		  int hostno, int inout)
+qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,
+		  int inout)
 {
 #if QLA1280_PROFILE
-	struct Scsi_Host *host;
 	struct scsi_qla_host *ha;
 	int size = 0;
 	scsi_lu_t *up;
@@ -637,22 +682,9 @@
 	host = NULL;
 
 	/* Find the host that was specified */
-	for (ha = qla1280_hostlist; (ha != NULL) && ha->host->host_no != hostno;
+	for (ha = qla1280_hostlist; (ha != NULL) && ha->host != host;
 	     ha = ha->next) ;
 
-	/* if host wasn't found then exit */
-	if (!ha) {
-		size =  sprintf(buffer, "Can't find adapter for host "
-				"number %d\n", hostno);
-		if (size > length) {
-			return size;
-		} else {
-			return 0;
-		}
-	}
-
-	host = ha->host;
-
 	if (inout == TRUE) {	/* Has data been written to the file? */
 		printk(KERN_INFO
 		       "qla1280_proc: has data been written to the file.\n");
@@ -1226,280 +1258,36 @@
 	return 0;
 }
 
-/**************************************************************************
- *   qla1200_abort
- *     Abort the speciifed SCSI command(s).
- **************************************************************************/
-int
-qla1280_abort(Scsi_Cmnd * cmd)
-{
-	struct scsi_qla_host *ha;
-	srb_t *sp;
-	struct Scsi_Host *host;
-	unsigned int bus, target, lun;
-	scsi_lu_t *q;
-	int return_status = SCSI_ABORT_SUCCESS;
-	int found = 0;
-	int i;
-	unsigned char *handle;
-	u16 data;
-
-	ENTER("qla1280_abort");
-	ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
-	host = cmd->device->host;
-
-	/* Get the SCSI request ptr */
-	sp = (srb_t *)CMD_SP(cmd);
-	handle = CMD_HANDLE(cmd);
-	if (qla1280_verbose)
-		printk(KERN_ERR "scsi(%li): ABORT Command=0x%p, handle=0x%p\n",
-		       ha->host_no, (void *) cmd, (void *) handle);
-
-	/* Check for pending interrupts. */
-	if (handle == NULL) {
-		/* we never got this command */
-		printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
-		return SCSI_ABORT_NOT_RUNNING;	/* no action - we don't have command */
-	}
-	data = qla1280_debounce_register(&ha->iobase->istatus);
-	/*
-	 * The io_request_lock is held when the reset handler is called, hence
-	 * the interrupt handler cannot be running in parallel as it also
-	 * grabs the lock. No reason to play funny games with set_bit() in
-	 * order to test for interrupt handler entry as the driver used to
-	 * do here.
-	 * /Jes
-	 */
-	if (data & RISC_INT) {
-		/* put any pending command in done queue */
-		qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
-	}
+typedef enum {
+	ABORT_COMMAND,
+	ABORT_DEVICE,
+	DEVICE_RESET,
+	BUS_RESET,
+	ADAPTER_RESET,
+	FAIL
+} action_t;
 
-	/*
-	 * This seems unnecessary, it's not used below! / Jes
-	 */
-#ifdef UNUSED
-	handle = CMD_HANDLE(cmd);
-#endif
-
-	/* Generate LU queue on bus, target, LUN */
-	bus = SCSI_BUS_32(cmd);
-	target = SCSI_TCN_32(cmd);
-	lun = SCSI_LUN_32(cmd);
-	if ((q = LU_Q(ha, bus, target, lun)) == NULL) {
-		/* No lun queue -- command must not be active */
-		printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the "
-		       "specified device\n", bus, target, lun);
-		return SCSI_ABORT_NOT_RUNNING;	/* no action - we don't have command */
-	}
-#if AUTO_ESCALATE_ABORT
-	if ((sp->flags & SRB_ABORTED)) {
-		dprintk(1, "qla1280_abort: Abort escalayted - returning "
-			"SCSI_ABORT_SNOOZE.\n");
-		return SCSI_ABORT_SNOOZE;
-	}
-#endif
-
-	if ((sp->flags & SRB_ABORT_PENDING)) {
-		if (qla1280_verbose)
-			printk(KERN_WARNING
-			       "scsi(): Command has a pending abort "
-			       "message - ABORT_PENDING.\n");
-
-		return SCSI_ABORT_PENDING;
-	}
-#if STOP_ON_ABORT
-	printk(KERN_WARNING "Scsi layer issued a ABORT command= 0x%p\n", cmd);
-	qla1280_print_scsi_cmd(2, cmd);
-#endif
-
-	/*
-	 * Normally, would would need to search our queue for the specified command
-	 * but; since our sp contains the cmd ptr, we can just remove it from our
-	 * LUN queue.
-	 */
-	if (!(sp->flags & SRB_SENT)) {
-		found++;
-		if (qla1280_verbose)
-			printk(KERN_WARNING
-			       "scsi(): Command returned from queue "
-			       "aborted.\n");
-
-		/* Remove srb from SCSI LU queue. */
-		qla1280_removeq(q, sp);
-		sp->flags |= SRB_ABORTED;
-		CMD_RESULT(cmd) = DID_ABORT << 16;
-		qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
-		return_status = SCSI_ABORT_SUCCESS;
-	} else {		/* find the command in our active list */
-		for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
-			if (sp == ha->outstanding_cmds[i]) {
-				found++;
-				dprintk(1,
-					"qla1280: RISC aborting command.\n");
-				qla1280_abort_command(ha, sp);
-				return_status = SCSI_ABORT_PENDING;
-				break;
-			}
-		}
-	}
-
-#if STOP_ON_ABORT
-	qla1280_panic("qla1280_abort", ha->host);
-#endif
-	if (found == 0)
-		return_status = SCSI_ABORT_NOT_RUNNING;	/* no action - we don't have command */
-
-	dprintk(1, "qla1280_abort: Aborted status returned = 0x%x.\n",
-		return_status);
-
-	if (ha->done_q_first)
-		qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
-	if (found)
-		qla1280_restart_queues(ha);
-
-	LEAVE("qla1280_abort");
-	return return_status;
-}
-
-int
-qla1280_new_abort(Scsi_Cmnd * cmd)
+/* timer action for error action processor */
+static void qla1280_error_wait_timeout(unsigned long __data)
 {
-	struct scsi_qla_host *ha;
-	srb_t *sp;
-	struct Scsi_Host *host;
-	int bus, target, lun;
-	scsi_lu_t *q;
-	unsigned long cpu_flags;
-	int return_status = SCSI_ABORT_SUCCESS;
-	int found = 0;
-	int i;
-	unsigned char *handle;
-	u16 data;
-
-	ENTER("qla1280_abort");
-	host = cmd->device->host;
-	ha = (struct scsi_qla_host *)host->hostdata;
-
-	/* Get the SCSI request ptr */
-	sp = (srb_t *) CMD_SP(cmd);
-	handle = CMD_HANDLE(cmd);
-	if (qla1280_verbose)
-		printk(KERN_ERR "scsi(%li): ABORT Command=0x%p, handle=0x%p\n",
-		       ha->host_no, cmd, handle);
-
-	/* Check for pending interrupts. */
-	if (handle == NULL) {
-		/* we never got this command */
-		printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
-		return SUCCESS;	/* no action - we don't have command */
-	}
+	struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data;
+	srb_t *sp = (srb_t *)CMD_SP(cmd);
 
-	spin_lock_irqsave (ha->host->host_lock, cpu_flags);
-	data = qla1280_debounce_register(&ha->iobase->istatus);
-	/*
-	 * We grab the host lock in the interrupt handler to
-	 * prevent racing here.
-	 *
-	 * Then again, running the interrupt handler from here is somewhat
-	 * questionable.
-	 * /Jes
-	 */
-	if (data & RISC_INT) {
-		/* put any pending command in done queue */
-		qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
-	}
-
-	/* Generate LU queue on bus, target, LUN */
-	bus = SCSI_BUS_32(cmd);
-	target = SCSI_TCN_32(cmd);
-	lun = SCSI_LUN_32(cmd);
-	if ((q = LU_Q(ha, bus, target, lun)) == NULL) {
-		/* No lun queue -- command must not be active */
-		printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the "
-		       "specified device\n", bus, target, lun);
-		return_status = SUCCESS;	/* no action - we don't have command */
-		goto out;
-	}
-
-	if ((sp->flags & SRB_ABORT_PENDING)) {
-		if (qla1280_verbose)
-			printk(KERN_WARNING
-			       "scsi(): Command has a pending abort "
-			       "message - ABORT_PENDING.\n");
-
-		return_status = SCSI_ABORT_PENDING;
-		goto out;
-	}
-#if STOP_ON_ABORT
-	printk(KERN_WARNING "Scsi layer issued a ABORT command= 0x%p\n", cmd);
-	qla1280_print_scsi_cmd(2, cmd);
-#endif
-
-	/*
-	 * Normally, would would need to search our queue for the specified command
-	 * but; since our sp contains the cmd ptr, we can just remove it from our
-	 * LUN queue.
-	 */
-	if (!(sp->flags & SRB_SENT)) {
-		found++;
-		if (qla1280_verbose)
-			printk(KERN_WARNING
-			       "scsi(): Command returned from queue "
-			       "aborted.\n");
-
-		/* Remove srb from SCSI LU queue. */
-		qla1280_removeq(q, sp);
-		sp->flags |= SRB_ABORTED;
-		CMD_RESULT(cmd) = DID_ABORT << 16;
-		qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
-		return_status = SUCCESS;
-	} else {		/* find the command in our active list */
-		for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
-			if (sp == ha->outstanding_cmds[i]) {
-				found++;
-				dprintk(1,
-					"qla1280: RISC aborting command.\n");
-				qla1280_abort_command(ha, sp);
-				return_status = SCSI_ABORT_PENDING;
-				break;
-			}
-		}
-	}
-
-#if STOP_ON_ABORT
-	qla1280_panic("qla1280_abort", ha->host);
-#endif
-	if (found == 0)
-		return_status = SUCCESS;	/* no action - we don't have the command */
-
-	dprintk(1, "qla1280_abort: Aborted status returned = 0x%x.\n",
-		return_status);
-
-	if (ha->done_q_first)
-		qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
-	if (found)
-		qla1280_restart_queues(ha);
-
- out:
-	spin_unlock_irqrestore(ha->host->host_lock, cpu_flags);
-
-	LEAVE("qla1280_abort");
-	return return_status;
+	complete(sp->wait);
 }
 
 /**************************************************************************
- * qla1200_reset
- *    The reset function will reset the SCSI bus and abort any executing
- *    commands.
+ * qla1200_error_action
+ *    The function will attempt to perform a specified error action and
+ *    wait for the results (or time out).
  *
  * Input:
  *      cmd = Linux SCSI command packet of the command that cause the
  *            bus reset.
- *      flags = SCSI bus reset option flags (see scsi.h)
+ *      action = error action to take (see action_t)
  *
  * Returns:
- *      DID_RESET in cmd.host_byte of aborted command(s)
+ *      SUCCESS or FAIL
  *
  * Note:
  *      Resetting the bus always succeeds - is has to, otherwise the
@@ -1508,36 +1296,34 @@
  *      the SCSI bus reset line.
  **************************************************************************/
 int
-qla1280_reset(Scsi_Cmnd * cmd, unsigned int flags)
+qla1280_error_action(Scsi_Cmnd * cmd, action_t action)
 {
 	struct scsi_qla_host *ha;
 	int bus, target, lun;
 	srb_t *sp;
-	typedef enum {
-		ABORT_DEVICE = 1,
-		DEVICE_RESET = 2,
-		BUS_RESET = 3,
-		ADAPTER_RESET = 4,
-		RESET_DELAYED = 5,
-		FAIL = 6
-	} action_t;
-	action_t action = ADAPTER_RESET;
-	u16 data;
+	uint16_t data;
+	unsigned char *handle;
 	scsi_lu_t *q;
 	int result;
+	DECLARE_COMPLETION(wait);
+	struct timer_list timer;
 
-	ENTER("qla1280_reset");
+	ENTER("qla1280_error_action");
 	if (qla1280_verbose)
 		printk(KERN_INFO "scsi(): Resetting Cmnd=0x%p, Handle=0x%p, "
-		       "flags=0x%x\n", cmd, CMD_HANDLE(cmd), flags);
+		       "action=0x%x\n", cmd, CMD_HANDLE(cmd), action);
+
 	if (cmd == NULL) {
 		printk(KERN_WARNING
 		       "(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd "
 		       "pointer, failing.\n");
-		return SCSI_RESET_SNOOZE;
+		LEAVE("qla1280_error_action");
+		return FAIL;
 	}
+
 	ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
 	sp = (srb_t *)CMD_SP(cmd);
+	handle = CMD_HANDLE(cmd);
 
 #if STOP_ON_RESET
 	qla1280_panic("qla1280_reset", ha->host);
@@ -1557,27 +1343,14 @@
 	 * Determine the suggested action that the mid-level driver wants
 	 * us to perform.
 	 */
-	if (CMD_HANDLE(cmd) == NULL) {
-		/*
-		 * if mid-level driver called reset with a orphan SCSI_Cmnd
-		 * (i.e. a command that's not pending), so perform the
-		 * function specified.
-		 */
-		if (flags & SCSI_RESET_SUGGEST_HOST_RESET)
-			action = ADAPTER_RESET;
-		else
-			action = BUS_RESET;
+	if (handle == NULL) {
+		if(action == ABORT_COMMAND) {
+			/* we never got this command */
+			printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
+			return SUCCESS;	/* no action - we don't have command */
+		}
 	} else {
-		/*
-		 * Mid-level driver has called reset with this SCSI_Cmnd and
-		 * its pending.
-		 */
-		if (flags & SCSI_RESET_SUGGEST_HOST_RESET)
-			action = ADAPTER_RESET;
-		else if (flags & SCSI_RESET_SUGGEST_BUS_RESET)
-			action = BUS_RESET;
-		else
-			action = DEVICE_RESET;
+		sp->wait = &wait;
 	}
 
 	bus = SCSI_BUS_32(cmd);
@@ -1585,36 +1358,67 @@
 	lun = SCSI_LUN_32(cmd);
 	q = LU_Q(ha, bus, target, lun);
 
-#if AUTO_ESCALATE_RESET
-	if ((action & DEVICE_RESET) && (q->q_flag & QLA1280_QRESET)) {
-		printk(KERN_INFO
-		       "qla1280(%ld): Bus device reset already sent to "
-		       "device, escalating.\n", ha->host_no);
-		action = BUS_RESET;
-	}
-	if ((action & DEVICE_RESET) && (sp->flags & SRB_ABORT_PENDING)) {
-		printk(KERN_INFO
-		       "qla1280(%ld):Have already attempted to reach "
-		       "device with abort device\n", ha->host_no);
-		printk(KERN_INFO "qla1280(%ld):message, will escalate to BUS "
-		       "RESET.\n", ha->host_no);
-		action = BUS_RESET;
-	}
-#endif
-
-	/*
-	 *  By this point, we want to already know what we are going to do,
-	 *  so we only need to perform the course of action.
-	 */
-	result = SCSI_RESET_ERROR;
+	/* Overloading result.  Here it means the success or fail of the
+	 * *issue* of the action.  When we return from the routine, it must
+	 * mean the actual success or fail of the action */
+	result = FAIL;
 	switch (action) {
 	case FAIL:
 		break;
 
-	case RESET_DELAYED:
-		result = SCSI_RESET_PENDING;
+	case ABORT_COMMAND:
+		if (q == NULL) {
+			/* No lun queue -- command must not be active */
+			printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the "
+			       "specified device\n", bus, target, lun);
+			break;
+		}
+		if ((sp->flags & SRB_ABORT_PENDING)) {
+			printk(KERN_WARNING
+			       "scsi(): Command has a pending abort "
+			       "message - ABORT_PENDING.\n");
+			/* This should technically be impossible since we
+			 * now wait for abort completion */
+			break;
+		}
+
+		/*
+		 * Normally, would would need to search our queue for
+		 * the specified command but; since our sp contains
+		 * the cmd ptr, we can just remove it from our LUN
+		 * queue.
+		 */
+		if (!(sp->flags & SRB_SENT)) {
+			if (qla1280_verbose)
+				printk(KERN_WARNING
+				       "scsi(): Command returned from queue "
+				       "aborted.\n");
+			
+			/* Remove srb from SCSI LU queue. */
+			qla1280_removeq(q, sp);
+			sp->flags |= SRB_ABORTED;
+			CMD_RESULT(cmd) = DID_ABORT << 16;
+			qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
+			if (ha->done_q_first)
+				qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
+			
+			qla1280_restart_queues(ha);
+			
+		} else {	/* find the command in our active list */
+			int i;
+
+			for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
+				if (sp == ha->outstanding_cmds[i]) {
+					dprintk(1,
+						"qla1280: RISC aborting command.\n");
+					qla1280_abort_command(ha, sp);
+				}
+			}
+		}
 		break;
 
+
+
 	case ABORT_DEVICE:
 		ha->flags.in_reset = TRUE;
 		if (qla1280_verbose)
@@ -1623,7 +1427,7 @@
 			       "command.\n", ha->host_no, bus, target, lun);
 		qla1280_abort_queue_single(ha, bus, target, lun, DID_ABORT);
 		if (qla1280_abort_device(ha, bus, target, lun) == 0)
-			result = SCSI_RESET_PENDING;
+			result = SUCCESS;
 		break;
 
 	case DEVICE_RESET:
@@ -1636,7 +1440,7 @@
 			qla1280_abort_queue_single(ha, bus, target, lun,
 						   DID_ABORT);
 		if (qla1280_device_reset(ha, bus, target) == 0)
-			result = SCSI_RESET_PENDING;
+			result = SUCCESS;
 		q->q_flag |= QLA1280_QRESET;
 		break;
 
@@ -1651,24 +1455,12 @@
 				qla1280_abort_queue_single(ha, bus, target,
 							   lun, DID_RESET);
 		qla1280_bus_reset(ha, bus);
-		/*
-		 * The bus reset routine returns all the outstanding commands
-		 * back with "DID_RESET" in the status field after a short
-		 * delay by the firmware. If the mid-level time out the SCSI
-		 * reset before our delay we may need to ignore it.
-		 */
-		/* result = SCSI_RESET_PENDING | SCSI_RESET_BUS_RESET; */
-		result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
-		/*
-		 * Wheeeee!!!
-		 */
-		mdelay(4 * 1000);
-		barrier();
-		if (flags & SCSI_RESET_SYNCHRONOUS) {
-			CMD_RESULT(cmd) = DID_BUS_BUSY << 16;
-			(*(cmd)->scsi_done)(cmd);
-		}
-		/* ha->reset_start = jiffies; */
+
+		/* wait 4 seconds */
+		schedule_timeout(4*HZ);
+
+		result = SUCCESS;
+
 		break;
 
 	case ADAPTER_RESET:
@@ -1688,7 +1480,7 @@
 		 * mid-level code can expect completions momentitarily.
 		 */
 		if (qla1280_abort_isp(ha) == 0)
-			result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
+			result = SUCCESS;
 
 		ha->flags.reset_active = FALSE;
 	}
@@ -1698,13 +1490,81 @@
 	qla1280_restart_queues(ha);
 	ha->flags.in_reset = FALSE;
 
+	/* If we didn't manage to issue the action, or we have no
+	 * command to wait for, exit here */
+	if(result == FAIL || handle == NULL)
+		goto leave;
+
+	/* set up a timer just in case we're really jammed */
+	init_timer(&timer);
+	timer.expires = jiffies + 4*HZ;
+	timer.data = (unsigned long)cmd;
+	timer.function = qla1280_error_wait_timeout;
+	add_timer(&timer);
+
+	/* wait for the action to complete (or the timer to expire) */
+	spin_unlock_irq(ha->host->host_lock);
+	wait_for_completion(&wait);
+	del_timer_sync(&timer);
+	spin_lock_irq(ha->host->host_lock);
+	sp->wait = NULL;
+	
+	/* the only action we might get a fail for is abort */
+	if(action == ABORT_COMMAND) {
+		if(sp->flags & SRB_ABORTED)
+			result = SUCCESS;
+		else
+			result = FAILED;
+	}
+
+ leave:
 	dprintk(1, "RESET returning %d\n", result);
 
-	LEAVE("qla1280_reset");
+	LEAVE("qla1280_error_action");
 	return result;
 }
 
 /**************************************************************************
+ *   qla1200_abort
+ *     Abort the specified SCSI command(s).
+ **************************************************************************/
+int
+qla1280_eh_abort(struct scsi_cmnd * cmd)
+{
+	return qla1280_error_action(cmd, ABORT_COMMAND);
+}
+
+/**************************************************************************
+ *   qla1200_device_reset
+ *     Reset the specified SCSI device
+ **************************************************************************/
+int
+qla1280_eh_device_reset(struct scsi_cmnd *cmd)
+{
+	return qla1280_error_action(cmd, DEVICE_RESET);
+}
+
+/**************************************************************************
+ *   qla1200_bus_reset
+ *     Reset the specified bus.
+ **************************************************************************/
+int
+qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
+{
+	return qla1280_error_action(cmd, BUS_RESET);
+}
+
+/**************************************************************************
+ *   qla1200_adapter_reset
+ *     Reset the specified adapter (both channels)
+ **************************************************************************/
+int
+qla1280_eh_adapter_reset(struct scsi_cmnd *cmd)
+{
+	return qla1280_error_action(cmd, ADAPTER_RESET);
+}
+
+/**************************************************************************
  * qla1280_biosparam
  *   Return the disk geometry for the given SCSI device.
  **************************************************************************/
@@ -1934,6 +1794,9 @@
 
 		(*(cmd)->scsi_done)(cmd);
 
+		if(sp->wait != NULL)
+			complete(sp->wait);
+
 		qla1280_next(ha, q, bus);
 	}
 	LEAVE("qla1280_done");
@@ -2537,11 +2400,11 @@
 	dprintk(1, "qla1280_isp_firmware: Completed Reading NVRAM\n");
 
 	dprintk(3, "qla1280_isp_firmware: NVRAM Magic ID= %c %c %c\n",
-		(char *)nv->id[0], nv->id[1], nv->id[2]);
+		nv->id0, nv->id1, nv->id2);
 
 	/* Bad NVRAM data, load RISC code. */
-	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
-	    nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1) {
+	if (chksum || nv->id0 != 'I' || nv->id1 != 'S' ||
+	    nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) {
 		printk(KERN_INFO "qla1280_isp_firmware: Bad checksum or magic "
 		       "number or version in NVRAM.\n");
 		ha->flags.disable_risc_code_load = FALSE;
@@ -2791,7 +2654,7 @@
  * Returns:
  *      0 = success.
  */
-#define DUMP_IT_BACK 0		/* for debug of RISC loading */
+#define DUMP_IT_BACK 1		/* for debug of RISC loading */
 static int
 qla1280_setup_chip(struct scsi_qla_host *ha)
 {
@@ -2806,11 +2669,7 @@
 	int i;
 	uint8_t *sp;
 	uint8_t *tbuf;
-#ifdef QLA_64BIT_PTR
 	dma_addr_t p_tbuf;
-#else
-	uint32_t p_tbuf;
-#endif
 #endif
 
 	ENTER("qla1280_setup_chip");
@@ -2831,6 +2690,8 @@
 
 	num = 0;
 	while (risc_code_size > 0 && !status) {
+		int warn __attribute__((unused)) = 0;
+
 		cnt = 2000 >> 1;
 
 		if (cnt > risc_code_size)
@@ -2839,20 +2700,22 @@
 		dprintk(1, "qla1280_setup_chip:  loading risc @ =(0x%p),"
 			"%d,%d(0x%x)\n",
 			risc_code_address, cnt, num, risc_address);
-		memcpy(ha->request_ring, risc_code_address, (cnt << 1));
+		for(i = 0; i < cnt; i++)
+			((uint16_t *)ha->request_ring)[i] =
+				cpu_to_le16(risc_code_address[i]);
 
 		flush_cache_all();
 
 		mb[0] = MBC_LOAD_RAM;
 		mb[1] = risc_address;
 		mb[4] = cnt;
-		mb[3] = ha->request_dma & 0xffff;
-		mb[2] = (ha->request_dma >> 16) & 0xffff;
-		mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff;
-		mb[6] = pci_dma_hi32(ha->request_dma) >> 16;
+		mb[3] = qla1280_addr0_15(ha->request_dma);
+		mb[2] = qla1280_addr16_31(ha->request_dma);
+		mb[7] = qla1280_addr32_47(ha->request_dma);
+		mb[6] = qla1280_addr48_63(ha->request_dma);
 		dprintk(1, "qla1280_setup_chip: op=%d  0x%p = 0x%4x,0x%4x,"
 			"0x%4x,0x%4x\n",
-			mb[0], ha->request_dma, mb[6], mb[7], mb[2], mb[3]);
+			mb[0], (void *)ha->request_dma, mb[6], mb[7], mb[2], mb[3]);
 		if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 |
 						      BIT_2 | BIT_1 | BIT_0,
 						      &mb[0]))) {
@@ -2860,14 +2723,15 @@
 			       "Failed to load partial segment of f/w\n");
 			break;
 		}
+
 #if DUMP_IT_BACK
-		mb[0] = MBC_READ_RAM_WORD;
+		mb[0] = MBC_DUMP_RAM;
 		mb[1] = risc_address;
 		mb[4] = cnt;
-		mb[3] = p_tbuf & 0xffff;
-		mb[2] = (p_tbuf >> 16) & 0xffff;
-		mb[7] = pci_dma_hi32(p_tbuf) & 0xffff;
-		mb[6] = pci_dma_hi32(p_tbuf) >> 16;
+		mb[3] = qla1280_addr0_15(p_tbuf);
+		mb[2] = qla1280_addr16_31(p_tbuf);
+		mb[7] = qla1280_addr32_47(p_tbuf);
+		mb[6] = qla1280_addr48_63(p_tbuf);
 
 		if ((status = qla1280_mailbox_command(ha,
 						      BIT_4 | BIT_3 | BIT_2 |
@@ -2879,7 +2743,7 @@
 		}
 		sp = (uint8_t *)ha->request_ring;
 		for (i = 0; i < (cnt << 1); i++) {
-			if (tbuf[i] != sp[i]) {
+			if (tbuf[i] != sp[i] &&warn++ < 10) {
 				printk(KERN_ERR "qla1280_setup_chip: FW "
 				       "compare error @ byte(0x%x) loop#=%x\n",
 				       i, num);
@@ -3044,8 +2908,8 @@
 #endif
 
 	/* Bad NVRAM data, set defaults parameters. */
-	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
-	    nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1) {
+	if (chksum || nv->id0 != 'I' || nv->id1 != 'S' ||
+	    nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) {
 #if USE_NVRAM_DEFAULTS
 		dprintk(1, "Using defaults for NVRAM\n");
 #else
@@ -3262,14 +3126,14 @@
 			    ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) {
 				nvram160_t *nv2 = (nvram160_t *) nv;
 				mb[2] |=
-					nv2->bus[bus].target[target].flags.
+					nv2->bus[bus].target[target].flags2.
 					enable_ppr << 5;
 
 				mb[6] =
-					nv2->bus[bus].target[target].flags.
+					nv2->bus[bus].target[target].flags2.
 					ppr_options << 8;
 				mb[6] |=
-					nv2->bus[bus].target[target].flags.
+					nv2->bus[bus].target[target].flags2.
 					ppr_bus_width;
 				mr |= BIT_6;
 			}
@@ -3885,13 +3749,13 @@
 			pkt->entry_type = COMMAND_A64_TYPE;
 			pkt->entry_count = (uint8_t) req_cnt;
 			pkt->sys_define = (uint8_t) ha->req_ring_index;
-			pkt->handle = (uint32_t) cnt;
+			pkt->handle = cpu_to_le32(cnt);
 
 			/* Zero out remaining portion of packet. */
 			memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
 			/* Set ISP command timeout. */
-			pkt->timeout = 30;
+			pkt->timeout = cpu_to_le16(30);
 
 			/* Set device target ID and LUN */
 			pkt->lun = SCSI_LUN_32(cmd);
@@ -3900,28 +3764,24 @@
 
 			/* Enable simple tag queuing if device supports it. */
 			if (cmd->device->tagged_queue)
-				pkt->control_flags |= BIT_3;
+				pkt->control_flags |= cpu_to_le16(BIT_3);
 
 			/* Load SCSI command packet. */
-			pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd);
-			memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), pkt->cdb_len);
+			pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
+			memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
 			/* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
 
+			/* Set transfer direction. */
+			sp->dir = qla1280_data_direction(cmd);
+			pkt->control_flags |= cpu_to_le16(sp->dir);
+			
+			/* Set total data segment count. */
+			pkt->dseg_count = cpu_to_le16(seg_cnt);
+
 			/*
 			 * Load data segments.
 			 */
 			if (seg_cnt) {	/* If data transfer. */
-				/* Set transfer direction. */
-				if ((cmd->data_cmnd[0] == WRITE_6))
-					pkt->control_flags |= BIT_6;
-				else
-					pkt->control_flags |= (BIT_5 | BIT_6);
-
-				sp->dir = pkt->control_flags & (BIT_5 | BIT_6);
-
-				/* Set total data segment count. */
-				pkt->dseg_count = seg_cnt;
-
 				/* Setup packet address segment pointer. */
 				dword_ptr = (u32 *)&pkt->dseg_0_address;
 
@@ -4198,13 +4058,13 @@
 			pkt->entry_type = COMMAND_TYPE;
 			pkt->entry_count = (uint8_t) req_cnt;
 			pkt->sys_define = (uint8_t) ha->req_ring_index;
-			pkt->handle = (uint32_t) cnt;
+			pkt->handle = cpu_to_le32(cnt);
 
 			/* Zero out remaining portion of packet. */
 			memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
 			/* Set ISP command timeout. */
-			pkt->timeout = 30;
+			pkt->timeout = cpu_to_le16(30);
 
 			/* Set device target ID and LUN */
 			pkt->lun = SCSI_LUN_32(cmd);
@@ -4213,35 +4073,24 @@
 
 			/* Enable simple tag queuing if device supports it. */
 			if (cmd->device->tagged_queue)
-				pkt->control_flags |= BIT_3;
+				pkt->control_flags |= cpu_to_le16(BIT_3);
 
 			/* Load SCSI command packet. */
-			pkt->cdb_len = (uint16_t) CMD_CDBLEN(cmd);
-			memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), pkt->cdb_len);
+			pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
+			memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
 
 			/*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
+			/* Set transfer direction. */
+			sp->dir = qla1280_data_direction(cmd);
+			pkt->control_flags |= cpu_to_le16(sp->dir);
+			
+			/* Set total data segment count. */
+			pkt->dseg_count = cpu_to_le16(seg_cnt);
+
 			/*
 			 * Load data segments.
 			 */
 			if (seg_cnt) {
-				/* Set transfer direction (READ and WRITE) */
-				/* Linux doesn't tell us                   */
-				/*
-				 * For block devices, cmd->request->cmd has the operation
-				 * For character devices, this isn't always set properly, so
-				 * we need to check data_cmnd[0].  This catches the conditions
-				 * for st.c, but not sg. Generic commands are pass down to us.
-				 */
-				if ((cmd->data_cmnd[0] == WRITE_6))
-					pkt->control_flags |= BIT_6;
-				else
-					pkt->control_flags |= (BIT_5 | BIT_6);
-
-				sp->dir = pkt->control_flags & (BIT_5 | BIT_6);
-
-				/* Set total data segment count. */
-				pkt->dseg_count = seg_cnt;
-
 				/* Setup packet address segment pointer. */
 				dword_ptr = &pkt->dseg_0_address;
 
@@ -4258,7 +4107,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
 						*dword_ptr++ =
 							cpu_to_le32(virt_to_bus(sg->address));
-						*dword_ptr++ = sg->length;
+						*dword_ptr++ = cpu_to_le32(sg->length);
 						dprintk(1,
 							"S/G Segment phys_addr=0x%x, len=0x%x\n",
 							cpu_to_le32(virt_to_bus(sg->address)),
@@ -4269,8 +4118,8 @@
 						*dword_ptr++ =
 							cpu_to_le32(sg_dma_len(sg));
 						dprintk(1, "S/G Segment phys_addr=0x%x, len=0x%x\n",
-							cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
-							cpu_to_le32(sg_dma_len(sg)));
+							(pci_dma_lo32(sg_dma_address(sg))),
+							(sg_dma_len(sg)));
 #endif
 						sg++;
 					}
@@ -4321,7 +4170,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
 							*dword_ptr++ =
 								cpu_to_le32(virt_to_bus(sg->address));
-							*dword_ptr++ = sg->length;
+							*dword_ptr++ = cpu_to_le32(sg->length);
 							dprintk(1,
 								"S/G Segment Cont. phys_addr=0x%x, len=0x%x\n",
 								cpu_to_le32(pci_dma_lo32(virt_to_bus(sg->address))), sg->length);
@@ -4366,13 +4215,15 @@
 						cpu_to_le32(pci_dma_lo32(dma_handle));
 #endif
 					*dword_ptr =
-						(uint32_t)cmd->request_bufflen;
+						cpu_to_le32(cmd->request_bufflen);
+					qla1280_dump_buffer(1,(char *)pkt,
+							      REQUEST_ENTRY_SIZE);
 				}
 			} else {	/* No data transfer at all */
 
-				dword_ptr = (uint32_t *)(pkt + 1);
-				*dword_ptr++ = 0;
-				*dword_ptr = 0;
+				//dword_ptr = (uint32_t *)(pkt + 1);
+				//*dword_ptr++ = 0;
+				//*dword_ptr = 0;
 				dprintk(5,
 					"qla1280_32bit_start_scsi: No data, command "
 					"packet data - \n");
@@ -4543,12 +4394,12 @@
 	  if (pkt = (elun_entry_t *)qla1280_req_pkt(ha))
 	  {
 	  pkt->entry_type = ENABLE_LUN_TYPE;
-	  pkt->lun = (uint16_t)(bus ? lun | BIT_15 : lun);
+	  pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun);
 	  pkt->command_count = 32;
 	  pkt->immed_notify_count = 1;
 	  pkt->group_6_length = MAX_CMDSZ;
 	  pkt->group_7_length = MAX_CMDSZ;
-	  pkt->timeout = 0x30;
+	  pkt->timeout = cpu_to_le16(0x30);
 
 	  qla1280_isp_cmd(ha);
 	  }
@@ -4593,7 +4444,7 @@
 		if (inotify->seq_id == 0)
 			pkt->event = BIT_7;
 		else
-			pkt->seq_id = inotify->seq_id;
+			pkt->seq_id = cpu_to_le16(inotify->seq_id);
 
 		/* Issue command to ISP */
 		qla1280_isp_cmd(ha);
@@ -4697,17 +4548,17 @@
 		pkt->lun = atio->lun;
 		pkt->initiator_id = atio->initiator_id;
 		pkt->target_id = atio->target_id;
-		pkt->option_flags = atio->option_flags;
+		pkt->option_flags = cpu_to_le32(atio->option_flags);
 		pkt->tag_value = atio->tag_value;
 		pkt->scsi_status = atio->scsi_status;
 
 		if (len) {
-			pkt->dseg_count = 1;
-			pkt->transfer_length = len;
-			pkt->dseg_0_length = len;
+			pkt->dseg_count = cpu_to_le16(1);
+			pkt->transfer_length = cpu_to_le32(len);
+			pkt->dseg_0_length = cpu_to_le32(len);
 			dword_ptr = (uint32_t *) addr;
-			pkt->dseg_0_address[0] = *dword_ptr++;
-			pkt->dseg_0_address[1] = *dword_ptr;
+			pkt->dseg_0_address[0] = cpu_to_le32(*dword_ptr++);
+			pkt->dseg_0_address[1] = cpu_to_le32(*dword_ptr);
 		}
 
 		/* Issue command to ISP */
@@ -4745,16 +4596,16 @@
 		pkt->lun = atio->lun;
 		pkt->initiator_id = atio->initiator_id;
 		pkt->target_id = atio->target_id;
-		pkt->option_flags = atio->option_flags;
+		pkt->option_flags = cpu_to_le32(atio->option_flags);
 		pkt->tag_value = atio->tag_value;
 		pkt->scsi_status = atio->scsi_status;
 
 		if (len) {
-			pkt->dseg_count = 1;
-			pkt->transfer_length = len;
-			pkt->dseg_0_length = len;
-			dword_ptr = (uint32_t *) addr;
-			pkt->dseg_0_address = *dword_ptr;
+			pkt->dseg_count = cpu_to_le16(1);
+			pkt->transfer_length = cpu_to_le32(len);
+			pkt->dseg_0_length = cpu_to_le32(len);
+			dword_ptr = (uint32_t *)addr;
+			pkt->dseg_0_address = cpu_to_le32(*dword_ptr);
 		}
 
 		/* Issue command to ISP */
@@ -4967,7 +4818,7 @@
 						    RESPONSE_ENTRY_SIZE);
 
 				if (pkt->entry_type == STATUS_TYPE) {
-					if ((pkt->scsi_status & 0xff)
+					if ((le16_to_cpu(pkt->scsi_status) & 0xff)
 					    || pkt->comp_status
 					    || pkt->entry_status) {
 						dprintk(2,
@@ -4976,8 +4827,8 @@
 							"scsi_status = 0x%x\n",
 							ha->rsp_ring_index,
 							mailbox[5],
-							pkt->comp_status,
-							pkt->scsi_status);
+							le16_to_cpu(pkt->comp_status),
+							le16_to_cpu(pkt->scsi_status));
 					}
 				} else {
 					dprintk(2,
@@ -5169,7 +5020,7 @@
 			*(sense_ptr + 12) = SC_SELFAIL;
 		}
 		pkt->scsi_status = S_CKCON;
-		pkt->option_flags |= OF_SSTS | OF_NO_DATA;
+		pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
 		if (ha->flags.enable_64bit_addressing)
@@ -5212,7 +5063,7 @@
 				pkt->scsi_status = S_CKCON;
 			}
 
-			pkt->option_flags |= (OF_SSTS | OF_NO_DATA);
+			pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
 			break;
 
 		case SS_REQSEN:
@@ -5226,7 +5077,7 @@
 			else
 				len = pkt->cdb[4];
 			pkt->scsi_status = S_GOOD;
-			pkt->option_flags |= (OF_SSTS | OF_DATA_IN);
+			pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_DATA_IN);
 			break;
 
 		case SS_INQUIR:
@@ -5250,7 +5101,7 @@
 			else
 				len = pkt->cdb[4];
 			pkt->scsi_status = S_GOOD;
-			pkt->option_flags |= (OF_SSTS | OF_DATA_IN);
+			pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_DATA_IN);
 			break;
 
 		case SM_WRDB:
@@ -5281,12 +5132,12 @@
 					*(sense_ptr + 12) = SC_ILLCDB;
 					pkt->scsi_status = S_CKCON;
 					pkt->option_flags |=
-						(OF_SSTS | OF_NO_DATA);
+						cpu_to_le32(OF_SSTS | OF_NO_DATA);
 					len = 0;
 				} else if (len) {
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_DATA_OUT);
+						cpu_to_le32(OF_SSTS | OF_DATA_OUT);
 					dprintk(3,
 						"qla1280_atio_entry: Issuing "
 						"SDI_TARMOD_WRCOMP\n");
@@ -5301,7 +5152,7 @@
 
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_NO_DATA);
+						cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				}
 
 				break;
@@ -5327,11 +5178,11 @@
 					len = 0;
 					pkt->scsi_status = S_CKCON;
 					pkt->option_flags |=
-						(OF_SSTS | OF_NO_DATA);
+						cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				} else if (len) {
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_DATA_OUT);
+						cpu_to_le32(OF_SSTS | OF_DATA_OUT);
 					dprintk(3,
 						"qla1280_atio_entry: Issuing "
 						"SDI_TARMOD_WRCOMP\n");
@@ -5346,7 +5197,7 @@
 
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_NO_DATA);
+						cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				}
 				break;
 
@@ -5360,7 +5211,7 @@
 				*(sense_ptr + 12) = SC_ILLCDB;
 				len = 0;
 				pkt->scsi_status = S_CKCON;
-				pkt->option_flags |= (OF_SSTS | OF_NO_DATA);
+				pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				break;
 			}
 			break;
@@ -5393,7 +5244,7 @@
 						len = TARGET_DATA_SIZE + 4;
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_DATA_IN);
+						cpu_to_le32(OF_SSTS | OF_DATA_IN);
 				} else {
 					dprintk(2,
 						"qla1280_atio_entry: SM_RDDB, "
@@ -5401,7 +5252,7 @@
 
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_NO_DATA);
+						cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				}
 				break;
 			case RW_BUF_DATA:
@@ -5424,7 +5275,7 @@
 					len = 0;
 					pkt->scsi_status = S_CKCON;
 					pkt->option_flags |=
-						(OF_SSTS | OF_NO_DATA);
+						cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				} else {
 					if (*a64 + len > *end_a64)
 						len = *end_a64 - *a64;
@@ -5439,7 +5290,7 @@
 
 						pkt->scsi_status = S_GOOD;
 						pkt->option_flags |=
-							(OF_SSTS | OF_NO_DATA);
+							cpu_to_le32(OF_SSTS | OF_NO_DATA);
 					}
 				}
 				break;
@@ -5468,7 +5319,7 @@
 					}
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_DATA_IN);
+						cpu_to_le32(OF_SSTS | OF_DATA_IN);
 				} else {
 					dprintk(2,
 						"qla1280_atio_entry: SM_RDDB,"
@@ -5476,7 +5327,7 @@
 
 					pkt->scsi_status = S_GOOD;
 					pkt->option_flags |=
-						(OF_SSTS | OF_NO_DATA);
+						cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				}
 				break;
 			default:
@@ -5489,7 +5340,7 @@
 				*(sense_ptr + 12) = SC_ILLCDB;
 				len = 0;
 				pkt->scsi_status = S_CKCON;
-				pkt->option_flags |= (OF_SSTS | OF_NO_DATA);
+				pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
 				break;
 			}
 			break;
@@ -5506,7 +5357,7 @@
 			*(sense_ptr + 12) = SC_INVOPCODE;
 			len = 0;
 			pkt->scsi_status = S_CKCON;
-			pkt->option_flags |= (OF_SSTS | OF_NO_DATA);
+			pkt->option_flags |= cpu_to_le32(OF_SSTS | OF_NO_DATA);
 			break;
 		}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
@@ -5568,18 +5419,21 @@
 	srb_t *sp;
 	scsi_lu_t *q;
 	Scsi_Cmnd *cmd;
+	uint32_t handle = le32_to_cpu(pkt->handle);
+	uint16_t scsi_status = le16_to_cpu(pkt->scsi_status);
+	uint16_t comp_status = le16_to_cpu(pkt->comp_status);
 
 	ENTER("qla1280_status_entry");
 
 	/* Validate handle. */
-	if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
-		sp = ha->outstanding_cmds[pkt->handle];
+	if (handle < MAX_OUTSTANDING_COMMANDS)
+		sp = ha->outstanding_cmds[handle];
 	else
 		sp = 0;
 
 	if (sp) {
 		/* Free outstanding command slot. */
-		ha->outstanding_cmds[pkt->handle] = 0;
+		ha->outstanding_cmds[handle] = 0;
 
 		cmd = sp->cmd;
 
@@ -5589,27 +5443,29 @@
 		lun = SCSI_LUN_32(cmd);
 		q = LU_Q(ha, bus, target, lun);
 
-		if (pkt->comp_status || pkt->scsi_status) {
+		if (comp_status || scsi_status) {
 			dprintk(1, "scsi: comp_status = 0x%x, scsi_status = "
-				"0x%x, handle = 0x%x\n", pkt->comp_status,
-				pkt->scsi_status, pkt->handle);
+				"0x%x, handle = 0x%lx\n", comp_status,
+				scsi_status, handle);
 		}
 
 		/* Target busy */
-		if (pkt->scsi_status & SS_BUSY_CONDITION &&
-		    pkt->scsi_status != SS_RESERVE_CONFLICT) {
+		if (scsi_status & SS_BUSY_CONDITION &&
+		    scsi_status != SS_RESERVE_CONFLICT) {
 			CMD_RESULT(cmd) =
-				DID_BUS_BUSY << 16 | (pkt->scsi_status & 0xff);
+				DID_BUS_BUSY << 16 | (scsi_status & 0xff);
 		} else {
 
 			/* Save ISP completion status */
 			CMD_RESULT(cmd) = qla1280_return_status(pkt, cmd);
 
-			if (pkt->scsi_status & SS_CHECK_CONDITION) {
-				if (pkt->comp_status != CS_ARS_FAILED) {
-					if (pkt->req_sense_length <
+			if (scsi_status & SS_CHECK_CONDITION) {
+				if (comp_status != CS_ARS_FAILED) {
+					uint16_t req_sense_length =
+						le16_to_cpu(pkt->req_sense_length);
+					if (req_sense_length <
 					    CMD_SNSLEN(cmd))
-						sense_sz = pkt->req_sense_length;
+						sense_sz = req_sense_length;
 					else
 						/*
 						 * Scsi_Cmnd->sense_buffer is
@@ -5658,6 +5514,7 @@
 		    srb_t ** done_q_first, srb_t ** done_q_last)
 {
 	srb_t *sp;
+	uint32_t handle = le32_to_cpu(pkt->handle);
 
 	ENTER("qla1280_error_entry");
 
@@ -5671,14 +5528,14 @@
 		dprintk(2, "qla1280_error_entry: UNKNOWN flag error\n");
 
 	/* Validate handle. */
-	if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
-		sp = ha->outstanding_cmds[pkt->handle];
+	if (handle < MAX_OUTSTANDING_COMMANDS)
+		sp = ha->outstanding_cmds[handle];
 	else
 		sp = 0;
 
 	if (sp) {
 		/* Free outstanding command slot. */
-		ha->outstanding_cmds[pkt->handle] = 0;
+		ha->outstanding_cmds[handle] = 0;
 
 		/* Bad payload or header */
 		if (pkt->entry_status & (BIT_3 + BIT_2)) {
@@ -5946,8 +5803,10 @@
 	.release		= qla1280_release,
 	.info			= qla1280_info,
 	.queuecommand		= qla1280_queuecommand,
-	.abort			= qla1280_abort,
-	.reset			= qla1280_reset,
+	.eh_abort_handler	= qla1280_eh_abort,
+	.eh_device_reset_handler = qla1280_eh_device_reset,
+	.eh_bus_reset_handler	= qla1280_eh_bus_reset,
+	.eh_host_reset_handler	= qla1280_eh_adapter_reset,
 	.slave_configure	= qla1280_slave_configure,
 	.bios_param		= qla1280_biosparam,
 	.can_queue		= 255,
diff -Nru a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
--- a/drivers/scsi/qla1280.h	Sun May  4 02:56:45 2003
+++ b/drivers/scsi/qla1280.h	Mon May 26 16:33:44 2003
@@ -158,6 +158,9 @@
 	uint8_t dir;		/* direction of transfer */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
 	dma_addr_t saved_dma_handle;	/* for unmap of single transfers */
+	/* NOTE: the sp->cmd will be NULL when this completion is
+	 * called, so you should know the scsi_cmnd when using this */
+	struct completion *wait;
 #endif
 
 } srb_t;
@@ -317,6 +320,7 @@
 #define MBC_NOP                     0	/* No Operation. */
 #define MBC_LOAD_RAM                1	/* Load RAM. */
 #define MBC_EXECUTE_FIRMWARE        2	/* Execute firmware. */
+#define MBC_DUMP_RAM		     3   /* Dump RAM contents */
 #define MBC_WRITE_RAM_WORD          4	/* Write ram word. */
 #define MBC_READ_RAM_WORD           5	/* Read ram word. */
 #define MBC_MAILBOX_REGISTER_TEST   6	/* Wrap incoming mailboxes */
@@ -371,9 +375,170 @@
 
 /*
  *  QLogic ISP1280 NVRAM structure definition.
+ *
+ * NOTE: the firmware structure is byte reversed on big-endian systems
+ * because it is read a word at a time from the chip, so the in-memory
+ * representation becomes correct
  */
 typedef struct {
-	uint8_t id[4];		/* 0, 1, 2, 3 */
+#if defined(__BIG_ENDIAN)
+	uint8_t id1;		/* 1 */
+	uint8_t id0;		/* 0 */
+
+	uint8_t id3;		/* 3 */
+	uint8_t id2;		/* 2 */
+
+	struct {
+		uint8_t bios_configuration_mode:2;
+		uint8_t bios_disable:1;
+		uint8_t selectable_scsi_boot_enable:1;
+		uint8_t cd_rom_boot_enable:1;
+		uint8_t disable_loading_risc_code:1;
+		uint8_t enable_64bit_addressing:1;
+		uint8_t unused_7:1;
+	} cntr_flags_1;		/* 5 */
+	uint8_t version;	/* 4 */
+
+	struct {
+		uint8_t boot_lun_number:5;
+		uint8_t scsi_bus_number:1;
+		uint8_t unused_6:1;
+		uint8_t unused_7:1;
+		uint8_t boot_target_number:4;
+		uint8_t unused_12:1;
+		uint8_t unused_13:1;
+		uint8_t unused_14:1;
+		uint8_t unused_15:1;
+	} cntr_flags_2;		/* 6, 7 */
+
+	uint16_t unused_8;	/* 8, 9 */
+	uint16_t unused_10;	/* 10, 11 */
+	uint16_t unused_12;	/* 12, 13 */
+	uint16_t unused_14;	/* 14, 15 */
+
+	/* Termination
+	 * 0 = Disable, 1 = high only, 3 = Auto term
+	 */
+	union {
+		uint8_t c;
+		struct {
+			uint8_t scsi_bus_1_control:2;
+			uint8_t scsi_bus_0_control:2;
+			uint8_t unused_0:1;
+			uint8_t unused_1:1;
+			uint8_t unused_2:1;
+			uint8_t auto_term_support:1;
+		} f;
+	} termination;		/* 17 */
+	union {
+		uint8_t c;
+		struct {
+			uint8_t reserved:2;
+			uint8_t burst_enable:1;
+			uint8_t reserved_1:1;
+			uint8_t fifo_threshold:4;
+		} f;
+	} isp_config;		/* 16 */
+
+
+	uint16_t isp_parameter;	/* 18, 19 */
+
+	union {
+		uint16_t w;
+		struct {
+			uint16_t enable_fast_posting:1;
+			uint16_t report_lvd_bus_transition:1;
+			uint16_t unused_2:1;
+			uint16_t unused_3:1;
+			uint16_t unused_4:1;
+			uint16_t unused_5:1;
+			uint16_t unused_6:1;
+			uint16_t unused_7:1;
+			uint16_t unused_8:1;
+			uint16_t unused_9:1;
+			uint16_t unused_10:1;
+			uint16_t unused_11:1;
+			uint16_t unused_12:1;
+			uint16_t unused_13:1;
+			uint16_t unused_14:1;
+			uint16_t unused_15:1;
+		} f;
+	} firmware_feature;	/* 20, 21 */
+
+	uint16_t unused_22;	/* 22, 23 */
+
+	struct {
+		uint8_t bus_reset_delay;	/* 25 */
+		struct {
+			uint8_t initiator_id:4;
+			uint8_t scsi_reset_disable:1;
+			uint8_t scsi_bus_size:1;
+			uint8_t scsi_bus_type:1;
+			uint8_t unused_7:1;
+		} config_1;	/* 24 */
+
+		uint8_t retry_delay;	/* 27 */
+		uint8_t retry_count;	/* 26 */
+
+		uint8_t unused_29;	/* 29 */
+		struct {
+			uint8_t async_data_setup_time:4;
+			uint8_t req_ack_active_negation:1;
+			uint8_t data_line_active_negation:1;
+			uint8_t unused_6:1;
+			uint8_t unused_7:1;
+		} config_2;	/* 28 */
+
+
+		uint16_t selection_timeout;	/* 30, 31 */
+		uint16_t max_queue_depth;	/* 32, 33 */
+
+		uint16_t unused_34;	/* 34, 35 */
+		uint16_t unused_36;	/* 36, 37 */
+		uint16_t unused_38;	/* 38, 39 */
+
+		struct {
+			uint8_t execution_throttle;	/* 41 */
+			union {
+				uint8_t c;
+				struct {
+					uint8_t renegotiate_on_error:1;
+					uint8_t stop_queue_on_check:1;
+					uint8_t auto_request_sense:1;
+					uint8_t tag_queuing:1;
+					uint8_t sync_data_transfers:1;
+					uint8_t wide_data_transfers:1;
+					uint8_t parity_checking:1;
+					uint8_t disconnect_allowed:1;
+				} f;
+			} parameter;	/* 40 */
+
+			struct {
+				uint8_t sync_offset:4;
+				uint8_t device_enable:1;
+				uint8_t lun_disable:1;
+				uint8_t unused_6:1;
+				uint8_t unused_7:1;
+			} flags;	/* 43 */
+			uint8_t sync_period;	/* 42 */
+
+
+			uint16_t unused_44;	/* 44, 45 */
+		} target[MAX_TARGETS];
+	} bus[MAX_BUSES];
+
+	uint16_t unused_248;	/* 248, 249 */
+
+	uint16_t subsystem_id[2];	/* 250, 251, 252, 253 */
+
+	uint8_t chksum;		/* 255 */
+	uint8_t unused_254;	/* 254 */
+
+#elif defined(__LITTLE_ENDIAN)
+	uint8_t id0;		/* 0 */
+	uint8_t id1;		/* 1 */
+	uint8_t id2;		/* 2 */
+	uint8_t id3;		/* 3 */
 	uint8_t version;	/* 4 */
 
 	struct {
@@ -521,14 +686,26 @@
 	uint8_t unused_254;	/* 254 */
 
 	uint8_t chksum;		/* 255 */
+#else
+#error neither __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
+#endif
 } nvram_t;
 
 /*
  *  QLogic ISP12160 NVRAM structure definition.
+ *
+ * NOTE: the firmware structure is byte reversed on big-endian systems
+ * because it is read a word at a time from the chip, so the in-memory
+ * representation becomes correct
  */
 typedef struct {
-	uint8_t id[4];		/* 0, 1, 2, 3 */
-	uint8_t version;	/* 4 */
+#if defined(__BIG_ENDIAN)
+	uint8_t id1;		/* 1 */
+	uint8_t id0;		/* 0 */
+
+	uint8_t id3;		/* 3 */
+	uint8_t id2;		/* 2 */
+
 	/* Host/Bios Flags */
 	struct {
 		uint8_t bios_configuration_mode:2;
@@ -539,17 +716,179 @@
 		uint8_t unused_6:1;
 		uint8_t unused_7:1;
 	} cntr_flags_1;		/* 5 */
+	uint8_t version;	/* 4 */
+
 	/* Selectable Boot Support */
 	struct {
-		uint8_t boot_lun_number:5;
-		uint8_t scsi_bus_number:1;
+		uint16_t boot_lun_number:5;
+		uint16_t scsi_bus_number:1;
+		uint16_t unused_6:1;
+		uint16_t unused_7:1;
+		uint16_t boot_target_number:4;
+		uint16_t unused_12:1;
+		uint16_t unused_13:1;
+		uint16_t unused_14:1;
+		uint16_t unused_15:1;
+	} cntr_flags_2;		/* 6, 7 */
+
+	uint16_t unused_8;	/* 8, 9 */
+	uint16_t unused_10;	/* 10, 11 */
+	uint16_t unused_12;	/* 12, 13 */
+	uint16_t unused_14;	/* 14, 15 */
+
+	/* Termination
+	 * 0 = Disable, 1 = high only, 3 = Auto term
+	 */
+	union {
+		uint8_t c;
+		struct {
+			uint8_t scsi_bus_1_control:2;
+			uint8_t scsi_bus_0_control:2;
+			uint8_t unused_0:1;
+			uint8_t unused_1:1;
+			uint8_t unused_2:1;
+			uint8_t auto_term_support:1;
+		} f;
+	} termination;		/* 17 */
+	/* Auto Term - 3                          */
+	/* High Only - 1 (GPIO2 = 1 & GPIO3 = 0)  */
+	/* Disable - 0 (GPIO2 = 0 & GPIO3 = X)    */
+	/* ISP Config Parameters */
+	union {
+		uint8_t c;
+		struct {
+			uint8_t reserved:2;
+			uint8_t burst_enable:1;
+			uint8_t reserved_1:1;
+			uint8_t fifo_threshold:4;
+		} f;
+	} isp_config;		/* 16 */
+
+	uint16_t isp_parameter;	/* 18, 19 */
+
+	union {
+		uint16_t w;
+		struct {
+			uint16_t enable_fast_posting:1;
+			uint16_t report_lvd_bus_transition:1;
+			uint16_t unused_2:1;
+			uint16_t unused_3:1;
+			uint16_t unused_4:1;
+			uint16_t unused_5:1;
+			uint16_t unused_6:1;
+			uint16_t unused_7:1;
+			uint16_t unused_8:1;
+			uint16_t unused_9:1;
+			uint16_t unused_10:1;
+			uint16_t unused_11:1;
+			uint16_t unused_12:1;
+			uint16_t unused_13:1;
+			uint16_t unused_14:1;
+			uint16_t unused_15:1;
+		} f;
+	} firmware_feature;	/* 20, 21 */
+
+	uint16_t unused_22;	/* 22, 23 */
+
+	struct {
+		uint8_t bus_reset_delay;	/* 25 */
+		struct {
+			uint8_t initiator_id:4;
+			uint8_t scsi_reset_disable:1;
+			uint8_t scsi_bus_size:1;
+			uint8_t scsi_bus_type:1;
+			uint8_t unused_7:1;
+		} config_1;	/* 24 */
+
+		uint8_t retry_delay;	/* 27 */
+		uint8_t retry_count;	/* 26 */
+
+		uint8_t unused_29;	/* 29 */
+		/* Adapter Capabilities bits */
+		struct {
+			uint8_t async_data_setup_time:4;
+			uint8_t req_ack_active_negation:1;
+			uint8_t data_line_active_negation:1;
+			uint8_t unused_6:1;
+			uint8_t unused_7:1;
+		} config_2;	/* 28 */
+
+		uint16_t selection_timeout;	/* 30, 31 */
+		uint16_t max_queue_depth;	/* 32, 33 */
+
+		uint16_t unused_34;	/* 34, 35 */
+		uint16_t unused_36;	/* 36, 37 */
+		uint16_t unused_38;	/* 38, 39 */
+
+		struct {
+			uint8_t execution_throttle;	/* 41 */
+			union {
+				uint8_t c;
+				struct {
+					uint8_t renegotiate_on_error:1;
+					uint8_t stop_queue_on_check:1;
+					uint8_t auto_request_sense:1;
+					uint8_t tag_queuing:1;
+					uint8_t sync_data_transfers:1;
+					uint8_t wide_data_transfers:1;
+					uint8_t parity_checking:1;
+					uint8_t disconnect_allowed:1;
+				} f;
+			} parameter;	/* 40 */
+
+			struct {
+				uint8_t sync_offset:5;
+				uint8_t device_enable:1;
+				uint8_t unused_6:1;
+				uint8_t unused_7:1;
+			} flags1; /* 43 */
+			uint8_t sync_period;	/* 42 */
+
+			uint8_t unused_45;	/* 45 */
+			struct {
+				uint8_t ppr_options:4;
+				uint8_t ppr_bus_width:2;
+				uint8_t unused_8:1;
+				uint8_t enable_ppr:1;
+			} flags2;	/* 44 */
+
+		} target[MAX_TARGETS];
+	} bus[MAX_BUSES];
+
+	uint16_t unused_248;	/* 248, 249 */
+
+	uint16_t subsystem_id[2];	/* 250, 251, 252, 253 */
+
+	uint8_t chksum;		/* 255 */
+	uint8_t System_Id_Pointer;	/* 254 */
+
+#elif defined(__LITTLE_ENDIAN)
+	uint8_t id0;		/* 0 */
+	uint8_t id1;		/* 1 */
+	uint8_t id2;		/* 2 */
+	uint8_t id3;		/* 3 */
+	uint8_t version;	/* 4 */
+	/* Host/Bios Flags */
+	struct {
+		uint8_t bios_configuration_mode:2;
+		uint8_t bios_disable:1;
+		uint8_t selectable_scsi_boot_enable:1;
+		uint8_t cd_rom_boot_enable:1;
+		uint8_t disable_loading_risc_code:1;
 		uint8_t unused_6:1;
 		uint8_t unused_7:1;
-		uint8_t boot_target_number:4;
-		uint8_t unused_12:1;
-		uint8_t unused_13:1;
-		uint8_t unused_14:1;
-		uint8_t unused_15:1;
+	} cntr_flags_1;		/* 5 */
+	/* Selectable Boot Support */
+	struct {
+		uint16_t boot_lun_number:5;
+		uint16_t scsi_bus_number:1;
+		uint16_t unused_6:1;
+		uint16_t unused_7:1;
+		uint16_t boot_target_number:4;
+		uint16_t unused_12:1;
+		uint16_t unused_13:1;
+		uint16_t unused_14:1;
+		uint16_t unused_15:1;
 	} cntr_flags_2;		/* 6, 7 */
 
 	uint16_t unused_8;	/* 8, 9 */
@@ -591,22 +930,22 @@
 	union {
 		uint16_t w;
 		struct {
-			uint8_t enable_fast_posting:1;
-			uint8_t report_lvd_bus_transition:1;
-			uint8_t unused_2:1;
-			uint8_t unused_3:1;
-			uint8_t unused_4:1;
-			uint8_t unused_5:1;
-			uint8_t unused_6:1;
-			uint8_t unused_7:1;
-			uint8_t unused_8:1;
-			uint8_t unused_9:1;
-			uint8_t unused_10:1;
-			uint8_t unused_11:1;
-			uint8_t unused_12:1;
-			uint8_t unused_13:1;
-			uint8_t unused_14:1;
-			uint8_t unused_15:1;
+			uint16_t enable_fast_posting:1;
+			uint16_t report_lvd_bus_transition:1;
+			uint16_t unused_2:1;
+			uint16_t unused_3:1;
+			uint16_t unused_4:1;
+			uint16_t unused_5:1;
+			uint16_t unused_6:1;
+			uint16_t unused_7:1;
+			uint16_t unused_8:1;
+			uint16_t unused_9:1;
+			uint16_t unused_10:1;
+			uint16_t unused_11:1;
+			uint16_t unused_12:1;
+			uint16_t unused_13:1;
+			uint16_t unused_14:1;
+			uint16_t unused_15:1;
 		} f;
 	} firmware_feature;	/* 20, 21 */
 
@@ -665,11 +1004,14 @@
 				uint8_t device_enable:1;
 				uint8_t unused_6:1;
 				uint8_t unused_7:1;
+			} flags1; /* 43 */
+
+			struct {
 				uint8_t ppr_options:4;
 				uint8_t ppr_bus_width:2;
 				uint8_t unused_8:1;
 				uint8_t enable_ppr:1;
-			} flags;	/* 43, 44 */
+			} flags2;	/* 43 */
 
 			uint8_t unused_45;	/* 45 */
 		} target[MAX_TARGETS];
@@ -682,6 +1024,9 @@
 	uint8_t System_Id_Pointer;	/* 254 */
 
 	uint8_t chksum;		/* 255 */
+#else
+#error neither __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
+#endif
 } nvram160_t;
 
 /*
@@ -1306,7 +1651,6 @@
 /*
  *  Linux - SCSI Driver Interface Function Prototypes.
  */
-int qla1280_proc_info(char *, char **, off_t, int, int, int);
 const char *qla1280_info(struct Scsi_Host *host);
 int qla1280_detect(Scsi_Host_Template *);
 int qla1280_release(struct Scsi_Host *);
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Wed May  7 07:15:38 2003
+++ b/drivers/scsi/scsi.h	Mon May 26 14:53:23 2003
@@ -383,12 +383,14 @@
 				 * time. */
 	unsigned was_reset:1;	/* There was a bus reset on the bus for 
 				 * this device */
-	unsigned expecting_cc_ua:1;	/* Expecting a CHECK_CONDITION/UNIT_ATTN
-					 * because we did a bus reset. */
-	unsigned ten:1;		/* support ten byte read / write */
+	unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
+				     * because we did a bus reset. */
+	unsigned use_10_for_rw:1; /* first try 10-byte read / write */
+	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
 	unsigned remap:1;	/* support remapping  */
 //	unsigned sync:1;	/* Sync transfer state, managed by host */
 //	unsigned wide:1;	/* WIDE transfer state, managed by host */
+	unsigned no_start_on_add:1;	/* do not issue start on add */
 
 	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
 
@@ -402,10 +404,6 @@
 	container_of(d, struct scsi_device, sdev_driverfs_dev)
 
 
-/*
- * The Scsi_Cmnd structure is used by scsi.c internally, and for communication
- * with low level drivers that support multiple outstanding commands.
- */
 typedef struct scsi_pointer {
 	char *ptr;		/* data pointer */
 	int this_residual;	/* left in this buffer */
@@ -458,12 +456,13 @@
 };
 
 /*
- * FIXME(eric) - one of the great regrets that I have is that I failed to define
- * these structure elements as something like sc_foo instead of foo.  This would
- * make it so much easier to grep through sources and so forth.  I propose that
- * all new elements that get added to these structures follow this convention.
- * As time goes on and as people have the stomach for it, it should be possible to 
- * go back and retrofit at least some of the elements here with with the prefix.
+ * FIXME(eric) - one of the great regrets that I have is that I failed to
+ * define these structure elements as something like sc_foo instead of foo.
+ * This would make it so much easier to grep through sources and so forth.
+ * I propose that all new elements that get added to these structures follow
+ * this convention.  As time goes on and as people have the stomach for it,
+ * it should be possible to go back and retrofit at least some of the elements
+ * here with with the prefix.
  */
 struct scsi_cmnd {
 	int     sc_magic;
@@ -682,5 +681,10 @@
 }
 
 int scsi_set_medium_removal(Scsi_Device *dev, char state);
+
+extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
+					    struct device_attribute *attr);
+extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
+					     struct class_device_attribute *attr);
 
 #endif /* _SCSI_H */
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Thu May  8 15:46:47 2003
+++ b/drivers/scsi/scsi_debug.c	Mon May 12 07:26:14 2003
@@ -1259,8 +1259,8 @@
 /* scsi_debug_proc_info
  * Used if the driver currently has no own support for /proc/scsi
  */
-static int scsi_debug_proc_info(char *buffer, char **start, off_t offset,
-				int length, int inode, int inout)
+static int scsi_debug_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+				int length, int inout)
 {
 	int len, pos, begin;
 	int orig_length;
diff -Nru a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h
--- a/drivers/scsi/scsi_debug.h	Thu May  8 15:46:47 2003
+++ b/drivers/scsi/scsi_debug.h	Mon May 12 07:26:14 2003
@@ -14,7 +14,7 @@
 static int scsi_debug_bus_reset(struct scsi_cmnd *);
 static int scsi_debug_device_reset(struct scsi_cmnd *);
 static int scsi_debug_host_reset(struct scsi_cmnd *);
-static int scsi_debug_proc_info(char *, char **, off_t, int, int, int);
+static int scsi_debug_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 static const char * scsi_debug_info(struct Scsi_Host *);
 
 /*
diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
--- a/drivers/scsi/scsi_devinfo.c	Thu May  8 15:35:53 2003
+++ b/drivers/scsi/scsi_devinfo.c	Fri May 23 04:01:50 2003
@@ -131,7 +131,7 @@
 	{"EMULEX", "MD21/S2     ESDI", NULL, BLIST_SINGLELUN},
 	{"CANON", "IPUBJD", NULL, BLIST_SPARSELUN},
 	{"nCipher", "Fastness Crypto", NULL, BLIST_FORCELUN},
-	{"DEC", "HSG80", NULL, BLIST_FORCELUN},
+	{"DEC", "HSG80", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
 	{"COMPAQ", "LOGICAL VOLUME", NULL, BLIST_FORCELUN},
 	{"COMPAQ", "CR3500", NULL, BLIST_FORCELUN},
 	{"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
@@ -159,7 +159,10 @@
 	{"HP", "NetRAID-4M", NULL, BLIST_FORCELUN},
 	{"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN},
 	{"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN},
-	{"COMPAQ", "MSA1000", NULL, BLIST_FORCELUN},
+	{"COMPAQ", "MSA1000", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
+	{"COMPAQ", "MSA1000 VOLUME", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
+	{"COMPAQ", "HSV110", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
+	{"HP", "HSV100", NULL, BLIST_SPARSELUN | BLIST_NOSTARTONADD},
 	{"HP", "C1557A", NULL, BLIST_FORCELUN},
 	{"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
 	{"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
diff -Nru a/drivers/scsi/scsi_devinfo.h b/drivers/scsi/scsi_devinfo.h
--- a/drivers/scsi/scsi_devinfo.h	Thu May  1 11:29:55 2003
+++ b/drivers/scsi/scsi_devinfo.h	Fri May 23 04:01:50 2003
@@ -14,3 +14,4 @@
 #define BLIST_LARGELUN		0x200	/* LUNs past 7 on a SCSI-2 device */
 #define BLIST_INQUIRY_36	0x400	/* override additional length field */
 #define BLIST_INQUIRY_58	0x800	/* ... for broken inquiry responses */
+#define BLIST_NOSTARTONADD      0x1000  /* do not do automatic start on add */
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Thu May  8 12:14:09 2003
+++ b/drivers/scsi/scsi_lib.c	Fri May 23 03:02:30 2003
@@ -662,7 +662,6 @@
  *
  *		b) We can just use scsi_requeue_command() here.  This would
  *		   be used if we just wanted to retry, for example.
- *
  */
 void scsi_io_completion(struct scsi_cmnd *cmd, int good_sectors,
 			int block_sectors)
@@ -796,17 +795,20 @@
 				}
 			}
 		}
-		/* If we had an ILLEGAL REQUEST returned, then we may have
-		 * performed an unsupported command.  The only thing this should be
-		 * would be a ten byte read where only a six byte read was supported.
-		 * Also, on a system where READ CAPACITY failed, we have have read
-		 * past the end of the disk.
+		/*
+		 * If we had an ILLEGAL REQUEST returned, then we may have
+		 * performed an unsupported command.  The only thing this
+		 * should be would be a ten byte read where only a six byte
+		 * read was supported.  Also, on a system where READ CAPACITY
+		 * failed, we may have read past the end of the disk.
 		 */
 
 		switch (cmd->sense_buffer[2]) {
 		case ILLEGAL_REQUEST:
-			if (cmd->device->ten) {
-				cmd->device->ten = 0;
+			if (cmd->device->use_10_for_rw &&
+			    (cmd->cmnd[0] == READ_10 ||
+			     cmd->cmnd[0] == WRITE_10)) {
+				cmd->device->use_10_for_rw = 0;
 				/*
 				 * This will cause a retry with a 6-byte
 				 * command.
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h	Sun May 11 15:12:54 2003
+++ b/drivers/scsi/scsi_priv.h	Fri May 23 05:35:11 2003
@@ -59,6 +59,8 @@
 extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *);
 extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *);
 extern struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *);
+extern struct Scsi_Host *scsi_host_hn_get(unsigned short);
+extern void scsi_host_put(struct Scsi_Host *);
 extern void scsi_host_init(void);
 
 /* scsi.c */
@@ -128,5 +130,10 @@
 extern void scsi_sysfs_remove_host(struct Scsi_Host *);
 extern int scsi_sysfs_register(void);
 extern void scsi_sysfs_unregister(void);
+
+/* definitions for the linker default sections covering the host
+ * class and device attributes */
+extern struct class_device_attribute *scsi_sysfs_shost_attrs[];
+extern struct device_attribute *scsi_sysfs_sdev_attrs[];
 
 #endif /* _SCSI_PRIV_H */
diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
--- a/drivers/scsi/scsi_proc.c	Thu May  8 11:24:15 2003
+++ b/drivers/scsi/scsi_proc.c	Mon May 12 07:26:15 2003
@@ -79,8 +79,8 @@
 		n = generic_proc_info(buffer, start, offset, length,
 				      shost->hostt->info, shost);
 	else
-		n = (shost->hostt->proc_info(buffer, start, offset,
-					   length, shost->host_no, 0));
+		n = shost->hostt->proc_info(shost, buffer, start, offset,
+					   length, 0);
 
 	*eof = (n < length);
 	return n;
@@ -104,8 +104,7 @@
 		ret = -EFAULT;
 		if (copy_from_user(page, buf, count))
 			goto out;
-		ret = shost->hostt->proc_info(page, &start, 0, count,
-					      shost->host_no, 1);
+		ret = shost->hostt->proc_info(shost, page, &start, 0, count, 1);
 	}
 out:
 	free_page((unsigned long)page);
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Thu May  8 11:24:15 2003
+++ b/drivers/scsi/scsi_scan.c	Fri May 23 04:01:50 2003
@@ -641,6 +641,13 @@
 		sdev->borken = 0;
 
 	/*
+	 * Some devices may not want to have a start command automatically
+	 * issued when a device is added.
+	 */
+	if (*bflags & BLIST_NOSTARTONADD)
+		sdev->no_start_on_add = 1;
+
+	/*
 	 * If we need to allow I/O to only one of the luns attached to
 	 * this target id at a time set single_lun, and allocate or modify
 	 * sdev_target.
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Thu May  8 11:24:15 2003
+++ b/drivers/scsi/scsi_syms.c	Mon May 12 07:26:15 2003
@@ -89,11 +89,6 @@
  */
 EXPORT_SYMBOL(scsi_reset_provider);
 
-/*
- * These are here only while I debug the rest of the scsi stuff.
- */
-EXPORT_SYMBOL(scsi_host_hn_get);
-EXPORT_SYMBOL(scsi_host_put);
 EXPORT_SYMBOL(scsi_device_types);
 
 /*
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	Sun May 11 15:12:40 2003
+++ b/drivers/scsi/scsi_sysfs.c	Mon May 26 14:47:09 2003
@@ -45,12 +45,13 @@
 shost_rd_attr(sg_tablesize, "%hu\n");
 shost_rd_attr(unchecked_isa_dma, "%d\n");
 
-static struct class_device_attribute *const shost_attrs[] = {
+struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
 	&class_device_attr_unique_id,
 	&class_device_attr_host_busy,
 	&class_device_attr_cmd_per_lun,
 	&class_device_attr_sg_tablesize,
 	&class_device_attr_unchecked_isa_dma,
+	NULL
 };
 
 static struct class shost_class = {
@@ -243,7 +244,8 @@
 
 static DEVICE_ATTR(rescan, S_IRUGO | S_IWUSR, show_rescan_field, store_rescan_field)
 
-static struct device_attribute * const sdev_attrs[] = {
+/* Default template for device attributes.  May NOT be modified */
+struct device_attribute *scsi_sysfs_sdev_attrs[] = {
 	&dev_attr_device_blocked,
 	&dev_attr_queue_depth,
 	&dev_attr_type,
@@ -254,6 +256,7 @@
 	&dev_attr_rev,
 	&dev_attr_online,
 	&dev_attr_rescan,
+	NULL
 };
 
 static void scsi_device_release(struct device *dev)
@@ -287,9 +290,9 @@
 	if (error)
 		return error;
 
-	for (i = 0; !error && i < ARRAY_SIZE(sdev_attrs); i++)
+	for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++)
 		error = device_create_file(&sdev->sdev_driverfs_dev,
-					   sdev_attrs[i]);
+					   sdev->host->hostt->sdev_attrs[i]);
 
 	if (error)
 		scsi_device_unregister(sdev);
@@ -305,8 +308,8 @@
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(sdev_attrs); i++)
-		device_remove_file(&sdev->sdev_driverfs_dev, sdev_attrs[i]);
+	for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++)
+		device_remove_file(&sdev->sdev_driverfs_dev, sdev->host->hostt->sdev_attrs[i]);
 	device_unregister(&sdev->sdev_driverfs_dev);
 }
 
@@ -357,9 +360,9 @@
 	if (error)
 		goto clean_device;
 
-	for (i = 0; !error && i < ARRAY_SIZE(shost_attrs); i++)
+	for (i = 0; !error && shost->hostt->shost_attrs[i] != NULL; i++)
 		error = class_device_create_file(&shost->class_dev,
-					   shost_attrs[i]);
+					   shost->hostt->shost_attrs[i]);
 	if (error)
 		goto clean_class;
 
@@ -383,3 +386,118 @@
 	device_del(&shost->host_gendev);
 }
 
+/** scsi_sysfs_modify_shost_attribute - modify or add a host class attribute
+ *
+ * @class_attrs:host class attribute list to be added to or modified
+ * @attr:	individual attribute to change or added
+ *
+ * returns zero if successful or error if not
+ **/
+int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
+				      struct class_device_attribute *attr)
+{
+	int modify = 0;
+	int num_attrs;
+
+	if(*class_attrs == NULL)
+		*class_attrs = scsi_sysfs_shost_attrs;
+
+	for(num_attrs=0; (*class_attrs)[num_attrs] != NULL; num_attrs++)
+		if(strcmp((*class_attrs)[num_attrs]->attr.name, attr->attr.name) == 0)
+			modify = num_attrs;
+
+	if(*class_attrs == scsi_sysfs_shost_attrs || !modify) {
+		/* note: need space for null at the end as well */
+		struct class_device_attribute **tmp_attrs = kmalloc(sizeof(struct class_device_attribute)*(num_attrs + (modify ? 1 : 2)), GFP_KERNEL);
+		if(tmp_attrs == NULL)
+			return -ENOMEM;
+		memcpy(tmp_attrs, *class_attrs, sizeof(struct class_device_attribute)*num_attrs);
+		if(*class_attrs != scsi_sysfs_shost_attrs)
+			kfree(*class_attrs);
+		*class_attrs = tmp_attrs;
+	}
+	if(modify) {
+		/* spare the caller from having to copy things it's
+		 * not interested in */
+		struct class_device_attribute *old_attr =
+			(*class_attrs)[modify];
+		/* extend permissions */
+		attr->attr.mode |= old_attr->attr.mode;
+
+		/* override null show/store with default */
+		if(attr->show == NULL)
+			attr->show = old_attr->show;
+		if(attr->store == NULL)
+			attr->store = old_attr->store;
+		(*class_attrs)[modify] = attr;
+	} else {
+		(*class_attrs)[num_attrs++] = attr;
+		(*class_attrs)[num_attrs] = NULL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(scsi_sysfs_modify_shost_attribute);
+
+/** scsi_sysfs_modify_sdev_attribute - modify or add a host device attribute
+ *
+ * @dev_attrs:	pointer to the attribute list to be added to or modified
+ * @attr:	individual attribute to change or added
+ *
+ * returns zero if successful or error if not
+ **/
+int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
+				     struct device_attribute *attr)
+{
+	int modify = 0;
+	int num_attrs;
+
+	if(*dev_attrs == NULL)
+		*dev_attrs = scsi_sysfs_sdev_attrs;
+
+	for(num_attrs=0; (*dev_attrs)[num_attrs] != NULL; num_attrs++)
+		if(strcmp((*dev_attrs)[num_attrs]->attr.name, attr->attr.name) == 0)
+			modify = num_attrs;
+
+	if(*dev_attrs == scsi_sysfs_sdev_attrs || !modify) {
+		/* note: need space for null at the end as well */
+		struct device_attribute **tmp_attrs = kmalloc(sizeof(struct device_attribute)*(num_attrs + (modify ? 1 : 2)), GFP_KERNEL);
+		if(tmp_attrs == NULL)
+			return -ENOMEM;
+		memcpy(tmp_attrs, *dev_attrs, sizeof(struct device_attribute)*num_attrs);
+		if(*dev_attrs != scsi_sysfs_sdev_attrs)
+			kfree(*dev_attrs);
+		*dev_attrs = tmp_attrs;
+	}
+	if(modify) {
+		/* spare the caller from having to copy things it's
+		 * not interested in */
+		struct device_attribute *old_attr =
+			(*dev_attrs)[modify];
+		/* extend permissions */
+		attr->attr.mode |= old_attr->attr.mode;
+
+		/* override null show/store with default */
+		if(attr->show == NULL)
+			attr->show = old_attr->show;
+		if(attr->store == NULL)
+			attr->store = old_attr->store;
+		(*dev_attrs)[modify] = attr;
+	} else {
+		(*dev_attrs)[num_attrs++] = attr;
+		(*dev_attrs)[num_attrs] = NULL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(scsi_sysfs_modify_sdev_attribute);
+
+void scsi_sysfs_release_attributes(struct SHT *hostt)
+{
+	if(hostt->sdev_attrs != scsi_sysfs_sdev_attrs)
+		kfree(hostt->sdev_attrs);
+
+	if(hostt->shost_attrs != scsi_sysfs_shost_attrs)
+		kfree(hostt->shost_attrs);
+}
+EXPORT_SYMBOL(scsi_sysfs_release_attributes);
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Mon May 12 20:52:56 2003
+++ b/drivers/scsi/sd.c	Fri May 23 04:01:50 2003
@@ -320,7 +320,8 @@
 		SCpnt->cmnd[12] = (unsigned char) (this_count >> 8) & 0xff;
 		SCpnt->cmnd[13] = (unsigned char) this_count & 0xff;
 		SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0;
-	} else if (((this_count > 0xff) || (block > 0x1fffff)) || SCpnt->device->ten) {
+	} else if ((this_count > 0xff) || (block > 0x1fffff) ||
+		   SCpnt->device->use_10_for_rw) {
 		if (this_count > 0xffff)
 			this_count = 0xffff;
 
@@ -768,11 +769,14 @@
 			break;
 
 		case ILLEGAL_REQUEST:
-			if (SCpnt->device->ten == 1) {
-				if (SCpnt->cmnd[0] == READ_10 ||
-				    SCpnt->cmnd[0] == WRITE_10)
-					SCpnt->device->ten = 0;
-			}
+			if (SCpnt->device->use_10_for_rw &&
+			    (SCpnt->cmnd[0] == READ_10 ||
+			     SCpnt->cmnd[0] == WRITE_10))
+				SCpnt->device->use_10_for_rw = 0;
+			if (SCpnt->device->use_10_for_ms &&
+			    (SCpnt->cmnd[0] == MODE_SENSE_10 ||
+			     SCpnt->cmnd[0] == MODE_SELECT_10))
+				SCpnt->device->use_10_for_ms = 0;
 			break;
 
 		default:
@@ -835,9 +839,10 @@
 
 			the_result = SRpnt->sr_result;
 			retries++;
-		} while (retries < 3 && !scsi_status_is_good(the_result)
-			 && ((driver_byte(the_result) & DRIVER_SENSE)
-			     && SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION));
+		} while (retries < 3 && 
+			 (!scsi_status_is_good(the_result) ||
+			  ((driver_byte(the_result) & DRIVER_SENSE) &&
+			   SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)));
 
 		/*
 		 * If the drive has indicated to us that it doesn't have
@@ -855,7 +860,12 @@
 			break;
 		}
 					
-					
+		/*
+		 * The device does not want the automatic start to be issued.
+		 */
+		if (sdkp->device->no_start_on_add) {
+			break;
+		}
 
 		/*
 		 * If manual intervention is required, or this is an
@@ -1093,16 +1103,29 @@
 	sdkp->device->sector_size = sector_size;
 }
 
+/* called with buffer of length 512 */
 static int
-sd_do_mode_sense6(struct scsi_device *sdp, struct scsi_request *SRpnt,
-		  int dbd, int modepage, unsigned char *buffer, int len) {
-	unsigned char cmd[8];
+sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
+		 unsigned char *buffer, int len) {
+	unsigned char cmd[12];
 
-	memset((void *) &cmd[0], 0, 8);
-	cmd[0] = MODE_SENSE;
+	memset((void *) &cmd[0], 0, 12);
 	cmd[1] = dbd;
 	cmd[2] = modepage;
-	cmd[4] = len;
+
+	if (SRpnt->sr_device->use_10_for_ms) {
+		if (len < 8)
+			len = 8;
+
+		cmd[0] = MODE_SENSE_10;
+		cmd[8] = len;
+	} else {
+		if (len < 4)
+			len = 4;
+
+		cmd[0] = MODE_SENSE;
+		cmd[4] = len;
+	}
 
 	SRpnt->sr_cmd_len = 0;
 	SRpnt->sr_sense_buffer[0] = 0;
@@ -1119,11 +1142,11 @@
 
 /*
  * read write protect setting, if possible - called only in sd_init_onedisk()
+ * called with buffer of length 512
  */
 static void
 sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
 		   struct scsi_request *SRpnt, unsigned char *buffer) {
-	struct scsi_device *sdp = sdkp->device;
 	int res;
 
 	/*
@@ -1131,7 +1154,7 @@
 	 * We have to start carefully: some devices hang if we ask
 	 * for more than is available.
 	 */
-	res = sd_do_mode_sense6(sdp, SRpnt, 0, 0x3F, buffer, 4);
+	res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 4);
 
 	/*
 	 * Second attempt: ask for page 0
@@ -1139,13 +1162,13 @@
 	 * Sense Key 5: Illegal Request, Sense Code 24: Invalid field in CDB.
 	 */
 	if (res)
-		res = sd_do_mode_sense6(sdp, SRpnt, 0, 0, buffer, 4);
+		res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4);
 
 	/*
 	 * Third attempt: ask 255 bytes, as we did earlier.
 	 */
 	if (res)
-		res = sd_do_mode_sense6(sdp, SRpnt, 0, 0x3F, buffer, 255);
+		res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255);
 
 	if (res) {
 		printk(KERN_WARNING
@@ -1161,25 +1184,25 @@
 
 /*
  * sd_read_cache_type - called only from sd_init_onedisk()
+ * called with buffer of length 512
  */
 static void
 sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 		   struct scsi_request *SRpnt, unsigned char *buffer) {
-	struct scsi_device *sdp = sdkp->device;
 	int len = 0, res;
 
 	const int dbd = 0x08;	   /* DBD */
 	const int modepage = 0x08; /* current values, cache page */
 
 	/* cautiously ask */
-	res = sd_do_mode_sense6(sdp, SRpnt, dbd, modepage, buffer, 4);
+	res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4);
 
 	if (res == 0) {
 		/* that went OK, now ask for the proper length */
 		len = buffer[0] + 1;
 		if (len > 128)
 			len = 128;
-		res = sd_do_mode_sense6(sdp, SRpnt, dbd, modepage, buffer, len);
+		res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, len);
 	}
 
 	if (res == 0 && buffer[3] + 6 < len) {
@@ -1278,7 +1301,8 @@
 	if (sdkp->media_present)
 		sd_read_cache_type(sdkp, disk->disk_name, SRpnt, buffer);
 		
-	SRpnt->sr_device->ten = 1;
+	SRpnt->sr_device->use_10_for_rw = 1;
+	SRpnt->sr_device->use_10_for_ms = 0;
 	SRpnt->sr_device->remap = 1;
 
  leave:
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Wed May  7 07:15:41 2003
+++ b/drivers/scsi/sr.c	Fri May 23 03:02:30 2003
@@ -559,7 +559,8 @@
 	sprintf(cd->cdi.name, "sr%d", minor);
 
 	sdev->sector_size = 2048;	/* A guess, just in case */
-	sdev->ten = 1;
+	sdev->use_10_for_rw = 1;
+	sdev->use_10_for_ms = 0;
 	sdev->remap = 1;
 
 	/* FIXME: need to handle a get_capabilities failure properly ?? */
diff -Nru a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
--- a/drivers/scsi/sun3_NCR5380.c	Fri May  9 03:21:35 2003
+++ b/drivers/scsi/sun3_NCR5380.c	Mon May 26 18:54:39 2003
@@ -726,7 +726,7 @@
 	printk("NCR5380_print_status: no memory for print buffer\n");
 	return;
     }
-    len = NCR5380_proc_info(pr_bfr, &start, 0, PAGE_SIZE, HOSTNO, 0);
+    len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0);
     pr_bfr[len] = 0;
     printk("\n%s\n", pr_bfr);
     free_page((unsigned long) pr_bfr);
@@ -754,11 +754,10 @@
 static
 char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
 
-static int NCR5380_proc_info (char *buffer, char **start, off_t offset,
-			      int length, int hostno, int inout)
+static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start, off_t offset,
+			      int length, int inout)
 {
     char *pos = buffer;
-    struct Scsi_Host *instance;
     struct NCR5380_hostdata *hostdata;
     Scsi_Cmnd *ptr;
     unsigned long flags;
@@ -771,9 +770,6 @@
 	}					\
     } while (0)
 
-    instance = scsi_host_hn_get(hostno);
-    if (!instance)
-	return(-ESRCH);
     hostdata = (struct NCR5380_hostdata *)instance->hostdata;
 
     if (inout) { /* Has data been written to the file ? */
diff -Nru a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h
--- a/drivers/scsi/sun3_scsi.h	Fri Feb  7 14:02:17 2003
+++ b/drivers/scsi/sun3_scsi.h	Mon May 12 07:26:15 2003
@@ -57,8 +57,6 @@
 static const char *sun3scsi_info (struct Scsi_Host *);
 static int sun3scsi_bus_reset(Scsi_Cmnd *);
 static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int sun3scsi_proc_info (char *buffer, char **start, off_t offset,
-			int length, int hostno, int inout);
 #ifdef MODULE
 static int sun3scsi_release (struct Scsi_Host *);
 #else
diff -Nru a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
--- a/drivers/scsi/sym53c8xx.c	Sun May 25 17:00:00 2003
+++ b/drivers/scsi/sym53c8xx.c	Mon May 26 18:54:40 2003
@@ -1288,8 +1288,8 @@
 };
 #endif
 #ifdef SCSI_NCR_PROC_INFO_SUPPORT
-static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,
-			int length, int hostno, int func);
+static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			int length, int func);
 #endif
 
 /*
@@ -14226,22 +14226,17 @@
 **	- func = 1 means write (parse user control command)
 */
 
-static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,
-			int length, int hostno, int func)
+static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			int length, int func)
 {
-	struct Scsi_Host *host;
 	struct host_data *host_data;
 	ncb_p ncb = 0;
 	int retv;
 
 #ifdef DEBUG_PROC_INFO
-printk("sym53c8xx_proc_info: hostno=%d, func=%d\n", hostno, func);
+printk("sym53c8xx_proc_info: hostno=%d, func=%d\n", host->host_no, func);
 #endif
 
-	host = scsi_host_hn_get(hostno);
-	if (!host)
-		return -EINVAL;
-
 	host_data = (struct host_data *) host->hostdata;
 	ncb = host_data->ncb;
 	retv = -EINVAL;
@@ -14261,7 +14256,6 @@
 	}
 
 out:
-	scsi_host_put(host);
 	return retv;
 }
 
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c	Sun May 25 17:00:00 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c	Mon May 26 18:54:41 2003
@@ -1787,18 +1787,13 @@
  *  - func = 0 means read  (returns adapter infos)
  *  - func = 1 means write (not yet merget from sym53c8xx)
  */
-static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,
-			int length, int hostno, int func)
+static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
+			int length, int func)
 {
-	struct Scsi_Host *host;
 	struct host_data *host_data;
 	hcb_p np = 0;
 	int retv;
 
-	host = scsi_host_hn_get(hostno);
-	if (!host)
-		return -EINVAL;
-
 	host_data = (struct host_data *) host->hostdata;
 	np = host_data->ncb;
 	if (!np)
@@ -1821,7 +1816,6 @@
 #endif
 	}
 
-	scsi_host_put(host);
 	return retv;
 }
 #endif /* SYM_LINUX_PROC_INFO_SUPPORT */
diff -Nru a/drivers/scsi/t128.h b/drivers/scsi/t128.h
--- a/drivers/scsi/t128.h	Sun May  4 02:56:46 2003
+++ b/drivers/scsi/t128.h	Mon May 12 07:26:16 2003
@@ -99,8 +99,6 @@
 static int t128_host_reset(Scsi_Cmnd *);
 static int t128_bus_reset(Scsi_Cmnd *);
 static int t128_device_reset(Scsi_Cmnd *);
-static int t128_proc_info (char *buffer, char **start, off_t offset,
-		   int length, int hostno, int inout);
 
 #ifndef NULL
 #define NULL 0
diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
--- a/drivers/scsi/tmscsim.c	Sun May  4 02:56:46 2003
+++ b/drivers/scsi/tmscsim.c	Mon May 12 07:26:16 2003
@@ -2855,12 +2855,11 @@
  else SPRINTF(" No  ")
 
 
-int DC390_proc_info (char *buffer, char **start,
-		     off_t offset, int length, int hostno, int inout)
+int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
+		     off_t offset, int length, int inout)
 {
   int dev, spd, spd1;
   char *pos = buffer;
-  PSH shpnt = 0;
   PACB pACB;
   PDCB pDCB;
   PSCSICMD pcmd;
@@ -2870,13 +2869,12 @@
 
   while(pACB != (PACB)-1)
      {
-	shpnt = pACB->pScsiHost;
-	if (shpnt->host_no == hostno) break;
+	if (shpnt == pACB->pScsiHost)
+		break;
 	pACB = pACB->pNextACB;
      }
 
   if (pACB == (PACB)-1) return(-ESRCH);
-  if(!shpnt) return(-ESRCH);
 
   if(inout) /* Has data been written to the file ? */
       return dc390_set_info(buffer, length, pACB);
diff -Nru a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
--- a/drivers/scsi/wd33c93.c	Sat Mar 22 18:30:53 2003
+++ b/drivers/scsi/wd33c93.c	Mon May 12 07:26:16 2003
@@ -1913,7 +1913,7 @@
 }
 
 int
-wd33c93_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
+wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off, int len, int in)
 {
 
 #ifdef PROC_INTERFACE
@@ -1921,16 +1921,10 @@
 	char *bp;
 	char tbuf[128];
 	struct Scsi_Host *instance;
-	struct WD33C93_hostdata *hd;
 	Scsi_Cmnd *cmd;
 	int x, i;
 	static int stop = 0;
 
-	instance = scsi_host_hn_get(hn);
-	if (!instance) {
-		printk("*** Hmm... Can't find host #%d!\n", hn);
-		return (-ESRCH);
-	}
 	hd = (struct WD33C93_hostdata *) instance->hostdata;
 
 /* If 'in' is TRUE we need to _read_ the proc file. We accept the following
diff -Nru a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h
--- a/drivers/scsi/wd33c93.h	Wed Mar 12 21:38:15 2003
+++ b/drivers/scsi/wd33c93.h	Mon May 12 07:26:16 2003
@@ -338,7 +338,7 @@
 int wd33c93_abort (Scsi_Cmnd *cmd);
 int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
 void wd33c93_intr (struct Scsi_Host *instance);
-int wd33c93_proc_info(char *, char **, off_t, int, int, int);
+int wd33c93_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 int wd33c93_host_reset (Scsi_Cmnd *);
 void wd33c93_release(void);
 
diff -Nru a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
--- a/drivers/scsi/wd7000.c	Thu May  8 11:24:15 2003
+++ b/drivers/scsi/wd7000.c	Mon May 12 08:12:55 2003
@@ -1372,45 +1372,24 @@
 }
 
 
-static int wd7000_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,  int inout)
 {
-	struct Scsi_Host *host = NULL;
-	Adapter *adapter;
+	Adapter *adapter = (Adapter *)host->hostdata;
 	unsigned long flags;
 	char *pos = buffer;
-	short i;
-
 #ifdef WD7000_DEBUG
 	Mailbox *ogmbs, *icmbs;
 	short count;
 #endif
 
 	/*
-	 * Find the specified host board.
-	 */
-	for (i = 0; i < UNITS; i++)
-		if (wd7000_host[i] && (wd7000_host[i]->host_no == hostno)) {
-			host = wd7000_host[i];
-
-			break;
-		}
-
-	/*
-	 * Host not found!
-	 */
-	if (!host)
-		return (-ESRCH);
-
-	/*
 	 * Has data been written to the file ?
 	 */
 	if (inout)
 		return (wd7000_set_info(buffer, length, host));
 
-	adapter = (Adapter *) host->hostdata;
-
 	spin_lock_irqsave(host->host_lock, flags);
-	SPRINTF("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", hostno, adapter->rev1, adapter->rev2);
+	SPRINTF("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", host->host_no, adapter->rev1, adapter->rev2);
 	SPRINTF("  IO base:      0x%x\n", adapter->iobase);
 	SPRINTF("  IRQ:          %d\n", adapter->irq);
 	SPRINTF("  DMA channel:  %d\n", adapter->dma);
diff -Nru a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
--- a/drivers/serial/68328serial.c	Thu Apr 24 03:30:40 2003
+++ b/drivers/serial/68328serial.c	Mon May 26 15:29:13 2003
@@ -83,13 +83,12 @@
 extern wait_queue_head_t keypress_wait; 
 #endif
 
-struct tty_driver serial_driver, callout_driver;
+struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* serial subtype definitions */
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
-  
+ 
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
 
@@ -1178,8 +1177,6 @@
 	 */
 	if (info->flags & S_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & S_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1220,8 +1217,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE|
-			 S_CLOSING);
+	info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	restore_flags(flags);
 }
@@ -1240,7 +1236,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(S_NORMAL_ACTIVE|S_CALLOUT_ACTIVE);
+	info->flags &= ~S_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1272,25 +1268,6 @@
 		return -EAGAIN;
 #endif
 	}
-
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & S_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & S_CALLOUT_ACTIVE) &&
-		    (info->flags & S_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & S_CALLOUT_ACTIVE) &&
-		    (info->flags & S_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= S_CALLOUT_ACTIVE;
-		return 0;
-	}
 	
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
@@ -1298,20 +1275,13 @@
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & S_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= S_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & S_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1326,8 +1296,7 @@
 	info->blocked_open++;
 	while (1) {
 		cli();
-		if (!(info->flags & S_CALLOUT_ACTIVE))
-			m68k_rtsdtr(info, 1);
+		m68k_rtsdtr(info, 1);
 		sti();
 		current->state = TASK_INTERRUPTIBLE;
 		if (tty_hung_up_p(filp) ||
@@ -1342,8 +1311,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & S_CALLOUT_ACTIVE) &&
-		    !(info->flags & S_CLOSING) && do_clocal)
+		if (!(info->flags & S_CLOSING) && do_clocal)
 			break;
                 if (signal_pending(current)) {
 			retval = -ERESTARTSYS;
@@ -1401,16 +1369,10 @@
 	}
 
 	if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 	return 0;
 }
 
@@ -1519,20 +1481,9 @@
 	serial_driver.hangup = rs_hangup;
 	serial_driver.set_ldisc = rs_set_ldisc;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-	
+
 	save_flags(flags); cli();
 
 	for(i=0;i<NR_PORTS;i++) {
@@ -1551,7 +1502,6 @@
 	    info->blocked_open = 0;
 	    INIT_WORK(&info->tqueue, do_softint, info);
 	    INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
-	    info->callout_termios =callout_driver.init_termios;
 	    info->normal_termios = serial_driver.init_termios;
 	    init_waitqueue_head(&info->open_wait);
 	    init_waitqueue_head(&info->close_wait);
diff -Nru a/drivers/serial/68328serial.h b/drivers/serial/68328serial.h
--- a/drivers/serial/68328serial.h	Mon Mar 10 16:26:26 2003
+++ b/drivers/serial/68328serial.h	Mon May 26 15:29:13 2003
@@ -155,8 +155,6 @@
 	int			line;
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -164,7 +162,6 @@
 	struct work_struct	tqueue;
 	struct work_struct	tqueue_hangup;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 };
diff -Nru a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
--- a/drivers/serial/68360serial.c	Thu Apr 24 03:30:40 2003
+++ b/drivers/serial/68360serial.c	Mon May 26 15:29:08 2003
@@ -73,7 +73,7 @@
 static char *serial_name = "CPM UART driver";
 static char *serial_version = "0.03";
 
-static struct tty_driver serial_driver, callout_driver;
+static struct tty_driver serial_driver;
 static int serial_refcount;
 int serial_console_setup(struct console *co, char *options);
 
@@ -164,7 +164,6 @@
         unsigned short  closing_wait; /* time to wait before closing */
         struct async_icount_24     icount; 
         struct termios          normal_termios;
-        struct termios          callout_termios;
         int     io_type;
         struct async_struct *info;
 };
@@ -256,8 +255,6 @@
 	unsigned long		event;
 	unsigned long		last_active;
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	struct work_struct	tqueue;
 	struct work_struct	tqueue_hangup;
  	wait_queue_head_t	open_wait; 
@@ -610,8 +607,7 @@
 #endif		
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+		else {
 #ifdef SERIAL_DEBUG_OPEN
 			printk("scheduling hangup...");
 #endif
@@ -1718,8 +1714,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->state->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->state->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1768,8 +1762,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	MOD_DEC_USE_COUNT;
 	local_irq_restore(flags);
@@ -1861,7 +1854,7 @@
 	shutdown(info);
 	info->event = 0;
 	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1899,28 +1892,6 @@
 #endif
 	}
 
-
-#if 0 /* FIXME */
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-#endif	
-
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
@@ -1930,19 +1901,12 @@
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR)) ||
 	    !(info->state->smc_scc_num & NUM_IS_SCC)) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (state->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 	
 	/*
 	 * Block waiting for the carrier detect and the line to become
@@ -1965,8 +1929,7 @@
 	info->blocked_open++;
 	while (1) {
 		local_irq_disable();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
+		if (tty->termios->c_cflag & CBAUD)
 			serial_out(info, UART_MCR,
 				   serial_inp(info, UART_MCR) |
 				   (UART_MCR_DTR | UART_MCR_RTS));
@@ -1984,8 +1947,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (serial_in(info, UART_MSR) &
 				   UART_MSR_DCD)))
 			break;
@@ -2076,16 +2038,10 @@
 
 	if ((info->state->count == 1) &&
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else 
-			*tty->termios = info->state->callout_termios;
+		*tty->termios = info->state->normal_termios;
 		change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open %s successful...", tty->name);
 #endif
@@ -2617,22 +2573,9 @@
 	/* serial_driver.wait_until_sent = rs_360_wait_until_sent; */
 	/* serial_driver.read_proc = rs_360_read_proc; */
 	
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	/* callout_driver.read_proc = 0; */
-	/* callout_driver.proc_entry = 0; */
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-	
+
 	cp = pquicc;	/* Get pointer to Communication Processor */
 	/* immap = (immap_t *)IMAP_ADDR; */	/* and to internal registers */
 
@@ -2690,7 +2633,6 @@
 		state->custom_divisor = 0;
 		state->close_delay = 5*HZ/10;
 		state->closing_wait = 30*HZ;
-		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
 		state->icount.cts = state->icount.dsr = 
 			state->icount.rng = state->icount.dcd = 0;
diff -Nru a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
--- a/drivers/serial/mcfserial.c	Thu May  8 15:48:31 2003
+++ b/drivers/serial/mcfserial.c	Mon May 26 15:29:08 2003
@@ -76,12 +76,11 @@
 /*
  *	Driver data structures.
  */
-struct tty_driver	mcfrs_serial_driver, mcfrs_callout_driver;
+struct tty_driver	mcfrs_serial_driver;
 static int		mcfrs_serial_refcount;
 
 /* serial subtype definitions */
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
   
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
@@ -450,12 +449,10 @@
 		return;
 
 	if (info->flags & ASYNC_CHECK_CD) {
-		if (dcd) {
+		if (dcd)
 			wake_up_interruptible(&info->open_wait);
-		} else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_CALLOUT_NOHUP))) {
+		else 
 			schedule_work(&info->tqueue_hangup);
-		}
 	}
 }
 
@@ -1198,8 +1195,6 @@
 	 */
 	if (info->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
@@ -1248,8 +1243,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	local_irq_restore(flags);
 }
@@ -1268,7 +1262,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1300,25 +1294,6 @@
 		return -EAGAIN;
 #endif
 	}
-
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
 	
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
@@ -1326,20 +1301,13 @@
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1357,8 +1325,7 @@
 	info->blocked_open++;
 	while (1) {
 		local_irq_disable();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE))
-			mcfrs_setsignals(info, 1, 1);
+		mcfrs_setsignals(info, 1, 1);
 		local_irq_enable();
 		current->state = TASK_INTERRUPTIBLE;
 		if (tty_hung_up_p(filp) ||
@@ -1373,8 +1340,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (mcfrs_getsignals(info) & TIOCM_CD)))
 			break;
 		if (signal_pending(current)) {
@@ -1443,16 +1409,10 @@
 	}
 
 	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		mcfrs_change_speed(info);
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
 	printk("mcfrs_open %s successful...\n", tty->name);
 #endif
@@ -1658,26 +1618,11 @@
 	mcfrs_serial_driver.read_proc = mcfrs_readproc;
 	mcfrs_serial_driver.driver_name = "serial";
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	mcfrs_callout_driver = mcfrs_serial_driver;
-	mcfrs_callout_driver.name = "cua";
-	mcfrs_callout_driver.major = TTYAUX_MAJOR;
-	mcfrs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	mcfrs_callout_driver.read_proc = 0;
-	mcfrs_callout_driver.proc_entry = 0;
-
 	if (tty_register_driver(&mcfrs_serial_driver)) {
 		printk("MCFRS: Couldn't register serial driver\n");
 		return(-EBUSY);
 	}
-	if (tty_register_driver(&mcfrs_callout_driver)) {
-		printk("MCFRS: Couldn't register callout driver\n");
-		return(-EBUSY);
-	}
-	
+
 	local_irq_save(flags);
 
 	/*
@@ -1696,7 +1641,6 @@
 		info->blocked_open = 0;
 		INIT_WORK(&info->tqueue, mcfrs_offintr, info);
 		INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
-		info->callout_termios = mcfrs_callout_driver.init_termios;
 		info->normal_termios = mcfrs_serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
diff -Nru a/drivers/serial/mcfserial.h b/drivers/serial/mcfserial.h
--- a/drivers/serial/mcfserial.h	Tue Jan 14 03:33:49 2003
+++ b/drivers/serial/mcfserial.h	Mon May 26 15:29:08 2003
@@ -58,8 +58,6 @@
 	int			line;
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -68,7 +66,6 @@
 	struct work_struct	tqueue;
 	struct work_struct	tqueue_hangup;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 
diff -Nru a/drivers/sgi/char/sgiserial.c b/drivers/sgi/char/sgiserial.c
--- a/drivers/sgi/char/sgiserial.c	Thu May  8 06:26:46 2003
+++ b/drivers/sgi/char/sgiserial.c	Mon May 26 15:29:09 2003
@@ -97,14 +97,13 @@
 
 DECLARE_TASK_QUEUE(tq_serial);
 
-struct tty_driver serial_driver, callout_driver;
+struct tty_driver serial_driver;
 struct console *sgisercon;
 static int serial_refcount;
 
 /* serial subtype definitions */
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
-  
+
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
 
@@ -1514,8 +1513,6 @@
 	 */
 	if (info->flags & ZILOG_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ZILOG_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1561,8 +1558,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE|
-			 ZILOG_CLOSING);
+	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	restore_flags(flags);
 }
@@ -1581,7 +1577,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE);
+	info->flags &= ~ZILOG_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1615,44 +1611,18 @@
 	}
 
 	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ZILOG_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ZILOG_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ZILOG_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ZILOG_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ZILOG_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1670,8 +1640,7 @@
 	info->blocked_open++;
 	while (1) {
 		cli();
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE))
-			zs_rtsdtr(info, 1);
+		zs_rtsdtr(info, 1);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -1686,8 +1655,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    !(info->flags & ZILOG_CLOSING) && do_clocal)
+		if (!(info->flags & ZILOG_CLOSING) && do_clocal)
 			break;
 		if (signal_pending(current)) {
 			retval = -ERESTARTSYS;
@@ -1761,10 +1729,7 @@
 	}
 
 	if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_speed(info);
 	}
 
@@ -1776,9 +1741,6 @@
 		change_speed(info);		
 	}
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open %s successful...\n", tty->name);
 #endif
@@ -1899,20 +1861,9 @@
 	serial_driver.start = rs_start;
 	serial_driver.hangup = rs_hangup;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-	
+
 	save_flags(flags); cli();
 
 	/* Set up our interrupt linked list */
@@ -1999,7 +1950,6 @@
 		info->tqueue.data = info;
 		info->tqueue_hangup.routine = do_serial_hangup;
 		info->tqueue_hangup.data = info;
-		info->callout_termios =callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
diff -Nru a/drivers/sgi/char/sgiserial.h b/drivers/sgi/char/sgiserial.h
--- a/drivers/sgi/char/sgiserial.h	Mon Feb  4 23:44:52 2002
+++ b/drivers/sgi/char/sgiserial.h	Mon May 26 15:29:09 2003
@@ -148,8 +148,6 @@
 	int			line;
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -157,7 +155,6 @@
 	struct tq_struct	tqueue;
 	struct tq_struct	tqueue_hangup;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 };
diff -Nru a/drivers/tc/zs.c b/drivers/tc/zs.c
--- a/drivers/tc/zs.c	Wed May  7 15:51:55 2003
+++ b/drivers/tc/zs.c	Mon May 26 15:29:09 2003
@@ -180,12 +180,11 @@
 
 DECLARE_TASK_QUEUE(tq_zs_serial);
 
-struct tty_driver serial_driver, callout_driver;
+struct tty_driver serial_driver;
 static int serial_refcount;
 
 /* serial subtype definitions */
 #define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
 
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
@@ -526,7 +525,7 @@
 		    && info->tty && !C_CLOCAL(info->tty)) {
 			if (stat & DCD) {
 				wake_up_interruptible(&info->open_wait);
-			} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
+			} else {
 				tty_hangup(info->tty);
 			}
 		}
@@ -1397,8 +1396,6 @@
 	 */
 	if (info->flags & ZILOG_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
-	if (info->flags & ZILOG_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1438,8 +1435,7 @@
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE|
-			 ZILOG_CLOSING);
+	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	restore_flags(flags);
 }
@@ -1492,7 +1488,7 @@
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE);
+	info->flags &= ~ZILOG_NORMAL_ACTIVE;
 	info->tty = 0;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1527,20 +1523,6 @@
 	 * If this is a callout device, then just make sure the normal
 	 * device isn't being used.
 	 */
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ZILOG_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ZILOG_CALLOUT_ACTIVE;
-		return 0;
-	}
 	
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
@@ -1548,20 +1530,13 @@
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ZILOG_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ZILOG_NORMAL_ACTIVE;
 		return 0;
 	}
 
-	if (info->flags & ZILOG_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1582,8 +1557,7 @@
 	info->blocked_open++;
 	while (1) {
 		cli();
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
+		if (tty->termios->c_cflag & CBAUD)
 			zs_rtsdtr(info, RTS | DTR, 1);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -1599,8 +1573,7 @@
 #endif
 			break;
 		}
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    !(info->flags & ZILOG_CLOSING) &&
+		if (!(info->flags & ZILOG_CLOSING) &&
 		    (do_clocal || (read_zsreg(info->zs_channel, 0) & DCD)))
 			break;
 		if (signal_pending(current)) {
@@ -1689,10 +1662,7 @@
 	}
 
 	if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) {
-		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
+		*tty->termios = info->normal_termios;
 		change_speed(info);
 	}
 #ifdef CONFIG_SERIAL_CONSOLE
@@ -1703,9 +1673,6 @@
 	}
 #endif
 
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open %s successful...", tty->name);
 #endif
@@ -1910,23 +1877,8 @@
 	serial_driver.break_ctl = rs_break;
 	serial_driver.wait_until_sent = rs_wait_until_sent;
 
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
-	callout_driver.name = "cua/";
-#else
-	callout_driver.name = "cua";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
 	if (tty_register_driver(&serial_driver))
 		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
 
 	save_flags(flags); cli();
 
@@ -1964,7 +1916,6 @@
 		info->blocked_open = 0;
 		info->tqueue.routine = do_softint;
 		info->tqueue.data = info;
-		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
@@ -1972,8 +1923,6 @@
 		       info->port, info->irq);
 		printk(" is a Z85C30 SCC\n");
 		tty_register_device(&serial_driver, info->line, NULL);
-		tty_register_device(&callout_driver, info->line, NULL);
-
 	}
 
 	restore_flags(flags);
diff -Nru a/drivers/tc/zs.h b/drivers/tc/zs.h
--- a/drivers/tc/zs.h	Sun Sep 29 15:28:06 2002
+++ b/drivers/tc/zs.h	Mon May 26 15:29:09 2003
@@ -144,8 +144,6 @@
 	int			line;
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -153,7 +151,6 @@
 	struct tq_struct	tqueue;
 	struct tq_struct	tqueue_hangup;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 };
diff -Nru a/drivers/usb/media/pwc-if.c b/drivers/usb/media/pwc-if.c
--- a/drivers/usb/media/pwc-if.c	Thu Apr 24 03:35:40 2003
+++ b/drivers/usb/media/pwc-if.c	Mon May 26 16:23:35 2003
@@ -1804,7 +1804,7 @@
 	}
 	memcpy(vdev, &pwc_template, sizeof(pwc_template));
 	strcpy(vdev->name, name);
-	SET_MODULE_OWNER(vdev);
+	vdev->owner = THIS_MODULE;
 	pdev->vdev = vdev;
 	vdev->priv = pdev;
 
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c	Sun Apr  6 04:58:42 2003
+++ b/drivers/usb/storage/scsiglue.c	Mon May 12 08:21:06 2003
@@ -264,33 +264,21 @@
 #define SPRINTF(args...) \
 	do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
 
-static int usb_storage_proc_info (char *buffer, char **start, off_t offset,
-		int length, int hostno, int inout)
+static int usb_storage_proc_info (struct Scsi_Host *hostptr, char *buffer, char **start, off_t offset,
+		int length, int inout)
 {
 	struct us_data *us;
 	char *pos = buffer;
-	struct Scsi_Host *hostptr;
 	unsigned long f;
 
 	/* if someone is sending us data, just throw it away */
 	if (inout)
 		return length;
 
-	/* find our data from the given hostno */
-	hostptr = scsi_host_hn_get(hostno);
-	if (!hostptr) {	 /* if we couldn't find it, we return an error */
-		return -ESRCH;
-	}
 	us = (struct us_data*)hostptr->hostdata[0];
 
-	/* if we couldn't find it, we return an error */
-	if (!us) {
-		scsi_host_put(hostptr);
-		return -ESRCH;
-	}
-
 	/* print the controller name */
-	SPRINTF("   Host scsi%d: usb-storage\n", hostno);
+	SPRINTF("   Host scsi%d: usb-storage\n", hostptr->host_no);
 
 	/* print product, vendor, and serial number strings */
 	SPRINTF("       Vendor: %s\n", us->vendor);
@@ -318,9 +306,6 @@
 
 		*(pos++) = '\n';
 		}
-
-	/* release the reference count on this host */
-	scsi_host_put(hostptr);
 
 	/*
 	 * Calculate start of next buffer, and return value.
diff -Nru a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
--- a/drivers/video/i810/i810.h	Thu Apr 10 08:47:57 2003
+++ b/drivers/video/i810/i810.h	Mon May 26 17:59:07 2003
@@ -203,8 +203,8 @@
 #define LOCKUP                      8
 
 struct gtt_data {
-	agp_memory *i810_fb_memory;
-	agp_memory *i810_cursor_memory;
+	struct agp_memory *i810_fb_memory;
+	struct agp_memory *i810_cursor_memory;
 };
 
 struct mode_registers {
diff -Nru a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
--- a/drivers/video/i810/i810_main.c	Thu Apr 24 03:30:41 2003
+++ b/drivers/video/i810/i810_main.c	Mon May 26 18:03:39 2003
@@ -1926,11 +1926,6 @@
 #ifndef MODULE
 int __init i810fb_init(void)
 {
-	if (agp_init()) {
-		printk("i810fb_init: cannot initialize agpgart\n");
-		return -ENODEV;
-	}
-
 	if (agp_intel_init()) {
 		printk("i810fb_init: cannot initialize intel agpgart\n");
 		return -ENODEV;
diff -Nru a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h
--- a/drivers/video/i810/i810_main.h	Wed Mar 26 10:59:20 2003
+++ b/drivers/video/i810/i810_main.h	Mon May 26 18:03:39 2003
@@ -111,7 +111,6 @@
 /* Initialization */
 static void i810fb_release_resource       (struct fb_info *info, struct i810fb_par *par);
 extern int __init agp_intel_init(void);
-extern int __init agp_init(void);
 
 
 /* Video Timings */
diff -Nru a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
--- a/drivers/video/sis/sis_main.c	Thu Apr 24 03:30:41 2003
+++ b/drivers/video/sis/sis_main.c	Tue May 27 03:59:57 2003
@@ -2868,8 +2868,8 @@
 	unsigned long *write_port = 0;
 	SIS_CMDTYPE    cmd_type;
 #ifndef AGPOFF
-	agp_kern_info  *agp_info;
-	agp_memory     *agp;
+	struct agp_kern_info  *agp_info;
+	struct agp_memory     *agp;
 	u32            agp_phys;
 #endif
 #endif
@@ -2946,8 +2946,8 @@
 
 #ifndef AGPOFF
 	if (sisfb_queuemode == AGP_CMD_QUEUE) {
-		agp_info = vmalloc(sizeof(agp_kern_info));
-		memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
+		agp_info = vmalloc(sizeof(*agp_info));
+		memset((void*)agp_info, 0x00, sizeof(*agp_info));
 		agp_copy_info(agp_info);
 
 		agp_backend_acquire();
diff -Nru a/fs/attr.c b/fs/attr.c
--- a/fs/attr.c	Sun Mar 16 00:39:53 2003
+++ b/fs/attr.c	Thu May 22 22:14:06 2003
@@ -68,10 +68,17 @@
 	int error = 0;
 
 	if (ia_valid & ATTR_SIZE) {
-		if (attr->ia_size != inode->i_size)
+		if (attr->ia_size != inode->i_size) {
 			error = vmtruncate(inode, attr->ia_size);
-		if (error || (ia_valid == ATTR_SIZE))
-			goto out;
+			if (error || (ia_valid == ATTR_SIZE))
+				goto out;
+		} else {
+			/*
+			 * We skipped the truncate but must still update
+			 * timestamps
+			 */
+			ia_valid |= ATTR_MTIME|ATTR_CTIME;
+		}
 	}
 
 	lock_kernel();
diff -Nru a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c	Sun May 25 09:19:53 2003
+++ b/fs/bio.c	Mon May 26 18:53:39 2003
@@ -38,7 +38,7 @@
  * basically we just need to survive
  */
 #define BIO_SPLIT_ENTRIES 8	
-static mempool_t *bio_split_pool;
+mempool_t *bio_split_pool;
 
 struct biovec_pool {
 	int nr_vecs;
@@ -916,3 +916,4 @@
 EXPORT_SYMBOL(bio_unmap_user);
 EXPORT_SYMBOL(bio_pair_release);
 EXPORT_SYMBOL(bio_split);
+EXPORT_SYMBOL(bio_split_pool);
diff -Nru a/fs/char_dev.c b/fs/char_dev.c
--- a/fs/char_dev.c	Sun May 25 14:52:51 2003
+++ b/fs/char_dev.c	Tue May 27 07:48:53 2003
@@ -89,6 +89,8 @@
 	if (cd == NULL)
 		return ERR_PTR(-ENOMEM);
 
+	memset(cd, 0, sizeof(struct char_device_struct));
+
 	write_lock_irq(&chrdevs_lock);
 
 	/* temporary */
diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
--- a/fs/cifs/cifsfs.c	Sun May 25 19:29:11 2003
+++ b/fs/cifs/cifsfs.c	Tue May 27 07:50:56 2003
@@ -94,13 +94,17 @@
 	sb->s_blocksize_bits = 14;	/* default 2**14 = CIFS_MAX_MSGSIZE */
 	inode = iget(sb, ROOT_I);
 
-	if (!inode)
+	if (!inode) {
+		rc = -ENOMEM;
 		goto out_no_root;
+	}
 
 	sb->s_root = d_alloc_root(inode);
 
-	if (!sb->s_root)
+	if (!sb->s_root) {
+		rc = -ENOMEM;
 		goto out_no_root;
+	}
 
 	return 0;
 
@@ -114,7 +118,7 @@
 		unload_nls(cifs_sb->local_nls);	
 	if(cifs_sb)
 		kfree(cifs_sb);
-	return -EINVAL;
+	return rc;
 }
 
 void
@@ -332,7 +336,7 @@
 	.release = cifs_close,
 	.lock = cifs_lock,
 	.fsync = cifs_fsync,
-    .flush = cifs_flush,
+	.flush = cifs_flush,
 	.mmap  = cifs_file_mmap,
 	.sendfile = generic_file_sendfile,
 };
diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c
--- a/fs/cifs/connect.c	Sun May 25 19:30:34 2003
+++ b/fs/cifs/connect.c	Tue May 27 11:28:27 2003
@@ -346,6 +346,7 @@
 {
 	char *value;
 	char *data;
+	int  temp_len;
 
 	memset(vol,0,sizeof(struct smb_vol));
 	vol->linux_uid = current->uid;	/* current->euid instead? */
@@ -398,8 +399,9 @@
 				       "CIFS: invalid path to network resource\n");
 				return 1;	/* needs_arg; */
 			}
-			if (strnlen(value, 300) < 300) {
-				vol->UNC = value;
+			if ((temp_len = strnlen(value, 300)) < 300) {
+				vol->UNC = kmalloc(GFP_KERNEL, temp_len);
+				strcpy(vol->UNC,value);
 				if (strncmp(vol->UNC, "//", 2) == 0) {
 					vol->UNC[0] = '\\';
 					vol->UNC[1] = '\\';
@@ -472,8 +474,9 @@
 			printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
 			return 1;
 		}
-		if (strnlen(devname, 300) < 300) {
-			vol->UNC = devname;
+		if ((temp_len = strnlen(devname, 300)) < 300) {
+			vol->UNC = kmalloc(GFP_KERNEL, temp_len);
+			strcpy(vol->UNC,devname);
 			if (strncmp(vol->UNC, "//", 2) == 0) {
 				vol->UNC[0] = '\\';
 				vol->UNC[1] = '\\';
@@ -812,6 +815,8 @@
 	cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data));
 
 	if (parse_mount_options(mount_data, devname, &volume_info)) {
+		if(volume_info.UNC)
+			kfree(volume_info.UNC);
 		FreeXid(xid);
 		return -EINVAL;
 	}
@@ -852,6 +857,8 @@
 			       ("Error connecting to IPv4 socket. Aborting operation"));
 			if(csocket != NULL)
 				sock_release(csocket);
+			if(volume_info.UNC)
+				kfree(volume_info.UNC);
 			FreeXid(xid);
 			return rc;
 		}
@@ -860,6 +867,8 @@
 		if (srvTcp == NULL) {
 			rc = -ENOMEM;
 			sock_release(csocket);
+			if(volume_info.UNC)
+				kfree(volume_info.UNC);
 			FreeXid(xid);
 			return rc;
 		} else {
@@ -943,6 +952,8 @@
 								 "",
 								 cifs_sb->
 								 local_nls);
+					if(volume_info.UNC)
+						kfree(volume_info.UNC);
 					FreeXid(xid);
 					return -ENODEV;
 				} else {
@@ -995,7 +1006,8 @@
 		if (tcon->ses->capabilities & CAP_UNIX)
 			CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls);
 	}
-
+	if(volume_info.UNC)
+		kfree(volume_info.UNC);
 	FreeXid(xid);
 	return rc;
 }
@@ -2293,7 +2305,7 @@
 		length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
         /* skip service field (NB: this field is always ASCII) */
 		bcc_ptr += length + 1;	
-        strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
+		strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
 		if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
 			length = UniStrnlen((wchar_t *) bcc_ptr, 512);
 			if (((long) bcc_ptr + (2 * length)) -
diff -Nru a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
--- a/fs/cifs/netmisc.c	Sat Feb 15 14:10:24 2003
+++ b/fs/cifs/netmisc.c	Tue May 20 07:48:11 2003
@@ -46,7 +46,7 @@
 const struct smb_to_posix_error mapping_table_ERRDOS[] = {
 	{ERRbadfunc, -EINVAL},
 	{ERRbadfile, -ENOENT},
-	{ERRbadpath, -ENOENT},
+	{ERRbadpath, -ENOTDIR},
 	{ERRnofids, -EMFILE},
 	{ERRnoaccess, -EACCES},
 	{ERRbadfid, -EBADF},
@@ -63,26 +63,29 @@
 	{ERRnofiles, -ENOENT},
 	{ERRbadshare, -ETXTBSY},
 	{ERRlock, -EACCES},
-	{ERRfilexists, -EINVAL},
+	{ERRunsup, -EINVAL},
+	{ERRnosuchshare,-ENXIO},
+	{ERRfilexists, -EEXIST},
 	{ERRinvparm, -EINVAL},
 	{ERRdiskfull, -ENOSPC},
-	{ERRinvnum, -EINVAL},
+	{ERRinvname, -ENOENT},
 	{ERRdirnotempty, -ENOTEMPTY},
 	{ERRnotlocked, -ENOLCK},
 	{ERRalreadyexists, -EEXIST},
 	{ERRmoredata, -EOVERFLOW},
 	{ErrQuota, -EDQUOT},
 	{ErrNotALink, -ENOLINK},
+	{ERRnetlogonNotStarted,-ENOPROTOOPT},
 	{0, 0}
 };
 
 const struct smb_to_posix_error mapping_table_ERRSRV[] = {
 	{ERRerror, -EIO},
-	{ERRbadpw, -EACCES},
+	{ERRbadpw, -EPERM},
 	{ERRbadtype, -EREMOTE},
 	{ERRaccess, -EACCES},
 	{ERRinvtid, -ENXIO},
-	{ERRinvnetname, -ENOENT},
+	{ERRinvnetname, -ENODEV},
 	{ERRinvdevice, -ENXIO},
 	{ERRqfull, -ENOSPC},
 	{ERRqtoobig, -ENOSPC},
@@ -617,7 +620,7 @@
 	ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, {
 	ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {
 	ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {
-	ERRDOS, 2455, NT_STATUS_NETLOGON_NOT_STARTED}, {
+	ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {
 	ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {
 	ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {
diff -Nru a/fs/cifs/smberr.h b/fs/cifs/smberr.h
--- a/fs/cifs/smberr.h	Thu Oct 10 12:16:14 2002
+++ b/fs/cifs/smberr.h	Tue May 20 07:48:11 2003
@@ -59,7 +59,7 @@
 #define ERRfilexists 80		/* The file named in the request already exists. */
 #define ERRinvparm   87
 #define ERRdiskfull  112
-#define ERRinvnum    123
+#define ERRinvname   123
 #define ERRdirnotempty 145
 #define ERRnotlocked   158
 #define ERRalreadyexists 183
@@ -109,4 +109,5 @@
 #define ERRbadclient      2240
 #define ERRbadLogonTime   2241
 #define ERRpasswordExpired 2242
+#define ERRnetlogonNotStarted 2455
 #define ERRnosupport       0xFFFF
diff -Nru a/fs/fat/cache.c b/fs/fat/cache.c
--- a/fs/fat/cache.c	Wed Oct 23 08:14:05 2002
+++ b/fs/fat/cache.c	Tue May 27 07:32:56 2003
@@ -12,9 +12,6 @@
 #include <linux/msdos_fs.h>
 #include <linux/buffer_head.h>
 
-static struct fat_cache *fat_cache,cache[FAT_CACHE];
-static spinlock_t fat_cache_lock = SPIN_LOCK_UNLOCKED;
-
 int __fat_access(struct super_block *sb, int nr, int new_value)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -133,148 +130,163 @@
 	return next;
 }
 
-void fat_cache_init(void)
+void fat_cache_init(struct super_block *sb)
 {
-	static int initialized;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	int count;
 
-	spin_lock(&fat_cache_lock);
-	if (initialized) {
-		spin_unlock(&fat_cache_lock);
-		return;
-	}
-	fat_cache = &cache[0];
-	for (count = 0; count < FAT_CACHE; count++) {
-		cache[count].sb = NULL;
-		cache[count].next = count == FAT_CACHE-1 ? NULL :
-		    &cache[count+1];
-	}
-	initialized = 1;
-	spin_unlock(&fat_cache_lock);
-}
+	spin_lock_init(&sbi->cache_lock);
 
+	for (count = 0; count < FAT_CACHE_NR - 1; count++) {
+		sbi->cache_array[count].start_cluster = 0;
+		sbi->cache_array[count].next = &sbi->cache_array[count + 1];
+	}
+	sbi->cache_array[count].start_cluster = 0;
+	sbi->cache_array[count].next = NULL;
+	sbi->cache = sbi->cache_array;
+}
 
-void fat_cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu)
+void fat_cache_lookup(struct inode *inode, int cluster, int *f_clu, int *d_clu)
 {
+	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
 	struct fat_cache *walk;
-	int first = MSDOS_I(inode)->i_start;
+	int first;
 
+	BUG_ON(cluster == 0);
+	
+	first = MSDOS_I(inode)->i_start;
 	if (!first)
 		return;
-	spin_lock(&fat_cache_lock);
-	for (walk = fat_cache; walk; walk = walk->next)
-		if (inode->i_sb == walk->sb
-		    && walk->start_cluster == first
+
+	spin_lock(&sbi->cache_lock);
+
+	if (MSDOS_I(inode)->disk_cluster &&
+	    MSDOS_I(inode)->file_cluster <= cluster) {
+		*d_clu = MSDOS_I(inode)->disk_cluster;
+		*f_clu = MSDOS_I(inode)->file_cluster;
+	}
+
+	for (walk = sbi->cache; walk; walk = walk->next) {
+		if (walk->start_cluster == first
 		    && walk->file_cluster <= cluster
 		    && walk->file_cluster > *f_clu) {
 			*d_clu = walk->disk_cluster;
+			*f_clu = walk->file_cluster;
 #ifdef DEBUG
-printk("cache hit: %d (%d)\n",walk->file_cluster,*d_clu);
+			printk("cache hit: %d (%d)\n", *f_clu, *d_clu);
 #endif
-			if ((*f_clu = walk->file_cluster) == cluster) { 
-				spin_unlock(&fat_cache_lock);
-				return;
-			}
+			if (*f_clu == cluster)
+				goto out;
 		}
-	spin_unlock(&fat_cache_lock);
+	}
 #ifdef DEBUG
-printk("cache miss\n");
+	printk("cache miss\n");
 #endif
+out:
+	spin_unlock(&sbi->cache_lock);
 }
 
-
 #ifdef DEBUG
-static void list_cache(void)
+static void list_cache(struct super_block *sb)
 {
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	struct fat_cache *walk;
 
-	for (walk = fat_cache; walk; walk = walk->next) {
-		if (walk->sb)
-			printk("<%s,%d>(%d,%d) ", walk->sb->s_id,
+	for (walk = sbi->cache; walk; walk = walk->next) {
+		if (walk->start_cluster)
+			printk("<%s,%d>(%d,%d) ", sb->s_id,
 			       walk->start_cluster, walk->file_cluster,
 			       walk->disk_cluster);
-		else printk("-- ");
+		else
+			printk("-- ");
 	}
 	printk("\n");
 }
 #endif
 
-
-void fat_cache_add(struct inode *inode,int f_clu,int d_clu)
+/*
+ * Cache invalidation occurs rarely, thus the LRU chain is not updated. It
+ * fixes itself after a while.
+ */
+static void __fat_cache_inval_inode(struct inode *inode)
 {
-	struct fat_cache *walk,*last;
+	struct fat_cache *walk;
 	int first = MSDOS_I(inode)->i_start;
+	MSDOS_I(inode)->file_cluster = MSDOS_I(inode)->disk_cluster = 0;
+	for (walk = MSDOS_SB(inode->i_sb)->cache; walk; walk = walk->next)
+		if (walk->start_cluster == first)
+			walk->start_cluster = 0;
+}
+
+void fat_cache_inval_inode(struct inode *inode)
+{
+	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+	spin_lock(&sbi->cache_lock);
+	__fat_cache_inval_inode(inode);
+	spin_unlock(&sbi->cache_lock);
+}
+
+void fat_cache_add(struct inode *inode, int f_clu, int d_clu)
+{
+	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+	struct fat_cache *walk, *last;
+	int first, prev_f_clu, prev_d_clu;
+
+	first = MSDOS_I(inode)->i_start;
+	if (!first)
+		return;
 
 	last = NULL;
-	spin_lock(&fat_cache_lock);
-	for (walk = fat_cache; walk->next; walk = (last = walk)->next)
-		if (inode->i_sb == walk->sb
-		    && walk->start_cluster == first
-		    && walk->file_cluster == f_clu) {
+	spin_lock(&sbi->cache_lock);
+
+	if (MSDOS_I(inode)->file_cluster == f_clu)
+		goto out;
+	else {
+		prev_f_clu = MSDOS_I(inode)->file_cluster;
+		prev_d_clu = MSDOS_I(inode)->disk_cluster;
+		MSDOS_I(inode)->file_cluster = f_clu;
+		MSDOS_I(inode)->disk_cluster = d_clu;
+		if (prev_f_clu == 0)
+			goto out;
+		f_clu = prev_f_clu;
+		d_clu = prev_d_clu;
+	}
+	
+	for (walk = sbi->cache; walk->next; walk = (last = walk)->next) {
+		if (walk->start_cluster == first &&
+		    walk->file_cluster == f_clu) {
 			if (walk->disk_cluster != d_clu) {
 				printk(KERN_ERR "FAT: cache corruption"
 				       " (ino %lu)\n", inode->i_ino);
-				spin_unlock(&fat_cache_lock);
-				fat_cache_inval_inode(inode);
-				return;
+				__fat_cache_inval_inode(inode);
+				goto out;
 			}
+			if (last == NULL)
+				goto out;
+
 			/* update LRU */
-			if (last == NULL) {
-				spin_unlock(&fat_cache_lock);
-				return;
-			}
 			last->next = walk->next;
-			walk->next = fat_cache;
-			fat_cache = walk;
+			walk->next = sbi->cache;
+			sbi->cache = walk;
 #ifdef DEBUG
-list_cache();
+			list_cache();
 #endif
-			spin_unlock(&fat_cache_lock);
-			return;
+			goto out;
 		}
-	walk->sb = inode->i_sb;
+	}
 	walk->start_cluster = first;
 	walk->file_cluster = f_clu;
 	walk->disk_cluster = d_clu;
 	last->next = NULL;
-	walk->next = fat_cache;
-	fat_cache = walk;
-	spin_unlock(&fat_cache_lock);
+	walk->next = sbi->cache;
+	sbi->cache = walk;
 #ifdef DEBUG
-list_cache();
+	list_cache();
 #endif
+out:
+	spin_unlock(&sbi->cache_lock);
 }
 
-
-/* Cache invalidation occurs rarely, thus the LRU chain is not updated. It
-   fixes itself after a while. */
-
-void fat_cache_inval_inode(struct inode *inode)
-{
-	struct fat_cache *walk;
-	int first = MSDOS_I(inode)->i_start;
-
-	spin_lock(&fat_cache_lock);
-	for (walk = fat_cache; walk; walk = walk->next)
-		if (walk->sb == inode->i_sb
-		    && walk->start_cluster == first)
-			walk->sb = NULL;
-	spin_unlock(&fat_cache_lock);
-}
-
-
-void fat_cache_inval_dev(struct super_block *sb)
-{
-	struct fat_cache *walk;
-
-	spin_lock(&fat_cache_lock);
-	for (walk = fat_cache; walk; walk = walk->next)
-		if (walk->sb == sb)
-			walk->sb = 0;
-	spin_unlock(&fat_cache_lock);
-}
-
-
 static int fat_get_cluster(struct inode *inode, int cluster)
 {
 	struct super_block *sb = inode->i_sb;
@@ -302,32 +314,36 @@
 	return nr;
 }
 
-int fat_bmap(struct inode *inode, int sector)
+int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
 {
 	struct super_block *sb = inode->i_sb;
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
-	int cluster, offset, last_block;
+	sector_t last_block;
+	int cluster, offset;
 
+	*phys = 0;
 	if ((sbi->fat_bits != 32) &&
 	    (inode->i_ino == MSDOS_ROOT_INO || (S_ISDIR(inode->i_mode) &&
 	     !MSDOS_I(inode)->i_start))) {
-		if (sector >= sbi->dir_entries >> sbi->dir_per_block_bits)
-			return 0;
-		return sector + sbi->dir_start;
+		if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits))
+			*phys = sector + sbi->dir_start;
+		return 0;
 	}
 	last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
 		>> sb->s_blocksize_bits;
 	if (sector >= last_block)
 		return 0;
 
-	cluster = sector / sbi->cluster_size;
-	offset  = sector % sbi->cluster_size;
+	cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits);
+	offset  = sector & (sbi->cluster_size - 1);
 	cluster = fat_get_cluster(inode, cluster);
 	if (cluster < 0)
 		return cluster;
-	else if (!cluster)
-		return 0;
-	return (cluster - 2) * sbi->cluster_size + sbi->data_start + offset;
+	else if (cluster) {
+		*phys = ((sector_t)cluster - 2) * sbi->cluster_size
+			+ sbi->data_start + offset;
+	}
+	return 0;
 }
 
 
diff -Nru a/fs/fat/dir.c b/fs/fat/dir.c
--- a/fs/fat/dir.c	Sun Nov 17 11:53:57 2002
+++ b/fs/fat/dir.c	Tue May 27 07:32:48 2003
@@ -191,11 +191,11 @@
 	int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate;
 	int utf8 = MSDOS_SB(sb)->options.utf8;
 	unsigned short opt_shortname = MSDOS_SB(sb)->options.shortname;
-	int ino, chl, i, j, last_u, res = 0;
-	loff_t cpos = 0;
+	int chl, i, j, last_u, res = 0;
+	loff_t i_pos, cpos = 0;
 
 	while(1) {
-		if (fat_get_entry(inode,&cpos,&bh,&de,&ino) == -1)
+		if (fat_get_entry(inode,&cpos,&bh,&de,&i_pos) == -1)
 			goto EODir;
 parse_record:
 		long_slots = 0;
@@ -246,7 +246,7 @@
 				if (ds->id & 0x40) {
 					unicode[offset + 13] = 0;
 				}
-				if (fat_get_entry(inode,&cpos,&bh,&de,&ino)<0)
+				if (fat_get_entry(inode,&cpos,&bh,&de,&i_pos)<0)
 					goto EODir;
 				if (slot == 0)
 					break;
@@ -358,14 +358,15 @@
 	int utf8 = MSDOS_SB(sb)->options.utf8;
 	int nocase = MSDOS_SB(sb)->options.nocase;
 	unsigned short opt_shortname = MSDOS_SB(sb)->options.shortname;
-	int ino, inum, chi, chl, i, i2, j, last, last_u, dotoffset = 0;
-	loff_t cpos;
+	unsigned long inum;
+	int chi, chl, i, i2, j, last, last_u, dotoffset = 0;
+	loff_t i_pos, cpos;
 	int ret = 0;
 	
 	lock_kernel();
 
 	cpos = filp->f_pos;
-/* Fake . and .. for the root directory. */
+	/* Fake . and .. for the root directory. */
 	if (inode->i_ino == MSDOS_ROOT_INO) {
 		while (cpos < 2) {
 			if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0)
@@ -387,7 +388,7 @@
  	bh = NULL;
 GetNew:
 	long_slots = 0;
-	if (fat_get_entry(inode,&cpos,&bh,&de,&ino) == -1)
+	if (fat_get_entry(inode,&cpos,&bh,&de,&i_pos) == -1)
 		goto EODir;
 	/* Check for long filename entry */
 	if (isvfat) {
@@ -445,7 +446,7 @@
 			if (ds->id & 0x40) {
 				unicode[offset + 13] = 0;
 			}
-			if (fat_get_entry(inode,&cpos,&bh,&de,&ino) == -1)
+			if (fat_get_entry(inode,&cpos,&bh,&de,&i_pos) == -1)
 				goto EODir;
 			if (slot == 0)
 				break;
@@ -533,7 +534,7 @@
 	else if (!memcmp(de->name,MSDOS_DOTDOT,11)) {
 		inum = parent_ino(filp->f_dentry);
 	} else {
-		struct inode *tmp = fat_iget(sb, ino);
+		struct inode *tmp = fat_iget(sb, i_pos);
 		if (tmp) {
 			inum = tmp->i_ino;
 			iput(tmp);
@@ -591,23 +592,23 @@
 	return fat_readdirx(inode, filp, dirent, filldir, 0, 0);
 }
 
-static int vfat_ioctl_fill(
-	void * buf,
-	const char * name,
-	int name_len,
-	loff_t offset,
-	ino_t ino,
-	unsigned int d_type)
+struct fat_ioctl_filldir_callback {
+	struct dirent __user *dirent;
+	int result;
+};
+
+static int fat_ioctl_filldir(void *__buf, const char * name, int name_len,
+			     loff_t offset, ino_t ino, unsigned int d_type)
 {
-	struct dirent *d1 = (struct dirent *)buf;
-	struct dirent *d2 = d1 + 1;
+	struct fat_ioctl_filldir_callback *buf = __buf;
+	struct dirent __user *d1 = buf->dirent;
+	struct dirent __user *d2 = d1 + 1;
 	int len, slen;
 	int dotdir;
 
-	get_user(len, &d1->d_reclen);
-	if (len != 0) {
-		return -1;
-	}
+	if (buf->result)
+		return -EINVAL;
+	buf->result++;
 
 	if ((name_len == 1 && name[0] == '.') ||
 	    (name_len == 2 && name[0] == '.' && name[1] == '.')) {
@@ -618,73 +619,79 @@
 		len = strlen(name);
 	}
 	if (len != name_len) {
-		copy_to_user(d2->d_name, name, len);
-		put_user(0, d2->d_name + len);
-		put_user(len, &d2->d_reclen);
-		put_user(ino, &d2->d_ino);
-		put_user(offset, &d2->d_off);
 		slen = name_len - len;
-		copy_to_user(d1->d_name, name+len+1, slen);
-		put_user(0, d1->d_name+slen);
-		put_user(slen, &d1->d_reclen);
+		if (copy_to_user(d2->d_name, name, len)		||
+		    put_user(0, d2->d_name + len)		||
+		    put_user(len, &d2->d_reclen)		||
+		    put_user(ino, &d2->d_ino)			||
+		    put_user(offset, &d2->d_off)		||
+		    copy_to_user(d1->d_name, name+len+1, slen)	||
+		    put_user(0, d1->d_name+slen)		||
+		    put_user(slen, &d1->d_reclen))
+			goto efault;
 	} else {
-		put_user(0, d2->d_name);
-		put_user(0, &d2->d_reclen);
-		copy_to_user(d1->d_name, name, len);
-		put_user(0, d1->d_name+len);
-		put_user(len, &d1->d_reclen);
+		if (put_user(0, d2->d_name)			||
+		    put_user(0, &d2->d_reclen)			||
+		    copy_to_user(d1->d_name, name, len)		||
+		    put_user(0, d1->d_name+len)			||
+		    put_user(len, &d1->d_reclen))
+			goto efault;
 	}
-
 	return 0;
+efault:
+	buf->result = -EFAULT;
+	return -EFAULT;
 }
 
 int fat_dir_ioctl(struct inode * inode, struct file * filp,
 		  unsigned int cmd, unsigned long arg)
 {
-	int err;
+	struct fat_ioctl_filldir_callback buf;
+	struct dirent __user *d1 = (struct dirent *)arg;
+	int ret, shortname, both;
+
+	if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2])))
+		return -EFAULT;
 	/*
-	 * We want to provide an interface for Samba to be able
-	 * to get the short filename for a given long filename.
-	 * Samba should use this ioctl instead of readdir() to
-	 * get the information it needs.
+	 * Yes, we don't need this put_user() absolutely. However old
+	 * code didn't return the right value. So, app use this value,
+	 * in order to check whether it is EOF.
 	 */
+	if (put_user(0, &d1->d_reclen))
+		return -EFAULT;
+
+	buf.dirent = d1;
+	buf.result = 0;
 	switch (cmd) {
-	case VFAT_IOCTL_READDIR_BOTH: {
-		struct dirent *d1 = (struct dirent *)arg;
-		err = verify_area(VERIFY_WRITE, d1, sizeof(struct dirent[2]));
-		if (err)
-			return err;
-		put_user(0, &d1->d_reclen);
-		return fat_readdirx(inode,filp,(void *)arg,
-				    vfat_ioctl_fill, 0, 1);
-	}
-	case VFAT_IOCTL_READDIR_SHORT: {
-		struct dirent *d1 = (struct dirent *)arg;
-		put_user(0, &d1->d_reclen);
-		err = verify_area(VERIFY_WRITE, d1, sizeof(struct dirent[2]));
-		if (err)
-			return err;
-		return fat_readdirx(inode,filp,(void *)arg,
-				    vfat_ioctl_fill, 1, 1);
-	}
+	case VFAT_IOCTL_READDIR_SHORT:
+		shortname = 1;
+		both = 1;
+		break;
+	case VFAT_IOCTL_READDIR_BOTH:
+		shortname = 0;
+		both = 1;
+		break;
 	default:
 		return -EINVAL;
 	}
-
-	return 0;
+	ret = fat_readdirx(inode, filp, &buf, fat_ioctl_filldir,
+			   shortname, both);
+	if (ret >= 0)
+		ret = buf.result;
+	return ret;
 }
 
 /***** See if directory is empty */
 int fat_dir_empty(struct inode *dir)
 {
-	loff_t pos;
+	loff_t pos, i_pos;
 	struct buffer_head *bh;
 	struct msdos_dir_entry *de;
-	int ino,result = 0;
+	int result = 0;
 
 	pos = 0;
 	bh = NULL;
-	while (fat_get_entry(dir,&pos,&bh,&de,&ino) > -1) {
+	while (fat_get_entry(dir,&pos,&bh,&de,&i_pos) > -1) {
 		/* Ignore vfat longname entries */
 		if (de->attr == ATTR_EXT)
 			continue;
@@ -703,7 +710,7 @@
 /* This assumes that size of cluster is above the 32*slots */
 
 int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
-		  struct msdos_dir_entry **de, int *ino)
+		  struct msdos_dir_entry **de, loff_t *i_pos)
 {
 	struct super_block *sb = dir->i_sb;
 	loff_t offset, curr;
@@ -713,7 +720,7 @@
 	offset = curr = 0;
 	*bh = NULL;
 	row = 0;
-	while (fat_get_entry(dir, &curr, bh, de, ino) > -1) {
+	while (fat_get_entry(dir, &curr, bh, de, i_pos) > -1) {
 		/* check the maximum size of directory */
 		if (curr >= FAT_MAX_DIR_SIZE) {
 			brelse(*bh);
@@ -735,7 +742,7 @@
 		return PTR_ERR(new_bh);
 	brelse(new_bh);
 	do {
-		fat_get_entry(dir, &curr, bh, de, ino);
+		fat_get_entry(dir, &curr, bh, de, i_pos);
 	} while (++row < slots);
 
 	return offset;
diff -Nru a/fs/fat/file.c b/fs/fat/file.c
--- a/fs/fat/file.c	Tue Nov  5 07:36:01 2002
+++ b/fs/fat/file.c	Tue May 27 07:32:40 2003
@@ -32,11 +32,12 @@
 		  struct buffer_head *bh_result, int create)
 {
 	struct super_block *sb = inode->i_sb;
-	unsigned long phys;
+	sector_t phys;
+	int err;
 
-	phys = fat_bmap(inode, iblock);
-	if (phys < 0)
-		return phys;
+	err = fat_bmap(inode, iblock, &phys);
+	if (err)
+		return err;
 	if (phys) {
 		map_bh(bh_result, sb, phys);
 		return 0;
@@ -55,9 +56,9 @@
 			return error;
 	}
 	MSDOS_I(inode)->mmu_private += sb->s_blocksize;
-	phys = fat_bmap(inode, iblock);
-	if (phys < 0)
-		return phys;
+	err = fat_bmap(inode, iblock, &phys);
+	if (err)
+		return err;
 	if (!phys)
 		BUG();
 	set_buffer_new(bh_result);
diff -Nru a/fs/fat/inode.c b/fs/fat/inode.c
--- a/fs/fat/inode.c	Sun May 25 14:07:56 2003
+++ b/fs/fat/inode.c	Tue May 27 07:32:57 2003
@@ -60,17 +60,17 @@
 	}
 }
 
-static inline unsigned long fat_hash(struct super_block *sb, int i_pos)
+static inline unsigned long fat_hash(struct super_block *sb, loff_t i_pos)
 {
 	unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb;
 	tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS * 2);
 	return tmp & FAT_HASH_MASK;
 }
 
-void fat_attach(struct inode *inode, int i_pos)
+void fat_attach(struct inode *inode, loff_t i_pos)
 {
 	spin_lock(&fat_inode_lock);
-	MSDOS_I(inode)->i_location = i_pos;
+	MSDOS_I(inode)->i_pos = i_pos;
 	list_add(&MSDOS_I(inode)->i_fat_hash,
 		fat_inode_hashtable + fat_hash(inode->i_sb, i_pos));
 	spin_unlock(&fat_inode_lock);
@@ -79,12 +79,12 @@
 void fat_detach(struct inode *inode)
 {
 	spin_lock(&fat_inode_lock);
-	MSDOS_I(inode)->i_location = 0;
+	MSDOS_I(inode)->i_pos = 0;
 	list_del_init(&MSDOS_I(inode)->i_fat_hash);
 	spin_unlock(&fat_inode_lock);
 }
 
-struct inode *fat_iget(struct super_block *sb, int i_pos)
+struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
 {
 	struct list_head *p = fat_inode_hashtable + fat_hash(sb, i_pos);
 	struct list_head *walk;
@@ -96,7 +96,7 @@
 		i = list_entry(walk, struct msdos_inode_info, i_fat_hash);
 		if (i->vfs_inode.i_sb != sb)
 			continue;
-		if (i->i_location != i_pos)
+		if (i->i_pos != i_pos)
 			continue;
 		inode = igrab(&i->vfs_inode);
 		if (inode)
@@ -109,11 +109,11 @@
 static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de);
 
 struct inode *fat_build_inode(struct super_block *sb,
-				struct msdos_dir_entry *de, int ino, int *res)
+			struct msdos_dir_entry *de, loff_t i_pos, int *res)
 {
 	struct inode *inode;
 	*res = 0;
-	inode = fat_iget(sb, ino);
+	inode = fat_iget(sb, i_pos);
 	if (inode)
 		goto out;
 	inode = new_inode(sb);
@@ -128,7 +128,7 @@
 		inode = NULL;
 		goto out;
 	}
-	fat_attach(inode, ino);
+	fat_attach(inode, i_pos);
 	insert_inode_hash(inode);
 out:
 	return inode;
@@ -160,7 +160,6 @@
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 
 	fat_clusters_flush(sb);
-	fat_cache_inval_dev(sb);
 	if (sbi->nls_disk) {
 		unload_nls(sbi->nls_disk);
 		sbi->nls_disk = NULL;
@@ -500,7 +499,7 @@
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	int error;
 
-	MSDOS_I(inode)->i_location = 0;
+	MSDOS_I(inode)->i_pos = 0;
 	inode->i_uid = sbi->options.fs_uid;
 	inode->i_gid = sbi->options.fs_gid;
 	inode->i_version++;
@@ -537,9 +536,10 @@
  *  0/  i_ino - for fast, reliable lookup if still in the cache
  *  1/  i_generation - to see if i_ino is still valid
  *          bit 0 == 0 iff directory
- *  2/  i_location - if ino has changed, but still in cache
- *  3/  i_logstart - to semi-verify inode found at i_location
- *  4/  parent->i_logstart - maybe used to hunt for the file on disc
+ *  2/  i_pos - if ino has changed, but still in cache (hi)
+ *  3/  i_pos - if ino has changed, but still in cache (low)
+ *  4/  i_logstart - to semi-verify inode found at i_location
+ *  5/  parent->i_logstart - maybe used to hunt for the file on disc
  *
  */
 
@@ -551,7 +551,7 @@
 
 	if (fhtype != 3)
 		return ERR_PTR(-ESTALE);
-	if (len < 5)
+	if (len < 6)
 		return ERR_PTR(-ESTALE);
 
 	return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
@@ -570,13 +570,15 @@
 		inode = NULL;
 	}
 	if (!inode) {
-		/* try 2 - see if i_location is in F-d-c
+		loff_t i_pos = ((loff_t)fh[2] << 32) | fh[3];
+
+		/* try 2 - see if i_pos is in F-d-c
 		 * require i_logstart to be the same
 		 * Will fail if you truncate and then re-write
 		 */
 
-		inode = fat_iget(sb, fh[2]);
-		if (inode && MSDOS_I(inode)->i_logstart != fh[3]) {
+		inode = fat_iget(sb, i_pos);
+		if (inode && MSDOS_I(inode)->i_logstart != fh[4]) {
 			iput(inode);
 			inode = NULL;
 		}
@@ -616,15 +618,16 @@
 	int len = *lenp;
 	struct inode *inode =  de->d_inode;
 	
-	if (len < 5)
+	if (len < 6)
 		return 255; /* no room */
-	*lenp = 5;
+	*lenp = 6;
 	fh[0] = inode->i_ino;
 	fh[1] = inode->i_generation;
-	fh[2] = MSDOS_I(inode)->i_location;
-	fh[3] = MSDOS_I(inode)->i_logstart;
+	fh[2] = (__u32)(MSDOS_I(inode)->i_pos >> 32);
+	fh[3] = (__u32)MSDOS_I(inode)->i_pos;
+	fh[4] = MSDOS_I(inode)->i_logstart;
 	spin_lock(&de->d_lock);
-	fh[4] = MSDOS_I(de->d_parent->d_inode)->i_logstart;
+	fh[5] = MSDOS_I(de->d_parent->d_inode)->i_logstart;
 	spin_unlock(&de->d_lock);
 	return 3;
 }
@@ -635,15 +638,15 @@
 	struct msdos_dir_entry *de = NULL;
 	struct dentry *parent = NULL;
 	int res;
-	int ino = 0;
+	loff_t i_pos = 0;
 	struct inode *inode;
 
 	lock_kernel();
-	res = fat_scan(child->d_inode, MSDOS_DOTDOT, &bh, &de, &ino);
+	res = fat_scan(child->d_inode, MSDOS_DOTDOT, &bh, &de, &i_pos);
 
 	if (res < 0)
 		goto out;
-	inode = fat_build_inode(child->d_sb, de, ino, &res);
+	inode = fat_build_inode(child->d_sb, de, i_pos, &res);
 	if (res)
 		goto out;
 	if (!inode)
@@ -762,7 +765,7 @@
 	if (!parse_options(data, isvfat, &debug, &sbi->options))
 		goto out_fail;
 
-	fat_cache_init();
+	fat_cache_init(sb);
 	/* set up enough so that it can read an inode */
 	init_MUTEX(&sbi->fat_lock);
 
@@ -1098,7 +1101,8 @@
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	int error;
 
-	MSDOS_I(inode)->i_location = 0;
+	MSDOS_I(inode)->file_cluster = MSDOS_I(inode)->disk_cluster = 0;
+	MSDOS_I(inode)->i_pos = 0;
 	inode->i_uid = sbi->options.fs_uid;
 	inode->i_gid = sbi->options.fs_gid;
 	inode->i_version++;
@@ -1112,10 +1116,9 @@
 		inode->i_fop = &fat_dir_operations;
 
 		MSDOS_I(inode)->i_start = CF_LE_W(de->start);
-		if (sbi->fat_bits == 32) {
-			MSDOS_I(inode)->i_start |=
-				(CF_LE_W(de->starthi) << 16);
-		}
+		if (sbi->fat_bits == 32)
+			MSDOS_I(inode)->i_start |= (CF_LE_W(de->starthi) << 16);
+
 		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
 		error = fat_calc_dir_size(inode);
 		if (error < 0)
@@ -1131,10 +1134,9 @@
 		    	? S_IRUGO|S_IWUGO : S_IRWXUGO)
 		    & ~sbi->options.fs_fmask) | S_IFREG;
 		MSDOS_I(inode)->i_start = CF_LE_W(de->start);
-		if (sbi->fat_bits == 32) {
-			MSDOS_I(inode)->i_start |=
-				(CF_LE_W(de->starthi) << 16);
-		}
+		if (sbi->fat_bits == 32)
+			MSDOS_I(inode)->i_start |= (CF_LE_W(de->starthi) << 16);
+
 		MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
 		inode->i_size = CF_LE_L(de->size);
 	        inode->i_op = &fat_file_inode_operations;
@@ -1168,22 +1170,22 @@
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *bh;
 	struct msdos_dir_entry *raw_entry;
-	unsigned int i_pos;
+	loff_t i_pos;
 
 retry:
-	i_pos = MSDOS_I(inode)->i_location;
+	i_pos = MSDOS_I(inode)->i_pos;
 	if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) {
 		return;
 	}
 	lock_kernel();
 	if (!(bh = sb_bread(sb, i_pos >> MSDOS_SB(sb)->dir_per_block_bits))) {
-		fat_fs_panic(sb, "unable to read i-node block (ino %lu)",
+		fat_fs_panic(sb, "unable to read i-node block (i_pos %llu)",
 			     i_pos);
 		unlock_kernel();
 		return;
 	}
 	spin_lock(&fat_inode_lock);
-	if (i_pos != MSDOS_I(inode)->i_location) {
+	if (i_pos != MSDOS_I(inode)->i_pos) {
 		spin_unlock(&fat_inode_lock);
 		brelse(bh);
 		unlock_kernel();
diff -Nru a/fs/fat/misc.c b/fs/fat/misc.c
--- a/fs/fat/misc.c	Mon May 12 21:23:11 2003
+++ b/fs/fat/misc.c	Tue May 27 07:32:40 2003
@@ -178,9 +178,9 @@
 struct buffer_head *fat_extend_dir(struct inode *inode)
 {
 	struct super_block *sb = inode->i_sb;
-	int nr, sector, last_sector;
 	struct buffer_head *bh, *res = NULL;
-	int cluster_size = MSDOS_SB(sb)->cluster_size;
+	int nr, cluster_size = MSDOS_SB(sb)->cluster_size;
+	sector_t sector, last_sector;
 
 	if (MSDOS_SB(sb)->fat_bits != 32) {
 		if (inode->i_ino == MSDOS_ROOT_INO)
@@ -191,7 +191,7 @@
 	if (nr < 0)
 		return ERR_PTR(nr);
 	
-	sector = MSDOS_SB(sb)->data_start + (nr - 2) * cluster_size;
+	sector = ((sector_t)nr - 2) * cluster_size + MSDOS_SB(sb)->data_start;
 	last_sector = sector + cluster_size;
 	for ( ; sector < last_sector; sector++) {
 		if ((bh = sb_getblk(sb, sector))) {
@@ -289,11 +289,13 @@
  */
 
 int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
-    struct msdos_dir_entry **de, int *ino)
+		   struct msdos_dir_entry **de, loff_t *i_pos)
 {
 	struct super_block *sb = dir->i_sb;
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
-	int sector, offset, iblock;
+	sector_t phys, iblock;
+	loff_t offset;
+	int err;
 
 next:
 	offset = *pos;
@@ -302,14 +304,14 @@
 
 	*bh = NULL;
 	iblock = *pos >> sb->s_blocksize_bits;
-	sector = fat_bmap(dir, iblock);
-	if (sector <= 0)
+	err = fat_bmap(dir, iblock, &phys);
+	if (err || !phys)
 		return -1;	/* beyond EOF or error */
 
-	*bh = sb_bread(sb, sector);
+	*bh = sb_bread(sb, phys);
 	if (*bh == NULL) {
-		printk(KERN_ERR "FAT: Directory bread(block %d) failed\n",
-		       sector);
+		printk(KERN_ERR "FAT: Directory bread(block %llu) failed\n",
+		       phys);
 		/* skip this block */
 		*pos = (iblock + 1) << sb->s_blocksize_bits;
 		goto next;
@@ -318,7 +320,7 @@
 	offset &= sb->s_blocksize - 1;
 	*pos += sizeof(struct msdos_dir_entry);
 	*de = (struct msdos_dir_entry *)((*bh)->b_data + offset);
-	*ino = (sector << sbi->dir_per_block_bits) + (offset >> MSDOS_DIR_BITS);
+	*i_pos = ((loff_t)phys << sbi->dir_per_block_bits) + (offset >> MSDOS_DIR_BITS);
 
 	return 0;
 }
@@ -357,7 +359,7 @@
     done = !IS_FREE(data[entry].name) \
       && ( \
            ( \
-             (MSDOS_SB(sb)->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
+             (sbi->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
            ) \
            | CF_LE_W(data[entry].start) \
          ) == *number;
@@ -374,35 +376,38 @@
 	    (*number)++; \
     }
 
-static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
-    int *number,int *ino,struct buffer_head **res_bh,
-    struct msdos_dir_entry **res_de)
+static int raw_scan_sector(struct super_block *sb, sector_t sector,
+			   const char *name, int *number, loff_t *i_pos,
+			   struct buffer_head **res_bh,
+			   struct msdos_dir_entry **res_de)
 {
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	struct buffer_head *bh;
 	struct msdos_dir_entry *data;
 	int entry,start,done;
 
-	if (!(bh = sb_bread(sb,sector)))
+	if (!(bh = sb_bread(sb, sector)))
 		return -EIO;
 	data = (struct msdos_dir_entry *) bh->b_data;
-	for (entry = 0; entry < MSDOS_SB(sb)->dir_per_block; entry++) {
+	for (entry = 0; entry < sbi->dir_per_block; entry++) {
 /* RSS_COUNT:  if (data[entry].name == name) done=true else done=false. */
 		if (name) {
 			RSS_NAME
 		} else {
-			if (!ino) RSS_COUNT
+			if (!i_pos) RSS_COUNT
 			else {
 				if (number) RSS_START
 				else RSS_FREE
 			}
 		}
 		if (done) {
-			if (ino)
-				*ino = sector * MSDOS_SB(sb)->dir_per_block + entry;
+			if (i_pos) {
+				*i_pos = ((loff_t)sector << sbi->dir_per_block_bits) + entry;
+			}
 			start = CF_LE_W(data[entry].start);
-			if (MSDOS_SB(sb)->fat_bits == 32) {
+			if (sbi->fat_bits == 32)
 				start |= (CF_LE_W(data[entry].starthi) << 16);
-			}
+
 			if (!res_bh)
 				brelse(bh);
 			else {
@@ -422,16 +427,19 @@
  * requested entry is found or the end of the directory is reached.
  */
 
-static int raw_scan_root(struct super_block *sb,const char *name,int *number,int *ino,
-    struct buffer_head **res_bh,struct msdos_dir_entry **res_de)
+static int raw_scan_root(struct super_block *sb, const char *name,
+			 int *number, loff_t *i_pos,
+			 struct buffer_head **res_bh,
+			 struct msdos_dir_entry **res_de)
 {
 	int count,cluster;
 
 	for (count = 0;
 	     count < MSDOS_SB(sb)->dir_entries / MSDOS_SB(sb)->dir_per_block;
 	     count++) {
-		if ((cluster = raw_scan_sector(sb,MSDOS_SB(sb)->dir_start+count,
-					       name,number,ino,res_bh,res_de)) >= 0)
+		cluster = raw_scan_sector(sb, MSDOS_SB(sb)->dir_start + count,
+					  name, number, i_pos, res_bh, res_de);
+		if (cluster >= 0)
 			return cluster;
 	}
 	return -ENOENT;
@@ -443,24 +451,29 @@
  * requested entry is found or the end of the directory is reached.
  */
 
-static int raw_scan_nonroot(struct super_block *sb,int start,const char *name,
-    int *number,int *ino,struct buffer_head **res_bh,struct msdos_dir_entry
-    **res_de)
+static int raw_scan_nonroot(struct super_block *sb, int start, const char *name,
+			    int *number, loff_t *i_pos,
+			    struct buffer_head **res_bh,
+			    struct msdos_dir_entry **res_de)
 {
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	int count, cluster;
 	unsigned long dir_size = 0;
+	sector_t sector;
 
 #ifdef DEBUG
 	printk("raw_scan_nonroot: start=%d\n",start);
 #endif
 	do {
-		for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) {
-			if ((cluster = raw_scan_sector(sb,(start-2)*
-			    MSDOS_SB(sb)->cluster_size+MSDOS_SB(sb)->data_start+
-			    count,name,number,ino,res_bh,res_de)) >= 0)
+		for (count = 0; count < sbi->cluster_size; count++) {
+			sector = ((sector_t)start - 2) * sbi->cluster_size
+				+ count + sbi->data_start;
+			cluster = raw_scan_sector(sb, sector, name, number,
+						  i_pos, res_bh, res_de);
+			if (cluster >= 0)
 				return cluster;
 		}
-		dir_size += 1 << MSDOS_SB(sb)->cluster_bits;
+		dir_size += 1 << sbi->cluster_bits;
 		if (dir_size > FAT_MAX_DIR_SIZE) {
 			fat_fs_panic(sb, "Directory %d: "
 				     "exceeded the maximum size of directory",
@@ -492,13 +505,13 @@
  */
 
 static int raw_scan(struct super_block *sb, int start, const char *name,
-    int *number, int *ino, struct buffer_head **res_bh,
-    struct msdos_dir_entry **res_de)
+		    loff_t *i_pos, struct buffer_head **res_bh,
+		    struct msdos_dir_entry **res_de)
 {
 	if (start)
-		return raw_scan_nonroot(sb,start,name,number,ino,res_bh,res_de);
+		return raw_scan_nonroot(sb,start,name,NULL,i_pos,res_bh,res_de);
 	else
-		return raw_scan_root(sb,name,number,ino,res_bh,res_de);
+		return raw_scan_root(sb,name,NULL,i_pos,res_bh,res_de);
 }
 
 /*
@@ -507,19 +520,21 @@
  */
 int fat_subdirs(struct inode *dir)
 {
-	int count;
+	struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
+	int number;
 
-	count = 0;
-	if ((dir->i_ino == MSDOS_ROOT_INO) &&
-	    (MSDOS_SB(dir->i_sb)->fat_bits != 32)) {
-		(void) raw_scan_root(dir->i_sb,NULL,&count,NULL,NULL,NULL);
-	} else {
-		if ((dir->i_ino != MSDOS_ROOT_INO) &&
-		    !MSDOS_I(dir)->i_start) return 0; /* in mkdir */
-		else (void) raw_scan_nonroot(dir->i_sb,MSDOS_I(dir)->i_start,
-		    NULL,&count,NULL,NULL,NULL);
+	number = 0;
+	if ((dir->i_ino == MSDOS_ROOT_INO) && (sbi->fat_bits != 32))
+		raw_scan_root(dir->i_sb, NULL, &number, NULL, NULL, NULL);
+	else {
+		if ((dir->i_ino != MSDOS_ROOT_INO) && !MSDOS_I(dir)->i_start)
+			return 0; /* in mkdir */
+		else {
+			raw_scan_nonroot(dir->i_sb, MSDOS_I(dir)->i_start,
+					 NULL, &number, NULL, NULL, NULL);
+		}
 	}
-	return count;
+	return number;
 }
 
 
@@ -528,12 +543,12 @@
  * for an empty directory slot (name is NULL). Returns an error code or zero.
  */
 
-int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh,
-    struct msdos_dir_entry **res_de,int *ino)
+int fat_scan(struct inode *dir, const char *name, struct buffer_head **res_bh,
+	     struct msdos_dir_entry **res_de, loff_t *i_pos)
 {
 	int res;
 
-	res = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,
-		       name, NULL, ino, res_bh, res_de);
-	return res<0 ? res : 0;
+	res = raw_scan(dir->i_sb, MSDOS_I(dir)->i_start, name, i_pos,
+		       res_bh, res_de);
+	return (res < 0) ? res : 0;
 }
diff -Nru a/fs/msdos/namei.c b/fs/msdos/namei.c
--- a/fs/msdos/namei.c	Sun Nov 17 12:40:03 2002
+++ b/fs/msdos/namei.c	Tue May 27 07:32:40 2003
@@ -112,8 +112,9 @@
 }
 
 /***** Locates a directory entry.  Uses unformatted name. */
-static int msdos_find(struct inode *dir,const char *name,int len,
-    struct buffer_head **bh,struct msdos_dir_entry **de,int *ino)
+static int msdos_find(struct inode *dir, const char *name, int len,
+		      struct buffer_head **bh, struct msdos_dir_entry **de,
+		      loff_t *i_pos)
 {
 	int res;
 	char dotsOK;
@@ -123,7 +124,7 @@
 	res = msdos_format_name(name,len, msdos_name,&MSDOS_SB(dir->i_sb)->options);
 	if (res < 0)
 		return -ENOENT;
-	res = fat_scan(dir,msdos_name,bh,de,ino);
+	res = fat_scan(dir, msdos_name, bh, de, i_pos);
 	if (!res && dotsOK) {
 		if (name[0]=='.') {
 			if (!((*de)->attr & ATTR_HIDDEN))
@@ -134,7 +135,6 @@
 		}
 	}
 	return res;
-
 }
 
 /*
@@ -199,19 +199,19 @@
 	struct inode *inode = NULL;
 	struct msdos_dir_entry *de;
 	struct buffer_head *bh = NULL;
-	int ino,res;
+	loff_t i_pos;
+	int res;
 	
 	dentry->d_op = &msdos_dentry_operations;
 
 	lock_kernel();
 	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh,
-			&de, &ino);
-
+			 &de, &i_pos);
 	if (res == -ENOENT)
 		goto add;
 	if (res < 0)
 		goto out;
-	inode = fat_build_inode(sb, de, ino, &res);
+	inode = fat_build_inode(sb, de, i_pos, &res);
 	if (res)
 		goto out;
 add:
@@ -231,12 +231,11 @@
 static int msdos_add_entry(struct inode *dir, const char *name,
 			   struct buffer_head **bh,
 			   struct msdos_dir_entry **de,
-			   int *ino,
-			   int is_dir, int is_hid)
+			   loff_t *i_pos, int is_dir, int is_hid)
 {
 	int res;
 
-	res = fat_add_entries(dir, 1, bh, de, ino);
+	res = fat_add_entries(dir, 1, bh, de, i_pos);
 	if (res < 0)
 		return res;
 
@@ -268,7 +267,8 @@
 	struct buffer_head *bh;
 	struct msdos_dir_entry *de;
 	struct inode *inode;
-	int ino,res,is_hid;
+	loff_t i_pos;
+	int res, is_hid;
 	char msdos_name[MSDOS_NAME];
 
 	lock_kernel();
@@ -280,18 +280,18 @@
 	}
 	is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
 	/* Have to do it due to foo vs. .foo conflicts */
-	if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0) {
+	if (fat_scan(dir, msdos_name, &bh, &de, &i_pos) >= 0) {
 		brelse(bh);
 		unlock_kernel();
 		return -EINVAL;
  	}
 	inode = NULL;
-	res = msdos_add_entry(dir, msdos_name, &bh, &de, &ino, 0, is_hid);
+	res = msdos_add_entry(dir, msdos_name, &bh, &de, &i_pos, 0, is_hid);
 	if (res) {
 		unlock_kernel();
 		return res;
 	}
-	inode = fat_build_inode(dir->i_sb, de, ino, &res);
+	inode = fat_build_inode(dir->i_sb, de, i_pos, &res);
 	brelse(bh);
 	if (!inode) {
 		unlock_kernel();
@@ -308,14 +308,15 @@
 int msdos_rmdir(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
-	int res,ino;
+	loff_t i_pos;
+	int res;
 	struct buffer_head *bh;
 	struct msdos_dir_entry *de;
 
 	bh = NULL;
 	lock_kernel();
 	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len,
-				&bh, &de, &ino);
+			 &bh, &de, &i_pos);
 	if (res < 0)
 		goto rmdir_done;
 	/*
@@ -351,7 +352,7 @@
 	struct inode *inode;
 	int res,is_hid;
 	char msdos_name[MSDOS_NAME];
-	int ino;
+	loff_t i_pos;
 
 	lock_kernel();
 	res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
@@ -362,13 +363,13 @@
 	}
 	is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
 	/* foo vs .foo situation */
-	if (fat_scan(dir,msdos_name,&bh,&de,&ino) >= 0)
+	if (fat_scan(dir, msdos_name, &bh, &de, &i_pos) >= 0)
 		goto out_exist;
 
-	res = msdos_add_entry(dir, msdos_name, &bh, &de, &ino, 1, is_hid);
+	res = msdos_add_entry(dir, msdos_name, &bh, &de, &i_pos, 1, is_hid);
 	if (res)
 		goto out_unlock;
-	inode = fat_build_inode(dir->i_sb, de, ino, &res);
+	inode = fat_build_inode(dir->i_sb, de, i_pos, &res);
 	if (!inode) {
 		brelse(bh);
 		goto out_unlock;
@@ -414,14 +415,15 @@
 int msdos_unlink( struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
-	int res,ino;
+	loff_t i_pos;
+	int res;
 	struct buffer_head *bh;
 	struct msdos_dir_entry *de;
 
 	bh = NULL;
 	lock_kernel();
 	res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len,
-			&bh, &de, &ino);
+			 &bh, &de, &i_pos);
 	if (res < 0)
 		goto unlink_done;
 
@@ -443,12 +445,12 @@
     struct dentry *old_dentry,
     struct inode *new_dir,char *new_name, struct dentry *new_dentry,
     struct buffer_head *old_bh,
-    struct msdos_dir_entry *old_de, int old_ino, int is_hid)
+    struct msdos_dir_entry *old_de, loff_t old_i_pos, int is_hid)
 {
 	struct buffer_head *new_bh=NULL,*dotdot_bh=NULL;
 	struct msdos_dir_entry *new_de,*dotdot_de;
 	struct inode *old_inode,*new_inode;
-	int new_ino,dotdot_ino;
+	loff_t new_i_pos, dotdot_i_pos;
 	int error;
 	int is_dir;
 
@@ -456,7 +458,8 @@
 	new_inode = new_dentry->d_inode;
 	is_dir = S_ISDIR(old_inode->i_mode);
 
-	if (fat_scan(new_dir,new_name,&new_bh,&new_de,&new_ino)>=0 &&!new_inode)
+	if (fat_scan(new_dir, new_name, &new_bh, &new_de, &new_i_pos) >= 0
+	    && !new_inode)
 		goto degenerate_case;
 	if (is_dir) {
 		if (new_inode) {
@@ -465,7 +468,7 @@
 				goto out;
 		}
 		error = fat_scan(old_inode, MSDOS_DOTDOT, &dotdot_bh,
-				&dotdot_de, &dotdot_ino);
+				&dotdot_de, &dotdot_i_pos);
 		if (error < 0) {
 			printk(KERN_WARNING
 				"MSDOS: %s/%s, get dotdot failed, ret=%d\n",
@@ -476,7 +479,7 @@
 	}
 	if (!new_bh) {
 		error = msdos_add_entry(new_dir, new_name, &new_bh, &new_de,
-					&new_ino, is_dir, is_hid);
+					&new_i_pos, is_dir, is_hid);
 		if (error)
 			goto out;
 	}
@@ -489,7 +492,7 @@
 	old_de->name[0] = DELETED_FLAG;
 	mark_buffer_dirty(old_bh);
 	fat_detach(old_inode);
-	fat_attach(old_inode, new_ino);
+	fat_attach(old_inode, new_i_pos);
 	if (is_hid)
 		MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN;
 	else
@@ -544,8 +547,8 @@
 {
 	struct buffer_head *old_bh;
 	struct msdos_dir_entry *old_de;
-	int old_ino, error;
-	int is_hid,old_hid; /* if new file and old file are hidden */
+	loff_t old_i_pos;
+	int error, is_hid, old_hid; /* if new file and old file are hidden */
 	char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
 
 	lock_kernel();
@@ -562,13 +565,13 @@
 
 	is_hid  = (new_dentry->d_name.name[0]=='.') && (new_msdos_name[0]!='.');
 	old_hid = (old_dentry->d_name.name[0]=='.') && (old_msdos_name[0]!='.');
-	error = fat_scan(old_dir, old_msdos_name, &old_bh, &old_de, &old_ino);
+	error = fat_scan(old_dir, old_msdos_name, &old_bh, &old_de, &old_i_pos);
 	if (error < 0)
 		goto rename_done;
 
 	error = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
 				new_dir, new_msdos_name, new_dentry,
-				old_bh, old_de, (ino_t)old_ino, is_hid);
+				old_bh, old_de, old_i_pos, is_hid);
 	brelse(old_bh);
 
 rename_done:
diff -Nru a/fs/proc/inode.c b/fs/proc/inode.c
--- a/fs/proc/inode.c	Sun May 25 14:07:56 2003
+++ b/fs/proc/inode.c	Tue May 27 13:07:01 2003
@@ -61,8 +61,6 @@
 	struct proc_dir_entry *de;
 	struct task_struct *tsk;
 
-	inode->i_state = I_CLEAR;
-
 	/* Let go of any associated process */
 	tsk = PROC_I(inode)->task;
 	if (tsk)
@@ -75,6 +73,7 @@
 			module_put(de->owner);
 		de_put(de);
 	}
+	clear_inode(inode);
 }
 
 struct vfsmount *proc_mnt;
diff -Nru a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
--- a/fs/proc/proc_tty.c	Mon Apr 21 20:58:43 2003
+++ b/fs/proc/proc_tty.c	Mon May 26 15:29:30 2003
@@ -57,8 +57,6 @@
 		break;
 	case TTY_DRIVER_TYPE_SERIAL:
 		seq_printf(m, "serial");
-		if (p->subtype == 2)
-			seq_printf(m, ":callout");
 		break;
 	case TTY_DRIVER_TYPE_PTY:
 		if (p->subtype == PTY_TYPE_MASTER)
diff -Nru a/fs/vfat/namei.c b/fs/vfat/namei.c
--- a/fs/vfat/namei.c	Sun Nov 17 11:53:57 2002
+++ b/fs/vfat/namei.c	Tue May 27 07:32:40 2003
@@ -317,9 +317,10 @@
 {
 	struct msdos_dir_entry *de;
 	struct buffer_head *bh = NULL;
-	int ino,res;
+	loff_t i_pos;
+	int res;
 
-	res = fat_scan(dir,name,&bh,&de,&ino);
+	res = fat_scan(dir, name, &bh, &de, &i_pos);
 	brelse(bh);
 	if (res < 0)
 		return -ENOENT;
@@ -781,7 +782,7 @@
 	int res, len;
 	struct msdos_dir_entry *dummy_de;
 	struct buffer_head *dummy_bh;
-	int dummy_ino;
+	loff_t dummy_i_pos;
 
 	dir_slots = (struct msdos_dir_slot *)
 	       kmalloc(sizeof(struct msdos_dir_slot) * MSDOS_SLOTS, GFP_KERNEL);
@@ -797,7 +798,7 @@
 		goto cleanup;
 
 	/* build the empty directory entry of number of slots */
-	offset = fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_ino);
+	offset = fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_i_pos);
 	if (offset < 0) {
 		res = offset;
 		goto cleanup;
@@ -807,7 +808,7 @@
 	/* Now create the new entry */
 	*bh = NULL;
 	for (slot = 0; slot < slots; slot++) {
-		if (fat_get_entry(dir, &offset, bh, de, &sinfo_out->ino) < 0) {
+		if (fat_get_entry(dir, &offset, bh, de, &sinfo_out->i_pos) < 0) {
 			res = -EIO;
 			goto cleanup;
 		}
@@ -852,7 +853,7 @@
 			&offset,&sinfo->longname_offset);
 	if (res>0) {
 		sinfo->long_slots = res-1;
-		if (fat_get_entry(dir,&offset,last_bh,last_de,&sinfo->ino)>=0)
+		if (fat_get_entry(dir,&offset,last_bh,last_de,&sinfo->i_pos)>=0)
 			return 0;
 		res = -EIO;
 	} 
@@ -882,7 +883,7 @@
 		table++;
 		goto error;
 	}
-	inode = fat_build_inode(dir->i_sb, de, sinfo.ino, &res);
+	inode = fat_build_inode(dir->i_sb, de, sinfo.i_pos, &res);
 	brelse(bh);
 	if (res) {
 		unlock_kernel();
@@ -926,7 +927,7 @@
 		unlock_kernel();
 		return res;
 	}
-	inode = fat_build_inode(sb, de, sinfo.ino, &res);
+	inode = fat_build_inode(sb, de, sinfo.i_pos, &res);
 	brelse(bh);
 	if (!inode) {
 		unlock_kernel();
@@ -945,8 +946,8 @@
 static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo,
      struct buffer_head *bh, struct msdos_dir_entry *de)
 {
-	loff_t offset;
-	int i,ino;
+	loff_t offset, i_pos;
+	int i;
 
 	/* remove the shortname */
 	dir->i_mtime = CURRENT_TIME;
@@ -958,7 +959,7 @@
 	/* remove the longname */
 	offset = sinfo->longname_offset; de = NULL;
 	for (i = sinfo->long_slots; i > 0; --i) {
-		if (fat_get_entry(dir, &offset, &bh, &de, &ino) < 0)
+		if (fat_get_entry(dir, &offset, &bh, &de, &i_pos) < 0)
 			continue;
 		de->name[0] = DELETED_FLAG;
 		de->attr = ATTR_NONE;
@@ -1040,7 +1041,7 @@
 		unlock_kernel();
 		return res;
 	}
-	inode = fat_build_inode(sb, de, sinfo.ino, &res);
+	inode = fat_build_inode(sb, de, sinfo.i_pos, &res);
 	if (!inode)
 		goto out;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
@@ -1078,7 +1079,7 @@
 {
 	struct buffer_head *old_bh,*new_bh,*dotdot_bh;
 	struct msdos_dir_entry *old_de,*new_de,*dotdot_de;
-	int dotdot_ino;
+	loff_t dotdot_i_pos;
 	struct inode *old_inode, *new_inode;
 	int res, is_dir;
 	struct vfat_slot_info old_sinfo,sinfo;
@@ -1094,13 +1095,13 @@
 	is_dir = S_ISDIR(old_inode->i_mode);
 
 	if (is_dir && (res = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
-				&dotdot_de,&dotdot_ino)) < 0)
+				&dotdot_de,&dotdot_i_pos)) < 0)
 		goto rename_done;
 
 	if (new_dentry->d_inode) {
 		res = vfat_find(new_dir,&new_dentry->d_name,&sinfo,&new_bh,
 				&new_de);
-		if (res < 0 || MSDOS_I(new_inode)->i_location != sinfo.ino) {
+		if (res < 0 || MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
 			/* WTF??? Cry and fail. */
 			printk(KERN_WARNING "vfat_rename: fs corrupted\n");
 			goto rename_done;
@@ -1124,7 +1125,7 @@
 	vfat_remove_entry(old_dir,&old_sinfo,old_bh,old_de);
 	old_bh=NULL;
 	fat_detach(old_inode);
-	fat_attach(old_inode, sinfo.ino);
+	fat_attach(old_inode, sinfo.i_pos);
 	mark_inode_dirty(old_inode);
 
 	old_dir->i_version++;
diff -Nru a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
--- a/include/asm-alpha/bitops.h	Sat Apr 12 15:37:38 2003
+++ b/include/asm-alpha/bitops.h	Wed May 21 08:38:17 2003
@@ -233,7 +233,7 @@
 }
 
 static inline int
-test_bit(int nr, volatile void * addr)
+test_bit(int nr, const volatile void * addr)
 {
 	return (1UL & (((const int *) addr)[nr >> 5] >> (nr & 31))) != 0UL;
 }
diff -Nru a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
--- a/include/asm-v850/bitops.h	Sat Apr 12 15:37:38 2003
+++ b/include/asm-v850/bitops.h	Tue May 27 02:53:02 2003
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/bitops.h -- Bit operations
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *  Copyright (C) 1992  Linus Torvalds.
  *
  * This file is subject to the terms and conditions of the GNU General
@@ -133,7 +133,7 @@
                 "m" (*((const char *)(addr) + ((nr) >> 3))));		\
      __test_bit_res;							\
   })
-extern __inline__ int __test_bit (int nr, void *addr)
+extern __inline__ int __test_bit (int nr, const void *addr)
 {
 	int res;
 	__asm__ ("tst1 %1, [%2]; setf nz, %0"
diff -Nru a/include/asm-v850/nb85e_cache.h b/include/asm-v850/nb85e_cache.h
--- a/include/asm-v850/nb85e_cache.h	Sat Apr 12 16:21:01 2003
+++ b/include/asm-v850/nb85e_cache.h	Tue May 27 00:09:43 2003
@@ -35,7 +35,7 @@
 #define L1_CACHE_BYTES				NB85E_CACHE_LINE_SIZE
 
 
-#ifndef __ASSEMBLY__
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
 /* Set caching params via the BHC and DCC registers.  */
 void nb85e_cache_enable (u16 bhc, u16 dcc);
@@ -73,6 +73,6 @@
 #define flush_icache_user_range	nb85e_cache_flush_icache_user_range
 #define flush_cache_sigtramp	nb85e_cache_flush_sigtramp
 
-#endif /* !__ASSEMBLY__ */
+#endif /* __KERNEL__ && !__ASSEMBLY__ */
 
 #endif /* __V850_NB85E_CACHE_H__ */
diff -Nru a/include/asm-v850/sim.h b/include/asm-v850/sim.h
--- a/include/asm-v850/sim.h	Tue Feb 25 10:44:12 2003
+++ b/include/asm-v850/sim.h	Tue May 27 00:09:43 2003
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/sim.h -- Machine-dependent defs for GDB v850e simulator
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
diff -Nru a/include/linux/bio.h b/include/linux/bio.h
--- a/include/linux/bio.h	Sun May 25 09:19:53 2003
+++ b/include/linux/bio.h	Mon May 26 18:53:44 2003
@@ -222,6 +222,7 @@
 };
 extern struct bio_pair *bio_split(struct bio *bi, mempool_t *pool,
 				  int first_sectors);
+extern mempool_t *bio_split_pool;
 extern void bio_pair_release(struct bio_pair *dbio);
 
 extern struct bio *bio_alloc(int, int);
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Thu May  8 02:30:11 2003
+++ b/include/linux/blkdev.h	Tue May 27 13:15:31 2003
@@ -179,7 +179,8 @@
 	unsigned long *tag_map;		/* bit map of free/busy tags */
 	struct list_head busy_list;	/* fifo list of busy tags */
 	int busy;			/* current depth */
-	int max_depth;
+	int max_depth;			/* what we will send to device */
+	int real_max_depth;		/* what the array can hold */
 };
 
 struct request_queue
@@ -452,6 +453,7 @@
 extern void blk_queue_end_tag(request_queue_t *, struct request *);
 extern int blk_queue_init_tags(request_queue_t *, int);
 extern void blk_queue_free_tags(request_queue_t *);
+extern int blk_queue_resize_tags(request_queue_t *, int);
 extern void blk_queue_invalidate_tags(request_queue_t *);
 extern void blk_congestion_wait(int rw, long timeout);
 
diff -Nru a/include/linux/cyclades.h b/include/linux/cyclades.h
--- a/include/linux/cyclades.h	Fri Mar  7 23:24:39 2003
+++ b/include/linux/cyclades.h	Mon May 26 15:29:19 2003
@@ -588,8 +588,6 @@
 	int                     breakon;
 	int                     breakoff;
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -599,7 +597,6 @@
 	unsigned long		jiffies[3];
 	unsigned long		rflush_count;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	struct cyclades_monitor	mon;
 	struct cyclades_idle_stats	idle_stats;
 	struct cyclades_icount	icount;
diff -Nru a/include/linux/generic_serial.h b/include/linux/generic_serial.h
--- a/include/linux/generic_serial.h	Tue Jun 25 13:50:38 2002
+++ b/include/linux/generic_serial.h	Mon May 26 15:29:12 2003
@@ -37,11 +37,8 @@
   /*  struct semaphore        port_write_sem; */
   int                     flags;
   struct termios          normal_termios;
-  struct termios          callout_termios;
   wait_queue_head_t       open_wait;
   wait_queue_head_t       close_wait;
-  long                    session;
-  long                    pgrp;
   int                     count;
   int                     blocked_open;
   struct tty_struct       *tty;
@@ -67,8 +64,6 @@
 
 
 #define GS_TYPE_NORMAL   1
-#define GS_TYPE_CALLOUT  2
-
 
 #define GS_DEBUG_FLUSH   0x00000001
 #define GS_DEBUG_BTR     0x00000002
diff -Nru a/include/linux/hayesesp.h b/include/linux/hayesesp.h
--- a/include/linux/hayesesp.h	Tue Oct  1 09:43:11 2002
+++ b/include/linux/hayesesp.h	Mon May 26 15:29:18 2003
@@ -96,8 +96,6 @@
 	int			line;
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -105,7 +103,6 @@
 	struct work_struct	tqueue;
 	struct work_struct	tqueue_hangup;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 	wait_queue_head_t	delta_msr_wait;
diff -Nru a/include/linux/isdn.h b/include/linux/isdn.h
--- a/include/linux/isdn.h	Sun Apr 20 16:21:19 2003
+++ b/include/linux/isdn.h	Mon May 26 15:29:27 2003
@@ -250,8 +250,6 @@
 #define ISDN_ASYNC_SPLIT_TERMIOS      0x0008 /* Sep. termios for dialin/out  */
 #define ISDN_SERIAL_XMIT_SIZE           1024 /* Default bufsize for write    */
 #define ISDN_SERIAL_XMIT_MAX            4000 /* Maximum bufsize for write    */
-#define ISDN_SERIAL_TYPE_NORMAL            1
-#define ISDN_SERIAL_TYPE_CALLOUT           2
 
 #ifdef CONFIG_ISDN_AUDIO
 /* For using sk_buffs with audio we need some private variables
@@ -301,8 +299,6 @@
   int			line;
   int			count;		 /* # of fd on device              */
   int			blocked_open;	 /* # of blocked opens             */
-  long			session;	 /* Session of opening process     */
-  long			pgrp;		 /* pgrp of opening process        */
   int                   online;          /* 1 = B-Channel is up, drop data */
 					 /* 2 = B-Channel is up, deliver d.*/
   int                   dialing;         /* Dial in progress or ATA        */
@@ -348,7 +344,6 @@
   struct timer_list     connect_timer;   /* waiting for CONNECT            */
   struct timer_list     read_timer;      /* read incoming data             */
   struct termios	normal_termios;  /* For saving termios structs     */
-  struct termios	callout_termios;
   wait_queue_head_t	open_wait, close_wait;
   struct semaphore      write_sem;
 } modem_info;
diff -Nru a/include/linux/isicom.h b/include/linux/isicom.h
--- a/include/linux/isicom.h	Tue Oct  1 09:43:06 2002
+++ b/include/linux/isicom.h	Mon May 26 15:29:13 2003
@@ -148,8 +148,6 @@
 	unsigned short		channel;
 	unsigned short		status;
 	unsigned short		closing_wait;
-	long 			session;
-	long			pgrp;
 	struct isi_board	* card;
 	struct tty_struct 	* tty;
 	wait_queue_head_t	close_wait;
@@ -161,7 +159,6 @@
 	int			xmit_tail;
 	int			xmit_cnt;
 	struct termios 		normal_termios;
-	struct termios		callout_termios;
 };
 
 
diff -Nru a/include/linux/istallion.h b/include/linux/istallion.h
--- a/include/linux/istallion.h	Tue Oct  1 09:42:53 2002
+++ b/include/linux/istallion.h	Mon May 26 15:29:11 2003
@@ -66,8 +66,6 @@
 	int			rc;
 	int			argsize;
 	void			*argp;
-	long			session;
-	long			pgrp;
 	unsigned int		rxmarkmsk;
 	struct tty_struct	*tty;
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
@@ -81,7 +79,6 @@
 #endif
 	struct work_struct	tqhangup;
 	struct termios		normaltermios;
-	struct termios		callouttermios;
 	asysigs_t		asig;
 	unsigned long		addr;
 	unsigned long		rxoffset;
diff -Nru a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
--- a/include/linux/msdos_fs.h	Mon May 12 21:23:11 2003
+++ b/include/linux/msdos_fs.h	Tue May 27 07:32:54 2003
@@ -27,8 +27,6 @@
 
 #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */
 
-#define FAT_CACHE    8 /* FAT cache size */
-
 #define ATTR_NONE    0 /* no attribute bits */
 #define ATTR_RO      1  /* read-only */
 #define ATTR_HIDDEN  2  /* hidden */
@@ -178,7 +176,7 @@
 struct vfat_slot_info {
 	int long_slots;		       /* number of long slots in filename */
 	loff_t longname_offset;	       /* dir offset for longname start */
-	int ino;		       /* ino for the file */
+	loff_t i_pos;		       /* on-disk position of directory entry */
 };
 
 /* Convert attribute bits and a mask to the UNIX mode. */
@@ -204,14 +202,6 @@
 	return container_of(inode, struct msdos_inode_info, vfs_inode);
 }
 
-struct fat_cache {
-	struct super_block *sb; /* fs in question.  NULL means unused */
-	int start_cluster; /* first cluster of the chain. */
-	int file_cluster; /* cluster number in the file. */
-	int disk_cluster; /* cluster number on disk. */
-	struct fat_cache *next; /* next cache entry */
-};
-
 static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len)
 {
 #ifdef __BIG_ENDIAN
@@ -241,13 +231,12 @@
 /* fat/cache.c */
 extern int fat_access(struct super_block *sb, int nr, int new_value);
 extern int __fat_access(struct super_block *sb, int nr, int new_value);
-extern int fat_bmap(struct inode *inode, int sector);
-extern void fat_cache_init(void);
+extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys);
+extern void fat_cache_init(struct super_block *sb);
 extern void fat_cache_lookup(struct inode *inode, int cluster, int *f_clu,
 			     int *d_clu);
 extern void fat_cache_add(struct inode *inode, int f_clu, int d_clu);
 extern void fat_cache_inval_inode(struct inode *inode);
-extern void fat_cache_inval_dev(struct super_block *sb);
 extern int fat_free(struct inode *inode, int skip);
 
 /* fat/dir.c */
@@ -259,7 +248,7 @@
 			 unsigned int cmd, unsigned long arg);
 extern int fat_dir_empty(struct inode *dir);
 extern int fat_add_entries(struct inode *dir, int slots, struct buffer_head **bh,
-			   struct msdos_dir_entry **de, int *ino);
+			struct msdos_dir_entry **de, loff_t *i_pos);
 extern int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat);
 
 /* fat/file.c */
@@ -271,11 +260,11 @@
 
 /* fat/inode.c */
 extern void fat_hash_init(void);
-extern void fat_attach(struct inode *inode, int i_pos);
+extern void fat_attach(struct inode *inode, loff_t i_pos);
 extern void fat_detach(struct inode *inode);
-extern struct inode *fat_iget(struct super_block *sb, int i_pos);
+extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos);
 extern struct inode *fat_build_inode(struct super_block *sb,
-				     struct msdos_dir_entry *de, int ino, int *res);
+			struct msdos_dir_entry *de, loff_t i_pos, int *res);
 extern void fat_delete_inode(struct inode *inode);
 extern void fat_clear_inode(struct inode *inode);
 extern void fat_put_super(struct super_block *sb);
@@ -295,26 +284,27 @@
 extern int date_dos2unix(unsigned short time, unsigned short date);
 extern void fat_date_unix2dos(int unix_date, unsigned short *time,
 			      unsigned short *date);
-extern int fat__get_entry(struct inode *dir, loff_t *pos, struct buffer_head **bh,
-			  struct msdos_dir_entry **de, int *ino);
+extern int fat__get_entry(struct inode *dir, loff_t *pos,
+			  struct buffer_head **bh,
+			  struct msdos_dir_entry **de, loff_t *i_pos);
 static __inline__ int fat_get_entry(struct inode *dir, loff_t *pos,
 				    struct buffer_head **bh,
-				    struct msdos_dir_entry **de, int *ino)
+				    struct msdos_dir_entry **de, loff_t *i_pos)
 {
 	/* Fast stuff first */
 	if (*bh && *de &&
 	    (*de - (struct msdos_dir_entry *)(*bh)->b_data) < MSDOS_SB(dir->i_sb)->dir_per_block - 1) {
 		*pos += sizeof(struct msdos_dir_entry);
 		(*de)++;
-		(*ino)++;
+		(*i_pos)++;
 		return 0;
 	}
-	return fat__get_entry(dir,pos,bh,de,ino);
+	return fat__get_entry(dir, pos, bh, de, i_pos);
 }
 extern int fat_subdirs(struct inode *dir);
 extern int fat_scan(struct inode *dir, const char *name,
 		    struct buffer_head **res_bh,
-		    struct msdos_dir_entry **res_de, int *ino);
+		    struct msdos_dir_entry **res_de, loff_t *i_pos);
 
 /* msdos/namei.c  - these are for Umsdos */
 extern struct dentry *msdos_lookup(struct inode *dir, struct dentry *);
diff -Nru a/include/linux/msdos_fs_i.h b/include/linux/msdos_fs_i.h
--- a/include/linux/msdos_fs_i.h	Thu Jul 18 17:18:06 2002
+++ b/include/linux/msdos_fs_i.h	Tue May 27 07:32:57 2003
@@ -8,12 +8,16 @@
  */
 
 struct msdos_inode_info {
+	/* cache of lastest accessed cluster */
+	int file_cluster;	/* cluster number in the file. */
+	int disk_cluster;	/* cluster number on disk. */
+
 	loff_t mmu_private;
 	int i_start;	/* first cluster or 0 */
 	int i_logstart;	/* logical first cluster */
 	int i_attrs;	/* unused attribute bits */
 	int i_ctime_ms;	/* unused change time in milliseconds */
-	int i_location;	/* on-disk position of directory entry or 0 */
+	loff_t i_pos;	/* on-disk position of directory entry or 0 */
 	struct list_head i_fat_hash;	/* hash by i_location */
 	struct inode vfs_inode;
 };
diff -Nru a/include/linux/msdos_fs_sb.h b/include/linux/msdos_fs_sb.h
--- a/include/linux/msdos_fs_sb.h	Sat Nov 30 14:12:40 2002
+++ b/include/linux/msdos_fs_sb.h	Tue May 27 07:32:54 2003
@@ -26,6 +26,15 @@
 		 nocase:1;	  /* Does this need case conversion? 0=need case conversion*/
 };
 
+#define FAT_CACHE_NR	8 /* number of FAT cache */
+
+struct fat_cache {
+	int start_cluster; /* first cluster of the chain. */
+	int file_cluster; /* cluster number in the file. */
+	int disk_cluster; /* cluster number on disk. */
+	struct fat_cache *next; /* next cache entry */
+};
+
 struct msdos_sb_info {
 	unsigned short cluster_size; /* sectors/cluster */
 	unsigned short cluster_bits; /* sectors/cluster */
@@ -47,6 +56,9 @@
 	void *dir_ops;		     /* Opaque; default directory operations */
 	int dir_per_block;	     /* dir entries per block */
 	int dir_per_block_bits;	     /* log2(dir_per_block) */
+
+	spinlock_t cache_lock;
+	struct fat_cache cache_array[FAT_CACHE_NR], *cache;
 };
 
 #endif
diff -Nru a/include/linux/raid/linear.h b/include/linux/raid/linear.h
--- a/include/linux/raid/linear.h	Wed Aug 21 16:07:28 2002
+++ b/include/linux/raid/linear.h	Mon May 26 19:01:35 2003
@@ -19,9 +19,9 @@
 struct linear_private_data
 {
 	struct linear_hash	*hash_table;
-	dev_info_t		disks[MD_SB_DISKS];
 	dev_info_t		*smallest;
 	int			nr_zones;
+	dev_info_t		disks[0];
 };
 
 
diff -Nru a/include/linux/raid/md.h b/include/linux/raid/md.h
--- a/include/linux/raid/md.h	Wed May  7 21:18:43 2003
+++ b/include/linux/raid/md.h	Mon May 26 19:01:37 2003
@@ -40,6 +40,7 @@
 #include <linux/reboot.h>
 #include <linux/vmalloc.h>
 #include <linux/blkpg.h>
+#include <linux/bio.h>
 
 /*
  * 'md_p.h' holds the 'physical' layout of RAID devices
@@ -61,21 +62,6 @@
 #define MD_MINOR_VERSION                90
 #define MD_PATCHLEVEL_VERSION           0
 
-/*
- * XXX(hch): This function is broken.  Someone who understands the md
- * code needs to go through all callers, check whether bdev could
- * be NULL and replace it with direct calls to bdevmame.
- *
- * This would also fix the returns buffer on stack issue nicely :)
- */
-static inline const char *bdev_partition_name (struct block_device *bdev)
-{
-	char b[BDEVNAME_SIZE];
-
-	if (!bdev)
-		return __bdevname(0, b);
-	return bdevname(bdev, b);
-}
 extern int register_md_personality (int p_num, mdk_personality_t *p);
 extern int unregister_md_personality (int p_num);
 extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev),
diff -Nru a/include/linux/raid/multipath.h b/include/linux/raid/multipath.h
--- a/include/linux/raid/multipath.h	Tue Mar 11 18:15:04 2003
+++ b/include/linux/raid/multipath.h	Mon May 26 18:58:25 2003
@@ -2,7 +2,6 @@
 #define _MULTIPATH_H
 
 #include <linux/raid/md.h>
-#include <linux/bio.h>
 
 struct multipath_info {
 	mdk_rdev_t	*rdev;
@@ -10,7 +9,7 @@
 
 struct multipath_private_data {
 	mddev_t			*mddev;
-	struct multipath_info	multipaths[MD_SB_DISKS];
+	struct multipath_info	*multipaths;
 	int			raid_disks;
 	int			working_disks;
 	spinlock_t		device_lock;
diff -Nru a/include/linux/raid/raid0.h b/include/linux/raid/raid0.h
--- a/include/linux/raid/raid0.h	Tue Oct  8 11:40:47 2002
+++ b/include/linux/raid/raid0.h	Mon May 26 18:58:28 2003
@@ -8,22 +8,19 @@
 	sector_t zone_offset;	/* Zone offset in md_dev */
 	sector_t dev_offset;	/* Zone offset in real dev */
 	sector_t size;		/* Zone size */
-	int nb_dev;			/* # of devices attached to the zone */
-	mdk_rdev_t *dev[MD_SB_DISKS]; /* Devices attached to the zone */
-};
-
-struct raid0_hash
-{
-	struct strip_zone *zone0, *zone1;
+	int nb_dev;		/* # of devices attached to the zone */
+	mdk_rdev_t **dev;	/* Devices attached to the zone */
 };
 
 struct raid0_private_data
 {
-	struct raid0_hash *hash_table; /* Dynamically allocated */
-	struct strip_zone *strip_zone; /* This one too */
+	struct strip_zone **hash_table; /* Table of indexes into strip_zone */
+	struct strip_zone *strip_zone;
+	mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */
 	int nr_strip_zones;
-	struct strip_zone *smallest;
-	int nr_zones;
+
+	sector_t hash_spacing;
+	int preshift;			/* shift this before divide by hash_spacing */
 };
 
 typedef struct raid0_private_data raid0_conf_t;
diff -Nru a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
--- a/include/linux/raid/raid1.h	Tue Mar 11 18:15:04 2003
+++ b/include/linux/raid/raid1.h	Mon May 26 19:01:34 2003
@@ -14,7 +14,7 @@
 
 struct r1_private_data_s {
 	mddev_t			*mddev;
-	mirror_info_t		mirrors[MD_SB_DISKS];
+	mirror_info_t		*mirrors;
 	int			raid_disks;
 	int			working_disks;
 	int			last_used;
@@ -67,13 +67,14 @@
 	 */
 	struct bio		*read_bio;
 	int			read_disk;
-	/*
-	 * if the IO is in WRITE direction, then multiple bios are used:
-	 */
-	struct bio		*write_bios[MD_SB_DISKS];
 
 	r1bio_t			*next_r1; /* next for retry or in free list */
 	struct list_head	retry_list;
+	/*
+	 * if the IO is in WRITE direction, then multiple bios are used.
+	 * We choose the number when they are allocated.
+	 */
+	struct bio		*write_bios[0];
 };
 
 /* bits for r1bio.state */
diff -Nru a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
--- a/include/linux/raid/raid5.h	Tue Mar 11 18:15:04 2003
+++ b/include/linux/raid/raid5.h	Mon May 26 18:58:27 2003
@@ -3,7 +3,6 @@
 
 #include <linux/raid/md.h>
 #include <linux/raid/xor.h>
-#include <linux/bio.h>
 
 /*
  *
@@ -203,7 +202,6 @@
 struct raid5_private_data {
 	struct stripe_head	**stripe_hashtbl;
 	mddev_t			*mddev;
-	struct disk_info	disks[MD_SB_DISKS];
 	struct disk_info	*spare;
 	int			chunk_size, level, algorithm;
 	int			raid_disks, working_disks, failed_disks;
@@ -225,6 +223,7 @@
 							 * waiting for 25% to be free
 							 */        
 	spinlock_t		device_lock;
+	struct disk_info	disks[0];
 };
 
 typedef struct raid5_private_data raid5_conf_t;
diff -Nru a/include/linux/serial167.h b/include/linux/serial167.h
--- a/include/linux/serial167.h	Tue Oct  1 09:43:02 2002
+++ b/include/linux/serial167.h	Mon May 26 15:29:15 2003
@@ -43,8 +43,6 @@
 	int                     x_char; /* to be pushed out ASAP */
 	int                     x_break;
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
 	unsigned char 		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -53,7 +51,6 @@
         int                     default_timeout;
 	struct work_struct	tqueue;
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
         struct cyclades_monitor mon;
diff -Nru a/include/linux/serialP.h b/include/linux/serialP.h
--- a/include/linux/serialP.h	Sun Oct 13 03:55:56 2002
+++ b/include/linux/serialP.h	Mon May 26 15:29:28 2003
@@ -50,7 +50,6 @@
 	unsigned short	closing_wait; /* time to wait before closing */
 	struct async_icount	icount;	
 	struct termios		normal_termios;
-	struct termios		callout_termios;
 	int	io_type;
 	struct async_struct *info;
 	struct pci_dev	*dev;
@@ -80,8 +79,6 @@
 	unsigned long		last_active;
 	int			line;
 	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
  	struct circ_buf		xmit;
  	spinlock_t		xmit_lock;
 	u8			*iomem_base;
diff -Nru a/include/linux/stallion.h b/include/linux/stallion.h
--- a/include/linux/stallion.h	Tue Oct  1 09:43:14 2002
+++ b/include/linux/stallion.h	Mon May 26 15:29:09 2003
@@ -84,8 +84,6 @@
 	int			refcount;
 	int			openwaitcnt;
 	int			brklen;
-	long			session;
-	long			pgrp;
 	unsigned int		sigs;
 	unsigned int		rxignoremsk;
 	unsigned int		rxmarkmsk;
@@ -103,7 +101,6 @@
 	wait_queue_head_t	close_wait;
 #endif
 	struct termios		normaltermios;
-	struct termios		callouttermios;
 	struct work_struct	tqueue;
 	comstats_t		stats;
 	stlrq_t			tx;
diff -Nru a/include/linux/wanrouter.h b/include/linux/wanrouter.h
--- a/include/linux/wanrouter.h	Thu May 15 14:42:07 2003
+++ b/include/linux/wanrouter.h	Mon May 26 19:28:24 2003
@@ -534,7 +534,8 @@
 
 
 /* Public Data */
-extern struct wan_device *router_devlist;	/* list of registered devices */
+/* list of registered devices */
+extern struct wan_device *wanrouter_router_devlist;
 
 #endif	/* __KERNEL__ */
 #endif	/* _ROUTER_H */
diff -Nru a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
--- a/include/net/irda/ircomm_tty.h	Fri Oct 11 10:31:47 2002
+++ b/include/net/irda/ircomm_tty.h	Mon May 26 15:29:08 2003
@@ -93,7 +93,6 @@
 	void *ckey;
 
 	struct termios	  normal_termios;
-	struct termios	  callout_termios;
 
 	wait_queue_head_t open_wait;
 	wait_queue_head_t close_wait;
@@ -103,8 +102,6 @@
         unsigned short    close_delay;
         unsigned short    closing_wait; /* time to wait before closing */
 
-	long session;           /* Session of opening process */
-	long pgrp;		/* pgrp of opening process */
 	int  open_count;
 	int  blocked_open;	/* # of blocked opens */
 
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Sun May 25 17:00:00 2003
+++ b/kernel/sched.c	Tue May 27 04:05:34 2003
@@ -501,7 +501,7 @@
 			}
 			success = 1;
 		}
-#if CONFIG_SMP
+#ifdef CONFIG_SMP
 	       	else
 			if (unlikely(kick) && task_running(rq, p) && (p->thread_info->cpu != smp_processor_id()))
 				smp_send_reschedule(p->thread_info->cpu);
diff -Nru a/net/ipv4/esp.c b/net/ipv4/esp.c
--- a/net/ipv4/esp.c	Thu May 22 19:22:14 2003
+++ b/net/ipv4/esp.c	Mon May 26 16:26:22 2003
@@ -567,7 +567,7 @@
 	.no_policy	=	1,
 };
 
-int __init esp4_init(void)
+static int __init esp4_init(void)
 {
 	struct xfrm_decap_state decap;
 
@@ -578,7 +578,6 @@
 		decap_data_too_small();
 	}
 
-	esp_type.owner = THIS_MODULE;
 	if (xfrm_register_type(&esp_type, AF_INET) < 0) {
 		printk(KERN_INFO "ip esp init: can't add xfrm type\n");
 		return -EAGAIN;
diff -Nru a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
--- a/net/ipv4/ipcomp.c	Thu May 22 19:22:14 2003
+++ b/net/ipv4/ipcomp.c	Mon May 26 16:26:22 2003
@@ -382,9 +382,9 @@
 	goto out;
 }
 
-static struct xfrm_type ipcomp_type =
-{
+static struct xfrm_type ipcomp_type = {
 	.description	= "IPCOMP4",
+	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_COMP,
 	.init_state	= ipcomp_init_state,
 	.destructor	= ipcomp_destroy,
@@ -400,7 +400,6 @@
 
 static int __init ipcomp4_init(void)
 {
-	ipcomp_type.owner = THIS_MODULE;
 	if (xfrm_register_type(&ipcomp_type, AF_INET) < 0) {
 		printk(KERN_INFO "ipcomp init: can't add xfrm type\n");
 		return -EAGAIN;
diff -Nru a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
--- a/net/ipv4/xfrm4_tunnel.c	Thu May 22 19:22:14 2003
+++ b/net/ipv4/xfrm4_tunnel.c	Mon May 26 16:26:22 2003
@@ -215,6 +215,7 @@
 
 static struct xfrm_type ipip_type = {
 	.description	= "IPIP",
+	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_IPIP,
 	.init_state	= ipip_init_state,
 	.destructor	= ipip_destroy,
@@ -229,7 +230,6 @@
 
 static int __init ipip_init(void)
 {
-	ipip_type.owner = THIS_MODULE;
 	if (xfrm_register_type(&ipip_type, AF_INET) < 0) {
 		printk(KERN_INFO "ipip init: can't add xfrm type\n");
 		return -EAGAIN;
diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c	Mon May 19 23:49:42 2003
+++ b/net/ipv6/addrconf.c	Mon May 26 16:27:50 2003
@@ -33,6 +33,8 @@
  *	Yuji SEKIYA @USAGI		:	Don't assign a same IPv6
  *						address on a same interface.
  *	YOSHIFUJI Hideaki @USAGI	:	ARCnet support
+ *	YOSHIFUJI Hideaki @USAGI	:	convert /proc/net/if_inet6 to
+ *						seq_file.
  */
 
 #include <linux/config.h>
@@ -76,6 +78,9 @@
 
 #include <asm/uaccess.h>
 
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
 #define IPV6_MAX_ADDRESSES 16
 
 /* Set to 3 to get tracing... */
@@ -2090,57 +2095,141 @@
 }
 
 #ifdef CONFIG_PROC_FS
-static int iface_proc_info(char *buffer, char **start, off_t offset,
-			   int length)
+struct if6_iter_state {
+	int bucket;
+};
+
+static inline struct inet6_ifaddr *if6_get_bucket(struct seq_file *seq, loff_t *pos)
 {
-	struct inet6_ifaddr *ifp;
 	int i;
-	int len = 0;
-	off_t pos=0;
-	off_t begin=0;
+	struct inet6_ifaddr *ifa = NULL;
+	loff_t l = *pos;
+	struct if6_iter_state *state = seq->private;
+
+	for (; state->bucket < IN6_ADDR_HSIZE; ++state->bucket)
+		for (i = 0, ifa = inet6_addr_lst[state->bucket]; ifa; ++i, ifa=ifa->lst_next) {
+			if (l--)
+				continue;
+			*pos = i;
+			goto out;
+		}
+out:
+	return ifa;
+}
 
-	for (i=0; i < IN6_ADDR_HSIZE; i++) {
-		read_lock_bh(&addrconf_hash_lock);
-		for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
-			int j;
+static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	read_lock_bh(&addrconf_hash_lock);
+	return *pos ? if6_get_bucket(seq, pos) : (void *)1;
+}
 
-			for (j=0; j<16; j++) {
-				sprintf(buffer + len, "%02x",
-					ifp->addr.s6_addr[j]);
-				len += 2;
-			}
+static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct inet6_ifaddr *ifa;
+	struct if6_iter_state *state;
 
-			len += sprintf(buffer + len,
-				       " %02x %02x %02x %02x %8s\n",
-				       ifp->idev->dev->ifindex,
-				       ifp->prefix_len,
-				       ifp->scope,
-				       ifp->flags,
-				       ifp->idev->dev->name);
-			pos=begin+len;
-			if(pos<offset) {
-				len=0;
-				begin=pos;
-			}
-			if(pos>offset+length) {
-				read_unlock_bh(&addrconf_hash_lock);
-				goto done;
-			}
-		}
-		read_unlock_bh(&addrconf_hash_lock);
+	if (v == (void *)1) {
+		ifa = if6_get_bucket(seq, pos);
+		goto out;
 	}
 
-done:
+	state = seq->private;
+
+	ifa = v;
+	ifa = ifa->lst_next;
+	if (ifa)
+		goto out;
+
+	if (++state->bucket >= IN6_ADDR_HSIZE)
+		goto out;
 
-	*start=buffer+(offset-begin);
-	len-=(offset-begin);
-	if(len>length)
-		len=length;
-	if(len<0)
-		len=0;
-	return len;
+	*pos = 0;
+	ifa = if6_get_bucket(seq, pos);
+out:
+	++*pos;
+	return ifa;
 }
 
+static inline void if6_iface_seq_show(struct seq_file *seq, struct inet6_ifaddr *ifp)
+{
+	seq_printf(seq,
+		   "%04x%04x%04x%04x%04x%04x%04x%04x %02x %02x %02x %02x %8s\n",
+		   NIP6(ifp->addr),
+		   ifp->idev->dev->ifindex,
+		   ifp->prefix_len,
+		   ifp->scope,
+		   ifp->flags,
+		   ifp->idev->dev->name);
+}
+
+static int if6_seq_show(struct seq_file *seq, void *v)
+{
+	if (v == (void *)1)
+		return 0;
+	else
+		if6_iface_seq_show(seq, v);
+	return 0;
+}
+
+static void if6_seq_stop(struct seq_file *seq, void *v)
+{
+	read_unlock_bh(&addrconf_hash_lock);
+}
+
+static struct seq_operations if6_seq_ops = {
+	.start	= if6_seq_start,
+	.next	= if6_seq_next,
+	.show	= if6_seq_show,
+	.stop	= if6_seq_stop,
+};
+
+static int if6_seq_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq;
+	int rc = -ENOMEM;
+	struct if6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+
+	if (!s)
+		goto out;
+	memset(s, 0, sizeof(*s));
+
+	rc = seq_open(file, &if6_seq_ops);
+	if (rc)
+		goto out_kfree;
+
+	seq = file->private_data;
+	seq->private = s;
+out:
+	return rc;
+out_kfree:
+	kfree(s);
+	goto out;
+}
+
+static struct file_operations if6_fops = {
+	.owner		= THIS_MODULE,
+	.open		= if6_seq_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release_private,
+};
+
+int __init if6_proc_init(void)
+{
+	struct proc_dir_entry *p;
+	int rc = 0;
+
+	p = create_proc_entry("if_inet6", S_IRUGO, proc_net);
+	if (p)
+		p->proc_fops = &if6_fops;
+	else
+		rc = -ENOMEM;
+	return rc;
+}
+void if6_proc_exit(void)
+{
+	proc_net_remove("if_inet6");
+}
 #endif	/* CONFIG_PROC_FS */
 
 /*
@@ -2727,10 +2816,6 @@
 	rtnl_unlock();
 #endif
 
-#ifdef CONFIG_PROC_FS
-	proc_net_create("if_inet6", 0, iface_proc_info);
-#endif
-	
 	addrconf_verify(0);
 	rtnetlink_links[PF_INET6] = inet6_rtnetlink_table;
 #ifdef CONFIG_SYSCTL
diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
--- a/net/ipv6/af_inet6.c	Sun May 25 19:43:48 2003
+++ b/net/ipv6/af_inet6.c	Mon May 26 16:30:59 2003
@@ -75,18 +75,16 @@
 
 #ifdef CONFIG_PROC_FS
 extern int raw6_proc_init(void);
-extern int raw6_proc_exit(void);
-
+extern void raw6_proc_exit(void);
 extern int tcp6_proc_init(void);
 extern void tcp6_proc_exit(void);
-
 extern int udp6_proc_init(void);
 extern void udp6_proc_exit(void);
-
 extern int ipv6_misc_proc_init(void);
-extern int ipv6_misc_proc_exit(void);
-
+extern void ipv6_misc_proc_exit(void);
 extern int anycast6_get_info(char *, char **, off_t, int);
+extern int if6_proc_init(void);
+extern void if6_proc_exit(void);
 #endif
 
 #ifdef CONFIG_SYSCTL
@@ -799,6 +797,8 @@
 
 	if (!proc_net_create("anycast6", 0, anycast6_get_info))
 		goto proc_anycast6_fail;
+	if (if6_proc_init())
+		goto proc_if6_fail;
 #endif
 	ipv6_netdev_notif_init();
 	ipv6_packet_init();
@@ -820,6 +820,8 @@
 	return 0;
 
 #ifdef CONFIG_PROC_FS
+proc_if6_fail:
+	proc_net_remove("anycast6");
 proc_anycast6_fail:
 	ipv6_misc_proc_exit();
 proc_misc6_fail:
@@ -852,11 +854,12 @@
 	/* First of all disallow new sockets creation. */
 	sock_unregister(PF_INET6);
 #ifdef CONFIG_PROC_FS
-	raw6_proc_exit();
-	proc_net_remove("tcp6");
-	proc_net_remove("udp6");
-	ipv6_misc_proc_exit();
-	proc_net_remove("anycast6");
+	if6_proc_exit();
+ 	proc_net_remove("anycast6");
+ 	ipv6_misc_proc_exit();
+ 	udp6_proc_exit();
+ 	tcp6_proc_exit();
+ 	raw6_proc_exit();
 #endif
 	/* Cleanup code parts. */
 	sit_cleanup();
diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c
--- a/net/ipv6/icmp.c	Thu May 22 18:38:15 2003
+++ b/net/ipv6/icmp.c	Tue May 27 00:20:31 2003
@@ -263,7 +263,7 @@
 void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, 
 		 struct net_device *dev)
 {
-	struct inet6_dev *idev;
+	struct inet6_dev *idev = NULL;
 	struct ipv6hdr *hdr = skb->nh.ipv6h;
 	struct sock *sk = icmpv6_socket->sk;
 	struct ipv6_pinfo *np = inet6_sk(sk);
@@ -384,7 +384,7 @@
 				hlimit, NULL, &fl, (struct rt6_info*)dst, MSG_DONTWAIT);
 	if (err) {
 		ip6_flush_pending_frames(sk);
-		goto out;
+		goto out_put;
 	}
 	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
 	__skb_push(skb, plen);
@@ -393,6 +393,7 @@
 		ICMP6_INC_STATS_OFFSET_BH(idev, Icmp6OutDestUnreachs, type - ICMPV6_DEST_UNREACH);
 	ICMP6_INC_STATS_BH(idev, Icmp6OutMsgs);
 
+out_put:
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 out:
@@ -455,13 +456,14 @@
 
 	if (err) {
 		ip6_flush_pending_frames(sk);
-		goto out;
+		goto out_put;
 	}
 	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
 
         ICMP6_INC_STATS_BH(idev, Icmp6OutEchoReplies);
         ICMP6_INC_STATS_BH(idev, Icmp6OutMsgs);
 
+out_put: 
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 out: 
diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c	Thu May 22 18:38:15 2003
+++ b/net/ipv6/ndisc.c	Tue May 27 00:51:00 2003
@@ -431,22 +431,20 @@
 
 	len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
 
-	rt = ip6_dst_alloc();
-	if (!rt) 
-		return;
-
 	/* for anycast or proxy, solicited_addr != src_addr */
 	ifp = ipv6_get_ifaddr(solicited_addr, dev);
  	if (ifp) {
 		src_addr = solicited_addr;
 		in6_ifa_put(ifp);
 	} else {
-		if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0)) {
-			dst_free(dst);
+		if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0))
 			return;
-		}
 		src_addr = &tmpaddr;
 	}
+
+	rt = ip6_dst_alloc();
+	if (!rt) 
+		return;
 
 	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
 	ndisc_rt_init(rt, dev, neigh);	
diff -Nru a/net/ipv6/proc.c b/net/ipv6/proc.c
--- a/net/ipv6/proc.c	Thu May 22 19:11:15 2003
+++ b/net/ipv6/proc.c	Mon May 26 16:30:59 2003
@@ -299,11 +299,10 @@
 	goto out;
 }
 
-int ipv6_misc_proc_exit(void)
+void ipv6_misc_proc_exit(void)
 {
 	proc_net_remove("sockstat6");
 	proc_net_remove("dev_snmp6");
 	proc_net_remove("snmp6");
-	return 0;
 }
 
diff -Nru a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
--- a/net/irda/ircomm/ircomm_tty.c	Sun May 25 19:36:24 2003
+++ b/net/irda/ircomm/ircomm_tty.c	Mon May 26 15:29:08 2003
@@ -248,48 +248,20 @@
 
 	tty = self->tty;
 
-	if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
-		/* this is a callout device */
-		/* just verify that normal device is not in use */
-		if (self->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((self->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (self->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (self->session != current->session))
-			return -EBUSY;
-		if ((self->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (self->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (self->pgrp != current->pgrp))
-			return -EBUSY;
-		self->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
 	 */	
 	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
 		/* nonblock mode is set or port is not enabled */
-		/* just verify that callout device is not active */
-		if (self->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		self->flags |= ASYNC_NORMAL_ACTIVE;
-
 		IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __FUNCTION__ );
 		return 0;
 	}
 
-	if (self->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (self->normal_termios.c_cflag & CLOCAL) {
-			IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __FUNCTION__ );
-			do_clocal = 1;
-		}
-	} else {
-		if (tty->termios->c_cflag & CLOCAL) {
-			IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __FUNCTION__ );
-			do_clocal = 1;
-		}
+	if (tty->termios->c_cflag & CLOCAL) {
+		IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __FUNCTION__ );
+		do_clocal = 1;
 	}
 	
 	/* Wait for carrier detect and the line to become
@@ -315,8 +287,7 @@
 	self->blocked_open++;
 	
 	while (1) {
-		if (!(self->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    (tty->termios->c_cflag & CBAUD)) {
+		if (tty->termios->c_cflag & CBAUD) {
 			/* Here, we use to lock those two guys, but
 			 * as ircomm_param_request() does it itself,
 			 * I don't see the point (and I see the deadlock).
@@ -339,8 +310,7 @@
 		 * specified, we cannot return before the IrCOMM link is
 		 * ready 
 		 */
- 		if (!(self->flags & ASYNC_CALLOUT_ACTIVE) &&
- 		    !(self->flags & ASYNC_CLOSING) &&
+ 		if (!(self->flags & ASYNC_CLOSING) &&
  		    (do_clocal || (self->settings.dce & IRCOMM_CD)) &&
 		    self->state == IRCOMM_TTY_READY)
 		{
@@ -509,10 +479,6 @@
 
 		return ret;
 	}
-
-	self->session = current->session;
-	self->pgrp = current->pgrp;
-
 	return 0;
 }
 
@@ -605,8 +571,7 @@
 		wake_up_interruptible(&self->open_wait);
 	}
 
-	self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
+	self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&self->close_wait);
 
 	MOD_DEC_USE_COUNT;
@@ -1054,7 +1019,7 @@
 
 	/* I guess we need to lock here - Jean II */
 	spin_lock_irqsave(&self->spinlock, flags);
-	self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	self->flags &= ~ASYNC_NORMAL_ACTIVE;
 	self->tty = 0;
 	self->open_count = 0;
 	spin_unlock_irqrestore(&self->spinlock, flags);
@@ -1133,9 +1098,7 @@
 
 		if (status & IRCOMM_CD) {
 			wake_up_interruptible(&self->open_wait);
-		} else if (!((self->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (self->flags & ASYNC_CALLOUT_NOHUP))) 
-		{
+		} else {
 			IRDA_DEBUG(2, 
 				   "%s(), Doing serial hangup..\n", __FUNCTION__ );
 			if (tty)
@@ -1364,8 +1327,6 @@
 		ret += sprintf(buf+ret, "ASYNC_CLOSING|");
 	if (self->flags & ASYNC_NORMAL_ACTIVE)
 		ret += sprintf(buf+ret, "ASYNC_NORMAL_ACTIVE|");
-	if (self->flags & ASYNC_CALLOUT_ACTIVE)
-		ret += sprintf(buf+ret, "ASYNC_CALLOUT_ACTIVE|");
 	if (self->flags)
 		ret--; /* remove the last | */
 	ret += sprintf(buf+ret, "\n");
diff -Nru a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
--- a/net/wanrouter/wanproc.c	Sun May 18 07:58:29 2003
+++ b/net/wanrouter/wanproc.c	Mon May 26 19:28:25 2003
@@ -87,7 +87,8 @@
 	lock_kernel();
 	if (!l--)
 		return (void *)1;
-	for (wandev = router_devlist; l-- && wandev; wandev = wandev->next)
+	for (wandev = wanrouter_router_devlist; l-- && wandev;
+	     wandev = wandev->next)
 		;
 	return wandev;
 }
@@ -96,7 +97,7 @@
 {
 	struct wan_device *wandev = v;
 	(*pos)++;
-	return (v == (void *)1) ? router_devlist : wandev->next;
+	return (v == (void *)1) ? wanrouter_router_devlist : wandev->next;
 }
 
 static void r_stop(struct seq_file *m, void *v)
