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

diff -urN linux-2.2.17-pre13/CREDITS linux/CREDITS
--- linux-2.2.17-pre13/CREDITS	Mon Dec  3 22:10:05 2001
+++ linux/CREDITS	Mon Dec  3 22:10:12 2001
@@ -371,7 +371,7 @@
 S: USA
 
 N: Juan Jose Ciarlante
-W: http://juanjox.linuxhq.com/
+W: http://juanjox.kernelnotes.org/
 E: jjciarla@raiz.uncu.edu.ar
 E: jjo@mendoza.gov.ar
 D: Network driver alias support
diff -urN linux-2.2.17-pre13/Documentation/Changes linux/Documentation/Changes
--- linux-2.2.17-pre13/Documentation/Changes	Mon Dec  3 22:10:05 2001
+++ linux/Documentation/Changes	Mon Dec  3 22:10:12 2001
@@ -268,7 +268,7 @@
 ipfwadm.
 
    To use masq forwarding you will need to obtain "ipmasqadm,"
-available from http://juanjox.linuxhq.com/ .
+available from http://juanjox.kernelnotes.org/ .
 
    DHCP clients for 2.0 do not work with the new networking code in the
 2.2 kernel.  You will need to upgrade your dhcpcd / dhcpclient.
@@ -523,14 +523,14 @@
 ========
 
 The 2.9.1.0.25 release:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz
+ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/release.binutils-2.9.1.0.25
+ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/release.binutils-2.9.1.0.25
 
 The 2.9.5.0.16 release:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/binutils-2.9.5.0.16.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/binutils/binutils-2.9.5.0.16.tar.bz2
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/release.binutils-2.9.5.0.16
+ftp://ftp.valinux.com/pub/support/hjl/binutils/release.binutils-2.9.5.0.16
 
 Bin86
 =====
@@ -543,11 +543,11 @@
 =====
 
 The egcs-1.1.2 release:
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-glibc.x86.tar.bz2
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-libc5.x86.tar.bz2
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-alpha.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-glibc.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-libc5.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-alpha.x86.tar.bz2
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/release.egcs-1.1.2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/release.egcs-1.1.2
 
 Gnu C 2.7.2.3 source:
 ftp://ftp.gnu.org/gnu/gcc/gcc-2.7.2.3.tar.gz
@@ -726,7 +726,7 @@
 ===========
 
 The 0.4.2 release:
-http://juanjox.linuxhq.com/ipmasqadm-0.4.2.tar.gz
+http://juanjox.kernelnotes.org/ipmasqadm-0.4.2.tar.gz
 
 DHCP clients
 ============
diff -urN linux-2.2.17-pre13/Documentation/i386/boot.txt linux/Documentation/i386/boot.txt
--- linux-2.2.17-pre13/Documentation/i386/boot.txt	Mon Dec  3 22:10:05 2001
+++ linux/Documentation/i386/boot.txt	Mon Dec  3 22:10:12 2001
@@ -16,15 +16,20 @@
 Old kernels:	zImage/Image support only.  Some very early kernels
 		may not even support a command line.
 
-Protocol 2.00:	Added bzImage and initrd support, as well as a
-		formalized way to communicate between the boot loader
-		and the kernel.
-
-Protocol 2.01:	Added a heap overrun warning.
-
-Protocol 2.02:	New command line protocol.  Lower the
-		conventional-memory ceiling.  zImage deprecated but
-		still supported.
+Protocol 2.00:	(Kernel 1.3.73) Added bzImage and initrd support, as
+		well as a formalized way to communicate between the
+		boot loader and the kernel.  setup.S made relocatable,
+		although the traditional setup area still assumed
+		writable.
+
+Protocol 2.01:	(Kernel 1.3.76) Added a heap overrun warning.
+
+Protocol 2.02:	(Kernel 2.4.0-test3-pre3) New command line protocol.
+		Lower the conventional memory ceiling.  No overwrite
+		of the traditional setup area, thus making booting
+		safe for systems which use the EBDA from SMM or 32-bit
+		BIOS entry points.  zImage deprecated but still
+		supported.
 
 
 **** MEMORY LAYOUT
@@ -136,7 +141,7 @@
 supported by the protocol version in use.
 
 Most boot loaders will simply load the kernel at its target address
-directly.  Such a boot loader do not need to worry about filling in
+directly.  Such boot loaders do not need to worry about filling in
 most of the fields in the header.  The following fields should be
 filled out, however:
 
@@ -257,6 +262,8 @@
 			memcpy(0x90000, base_ptr, (setup_sects+1)*512);
 			/* Copy the command line */
 			memcpy(0x99000, base_ptr+0x9000, 256);
+
+			base_ptr = 0x90000;		 /* Relocated */
 		}
 
 		/* It is recommended to clear memory up to the 32K mark */
@@ -338,19 +345,25 @@
 sp should be set up properly, normally pointing to the top of the
 heap.  In our example from above, we would do:
 
+	/* Note: in the case of the "old" kernel protocol, base_ptr must
+	   be == 0x90000 at this point; see the previous sample code */
+
 	seg = base_ptr >> 4;
 
 	cli();	/* Enter with interrupts disabled! */
 
+	/* Set up the real-mode kernel stack */
 	_SS = seg;
 	_SP = 0x9000;	/* Load SP right after loading SS! */
+
 	_DS = _ES = _FS = _GS = seg;
 	jmp_far(seg+0x20, 0);	/* Run the kernel */
 
 If your boot sector accesses a floppy drive, it is recommended to
 switch off the floppy motor before running the kernel, since the
 kernel boot leaves interrupts off and thus the motor will not be
-switched off.
+switched off, especially if the loaded kernel has the floppy driver as
+a demand-loaded module!
 
 
 **** ADVANCED BOOT TIME HOOKS
diff -urN linux-2.2.17-pre13/MAINTAINERS linux/MAINTAINERS
--- linux-2.2.17-pre13/MAINTAINERS	Mon Dec  3 22:10:05 2001
+++ linux/MAINTAINERS	Mon Dec  3 22:10:12 2001
@@ -811,8 +811,8 @@
 S:	Maintained
 
 SMB FILESYSTEM
-P:	Andrew Tridgell
-M:	tridge@samba.org
+P:	Urban Widmark
+M:	urban@svenskatest.se
 W:	http://samba.org/
 L:	samba@samba.org
 S:	Maintained
@@ -911,7 +911,7 @@
 
 UMSDOS FILESYSTEM
 P:	Matija Nalis
-M:	mnalis@jagor.srce.hr
+M:	mnalis-umsdos@voyager.hr
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
diff -urN linux-2.2.17-pre13/Makefile linux/Makefile
--- linux-2.2.17-pre13/Makefile	Mon Dec  3 22:10:05 2001
+++ linux/Makefile	Mon Dec  3 22:10:12 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 17
-EXTRAVERSION = pre13
+EXTRAVERSION = pre14
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
@@ -22,7 +22,7 @@
 
 AS	=$(CROSS_COMPILE)as
 LD	=$(CROSS_COMPILE)ld
-CC	=$(CROSS_COMPILE)gcc -D__KERNEL__ -I$(HPATH)
+CC	=$(CROSS_COMPILE)cc -D__KERNEL__ -I$(HPATH)
 CPP	=$(CC) -E
 AR	=$(CROSS_COMPILE)ar
 NM	=$(CROSS_COMPILE)nm
@@ -325,13 +325,15 @@
 modules_install:
 	@( \
 	MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE); \
+	mkdir -p $$MODLIB; \
+	rm -f $$MODLIB/build; \
+	ln -s `pwd` $$MODLIB/build; \
 	cd modules; \
 	MODULES=""; \
 	inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \
 		mkdir -p $$MODLIB/$$2; cp $$These $$MODLIB/$$2; \
 		echo Installing modules under $$MODLIB/$$2; \
 	}; \
-	mkdir -p $$MODLIB; \
 	\
 	if [ -f BLOCK_MODULES ]; then inst_mod BLOCK_MODULES block; fi; \
 	if [ -f NET_MODULES   ]; then inst_mod NET_MODULES   net;   fi; \
diff -urN linux-2.2.17-pre13/arch/alpha/config.in linux/arch/alpha/config.in
--- linux-2.2.17-pre13/arch/alpha/config.in	Mon Dec  3 22:10:05 2001
+++ linux/arch/alpha/config.in	Mon Dec  3 22:10:12 2001
@@ -80,6 +80,10 @@
 	define_bool CONFIG_ALPHA_EV4 y
 	define_bool CONFIG_ALPHA_APECS y
 fi
+if [ "$CONFIG_ALPHA_CABRIOLET" = "y" ]
+then
+	define_bool CONFIG_ALPHA_EB64P y
+fi
 if [ "$CONFIG_ALPHA_EB164" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
 	-o "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_XLT" = "y" \
 	-o "$CONFIG_ALPHA_TAKARA" = "y" ]
@@ -161,7 +165,7 @@
         -o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \
         -o "$CONFIG_ALPHA_ALCOR" = "y"  -o "$CONFIG_ALPHA_MIATA" = "y" \
         -o "$CONFIG_ALPHA_LX164" = "y"  -o "$CONFIG_ALPHA_SX164" = "y" \
-	-o "$CONFIG_ALPHA_NAUTILUS" = "y" ]
+        -o "$CONFIG_ALPHA_NAUTILUS" = "y" ]
 then
   bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
 #  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -urN linux-2.2.17-pre13/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- linux-2.2.17-pre13/arch/alpha/kernel/setup.c	Wed Jun  7 14:26:42 2000
+++ linux/arch/alpha/kernel/setup.c	Mon Dec  3 22:10:12 2001
@@ -517,7 +517,7 @@
 	{
 		&eb64p_mv,
 		&cabriolet_mv,
-		NULL		/* AlphaPCI64 */
+		&cabriolet_mv		/* AlphaPCI64 */
 	};
 
 	static struct alpha_machine_vector *eb66_vecs[] __initlocaldata =
diff -urN linux-2.2.17-pre13/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c
--- linux-2.2.17-pre13/arch/alpha/kernel/sys_cabriolet.c	Sun Sep  6 10:34:33 1998
+++ linux/arch/alpha/kernel/sys_cabriolet.c	Mon Dec  3 22:10:12 2001
@@ -286,7 +286,9 @@
 	pci_fixup:		cabriolet_pci_fixup,
 	kill_arch:		generic_kill_arch,
 };
+#ifndef CONFIG_ALPHA_EB64P
 ALIAS_MV(cabriolet)
+#endif
 #endif
 
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB164)
diff -urN linux-2.2.17-pre13/arch/alpha/kernel/sys_eb64p.c linux/arch/alpha/kernel/sys_eb64p.c
--- linux-2.2.17-pre13/arch/alpha/kernel/sys_eb64p.c	Sun Sep  6 10:34:33 1998
+++ linux/arch/alpha/kernel/sys_eb64p.c	Mon Dec  3 22:10:12 2001
@@ -26,6 +26,7 @@
 #include <asm/pgtable.h>
 #include <asm/core_apecs.h>
 #include <asm/core_lca.h>
+#include <asm/hwrpb.h>
 
 #include "proto.h"
 #include "irq.h"
@@ -74,7 +75,7 @@
 static void __init
 eb64p_init_irq(void)
 {
-#ifdef CONFIG_ALPHA_GENERIC
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
 	/*
 	 * CABRIO SRM may not set variation correctly, so here we test
 	 * the high word of the interrupt summary register for the RAZ
@@ -82,9 +83,12 @@
 	 */
 	if (inw(0x806) != 0xffff) {
 		extern struct alpha_machine_vector cabriolet_mv;
-#if 1
-		printk("eb64p_init_irq: resetting for CABRIO\n");
-#endif
+
+		printk("Detected Cabriolet: correcting HWRPB.\n");
+
+		hwrpb->sys_variation |= 2L << 10;
+		hwrpb_update_checksum(hwrpb);
+
 		alpha_mv = cabriolet_mv;
 		alpha_mv.init_irq();
 		return;
diff -urN linux-2.2.17-pre13/drivers/block/ide-proc.c linux/drivers/block/ide-proc.c
--- linux-2.2.17-pre13/drivers/block/ide-proc.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/block/ide-proc.c	Mon Dec  3 22:10:12 2001
@@ -111,7 +111,7 @@
 	unsigned long	startn = 0, n, flags;
 	const char	*start = NULL, *msg = NULL;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 		return -EACCES;
 	/*
 	 * Skip over leading whitespace
diff -urN linux-2.2.17-pre13/drivers/block/ide.c linux/drivers/block/ide.c
--- linux-2.2.17-pre13/drivers/block/ide.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/block/ide.c	Mon Dec  3 22:10:12 2001
@@ -2254,7 +2254,7 @@
 		{
 			byte args[4], *argbuf = args;
 			int argsize = 4;
-			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES;
 			if (NULL == (void *) arg)
 				return ide_do_drive_cmd(drive, &rq, ide_wait);
 			if (copy_from_user(args, (void *)arg, 4))
@@ -2277,7 +2277,7 @@
 		case HDIO_SCAN_HWIF:
 		{
 			int args[3];
-			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES;
 			if (copy_from_user(args, (void *)arg, 3 * sizeof(int)))
 				return -EFAULT;
 			if (ide_register(args[0], args[1], args[2]) == -1)
diff -urN linux-2.2.17-pre13/drivers/block/raid0.c linux/drivers/block/raid0.c
--- linux-2.2.17-pre13/drivers/block/raid0.c	Tue Jan  4 10:12:14 2000
+++ linux/drivers/block/raid0.c	Mon Dec  3 22:10:12 2001
@@ -184,7 +184,7 @@
 
   if (hash - data->hash_table > data->nr_zones) 
   { 
-	  printk(KERN_DEBUG "raid0_map: invalid block %ul\n", block);
+	  printk(KERN_DEBUG "raid0_map: invalid block %li\n", block);
 	  return -1;
   }
 
diff -urN linux-2.2.17-pre13/drivers/char/generic_serial.c linux/drivers/char/generic_serial.c
--- linux-2.2.17-pre13/drivers/char/generic_serial.c	Wed May  3 17:16:33 2000
+++ linux/drivers/char/generic_serial.c	Mon Dec  3 22:10:12 2001
@@ -12,12 +12,18 @@
  *  Version 0.1 -- December, 1998. Initial version.
  *  Version 0.2 -- March, 1999.    Some more routines. Bugfixes. Etc.
  *  Version 0.5 -- August, 1999.   Some more fixes. Reformat for Linus.
- */
+ *
+ *  BitWizard is actively maintaining this file. We sometimes find
+ *  that someone submitted changes to this file. We really appreciate
+ *  your help, but please submit changes through us. We're doing our
+ *  best to be responsive.  -- REW
+ * */
 
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/mm.h>
 #include <asm/semaphore.h>
+#include <asm/uaccess.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/compatmac.h>
@@ -40,8 +46,6 @@
 #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n")
 #define func_exit()  gs_dprintk (GS_DEBUG_FLOW, "gs: exit  " __FUNCTION__ "\n")
 
-
-
 #if NEW_WRITE_LOCKING
 #define DECL      /* Nothing */
 #define LOCKIT    down (& port->port_write_sem);
@@ -52,6 +56,9 @@
 #define RELEASEIT restore_flags (flags)
 #endif
 
+#ifdef MODULE
+MODULE_PARM(gs_debug, "i");
+#endif
 
 #ifdef DEBUG
 static void my_hd (unsigned char *addr, int len)
@@ -77,10 +84,18 @@
 
 void gs_put_char(struct tty_struct * tty, unsigned char ch)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	DECL
 
-	/*  func_enter (); */
+	func_enter (); 
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
+	if (! (port->flags & ASYNC_INITIALIZED)) return;
 
 	/* Take a lock on the serial tranmit buffer! */
 	LOCKIT;
@@ -96,7 +111,7 @@
 	port->xmit_cnt++;  /* Characters in buffer */
 
 	RELEASEIT;
-	/* func_exit ();*/
+	func_exit ();
 }
 
 
@@ -112,11 +127,17 @@
 int gs_write(struct tty_struct * tty, int from_user, 
                     const unsigned char *buf, int count)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	int c, total = 0;
 	int t;
 
-	/* func_enter (); */
+	func_enter ();
+
+	if (!tty) return 0;
+
+	port = tty->driver;
+
+	if (!port) return 0;
 
 	if (! (port->flags & ASYNC_INITIALIZED))
 		return 0;
@@ -167,7 +188,7 @@
 		port->flags |= GS_TX_INTEN;
 		port->rd->enable_tx_interrupts (port);
 	}
-	/* func_exit (); */
+	func_exit ();
 	return total;
 }
 #else
@@ -210,12 +231,9 @@
 	if (!port || !port->xmit_buf || !tmp_buf)
 		return -EIO;
 
-	/* printk ("from_user = %d.\n", from_user); */
 	save_flags(flags);
 	if (from_user) {
-		/* printk ("Going into the semaphore\n"); */
 		down(&tmp_buf_sem);
-		/* printk ("got out of the semaphore\n"); */
 		while (1) {
 			c = count;
 
@@ -309,11 +327,11 @@
 	struct gs_port *port = tty->driver_data;
 	int ret;
 
-	/* func_enter (); */
+	func_enter ();
 	ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
 	if (ret < 0)
 		ret = 0;
-	/* func_exit (); */
+	func_exit ();
 	return ret;
 }
 
@@ -330,7 +348,7 @@
 
 int gs_real_chars_in_buffer(struct tty_struct *tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	func_enter ();
 
 	if (!tty) return 0;
@@ -361,22 +379,17 @@
 
 	if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
 		gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
-	func_exit();
+		func_exit();
 		return -EINVAL;  /* This is an error which we don't know how to handle. */
 	}
-	gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 1\n");
 
 	rcib = gs_real_chars_in_buffer(port->tty);
 
-	gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 2\n");
-
 	if(rcib <= 0) {
 		gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
 		func_exit();
 		return rv;
 	}
-	gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 3\n");
-
 	/* stop trying: now + twice the time it would normally take +  seconds */
 	end_jiffies  = jiffies; 
 	if (timeout !=  MAX_SCHEDULE_TIMEOUT)
@@ -424,17 +437,23 @@
 
 void gs_flush_buffer(struct tty_struct *tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	unsigned long flags;
 
 	func_enter ();
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
 	/* XXX Would the write semaphore do? */
 	save_flags(flags); cli();
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 	restore_flags(flags);
 
 	wake_up_interruptible(&tty->write_wait);
-	wake_up_interruptible(&tty->poll_wait);
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	    tty->ldisc.write_wakeup)
 		(tty->ldisc.write_wakeup)(tty);
@@ -444,9 +463,16 @@
 
 void gs_flush_chars(struct tty_struct * tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 
 	func_enter ();
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
 	if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
 	    !port->xmit_buf) {
 		func_exit ();
@@ -462,9 +488,16 @@
 
 void gs_stop(struct tty_struct * tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 
 	func_enter ();
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
 	if (port->xmit_cnt && 
 	    port->xmit_buf && 
 	    (port->flags & GS_TX_INTEN) ) {
@@ -477,7 +510,13 @@
 
 void gs_start(struct tty_struct * tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
 
 	if (port->xmit_cnt && 
 	    port->xmit_buf && 
@@ -492,7 +531,11 @@
 void gs_shutdown_port (struct gs_port *port)
 {
 	long flags;
+
 	func_enter();
+	
+	if (!port) return;
+	
 	if (!(port->flags & ASYNC_INITIALIZED))
 		return;
 
@@ -517,10 +560,13 @@
 
 void gs_hangup(struct tty_struct *tty)
 {
-	struct gs_port   *port = tty->driver_data;
+	struct gs_port   *port;
 
 	func_enter ();
 
+	if (!tty) return;
+
+	port = tty->driver_data;
 	tty = port->tty;
 	if (!tty) return;
 
@@ -541,15 +587,19 @@
 	struct gs_port *port = private_;
 	struct tty_struct *tty;
 
+	func_enter ();
+
+	if (!port) return;
+
 	tty = port->tty;
-	if(!tty) return;
+
+	if (!tty) return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
 		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 		    tty->ldisc.write_wakeup)
 			(tty->ldisc.write_wakeup)(tty);
 		wake_up_interruptible(&tty->write_wait);
-		wake_up_interruptible(&tty->poll_wait);
 	}
 	func_exit ();
 }
@@ -565,8 +615,13 @@
 	struct tty_struct *tty;
 
 	func_enter ();
+
+	if (!port) return 0;
+
 	tty = port->tty;
 
+	if (!tty) return 0;
+
 	gs_dprintk (GS_DEBUG_BTR, "Entering block_till_ready.\n"); 
 	/*
 	 * If the device is in the middle of being closed, then block
@@ -625,8 +680,6 @@
 			do_clocal = 1;
 	}
 
-	gs_dprintk (GS_DEBUG_BTR, "after clocal check.\n"); 
-
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -635,10 +688,10 @@
 	 * exit, either normal or abnormal.
 	 */
 	retval = 0;
+
 	add_wait_queue(&port->open_wait, &wait);
 
 	gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); 
-
 	cli();
 	if (!tty_hung_up_p(filp))
 		port->count--;
@@ -690,15 +743,12 @@
 	struct gs_port *port;
 
 	func_enter ();
-	port = (struct gs_port *) tty->driver_data;
 
-	gs_dprintk (GS_DEBUG_CLOSE, "tty=%p, port=%p port->tty=%p\n",
-	            tty, port, port->tty);
+	if (!tty) return;
 
-	if(! port) {
-		func_exit();
-		return;
-	}
+	port = (struct gs_port *) tty->driver_data;
+
+	if (!port) return;
 
 	if (!port->tty) {
 		/* This seems to happen when this is called from vhangup. */
@@ -706,7 +756,6 @@
 		port->tty = tty;
 	}
 
-
 	save_flags(flags); cli();
 
 	if (tty_hung_up_p(filp)) {
@@ -800,14 +849,19 @@
 void gs_set_termios (struct tty_struct * tty, 
                      struct termios * old_termios)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	int baudrate, tmp, rv;
 	struct termios *tiosp;
 
 	func_enter();
 
-	tiosp = tty->termios;
+	if (!tty) return;
+
+	port = tty->driver_data;
 
+	if (!port) return;
+
+	tiosp = tty->termios;
 
 	if (gs_debug & GS_DEBUG_TERMIOS) {
 		gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
diff -urN linux-2.2.17-pre13/drivers/char/i2c.c linux/drivers/char/i2c.c
--- linux-2.2.17-pre13/drivers/char/i2c.c	Tue Jan  4 10:12:14 2000
+++ linux/drivers/char/i2c.c	Mon Dec  3 22:10:12 2001
@@ -38,8 +38,8 @@
 
 #ifdef CONFIG_VIDEO_BT848
 extern int i2c_tuner_init(void);
-extern int msp3400c_init(void);
 #endif
+extern int msp3400c_init(void);
 #ifdef CONFIG_VIDEO_BUZ
 extern int saa7111_init(void);
 extern int saa7185_init(void);
diff -urN linux-2.2.17-pre13/drivers/char/ip2main.c linux/drivers/char/ip2main.c
--- linux-2.2.17-pre13/drivers/char/ip2main.c	Wed Jun  7 14:26:42 2000
+++ linux/drivers/char/ip2main.c	Mon Dec  3 22:10:12 2001
@@ -2585,7 +2585,7 @@
 	 * base. Also line nunber as such is meaningless but we use it for our
 	 * array index so it is fixed also.
 	 */
-	if ( ns.irq  	    != ip2config.irq
+	if ( ns.irq  	    != ip2config.irq[pCh->port_index]
 	    || (int) ns.port      != ((int) pCh->pMyBord->i2eBase)
 	    || ns.baud_base != pCh->BaudBase
 	    || ns.line      != pCh->port_index ) {
diff -urN linux-2.2.17-pre13/drivers/char/misc.c linux/drivers/char/misc.c
--- linux-2.2.17-pre13/drivers/char/misc.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/char/misc.c	Mon Dec  3 22:10:12 2001
@@ -74,6 +74,7 @@
 extern void wdt_init(void);
 extern void acq_init(void);
 extern void wdt60xx_init(void);
+extern void sbc60xxwdt_init(void);
 extern void dtlk_init(void);
 extern void pcwatchdog_init(void);
 extern int rtc_init(void);
diff -urN linux-2.2.17-pre13/drivers/char/rio/func.h linux/drivers/char/rio/func.h
--- linux-2.2.17-pre13/drivers/char/rio/func.h	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/func.h	Mon Dec  3 22:10:12 2001
@@ -168,4 +168,6 @@
 extern int rio_ismodem (kdev_t device);
 extern void rio_udelay (int usecs);
 
+extern void rio_start_card_running (struct Host * HostP);
+
 #endif	/* __func_h_def */
diff -urN linux-2.2.17-pre13/drivers/char/rio/host.h linux/drivers/char/rio/host.h
--- linux-2.2.17-pre13/drivers/char/rio/host.h	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/host.h	Mon Dec  3 22:10:12 2001
@@ -56,16 +56,16 @@
     uchar             	    Mode;      /* Control stuff */
     uchar                   Slot;      /* Slot */
     volatile caddr_t        Caddr;     /* KV address of DPRAM */
-    volatile struct DpRam   *CardP;    /* KV address of DPRAM, with overlay */
+    volatile struct DpRam  *CardP;     /* KV address of DPRAM, with overlay */
     paddr_t          	    PaddrP;    /* Phys. address of DPRAM */
     char                    Name[MAX_NAME_LEN];  /* The name of the host */
     uint            	    UniqueNum; /* host unique number */
-    semtype	    HostLock;  /* Lock structure for MPX */
-    /*struct pci_devinfo	    PciDevInfo; *//* PCI Bus/Device/Function stuff */
+    spinlock_t	            HostLock;  /* Lock structure for MPX */
+    /*struct pci_devinfo    PciDevInfo; *//* PCI Bus/Device/Function stuff */
     /*struct lockb	    HostLock;  *//* Lock structure for MPX */
     uint                    WorkToBeDone; /* set to true each interrupt */
     uint                    InIntr;    /* Being serviced? */
-    uint                    IntSrvDone;	/* host's interrupt has been serviced */
+    uint                    IntSrvDone;/* host's interrupt has been serviced */
     int			    (*Copy)( caddr_t, caddr_t, int ); /* copy func */
     struct timer_list timer;
     /*
diff -urN linux-2.2.17-pre13/drivers/char/rio/linux_compat.h linux/drivers/char/rio/linux_compat.h
--- linux-2.2.17-pre13/drivers/char/rio/linux_compat.h	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/linux_compat.h	Mon Dec  3 22:10:12 2001
@@ -47,9 +47,6 @@
 
 #define SEM_SIGIGNORE 0x1234
 
-typedef struct semaphore semtype;
-
-
 #ifdef DEBUG_SEM
 #define swait(a,b)      printk ("waiting:    " __FILE__ " line %d\n", __LINE__)
 #define ssignal(sem)    printk ("signalling: " __FILE__ " line %d\n", __LINE__)
diff -urN linux-2.2.17-pre13/drivers/char/rio/rio_linux.c linux/drivers/char/rio/rio_linux.c
--- linux-2.2.17-pre13/drivers/char/rio/rio_linux.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/rio_linux.c	Mon Dec  3 22:10:12 2001
@@ -109,108 +109,6 @@
 more than 512 ports.... */
 
 
-/* ************************************************************** */
-/* * This section can be removed when 2.0 becomes outdated....  * */
-/* ************************************************************** */
-
-#if LINUX_VERSION_CODE < 0x020100    /* Less than 2.1.0 */
-#define TWO_ZERO
-#else
-#if LINUX_VERSION_CODE < 0x020209   /* less than 2.2.x */
-#warning "Please use a recent 2.2.x kernel. "
-#endif
-#endif
-
-
-#ifdef TWO_ZERO
-
-/* Here is the section that makes the 2.2 compatible driver source 
-   work for 2.0 too! We mostly try to adopt the "new thingies" from 2.2, 
-   and provide for compatibility stuff here if possible. */
-
-#include <linux/bios32.h>
-
-#define Get_user(a,b)                a = get_user(b)
-#define Put_user(a,b)                0,put_user(a,b)
-#define copy_to_user(a,b,c)          memcpy_tofs(a,b,c)
-
-static inline int copy_from_user(void *to,const void *from, int c) 
-{
-  memcpy_fromfs(to, from, c);
-  return 0;
-}
-
-#define pci_present                  pcibios_present
-#define pci_read_config_word         pcibios_read_config_word
-#define pci_read_config_dword        pcibios_read_config_dword
-
-static inline unsigned char get_irq (unsigned char bus, unsigned char fn)
-{
-  unsigned char t; 
-  pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &t);
-  return t;
-}
-
-static inline void *ioremap(unsigned long base, long length)
-{
-  if (base < 0x100000) return (void *)base;
-  return vremap (base, length);
-}
-
-#define my_iounmap(x, b)             (((long)x<0x100000)?0:vfree ((void*)x))
-
-#define capable(x)                   suser()
-
-#define queue_task                   queue_task_irq_off
-#define tty_flip_buffer_push(tty)    queue_task(&tty->flip.tqueue, &tq_timer)
-#define signal_pending(current)      (current->signal & ~current->blocked)
-#define schedule_timeout(to)         do {current->timeout = jiffies + (to);schedule ();} while (0)
-#define time_after(t1,t2)            (((long)t1-t2) > 0)
-
-
-#define test_and_set_bit(nr, addr)   set_bit(nr, addr)
-#define test_and_clear_bit(nr, addr) clear_bit(nr, addr)
-
-/* Not yet implemented on 2.0 */
-#define ASYNC_SPD_SHI  -1
-#define ASYNC_SPD_WARP -1
-
-
-/* Ugly hack: the driver_name doesn't exist in 2.0.x . So we define it
-   to the "name" field that does exist. As long as the assignments are
-   done in the right order, there is nothing to worry about. */
-#define driver_name           name 
-
-/* Should be in a header somewhere. They are in tty.h on 2.2 */
-#define TTY_HW_COOK_OUT       14 /* Flag to tell ntty what we can handle */
-#define TTY_HW_COOK_IN        15 /* in hardware - output and input       */
-
-/* The return type of a "close" routine. */
-#define INT                   void
-#define NO_ERROR              /* Nothing */
-
-#else
-
-/* The 2.2.x compatibility section. */
-#include <asm/uaccess.h>
-
-#define Get_user(a,b)         get_user(a,b)
-#define Put_user(a,b)         put_user(a,b)
-#define get_irq(pdev)         pdev->irq
-
-#define INT                   int
-#define NO_ERROR              0              
-
-#define my_iounmap(x,b)       (iounmap((char *)(b)))
-
-#endif
-
-/* ************************************************************** */
-/* *                End of compatibility section..              * */
-/* ************************************************************** */
-
-
-
 /* Why the hell am I defining these here? */
 #define RIO_TYPE_NORMAL 1
 #define RIO_TYPE_CALLOUT 2
@@ -373,55 +271,15 @@
   NULL
 };
 
-
-/* 
-   This driver can spew a whole lot of debugging output at you. If you
-   need maximum performance, you should disable the DEBUG define. To
-   aid in debugging in the field, I'm leaving the compile-time debug
-   features enabled, and disable them "runtime". That allows me to
-   instruct people with problems to enable debugging without requiring
-   them to recompile... 
-*/
-#define DEBUG
-
-#ifdef DEBUG
-#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
-#else
-#define rio_dprintk(f, str...) /* nothing */
-#endif
-
-
-#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
-#define func_exit()  rio_dprintk (RIO_DEBUG_FLOW, "rio: exit  " __FUNCTION__ "\n")
-
-#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
-                                  "(port %d)\n", port->line)
-
-
-
-
 /* 
  *  Firmware loader driver specific routines
  *
  */
 
 static struct file_operations rio_fw_fops = {
-	NULL,	/*	lseek	*/
-	NULL,	/*	read	*/
-	NULL,	/*	write	*/
-	NULL,	/*	readdir	*/
-	NULL,	/*	select	*/
-	rio_fw_ioctl,
-	NULL,	/*	mmap	*/
-	rio_fw_open,
-#ifndef TWO_ZERO
-	NULL,	/*	flush	*/
-#endif
-	rio_fw_release,
-	NULL,	/*	fsync	*/
-	NULL,	/*	fasync	*/
-	NULL,	/*	check_media_change	*/
-	NULL,	/*	revalidate	*/
+        open:           rio_fw_open,
+        release:        rio_fw_release,
+	ioctl:		rio_fw_ioctl,
 };
 
 struct miscdevice rio_fw_device = {
@@ -446,11 +304,11 @@
     KERN_ERR "rio: Warning: null rio port for device %s in %s\n";
  
   if (!port) {
-    printk(badinfo, kdevname(device), routine);
+    printk (badinfo, kdevname(device), routine);
     return 1;
   }
   if (port->magic != RIO_MAGIC) {
-    printk(badmagic, kdevname(device), routine);
+    printk (badmagic, kdevname(device), routine);
     return 1;
   }
 
@@ -468,15 +326,15 @@
   unsigned char *addr = ad;
   
   for (i=0;i<len;i+=16) {
-    printk ("%08x ", (int) addr+i);
+    rio_dprintk (RIO_DEBUG_PARAM, "%08x ", (int) addr+i);
     for (j=0;j<16;j++) {
-      printk ("%02x %s", addr[j+i], (j==7)?" ":"");
+      rio_dprintk (RIO_DEBUG_PARAM, "%02x %s", addr[j+i], (j==7)?" ":"");
     }
     for (j=0;j<16;j++) {
       ch = addr[j+i];
-      printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
+      rio_dprintk (RIO_DEBUG_PARAM, "%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
     }
-    printk ("\n");
+    rio_dprintk (RIO_DEBUG_PARAM, "\n");
   }
 }
 #else
@@ -568,21 +426,26 @@
 
 void rio_reset_interrupt (struct Host *HostP)
 {
+  func_enter();
+
   switch( HostP->Type ) {
   case RIO_AT:
   case RIO_MCA:
   case RIO_PCI:
     WBYTE(HostP->ResetInt , 0xff);
   }
+
+  func_exit();
 }
 
 
 static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
 {
   struct Host *HostP;
+  func_enter ();
 
-  HostP = &p->RIOHosts[(long)ptr];
-  /*   func_enter ();  */
+  HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */
+  
   rio_dprintk (RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", 
                irq, HostP->Ivec); 
 
@@ -627,7 +490,7 @@
     }
   }
 #endif
-
+  rio_dprintk (RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); 
   if (HostP->Ivec == irq) {
     /* Tell the card we've noticed the interrupt. */
     rio_reset_interrupt (HostP);
@@ -649,7 +512,7 @@
   clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks);
   rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", 
                irq, HostP->Ivec); 
-  /*  func_exit ();  */
+  func_exit ();
 }
 
 
@@ -657,7 +520,7 @@
 {
   func_enter ();
 
-  rio_interrupt (0, (void *)data, NULL);
+  rio_interrupt (0, &p->RIOHosts[data], NULL);
   p->RIOHosts[data].timer.expires = jiffies + rio_poll;
   add_timer (&p->RIOHosts[data].timer);
 
@@ -756,11 +619,11 @@
 #if 0
   port->gs.flags &= ~ GS_ACTIVE;
   if (!port->gs.tty) {
-    printk ("No tty.\n");
+    rio_dprintk (RIO_DBUG_TTY, "No tty.\n");
     return;
   }
   if (!port->gs.tty->termios) {
-    printk ("No termios.\n");
+    rio_dprintk (RIO_DEBUG_TTY, "No termios.\n");
     return;
   }
   if (port->gs.tty->termios->c_cflag & HUPCL) {
@@ -772,7 +635,6 @@
 }
 
 
-
 /* ********************************************************************** *
  *                Here are the routines that actually                     *
  *               interface with the rest of the system                    *
@@ -1000,6 +862,8 @@
 
   if (rio_debug & RIO_DEBUG_PROBE)
     my_hd ((char *)&vpdp, 0x20);
+  
+  func_exit();
 
   return &vpdp;
 }
@@ -1099,7 +963,7 @@
   /* However, the RIO driver allows users to configure their first
      RTA as the ports numbered 504-511. We therefore need to allocate 
      the whole range. :-(   -- REW */
-
+  
 #define RI_SZ   sizeof(struct rio_info)
 #define HOST_SZ sizeof(struct Host)
 #define PORT_SZ sizeof(struct Port *)
@@ -1138,11 +1002,14 @@
     port->gs.close_delay = HZ/2;
     port->gs.closing_wait = 30 * HZ;
     port->gs.rd = &rio_real_driver;
+
   }
 #else
   /* We could postpone initializing them to when they are configured. */
 #endif
 
+
+  
   if (rio_debug & RIO_DEBUG_INIT) {
     my_hd (&rio_real_driver, sizeof (rio_real_driver));
   }
@@ -1165,7 +1032,7 @@
   return -ENOMEM;
 }
 
-
+#ifdef MODULE
 static void rio_release_drivers(void)
 {
   func_enter();
@@ -1175,6 +1042,7 @@
   tty_unregister_driver (&rio_driver);
   func_exit();
 }
+#endif 
 
 #ifdef TWO_ZERO
 #define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -1211,7 +1079,7 @@
   unsigned int t;
 
 #define CNTRL_REG_OFFSET        0x50
-#define CNTRL_REG_GOODVALUE     0x00260000
+#define CNTRL_REG_GOODVALUE     0x18260000
 
   pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
   hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
@@ -1292,7 +1160,6 @@
       pci_read_config_dword (pdev, 0x2c, &tint);
       tshort = (tint >> 16) & 0xffff;
       rio_dprintk (RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
-      /* rio_dprintk (RIO_DEBUG_PROBE, "pdev = %d/%d  (%x)\n", pdev, tint); */ 
       if (tshort != 0x0100) {
         rio_dprintk (RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", 
                     tshort);
@@ -1305,49 +1172,51 @@
       hp = &p->RIOHosts[p->RIONumHosts];
       hp->PaddrP =  tint & PCI_BASE_ADDRESS_MEM_MASK;
       hp->Ivec = get_irq (pdev);
-      if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+      if (((1 << hp->Ivec) & rio_irqmask) == 0)
+              hp->Ivec = 0;
       hp->CardP	= (struct DpRam *)
       hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy; 
-      hp->Mode  = RIO_PCI_DEFAULT_MODE;
- 
+      hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
+      rio_reset_interrupt (hp);
+      rio_start_card_running (hp);
+
       rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
                    (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
                    p->RIOHosts[p->RIONumHosts].Caddr);
       if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
                         p->RIOHosts[p->RIONumHosts].Caddr, 
                         RIO_PCI, 0 ) == RIO_SUCCESS) {
-        WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
-        p->RIOHosts[p->RIONumHosts].UniqueNum  =
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
-        rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
-                   p->RIOHosts[p->RIONumHosts].UniqueNum);
-
-#if 1
-        fix_rio_pci (pdev);
-#endif
-        p->RIOLastPCISearch = RIO_SUCCESS;
-        p->RIONumHosts++;
-        found++;
+              rio_dprintk (RIO_DEBUG_INIT, "Done RIOBoardTest\n");
+              WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
+              p->RIOHosts[p->RIONumHosts].UniqueNum  =
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
+              rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
+                           p->RIOHosts[p->RIONumHosts].UniqueNum);
+              
+              fix_rio_pci (pdev);
+              p->RIOLastPCISearch = RIO_SUCCESS;
+              p->RIONumHosts++;
+              found++;
       } else {
-        my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, 
-                    p->RIOHosts[p->RIONumHosts].Caddr);
+              my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, 
+                          p->RIOHosts[p->RIONumHosts].Caddr);
       }
-
+      
 #ifdef TWO_ZERO
     }  /* We have two variants with the opening brace, so to prevent */
 #else
     }  /* Emacs from getting confused we have two closing braces too. */
 #endif
     
-
     /* Then look for the older PCI card.... : */
 #ifndef TWO_ZERO
 
+
   /* These older PCI cards have problems (only byte-mode access is
      supported), which makes them a bit awkward to support. 
      They also have problems sharing interrupts. Be careful. 
@@ -1372,15 +1241,21 @@
       hp = &p->RIOHosts[p->RIONumHosts];
       hp->PaddrP =  tint & PCI_BASE_ADDRESS_MEM_MASK;
       hp->Ivec = get_irq (pdev);
-      if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+      if (((1 << hp->Ivec) & rio_irqmask) == 0) 
+      	hp->Ivec = 0;
       hp->Ivec |= 0x8000; /* Mark as non-sharable */
       hp->CardP	= (struct DpRam *)
       hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy;
-      hp->Mode  = RIO_PCI_DEFAULT_MODE;
- 
-      rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
+      hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
+
+      rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec);
+      rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode);
+
+      rio_reset_interrupt (hp);
+      rio_start_card_running (hp);
+       rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
                    (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
                    p->RIOHosts[p->RIONumHosts].Caddr);
       if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
@@ -1423,11 +1298,15 @@
     hp->CardP = (struct DpRam *)
     hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
     hp->Type = RIO_AT;
-    hp->Copy = rio_pcicopy;
+    hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL
+                             * -- YES! this is now a normal copy. Only the 
+                             * old PCI card uses the special PCI copy. 
+                             * Moreover, the ISA card will work with the 
+                             * special PCI copy anyway. -- REW */
     hp->Mode = 0;
 
     vpdp = get_VPD_PROM (hp);
-
+    rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n");
     okboard = 0;
     if ((strncmp (vpdp->identifier, RIO_ISA_IDENT, 16) == 0) ||
         (strncmp (vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) ||
@@ -1458,11 +1337,21 @@
     if (hp->Ivec) {
       int mode = SA_SHIRQ;
       if (hp->Ivec & 0x8000) {mode = 0; hp->Ivec &= 0x7fff;}
-      if (request_irq (hp->Ivec, rio_interrupt, mode, "rio", (void *)i)) {
-        printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
-        hp->Ivec = 0;
+      rio_dprintk (RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp,hp->Ivec, hp->Mode);
+      retval = request_irq (hp->Ivec, rio_interrupt, mode, "rio", hp);
+      rio_dprintk (RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval);
+      if (retval) {
+              printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
+              hp->Ivec = 0;
       }
       rio_dprintk (RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec);
+      if (hp->Ivec != 0){
+              rio_dprintk (RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); 
+              hp->Mode |= RIO_PCI_INT_ENABLE;
+      } else
+              hp->Mode &= !RIO_PCI_INT_ENABLE;
+      rio_dprintk (RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode);
+      rio_start_card_running (hp);
     }
     /* Init the timer "always" to make sure that it can safely be 
        deleted when we unload... */
@@ -1479,7 +1368,7 @@
   }
 
   if (found) {
-    printk (KERN_INFO "rio: total of %d boards detected.\n", found);
+    rio_dprintk (RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found);
 
     if (misc_register(&rio_fw_device) < 0) {
       printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n");
@@ -1504,7 +1393,7 @@
   for (i=0,hp=p->RIOHosts;i<p->RIONumHosts;i++, hp++) {
     RIOHostReset (hp->Type, hp->CardP, hp->Slot);
     if (hp->Ivec) {
-      free_irq (hp->Ivec, (void *)i);
+      free_irq (hp->Ivec, hp);
       rio_dprintk (RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec);
     }
     /* It is safe/allowed to del_timer a non-active timer */
diff -urN linux-2.2.17-pre13/drivers/char/rio/rio_linux.h linux/drivers/char/rio/rio_linux.h
--- linux-2.2.17-pre13/drivers/char/rio/rio_linux.h	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/rio_linux.h	Mon Dec  3 22:10:12 2001
@@ -23,6 +23,7 @@
  *  Version 1.0 -- July, 1999. 
  * 
  */
+#include <linux/config.h>
 
 #define RIO_NBOARDS        4
 #define RIO_PORTSPERBOARD 128
@@ -157,5 +158,30 @@
 #else
 #define rio_memcpy_toio(dummy,dest,source,n)   memcpy_toio(dest, source, n)
 #define rio_memcpy_fromio                      memcpy_fromio
+#endif
+
+#define DEBUG
+
+
+/* 
+   This driver can spew a whole lot of debugging output at you. If you
+   need maximum performance, you should disable the DEBUG define. To
+   aid in debugging in the field, I'm leaving the compile-time debug
+   features enabled, and disable them "runtime". That allows me to
+   instruct people with problems to enable debugging without requiring
+   them to recompile... 
+*/
+
+#ifdef DEBUG
+#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
+#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
+#define func_exit()  rio_dprintk (RIO_DEBUG_FLOW, "rio: exit  " __FUNCTION__ "\n")
+#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
+                                   "(port %d)\n", port->line)
+#else
+#define rio_dprintk(f, str...) /* nothing */
+#define func_enter()
+#define func_exit()
+#define func_enter2()
 #endif
 
diff -urN linux-2.2.17-pre13/drivers/char/rio/rioboot.c linux/drivers/char/rio/rioboot.c
--- linux-2.2.17-pre13/drivers/char/rio/rioboot.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/rioboot.c	Mon Dec  3 22:10:12 2001
@@ -35,7 +35,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -82,7 +81,6 @@
 #include "cmdblk.h"
 #include "route.h"
 
-
 static uchar
 RIOAtVec2Ctrl[] =
 {
@@ -114,6 +112,8 @@
 {
 	int offset;
 
+	func_enter ();
+
 	/* Linux doesn't allow you to disable interrupts during a
 	   "copyin". (Crash when a pagefault occurs). */
 	/* disable(oldspl); */
@@ -127,6 +127,7 @@
 		rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code Too Large!\n"));
 		p->RIOError.Error = HOST_FILE_TOO_LARGE;
 		/* restore(oldspl); */
+		func_exit ();
 		return ENOMEM;
 	}
 
@@ -134,6 +135,7 @@
 		rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code : BUSY BUSY BUSY!\n"));
 		p->RIOError.Error = BOOT_IN_PROGRESS;
 		/* restore(oldspl); */
+		func_exit ();
 		return EBUSY;
 	}
 
@@ -161,6 +163,7 @@
 		rio_dprint(RIO_DEBUG_BOOT, ("Bad data copy from user space\n"));
 		p->RIOError.Error = COPYIN_FAILED;
 		/* restore(oldspl); */
+		func_exit ();
 		return EFAULT;
 	}
 
@@ -172,9 +175,61 @@
 	p->RIOBootCount   = rbp->Count;
 
 	/* restore(oldspl); */
+	func_exit();
 	return 0;
 }
 
+void rio_start_card_running (struct Host * HostP)
+{
+	func_enter ();
+
+	switch ( HostP->Type ) {
+	case RIO_AT:
+		rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
+		WBYTE(HostP->Control, 
+		      BOOT_FROM_RAM | EXTERNAL_BUS_ON
+		      | HostP->Mode
+		      | RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
+		break;
+		
+#ifdef FUTURE_RELEASE
+	case RIO_MCA:
+				/*
+				** MCA handles IRQ vectors differently, so we don't write 
+				** them to this register.
+				*/
+		rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
+		WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
+		break;
+
+	case RIO_EISA:
+				/*
+				** EISA is totally different and expects OUTBZs to turn it on.
+				*/
+		rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n");
+		OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
+		break;
+#endif
+
+	case RIO_PCI:
+				/*
+				** PCI is much the same as MCA. Everything is once again memory
+				** mapped, so we are writing to memory registers instead of io
+				** ports.
+				*/
+		rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n"));
+		WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
+		break;
+	default:
+		rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type));
+		break;
+	}
+/* 
+	printk (KERN_INFO "Done with starting the card\n");
+	func_exit ();
+*/
+	return;
+}
 
 /*
 ** Load in the host boot code - load it directly onto all halted hosts
@@ -207,6 +262,10 @@
 	for ( host=0; host<p->RIONumHosts; host++ ) {
 		rio_dprint(RIO_DEBUG_BOOT, ("Attempt to boot host %d\n",host));
 		HostP = &p->RIOHosts[host];
+		
+		rio_dprint(RIO_DEBUG_BOOT,  ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+		    HostP->Type, HostP->Mode, HostP->Ivec ) );
+
 
 		if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) {
 			rio_dprint(RIO_DEBUG_BOOT, ("%s %d already running\n","Host",host));
@@ -234,6 +293,7 @@
 		if ( p->RIOConf.HostLoadBase < rbp->Count ) {
 			rio_dprint(RIO_DEBUG_BOOT, ("Bin too large\n"));
 			p->RIOError.Error = HOST_FILE_TOO_LARGE;
+			func_exit ();
 			return EFBIG;
 		}
 		/*
@@ -260,6 +320,7 @@
 			if ( !DownCode ) {
 				rio_dprint(RIO_DEBUG_BOOT, ("No system memory available\n"));
 				p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY;
+				func_exit ();
 				return ENOMEM;
 			}
 			bzero(DownCode, rbp->Count);
@@ -267,6 +328,7 @@
 			if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) {
 				rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
 				p->RIOError.Error = COPYIN_FAILED;
+				func_exit ();
 				return EFAULT;
 			}
 
@@ -277,6 +339,7 @@
 		else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) {
 			rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
 			p->RIOError.Error = COPYIN_FAILED;
+			func_exit ();
 			return EFAULT;
 		}
 
@@ -406,47 +469,8 @@
 		rio_dprint(RIO_DEBUG_BOOT,  ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
 		    HostP->Type, HostP->Mode, HostP->Ivec ) );
 
-		switch ( HostP->Type ) {
-			case RIO_AT:
-				rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
-				WBYTE(HostP->Control, 
-					BOOT_FROM_RAM | EXTERNAL_BUS_ON
-					| HostP->Mode
-					| RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
-				break;
-
-#ifdef FUTURE_RELEASE
-			case RIO_MCA:
-				/*
-				** MCA handles IRQ vectors differently, so we don't write 
-				** them to this register.
-				*/
-				rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
-				WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
-				break;
-
-			case RIO_EISA:
-				/*
-				** EISA is totally different and expects OUTBZs to turn it on.
-				*/
-				rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n");
-				OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
-				break;
-#endif
+		rio_start_card_running(HostP);
 
-			case RIO_PCI:
-				/*
-				** PCI is much the same as MCA. Everything is once again memory
-				** mapped, so we are writing to memory registers instead of io
-				** ports.
-				*/
-				rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n"));
-				WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
-				break;
-			default:
-				rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type));
-				break;
-		}
 		rio_dprint(RIO_DEBUG_BOOT, ("Set control port\n"));
 
 		/*
@@ -454,9 +478,10 @@
 		** pointer:
 		*/
 		for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&
-				(RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
+			(RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
 			rio_dprint(RIO_DEBUG_BOOT, ("Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)));
 			delay(HostP, HUNDRED_MS);
+
 		}
 
 		/*
@@ -614,6 +639,7 @@
 	p->RIOSystemUp++;
 	
 	rio_dprint(RIO_DEBUG_BOOT, ("Done everything %x\n", HostP->Ivec));
+	func_exit ();
 	return 0;
 }
 
diff -urN linux-2.2.17-pre13/drivers/char/rio/riocmd.c linux/drivers/char/rio/riocmd.c
--- linux-2.2.17-pre13/drivers/char/rio/riocmd.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/riocmd.c	Mon Dec  3 22:10:12 2001
@@ -35,7 +35,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -43,8 +42,6 @@
 #include <asm/system.h>
 #include <asm/string.h>
 #include <asm/semaphore.h>
-#include <asm/spinlock.h>
-
 
 #include <linux/termios.h>
 #include <linux/serial.h>
diff -urN linux-2.2.17-pre13/drivers/char/rio/rioctrl.c linux/drivers/char/rio/rioctrl.c
--- linux-2.2.17-pre13/drivers/char/rio/rioctrl.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/rioctrl.c	Mon Dec  3 22:10:12 2001
@@ -35,7 +35,6 @@
 
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -202,6 +201,8 @@
 	int		retval = 0;
 	unsigned long flags;
 	
+	func_enter ();
+	
 	/* Confuse teh compiler to think that we've initialized these */
 	Host=0;
 	PortP = NULL;
@@ -1777,6 +1778,8 @@
 	}
 	rio_dprint(RIO_DEBUG_CTRL, ("INVALID DAEMON IOCTL 0x%x\n",cmd));
 	p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
+
+	func_exit ();
 	return EINVAL;
 }
 
diff -urN linux-2.2.17-pre13/drivers/char/rio/riodrvr.h linux/drivers/char/rio/riodrvr.h
--- linux-2.2.17-pre13/drivers/char/rio/riodrvr.h	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/riodrvr.h	Mon Dec  3 22:10:12 2001
@@ -44,7 +44,7 @@
 
 struct rio_info {
 	int			mode;			/* Intr or polled, word/byte */
-	semtype			RIOIntrSem;		/* Interrupt thread sem */
+	spinlock_t		RIOIntrSem;		/* Interrupt thread sem */
 	int			current_chan;		/* current channel */
 	int			RIOFailed;		/* Not initialised ? */
 	int			RIOInstallAttempts;	/* no. of rio-install() calls */
diff -urN linux-2.2.17-pre13/drivers/char/rio/rioinit.c linux/drivers/char/rio/rioinit.c
--- linux-2.2.17-pre13/drivers/char/rio/rioinit.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/rioinit.c	Mon Dec  3 22:10:12 2001
@@ -1414,7 +1414,7 @@
 	    (int)p->RIOHosts, sizeof(struct Host) ) );
 
 	for( host=0; host<RIO_HOSTS; host++ ) {
-		p->RIOHosts[host].HostLock = -1; /* Let the first guy takes it */
+		spin_lock_init (&p->RIOHosts[host].HostLock);
 		p->RIOHosts[host].timeout_id = 0; /* Let the first guy takes it */
 	}
 	/*
diff -urN linux-2.2.17-pre13/drivers/char/rio/riointr.c linux/drivers/char/rio/riointr.c
--- linux-2.2.17-pre13/drivers/char/rio/riointr.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/riointr.c	Mon Dec  3 22:10:12 2001
@@ -35,7 +35,6 @@
 
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -254,7 +253,6 @@
     rio_dprint (RIO_DEBUG_INTR, ("(%d/%d)\n",
 		PortP->gs.wakeup_chars, PortP->gs.xmit_cnt)); 
     wake_up_interruptible(&PortP->gs.tty->write_wait);
-    wake_up_interruptible(&PortP->gs.tty->poll_wait);
   }
 
 }
diff -urN linux-2.2.17-pre13/drivers/char/rio/rioparam.c linux/drivers/char/rio/rioparam.c
--- linux-2.2.17-pre13/drivers/char/rio/rioparam.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/rioparam.c	Mon Dec  3 22:10:12 2001
@@ -35,7 +35,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
diff -urN linux-2.2.17-pre13/drivers/char/rio/rioroute.c linux/drivers/char/rio/rioroute.c
--- linux-2.2.17-pre13/drivers/char/rio/rioroute.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/rioroute.c	Mon Dec  3 22:10:12 2001
@@ -34,7 +34,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
diff -urN linux-2.2.17-pre13/drivers/char/rio/riotable.c linux/drivers/char/rio/riotable.c
--- linux-2.2.17-pre13/drivers/char/rio/riotable.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/riotable.c	Mon Dec  3 22:10:12 2001
@@ -34,7 +34,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
diff -urN linux-2.2.17-pre13/drivers/char/rio/riotty.c linux/drivers/char/rio/riotty.c
--- linux-2.2.17-pre13/drivers/char/rio/riotty.c	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/riotty.c	Mon Dec  3 22:10:12 2001
@@ -37,7 +37,6 @@
 #define __EXPLICIT_DEF_H__
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -90,7 +89,6 @@
 #include "list.h"
 #include "sam.h"
 
-
 #if 0
 static void ttyseth_pv(struct Port *, struct ttystatics *, 
 				struct termios *sg, int);
@@ -155,13 +153,21 @@
 	unsigned long flags;
 	int retval = 0;
 
+	func_enter ();
+
+	/* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
+	   is going to oops.
+	*/
+	tty->driver_data = NULL;
+        
 	SysPort = rio_minor (tty->device);
 	Modem   = rio_ismodem (tty->device);
 
 	if ( p->RIOFailed ) {
 		rio_dprint(RIO_DEBUG_TTY, ("System initialisation failed\n"));
 		pseterr(ENXIO);
-		return 0;
+		func_exit ();
+		return -ENXIO;
 	}
 
 	rio_dprint(RIO_DEBUG_TTY, ("port open SysPort %d (%s) (mapped:%d)\n",
@@ -177,22 +183,24 @@
 	if (SysPort >= RIO_PORTS) {	/* out of range ? */
 		rio_dprint(RIO_DEBUG_TTY, ("Illegal port number %d\n",SysPort));
 		pseterr(ENXIO);
-		return 0;
+		func_exit();
+		return -ENXIO;
 	}
 
 	/*
 	** Grab pointer to the port stucture
 	*/
 	PortP = p->RIOPortp[SysPort];	/* Get control struc */
-
+	rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP);
 	if ( !PortP->Mapped ) {	/* we aren't mapped yet! */
 		/*
 		** The system doesn't know which RTA this port
 		** corresponds to.
 		*/
 		rio_dprint(RIO_DEBUG_TTY, ("port not mapped into system\n"));
+		func_exit ();
 		pseterr(ENXIO);
-		return 0;
+		return -ENXIO;
 	}
 
 	tty->driver_data = PortP;
@@ -210,7 +218,8 @@
 	if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
 		rio_dprint(RIO_DEBUG_TTY, ("Host not running\n"));
 		pseterr(ENXIO);
-		return 0;
+		func_exit ();
+		return -ENXIO;
 	}
 
 	/*
@@ -225,12 +234,14 @@
 			do {
 				if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
 					rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+					func_exit ();
 					return -EINTR;
 				}
 				if (repeat_this -- <= 0) {
 					rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
 					RIOPreemptiveCmd(p, PortP, FCLOSE ); 
 					pseterr(EINTR);
+					func_exit ();
 					return -EIO;
 				}
 			} while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
@@ -238,6 +249,7 @@
 		} else {
 			rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
 			pseterr(ENXIO);
+			func_exit ();
 			return 0;
 		}
 	}
@@ -250,6 +262,7 @@
 	while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
 	  if (!PortP->WaitUntilBooted) {
 	    rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+	    func_exit ();
 	    return -ENXIO;
 	  }
 
@@ -259,10 +272,12 @@
 	  */
 	  if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
 	    rio_dprint(RIO_DEBUG_TTY, ("RTA_wait_for_boot: EINTR in delay \n"));
+	    func_exit ();
 	    return -EINTR;
 	  }
 	  if (repeat_this -- <= 0) {
 	    rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+	    func_exit ();
 	    return -EIO;
 	  }
 	}
@@ -277,8 +292,10 @@
 	}
 #if 0
 	retval = gs_init_port(&PortP->gs);
-	if (retval)
-	  return retval;
+	if (retval){
+		func_exit ();
+		return retval;
+	}
 #endif
 
 	/*
@@ -307,6 +324,7 @@
 		rio_dprint(RIO_DEBUG_TTY, ("Port unmapped while closing!\n"));
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		retval = -ENXIO;
+		func_exit ();
 		return retval;
 	}
 
@@ -376,6 +394,7 @@
 			if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
 				rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish broken by signal\n"));
 				RIOPreemptiveCmd(p, PortP, FCLOSE );
+				func_exit ();
 				return -EINTR;
 			}
 			rio_spin_lock_irqsave(&PortP->portSem, flags);
@@ -426,6 +445,7 @@
 					tp->tm.c_state &= ~WOPEN;
 					PortP->State &= ~RIO_WOPEN;
 					rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+					func_exit ();
 					return -EINTR;
 				}
 			}
@@ -463,6 +483,7 @@
 
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 	rio_dprint(RIO_DEBUG_TTY, ("Returning from open\n"));
+	func_exit ();
 	return 0;
 }
 
diff -urN linux-2.2.17-pre13/drivers/char/rio/unixrup.h linux/drivers/char/rio/unixrup.h
--- linux-2.2.17-pre13/drivers/char/rio/unixrup.h	Wed May  3 17:16:38 2000
+++ linux/drivers/char/rio/unixrup.h	Mon Dec  3 22:10:12 2001
@@ -49,7 +49,7 @@
     uint             Id;		/* Id number */
     uint             BaseSysPort;	/* SysPort of first tty on this RTA */
     uint             ModTypes;		/* Modules on this RTA */
-  semtype	RupLock;		/* Lock structure for MPX */
+    spinlock_t	     RupLock;		/* Lock structure for MPX */
 /*    struct lockb     RupLock;	*/	/* Lock structure for MPX */
 };
 
diff -urN linux-2.2.17-pre13/drivers/char/sx.c linux/drivers/char/sx.c
--- linux-2.2.17-pre13/drivers/char/sx.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/char/sx.c	Mon Dec  3 22:10:12 2001
@@ -33,7 +33,12 @@
  *
  * Revision history:
  * $Log: sx.c,v $
- * Revision 1.32  2000/03/07 90:00:00  wolff,pvdl
+ * Revision 1.33  2000/03/09 10:00:00  pvdl,wolff
+ * - Fixed module and port counting
+ * - Fixed signal handling
+ * - Fixed an Ooops
+ * 
+ * Revision 1.32  2000/03/07 09:00:00  wolff,pvdl
  * - Fixed some sx_dprintk typos
  * - added detection for an invalid board/module configuration
  *
@@ -195,8 +200,8 @@
  * */
 
 
-#define RCS_ID "$Id: sx.c,v 1.32 2000/03/07 17:01:02 wolff, pvdl Exp $"
-#define RCS_REV "$Revision: 1.32 $"
+#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $"
+#define RCS_REV "$Revision: 1.33 $"
 
 
 #include <linux/module.h>
@@ -414,22 +419,9 @@
  */
 
 static struct file_operations sx_fw_fops = {
-	NULL,	/*	lseek	*/
-	NULL,	/*	read	*/
-	NULL,	/*	write	*/
-	NULL,	/*	readdir	*/
-	NULL,	/*	select	*/
-	sx_fw_ioctl,
-	NULL,	/*	mmap	*/
-	sx_fw_open,
-#ifndef TWO_ZERO
-	NULL,	/*	flush	*/
-#endif
-	sx_fw_release,
-	NULL,	/*	fsync	*/
-	NULL,	/*	fasync	*/
-	NULL,	/*	check_media_change	*/
-	NULL,	/*	revalidate	*/
+	open:		sx_fw_open,
+	release:       	sx_fw_release,
+	ioctl:		sx_fw_ioctl
 };
 
 struct miscdevice sx_fw_device = {
@@ -781,6 +773,7 @@
 	if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS);
 	sx_write_channel_byte (port, hi_op, t);
 	sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts);
+
 	func_exit ();
 }
 
@@ -1035,8 +1028,8 @@
 		if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) 
 			c = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
 
-		sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) \n", 
-		            c, SERIAL_XMIT_SIZE- port->gs.xmit_tail);
+		sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%ld) \n", 
+		            c, (long)SERIAL_XMIT_SIZE- port->gs.xmit_tail);
 
 		/* If for one reason or another, we can't copy more data, we're done! */
 		if (c == 0) break;
@@ -1060,14 +1053,13 @@
 		sx_disable_tx_interrupts (port);
 	}
 
-	if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+	if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
 		if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 		    port->gs.tty->ldisc.write_wakeup)
 			(port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
 		sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
 		            port->gs.wakeup_chars); 
 		wake_up_interruptible(&port->gs.tty->write_wait);
-		wake_up_interruptible(&port->gs.tty->poll_wait);
 	}
 
 	clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks);
@@ -1087,7 +1079,7 @@
 	struct tty_struct *tty;
 	int copied=0;
 
-	/* func_enter2 (); */
+	func_enter2 ();
 	tty = port->gs.tty;
 	while (1) {
 		rx_op = sx_read_channel_byte (port, hi_rxopos);
@@ -1142,7 +1134,7 @@
 		/*    tty_schedule_flip (tty); */
 	}
 
-	/* func_exit (); */
+	func_exit ();
 }
 
 /* Inlined: it is called only once. Remove the inline if you add another 
@@ -1312,6 +1304,8 @@
 
 	sx_interrupt (0, board, NULL);
 
+	init_timer(&board->timer);
+
 	board->timer.expires = jiffies + sx_poll;
 	add_timer (&board->timer);
 	func_exit ();
@@ -1407,7 +1401,7 @@
 	func_enter();
 
 	port->gs.flags &= ~ GS_ACTIVE;
-	if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) {
+	if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) {
 		sx_setsignals (port, 0, 0);
 		sx_reconfigure_port(port);
 	}
@@ -1424,7 +1418,6 @@
  *               interface with the rest of the system                    *
  * ********************************************************************** */
 
-
 static int sx_fw_open(struct inode *inode, struct file *filp)
 {
 	func_enter ();
@@ -1443,6 +1436,7 @@
 }
 
 
+
 static int sx_open  (struct tty_struct * tty, struct file * filp)
 {
 	struct sx_port *port;
@@ -1470,6 +1464,8 @@
 
 	tty->driver_data = port;
 	port->gs.tty = tty;
+	if (!port->gs.count)
+		MOD_INC_USE_COUNT;
 	port->gs.count++;
 
 	sx_dprintk (SX_DEBUG_OPEN, "starting port\n");
@@ -1481,19 +1477,13 @@
 	sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n");
 	if (retval) {
 		port->gs.count--;
+		if (port->gs.count) MOD_DEC_USE_COUNT;
 		return retval;
 	}
 
 	port->gs.flags |= GS_ACTIVE;
 	sx_setsignals (port, 1,1);
 
-	sx_dprintk (SX_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
-	            port->gs.count);
-	if (port->gs.count == 1) {
-		MOD_INC_USE_COUNT;
-	}
-	sx_dprintk (SX_DEBUG_OPEN, "after inc_use_count\n");
-
 #if 0
 	if (sx_debug & SX_DEBUG_OPEN)
 		my_hd ((unsigned char *)port, sizeof (*port));
@@ -1505,8 +1495,8 @@
 
 	if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
 		printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
-		MOD_DEC_USE_COUNT;
 		port->gs.count--;
+		if (!port->gs.count) MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 
@@ -1515,8 +1505,10 @@
 	            retval, port->gs.count);
 
 	if (retval) {
-		MOD_DEC_USE_COUNT;
-		port->gs.count--;
+		/* 
+		 * Don't lower gs.count here because sx_close() will be called later
+		 */ 
+
 		return retval;
 	}
 	/* tty->low_latency = 1; */
@@ -1548,25 +1540,15 @@
    exit minicom.  I expect an "oops".  -- REW */
 static void sx_hungup (void *ptr)
 {
-/*
-	func_enter ();
-	MOD_DEC_USE_COUNT;
-	func_exit ();
-*/
-	/* 
-	 * Got this from the 2.4.0-test1 serie. The port was closed before
-	 * the lines were set in the proper condition. -- pvdl
-	 */
 	struct sx_port *port = ptr; 
 	func_enter ();
 
-	/* 
-	 *  Set the lines in the proper codition before closing the port.
-	 *  Got the from 2.4.0-test1 series. -- pvdl
-	 */
+	/* Don't force the SX card to close. mgetty doesn't like it !!!!!! -- pvdl */
+	/* For some reson we added this code. Don't know why anymore ;-) -- pvdl */
+	/*
 	sx_setsignals (port, 0, 0);
 	sx_reconfigure_port(port);	
-	sx_send_command (port, HS_CLOSE, -1, HS_IDLE_CLOSED);
+	sx_send_command (port, HS_CLOSE, 0, 0);
 
 	if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) {
 		if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) {
@@ -1575,7 +1557,7 @@
 		} else
 			sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");
 	}
-
+	*/
 	MOD_DEC_USE_COUNT;
 	func_exit ();
 }
@@ -1611,6 +1593,11 @@
 	sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 
 	            5 * HZ - to - 1, port->gs.count);
 
+	if(port->gs.count) {
+		sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);
+		port->gs.count = 0;
+	}
+
 	MOD_DEC_USE_COUNT;
 	func_exit ();
 }
@@ -1953,10 +1940,7 @@
 	func_enter();
 
 	/* This is preceded by downloading the download code. */
-	/* 
-	 * The board should be set to initialized to make sure 
-	 * we can boot the other cards. --pvdl
-	 */ 
+
 	board->flags |= SX_BOARD_INITIALIZED;
 
 	if (read_sx_byte (board, 0))
@@ -2362,6 +2346,13 @@
 #ifdef NEW_WRITE_LOCKING
 			port->gs.port_write_sem = MUTEX;
 #endif
+			/*
+			 * Initializing wait queue
+			 */
+			/*
+			init_waitqueue_head(&port->gs.open_wait);
+			init_waitqueue_head(&port->gs.close_wait); 		
+			*/
 			port++;
 		}
 	}
@@ -2403,7 +2394,7 @@
 	return 0;
 }
 
-
+#ifdef MODULE
 static void sx_release_drivers(void)
 {
 	func_enter();
@@ -2411,6 +2402,7 @@
 	tty_unregister_driver(&sx_callout_driver);
 	func_exit();
 }
+#endif
 
 #ifdef TWO_ZERO
 #define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -2491,6 +2483,10 @@
 		while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
 		                                PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
 			                              pdev))) {
+		  /*
+			if (pci_enable_device(pdev))
+				continue;
+		  */
 #else
 			for (i=0;i< SX_NBOARDS;i++) {
 				if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
@@ -2526,10 +2522,14 @@
 				                      &tint);
 			else
 				pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
-				                      &tint);
-			board->hw_base = tint & PCI_BASE_ADDRESS_MEM_MASK;
+						      &tint);
 			board->base2 = 
 			board->base = (ulong) ioremap(board->hw_base, WINDOW_LEN (board));
+			if (!board->base) {
+				printk(KERN_ERR "ioremap failed\n");
+				/* XXX handle error */
+			}
+
 			/* Most of the stuff on the CF board is offset by
 			   0x18000 ....  */
 			if (IS_CF_BOARD (board)) board->base += 0x18000;
diff -urN linux-2.2.17-pre13/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- linux-2.2.17-pre13/drivers/char/tty_io.c	Wed Jun  7 14:26:42 2000
+++ linux/drivers/char/tty_io.c	Mon Dec  3 22:10:12 2001
@@ -135,6 +135,8 @@
 #ifdef CONFIG_HWC_CONSOLE
 extern long hwc_console_init(long);
 #endif
+extern int rio_init(void);
+extern int sx_init(void);
 
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
diff -urN linux-2.2.17-pre13/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- linux-2.2.17-pre13/drivers/i2o/i2o_block.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/i2o/i2o_block.c	Mon Dec  3 22:10:12 2001
@@ -166,13 +166,14 @@
 
 static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
 static void i2ob_end_request(struct request *);
-static void i2ob_request(struct request  * q);
+static void i2ob_request(void);
 static int do_i2ob_revalidate(kdev_t, int);
 static int i2ob_query_device(struct i2ob_device *, int, int, void*, int);
 static int i2ob_evt(void *);
 
 static int evt_pid = 0;
 static int evt_running = 0;
+static int scan_unit = 0;
 
 static void i2ob_new_device(struct i2o_controller *, struct i2o_device *);
 static void i2ob_del_device(struct i2o_controller *, struct i2o_device *);
@@ -375,14 +376,14 @@
 		
 	}
 
-	 if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
-	 {
-		  spin_lock(&i2ob_evt_lock);
-		  memcpy(&evt_msg, m, msg->size);
-		  spin_unlock(&i2ob_evt_lock);
-		  wake_up_interruptible(&i2ob_evt_wait);
-		  return;
-	 }
+	if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
+	{
+		spin_lock(&i2ob_evt_lock);
+		memcpy(&evt_msg, m, msg->size);
+		spin_unlock(&i2ob_evt_lock);
+		wake_up_interruptible(&i2ob_evt_wait);
+		return;
+	}
 	if(!dev->i2odev)
 	{
 		/*
@@ -404,18 +405,17 @@
 		return;
 	}
 		 
-		/*
-		 *      Lets see what is cooking. We stuffed the
-		 *      request in the context.
-		 */
+	/*
+	 *      Lets see what is cooking. We stuffed the
+	 *      request in the context.
+	 */
 
-		ireq=&i2ob_queue[m[3]];
-		st=m[4]>>24;
+	ireq=&i2ob_queue[m[3]];
+	st=m[4]>>24;
 	
-		if(st!=0)
-		{
-			char *bsa_errors[] =
-			{
+	if(st!=0)
+	{
+		char *bsa_errors[] = {
 			"Success",
 			"Media Error",
 			"Failure communicating to device",
@@ -430,59 +430,57 @@
 			"Device is write protected",
 			"Device has reset",
 			"Volume has changed, waiting for acknowledgement"
-			};
-			printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, bsa_errors[m[4]&0XFFFF]);
+		};
 
-			if(m[4]&0x00FF0000)
-				printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF);
-			printk("\n");
+		printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, bsa_errors[m[4]&0XFFFF]);
 
-			ireq->req->errors++;	
+		if(m[4]&0x00FF0000)
+			printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF);
+		printk("\n");
 
-			if (ireq->req->errors < MAX_I2OB_RETRIES)
-			{
-				u32 retry_msg;
+		ireq->req->errors++;	
+		if (ireq->req->errors < MAX_I2OB_RETRIES)
+		{
+			u32 retry_msg;
+			printk(KERN_ERR "i2ob: attempting retry %d for request %p\n",ireq->req->errors+1,ireq->req);
+    				
+			/* 
+			 * Get a message for this retry.
+			 */
+	  		retry_msg = i2ob_get(dev);
 
-  				printk(KERN_ERR "i2ob: attempting retry %d for request %p\n",ireq->req->errors+1,ireq->req);
-     				
-				  /* 
-				 * Get a message for this retry.
+	  		/* 
+			 * If we cannot get a message then
+			 * forget the retry and fail the
+			 * request.   Note that since this is
+			 * being called from the interrupt 
+			 * handler, a request has just been 
+			 * completed and there will most likely 
+			 * be space on the inbound message
+			 * fifo so this won't happen often.
+			 */
+	  		if(retry_msg!=0xFFFFFFFF)
+			{
+				/*
+				 * Decrement the queue depth since
+				 * this request has completed and
+				 * it will be incremented again when
+				 * i2ob_send is called below.
 				 */
-		  		retry_msg = i2ob_get(dev);
-
-		  		/* 
-				 * If we cannot get a message then
-				 * forget the retry and fail the
-				 * request.   Note that since this is
-				 * being called from the interrupt 
-				 * handler, a request has just been 
-				 * completed and there will most likely 
-				 * be space on the inbound message
-				 * fifo so this won't happen often.
+				atomic_dec(&queue_depth);
+				/*
+				 * Send the request again.
 				 */
-		  		if(retry_msg!=0xFFFFFFFF)
-				{
-					  /*
-					   * Decrement the queue depth since
-					   * this request has completed and
-					   * it will be incremented again when
-					   * i2ob_send is called below.
-					   */
-					  atomic_dec(&queue_depth);
-
-					  /*
-					   * Send the request again.
-					   */
-					  i2ob_send(retry_msg, dev,ireq,i2ob[unit].start_sect, (unit&0xF0));
-					/*
-					 * Don't fall through.
-					 */
-					return;
-				}
-			}		
-		}
-		else
-			ireq->req->errors = 0;
+				i2ob_send(retry_msg, dev,ireq,i2ob[unit].start_sect, (unit&0xF0));
+				/*
+				 * Don't fall through.
+				 */
+				return;
+			}
+		}		
+	}
+	else
+		ireq->req->errors = 0;
 		
 	/*
 	 *	Dequeue the request. We use irqsave locks as one day we
@@ -498,7 +496,7 @@
 	 */
 	 
 	atomic_dec(&queue_depth);
-	i2ob_request(NULL);
+	i2ob_request();
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
@@ -675,7 +673,7 @@
 	/* 
 	 * Restart any requests.
 	 */
-	i2ob_request(NULL);
+	i2ob_request();
 
 	/* 
 	 * Free the lock.
@@ -691,7 +689,7 @@
  *	we use it.
  */
 
-static void i2ob_request(struct request * q)
+static void i2ob_request(void)
 {
 	unsigned long flags;
 	struct request *req;
@@ -732,10 +730,9 @@
 			CURRENT = CURRENT->next;
 			req->sem = NULL;	
 			i2ob_end_request(req);	
+			continue;
 		}
 
-		else
-		{
 		/* Get a message */
 		m = i2ob_get(dev);
 
@@ -778,7 +775,6 @@
 		ireq->req = req;
 
 		i2ob_send(m, dev, ireq, i2ob[unit].start_sect, (unit&0xF0));
-		} 
 	}
 }
 
@@ -1193,9 +1189,8 @@
 static int i2ob_scan(int bios)
 {
 	int i;
-	int unit = 0;
 	int warned = 0;
-	struct i2o_device *d, *b;
+	struct i2o_device *d, *b=NULL;
 	struct i2o_controller *c;
 	struct i2ob_device *dev;
 		
@@ -1257,22 +1252,22 @@
 					bios?"Boot d":"D");
 				continue;
 			}
-			if(unit<MAX_I2OB<<4)
+			if(scan_unit<MAX_I2OB<<4)
 			{
 				/*
 				 * Get the device and fill in the
 				 * Tid and controller.
 				 */
-				dev=&i2ob_dev[unit];
+				dev=&i2ob_dev[scan_unit];
 				dev->i2odev = d;
 				dev->controller = c;
 				dev->unit = c->unit;
 				dev->tid = d->lct_data.tid;
-				if(i2ob_install_device(c,d,unit))
+				if(i2ob_install_device(c,d,scan_unit))
 					printk(KERN_WARNING "Could not install I2O block device\n");
 				else
 				{
-					unit+=16;
+					scan_unit+=16;
 					i2ob_dev_count++;
 					/* We want to know when device goes away */
 					i2o_device_notify_on(d, &i2o_block_handler);
@@ -1281,12 +1276,13 @@
 			else
 			{
 				if(!warned++)
-					printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", unit>>4);
+					printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", scan_unit>>4);
 			}
 			i2o_release_device(d, &i2o_block_handler);
 		}
 		i2o_unlock_controller(c);
 	}
+	return 0;
 }
 
 static void i2ob_probe(void)
diff -urN linux-2.2.17-pre13/drivers/i2o/i2o_scsi.h linux/drivers/i2o/i2o_scsi.h
--- linux-2.2.17-pre13/drivers/i2o/i2o_scsi.h	Mon Dec  3 22:10:05 2001
+++ linux/drivers/i2o/i2o_scsi.h	Mon Dec  3 22:10:12 2001
@@ -5,7 +5,9 @@
 #include <linux/version.h>
 #endif
 
+#ifndef LinuxVersionCode
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#endif
 
 #include <linux/types.h>
 #include <linux/kdev_t.h>
diff -urN linux-2.2.17-pre13/drivers/isdn/isdn_cards.c linux/drivers/isdn/isdn_cards.c
--- linux-2.2.17-pre13/drivers/isdn/isdn_cards.c	Wed Aug 25 17:29:48 1999
+++ linux/drivers/isdn/isdn_cards.c	Mon Dec  3 22:10:12 2001
@@ -75,6 +75,7 @@
 extern void capi_init(void);
 extern void capidrv_init(void);
 #endif
+extern void act2000_init(void);
 
 void
 isdn_cards_init(void)
diff -urN linux-2.2.17-pre13/drivers/isdn/isdn_ppp.h linux/drivers/isdn/isdn_ppp.h
--- linux-2.2.17-pre13/drivers/isdn/isdn_ppp.h	Wed Jun  7 14:26:43 2000
+++ linux/drivers/isdn/isdn_ppp.h	Mon Dec  3 22:10:12 2001
@@ -76,6 +76,7 @@
  */
 
 #include <linux/ppp_defs.h>     /* for PPP_PROTOCOL */
+#include <linux/isdn_ppp.h>
 extern int isdn_ppp_read(int, struct file *, char *, int);
 extern int isdn_ppp_write(int, struct file *, const char *, int);
 extern int isdn_ppp_open(int, struct file *);
diff -urN linux-2.2.17-pre13/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- linux-2.2.17-pre13/drivers/macintosh/via-pmu.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/macintosh/via-pmu.c	Mon Dec  3 22:10:12 2001
@@ -107,6 +107,7 @@
 static int pmu_has_adb, pmu_has_backlight;
 static unsigned char *gpio_reg = NULL;
 static int gpio_irq = -1;
+static int irq_flag = 0;
 
 int asleep;
 
@@ -242,7 +243,7 @@
 
 		pmu_kind = PMU_KEYLARGO_BASED;
 		pmu_has_adb = (find_type_devices("adb") != NULL);
-		pmu_has_backlight = (find_type_devices("backlight") != NULL);
+		pmu_has_backlight = 0; /* Not driven by PMU */
 
 		gpiop = find_devices("gpio");
 		if (gpiop && gpiop->n_addrs) {
@@ -303,6 +304,11 @@
 
 	/* Enable backlight */
 	pmu_enable_backlight(1);
+
+	/* Make sure PMU settle down before continuing */
+	do {
+		pmu_poll();
+	} while (pmu_state != idle);
 }
 
 static int __openfirmware
@@ -632,43 +638,49 @@
 	int nloop = 0;
 	unsigned long flags;
 
-	/* Currently, we use brute-force cli() for syncing with GPIO
-	 * interrupt. I'll make this smarter later, along with some
-	 * spinlocks for SMP */
-	save_flags(flags);cli();
-	++disable_poll;
-	while ((intr = in_8(&via[IFR])) != 0) {
-		if (++nloop > 1000) {
-			printk(KERN_DEBUG "PMU: stuck in intr loop, "
-			       "intr=%x pmu_state=%d\n", intr, pmu_state);
-			break;
+	/* This is my 2 cents brain dead synchronisation mecanism */
+	if (test_and_set_bit(0, &irq_flag))
+		return;
+
+	while(test_and_clear_bit(0, &irq_flag)) {
+		++disable_poll;
+		while ((intr = in_8(&via[IFR])) != 0) {
+			if (++nloop > 1000) {
+				printk(KERN_DEBUG "PMU: stuck in intr loop, "
+				       "intr=%x pmu_state=%d\n", intr, pmu_state);
+				break;
+			}
+			if (intr & SR_INT)
+				pmu_sr_intr(regs);
+			else if (intr & CB1_INT) {
+				adb_int_pending = 1;
+				out_8(&via[IFR], CB1_INT);
+			}
+			intr &= ~(SR_INT | CB1_INT);
+			if (intr != 0) {
+				out_8(&via[IFR], intr);
+			}
 		}
-		if (intr & SR_INT)
-			pmu_sr_intr(regs);
-		else if (intr & CB1_INT) {
+		if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
 			adb_int_pending = 1;
-			out_8(&via[IFR], CB1_INT);
-		}
-		intr &= ~(SR_INT | CB1_INT);
-		if (intr != 0) {
-			out_8(&via[IFR], intr);
-		}
-	}
-	if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
-		adb_int_pending = 1;
 
-	if (pmu_state == idle) {
-		if (adb_int_pending) {
-			pmu_state = intack;
-			send_byte(PMU_INT_ACK);
-			adb_int_pending = 0;
-		} else if (current_req) {
-			pmu_start();
+		/* A spinlock would be nicer ... */
+		save_flags(flags);
+		cli();
+		if (pmu_state == idle) {
+			if (adb_int_pending) {
+				pmu_state = intack;
+				send_byte(PMU_INT_ACK);
+				adb_int_pending = 0;
+			} else if (current_req) {
+				pmu_start();
+			}
 		}
+		restore_flags(flags);
+		--disable_poll;
 	}
-	--disable_poll;
-	restore_flags(flags);
 }
+
 
 static void __openfirmware
 gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
diff -urN linux-2.2.17-pre13/drivers/net/Space.c linux/drivers/net/Space.c
--- linux-2.2.17-pre13/drivers/net/Space.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/net/Space.c	Mon Dec  3 22:10:12 2001
@@ -57,6 +57,7 @@
 extern int eepro100_probe(struct device *);
 extern int el3_probe(struct device *);
 extern int at1500_probe(struct device *);
+extern int bond_init(struct device *);
 extern int pcnet32_probe(struct device *);
 extern int at1700_probe(struct device *);
 extern int fmv18x_probe(struct device *);
@@ -122,6 +123,7 @@
 extern int lance_probe(struct device *dev);
 extern int rcpci_probe(struct device *);
 extern int dmfe_probe(struct device *);
+extern int sktr_probe(struct device *dev);
 
 /* Gigabit Ethernet adapters */
 extern int yellowfin_probe(struct device *dev);
diff -urN linux-2.2.17-pre13/drivers/net/bonding.c linux/drivers/net/bonding.c
--- linux-2.2.17-pre13/drivers/net/bonding.c	Mon Dec  3 22:10:05 2001
+++ linux/drivers/net/bonding.c	Mon Dec  3 22:10:12 2001
@@ -4,7 +4,7 @@
  * Copyright 1999, Thomas Davis, tadavis@lbl.gov.  
  * Licensed under the GPL. Based on dummy.c, and eql.c devices.
  *
- * bond.c: a bonding/etherchannel/sun trunking net driver
+ * bonding.c: a bonding/etherchannel/sun trunking net driver
  *
  * This is useful to talk to a Cisco 5500, running Etherchannel, aka:
  *	Linux Channel Bonding
diff -urN linux-2.2.17-pre13/drivers/net/c101.c linux/drivers/net/c101.c
--- linux-2.2.17-pre13/drivers/net/c101.c	Wed Jun  7 14:26:43 2000
+++ linux/drivers/net/c101.c	Mon Dec  3 22:10:12 2001
@@ -73,21 +73,21 @@
 typedef card_t port_t;
 
 
-#define sca_in(reg, card)	     readb(card->win0base+C101_SCA+reg)
-#define sca_out(value, reg, card)    writeb(value, card->win0base+C101_SCA+reg)
-#define sca_inw(reg, card)	     readw(card->win0base+C101_SCA+reg)
-#define sca_outw(value, reg, card)   writew(value, card->win0base+C101_SCA+reg)
+#define sca_in(reg, card)	   readb((card)->win0base+C101_SCA+(reg))
+#define sca_out(value, reg, card)  writeb(value, (card)->win0base+C101_SCA+(reg))
+#define sca_inw(reg, card)	   readw((card)->win0base+C101_SCA+(reg))
+#define sca_outw(value, reg, card) writew(value, (card)->win0base+C101_SCA+(reg))
 
 #define port_to_card(port)	     (port)
 #define log_node(port)		     (0)
 #define phy_node(port)		     (0)
 #define winsize(card)		     (C101_WINDOW_SIZE)
-#define win0base(card)		     (card->win0base)
-#define winbase(card)      	     (card->win0base+0x2000)
-#define get_port(card, port)	     (port == 0 ? card : NULL)
+#define win0base(card)		     ((card)->win0base)
+#define winbase(card)      	     ((card)->win0base+0x2000)
+#define get_port(card, port)	     ((port) == 0 ? (card) : NULL)
 
 
-static __inline__ u8 get_page(card_t *card)
+static __inline__ u8 sca_get_page(card_t *card)
 {
 	return card->page;
 }
diff -urN linux-2.2.17-pre13/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- linux-2.2.17-pre13/drivers/net/ewrk3.c	Mon Aug  9 12:04:39 1999
+++ linux/drivers/net/ewrk3.c	Mon Dec  3 22:10:12 2001
@@ -846,9 +846,9 @@
 						}
 					}
 
+					lp->stats.tx_bytes += skb->len;
 					dev->trans_start = jiffies;
 					dev_kfree_skb(skb);
-
 				} else {	/* return unused page to the free memory queue */
 					outb(page, EWRK3_FMQ);
 				}
@@ -1029,6 +1029,7 @@
 						   ** Update stats
 						 */
 						lp->stats.rx_packets++;
+						lp->stats.rx_bytes += pkt_len;
 						for (i = 1; i < EWRK3_PKT_STAT_SZ - 1; i++) {
 							if (pkt_len < i * EWRK3_PKT_BIN_SZ) {
 								lp->pktStats.bins[i]++;
diff -urN linux-2.2.17-pre13/drivers/net/gmac.c linux/drivers/net/gmac.c
--- linux-2.2.17-pre13/drivers/net/gmac.c	Mon Dec  3 22:10:06 2001
+++ linux/drivers/net/gmac.c	Mon Dec  3 22:10:12 2001
@@ -290,7 +290,7 @@
 	if (power_up) {
 		out_le32(gm->sysregs + 0x20/4,
 			in_le32(gm->sysregs + 0x20/4) | 0x02000000);
-		udelay(10);
+		udelay(20);
 		if (gm->pci_devfn != 0xff) {
 			u16 cmd;
 			
@@ -310,6 +310,7 @@
 		gm->phy_type = 0;
 		out_le32(gm->sysregs + 0x20/4,
 			in_le32(gm->sysregs + 0x20/4) & ~0x02000000);
+		udelay(20);
 	}
 }
 
@@ -396,6 +397,7 @@
 	GM_OUT(GM_RX_CONF,
 		(RX_OFFSET << GM_RX_CONF_FBYTE_OFF_SHIFT) |
 		(0x22 << GM_RX_CONF_CHK_START_SHIFT) |
+		(GM_RX_CONF_DMA_THR_DEFAULT << GM_RX_CONF_DMA_THR_SHIFT) |
 		NRX_CONF);
 
 	/* Configure other bits of MAC */
@@ -495,6 +497,10 @@
 	ring = (struct gmac_dma_desc *) gm->txring;
 	memset(ring, 0, NTX * sizeof(struct gmac_dma_desc));
 
+	gm->next_rx = 0;
+	gm->next_tx = 0;
+	gm->tx_gone = 0;
+
 	/* set pointers in chip */
 	mb();
 	GM_OUT(GM_RX_DESC_HI, 0);
@@ -552,14 +558,13 @@
 	unsigned long crc;
 	int multicast_hash = 0;
 	int multicast_all = 0;
-
+	int promisc = 0;
+	
 	/* Lock out others. */
 	set_bit(0, (void *) &dev->tbusy);
 
-	gm->promisc = 0;
-
 	if (dev->flags & IFF_PROMISC)
-		gm->promisc = 1;
+		promisc = 1;
 	else if ((dev->flags & IFF_ALLMULTI) /* || (dev->mc_count > XXX) */) {
 		multicast_all = 1;
 	} else {
@@ -591,7 +596,7 @@
 	    	multicast_hash = 1;
 	}
 
-	if (gm->promisc)
+	if (promisc)
 		GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL);
 	else
 		GM_BIC(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL);
@@ -632,7 +637,6 @@
 
 	gm->full_duplex = 0;
 	gm->phy_status = 0;
-	gm->promisc = 0;
 	
 	/* Find a PHY */
 	if (!mii_lookup_and_reset(gm))
@@ -641,12 +645,12 @@
 	/* Configure the PHY */
 	mii_setup_phy(gm);
 	
-	/* Initialize the MAC */
-	gmac_mac_init(gm, dev->dev_addr);
-	
 	/* Initialize the descriptor rings */
 	gmac_init_rings(gm, 0);
 
+	/* Initialize the MAC */
+	gmac_mac_init(gm, dev->dev_addr);
+	
 	/* Initialize the multicast tables & promisc mode if any */
 	gmac_set_multicast(dev);
 	
@@ -706,7 +710,7 @@
 gmac_tx_timeout(struct device *dev)
 {
 	struct gmac *gm = (struct gmac *) dev->priv;
-	int i;
+	int i, timeout;
 	unsigned long flags;
 
 	save_flags(flags);
@@ -731,8 +735,24 @@
 			gm->rx_buff[i] = 0;
 		}
 	}
+	/* Perform a software reset */
+	GM_OUT(GM_RESET, GM_RESET_TX | GM_RESET_RX);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mdelay(10);
+		if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) {
+			/* Mask out all chips interrupts */
+			GM_OUT(GM_IRQ_MASK, 0xffffffff);
+			break;
+		}
+	}
+	if (!timeout)
+		printk(KERN_ERR "%s reset chip failed !\n", dev->name);
 	/* Create fresh rings */
 	gmac_init_rings(gm, 1);
+	/* re-initialize the MAC */
+	gmac_mac_init(gm, dev->dev_addr);	
+	/* re-initialize the multicast tables & promisc mode if any */
+	gmac_set_multicast(dev);
 	/* Restart PHY auto-poll */
 	mii_interrupt(gm);
 	/* Restart chip */
@@ -832,10 +852,11 @@
 	int i = gm->next_rx;
 	volatile struct gmac_dma_desc *dp;
 	struct sk_buff *skb, *new_skb;
-	int len, flags, drop;
+	int len, flags, drop, last;
 	unsigned char *data;
 	u16 csum;
-	
+
+	last = -1;
 	for (;;) {
 		dp = &gm->rxring[i];
 		if (ld_le32(&dp->size) & RX_SZ_OWN)
@@ -931,10 +952,15 @@
 			++gm->stats.rx_packets;
 		}
 		
+		last = i;
 		if (++i >= NRX)
 			i = 0;
 	}
 	gm->next_rx = i;
+	if (last >= 0) {
+		mb();
+		GM_OUT(GM_RX_KICK, last & 0xfffffffc);
+	}
 }
 
 static void
@@ -952,7 +978,8 @@
 	}
 
 	status = GM_IN(GM_IRQ_STATUS);
-	GM_OUT(GM_IRQ_ACK, status);
+	if (status & (GM_IRQ_BUS_ERROR | GM_IRQ_MIF))
+		GM_OUT(GM_IRQ_ACK, status & (GM_IRQ_BUS_ERROR | GM_IRQ_MIF));
 	
 	if (status & (GM_IRQ_RX_TAG_ERR | GM_IRQ_BUS_ERROR)) {
 		printk(KERN_ERR "%s: IRQ Error status: 0x%08x\n",
diff -urN linux-2.2.17-pre13/drivers/net/gmac.h linux/drivers/net/gmac.h
--- linux-2.2.17-pre13/drivers/net/gmac.h	Mon Dec  3 22:10:06 2001
+++ linux/drivers/net/gmac.h	Mon Dec  3 22:10:12 2001
@@ -216,13 +216,16 @@
 #define GM_RX_PTH_UNITS			64
 
 /* -- 0x4100	RW	Rx Kick
- * d: 0x00000000	Written by the host with the last tx descriptor number +1 to send
- *					Must be a multiple of 4
+ * d: 0x00000000	The last valid RX descriptor is the one right before the value of the
+ *                      register. Initially set to 0 on reset. RX descriptors must be posted
+ *                      in multiples of 4. The first descriptor should be cache-line aligned
+ *                      for best performance.
  */
 #define GM_RX_KICK			(0x4100 | REG_SZ_16)
 
 /* -- 0x4104	RW	Rx Completion
- * d: 0x00000000	Written by the gmac with the last tx descriptor number +1 sent
+ * d: 0x00000000	All descriptors upto but excluding the register value are ready to be
+ *                      processed by the host.
  */
 #define GM_RX_COMP			(0x4104 | REG_SZ_16)
  
@@ -231,7 +234,7 @@
  *
  * Defines the values used for receive interrupt blanking.
  * For INTR_TIME field, every count is 2048 PCI clock time. For 66 Mhz, each
- * count is about 16 us.
+ * count is about 15 ns.
  */
 #define GM_RX_BLANK			(0x4108 | REG_SZ_32)
 			/*
@@ -251,7 +254,7 @@
 
 /* -- 0x4120	RO	Rx fifo size
  *
- * This 11-bit RO register indicates the size, in 64-bit multiples, of the
+ * This 11-bit RO register indicates the size, in 64-byte multiples, of the
  * RX FIFO. Software should use it to properly configure the PAUSE thresholds.
  * The value read is 0x140, indicating a 20kbyte RX FIFO.
  * -------------------------------------------------------------------------
@@ -842,7 +845,6 @@
 	int				phy_type;
 	int				phy_status;	/* Cached PHY status */
 	int				full_duplex;	/* Current set to full duplex */
-	int				promisc;
 	struct net_device_stats		stats;
 	u8				pci_bus;
 	u8				pci_devfn;
diff -urN linux-2.2.17-pre13/drivers/net/hd6457x.c linux/drivers/net/hd6457x.c
--- linux-2.2.17-pre13/drivers/net/hd6457x.c	Mon Dec  3 22:10:06 2001
+++ linux/drivers/net/hd6457x.c	Mon Dec  3 22:10:12 2001
@@ -406,7 +406,7 @@
 	u8 stat;
 
 #ifndef ALL_PAGES_ALWAYS_MAPPED
-	u8 page = get_page(card);
+	u8 page = sca_get_page(card);
 #endif
   
 	while((stat = sca_intr_status(card)) != 0) {
@@ -606,7 +606,7 @@
 #ifdef DEBUG_RINGS
 	default:
 #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
-		page=get_page(card);
+		page=sca_get_page(card);
 		openwin(card, 0);
 #endif
 
diff -urN linux-2.2.17-pre13/drivers/net/hdlc.c linux/drivers/net/hdlc.c
--- linux-2.2.17-pre13/drivers/net/hdlc.c	Mon Dec  3 22:10:06 2001
+++ linux/drivers/net/hdlc.c	Mon Dec  3 22:10:12 2001
@@ -41,7 +41,7 @@
 #ifndef MODULE
 static int version_printed=0;
 #endif
-static const char* version = "HDLC support routines revision: 1.0a1";
+static const char* version = "HDLC support routines revision: 1.0";
 
 
 #define CISCO_MULTICAST         0x8f    /* Cisco multicast address */
@@ -69,7 +69,10 @@
 	
 	skb_push(skb, sizeof(hdlc_header));
 	data=(hdlc_header*)skb->data;
-	data->address = CISCO_MULTICAST;
+	if (type == CISCO_KEEPALIVE)
+		data->address = CISCO_MULTICAST;
+	else
+		data->address = CISCO_UNICAST;
 	data->control = 0;
 	data->protocol = htons(type);
 	
@@ -1025,20 +1028,9 @@
 
 		switch(mode & ~MODE_SOFT) {
 		case MODE_CISCO:
-			result = hdlc->set_mode ?
-				hdlc->set_mode(hdlc, MODE_HDLC) : 0;
-			break;
-
 		case MODE_PPP:
-			result = hdlc->set_mode ?
-				hdlc->set_mode(hdlc, MODE_PPP) : 0;
-			break;
-	
-		case MODE_X25:
-			result = hdlc->set_mode ?
-				hdlc->set_mode(hdlc, MODE_X25) : 0;
 			break;
-	
+
 		case MODE_FR_ANSI:
 		case MODE_FR_CCITT:
 		case MODE_FR_ANSI  | MODE_DCE:
@@ -1046,13 +1038,14 @@
 			hdlc_to_dev(hdlc)->addr_len=2;
 			*(u16*)hdlc_to_dev(hdlc)->dev_addr=htons(LMI_DLCI);
 			dlci_to_q922(hdlc_to_dev(hdlc)->broadcast, LMI_DLCI);
-			result = hdlc->set_mode ?
-				hdlc->set_mode(hdlc, MODE_HDLC) : 0;
 			break;
 
 		default:
 			return -EINVAL;
 		}
+
+		result = hdlc->set_mode ?
+			hdlc->set_mode(hdlc, MODE_HDLC) : 0;
 	}
 
 	if (result)
diff -urN linux-2.2.17-pre13/drivers/net/n2.c linux/drivers/net/n2.c
--- linux-2.2.17-pre13/drivers/net/n2.c	Wed Jun  7 14:26:43 2000
+++ linux/drivers/net/n2.c	Mon Dec  3 22:10:12 2001
@@ -122,23 +122,23 @@
 
 
 
-#define sca_reg(reg, card) (0x8000 | card->io | \
+#define sca_reg(reg, card) (0x8000 | (card)->io | \
 			    ((reg)&0x0F) | (((reg)&0xF0) << 6))
 #define sca_in(reg, card)		readb(sca_reg(reg, card))
 #define sca_out(value, reg, card)	writeb(value, sca_reg(reg, card))
 #define sca_inw(reg, card)		readw(sca_reg(reg, card))
 #define sca_outw(value, reg, card)	writew(value, sca_reg(reg, card))
 
-#define port_to_card(port)		(port->card)
-#define log_node(port)			(port->log_node)
-#define phy_node(port)			(port->phy_node)
+#define port_to_card(port)		((port)->card)
+#define log_node(port)			((port)->log_node)
+#define phy_node(port)			((port)->phy_node)
 #define winsize(card)			(USE_WINDOWSIZE)
-#define winbase(card)      	     	(card->winbase)
-#define get_port(card, port)		(card->ports[port].valid ? \
-					 &card->ports[port] : NULL)
+#define winbase(card)      	     	((card)->winbase)
+#define get_port(card, port)		((card)->ports[port].valid ? \
+					 &(card)->ports[port] : NULL)
 
 
-static __inline__ u8 get_page(card_t *card)
+static __inline__ u8 sca_get_page(card_t *card)
 {
 	return inb(card->io+N2_PSR) & PSR_PAGEBITS;
 }
diff -urN linux-2.2.17-pre13/drivers/net/slhc.c linux/drivers/net/slhc.c
--- linux-2.2.17-pre13/drivers/net/slhc.c	Wed Jun  7 14:26:43 2000
+++ linux/drivers/net/slhc.c	Mon Dec  3 22:10:12 2001
@@ -56,6 +56,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <net/slhc_vj.h>
 
 #ifdef CONFIG_INET
 /* Entire module is for IP only */
@@ -79,7 +80,6 @@
 #include <asm/uaccess.h>
 #include <linux/mm.h>
 #include <net/checksum.h>
-#include <net/slhc_vj.h>
 #include <asm/unaligned.h>
 
 int last_retran;
diff -urN linux-2.2.17-pre13/drivers/pnp/parport_probe.c linux/drivers/pnp/parport_probe.c
--- linux-2.2.17-pre13/drivers/pnp/parport_probe.c	Wed May  3 17:16:43 2000
+++ linux/drivers/pnp/parport_probe.c	Mon Dec  3 22:10:12 2001
@@ -7,6 +7,7 @@
 
 #include <linux/tasks.h>
 #include <linux/parport.h>
+#include <linux/parport_pc.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
diff -urN linux-2.2.17-pre13/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- linux-2.2.17-pre13/drivers/scsi/3w-xxxx.c	Wed May  3 17:16:44 2000
+++ linux/drivers/scsi/3w-xxxx.c	Mon Dec  3 22:10:12 2001
@@ -2,6 +2,8 @@
    3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
 
    Written By: Adam Radford <linux@3ware.com>
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
    Copyright (C) 1999-2000 3ware Inc.
 
    Kernel compatablity By: 	Andre Hedrick <andre@suse.com>
@@ -47,6 +49,19 @@
 
    For more information, goto:
    http://www.3ware.com
+
+   History
+   -------
+   0.1.000 -     Initial release.
+   0.4.000 -     Added support for Asynchronous Event Notification through
+                 ioctls for 3DM.
+   1.0.000 -     Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
+                 to disable drive write-cache before writes.
+   1.1.000 -     Fixed performance bug with DPO & FUA not existing for WRITE_6.
+   1.2.000 -     Added support for clean shutdown notification/feature table.
+   1.02.00.001 - Added support for full command packet posts through ioctls
+                 for 3DM.
+                 Bug fix so hot spare drives don't show up.
 */
 
 #include <linux/module.h>
@@ -65,6 +80,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
+#include <linux/reboot.h>
 
 #include <asm/spinlock.h>
 #include <asm/errno.h>
@@ -83,6 +99,12 @@
 static int tw_copy_info(TW_Info *info, char *fmt, ...);
 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
+
+/* Notifier block to get a notify on system shutdown/halt/reboot */
+static struct notifier_block tw_notifier = {
+  tw_halt, NULL, 0
+};
 
 struct proc_dir_entry tw_scsi_proc_entry = {
 	PROC_SCSI_3W_XXXX,
@@ -91,7 +113,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.1.000";
+char *tw_driver_version="1.02.00.001";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -230,7 +252,7 @@
 				if (command_packet->status != 0) {
 					if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
 						/* Bad response */
-						printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, flags = 0x%x.\n", command_packet->flags);
+						printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 						return 1;
 					} else {
 						/* We know this is a 3w-1x00, and doesn't support aen's */
@@ -568,6 +590,7 @@
 	TW_Device_Extension *tw_dev2;
 	struct pci_dev *tw_pci_dev = pci_devices;
 	u32 status_reg_value;
+	unsigned char c = 1;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
 	while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) {
@@ -666,7 +689,7 @@
 			continue;
 		}
 
-		error = tw_initconnection(tw_dev);
+		error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
 		if (error) {
 			printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards);
 			release_region((tw_dev->tw_pci_dev->base_address[0]), TW_IO_ADDRESS_RANGE);
@@ -726,10 +749,14 @@
 		/* Free the temporary device extension */
 		if (tw_dev)
 			kfree(tw_dev);
+		/* Tell the firmware we support shutdown notification*/
+		tw_setfeature(tw_dev, 2, 1, &c);
 	}
 
 	if (numcards == 0) 
 		printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n");
+	else
+	  register_reboot_notifier(&tw_notifier);
 
 	return numcards;
 } /* End tw_findcards() */
@@ -751,8 +778,22 @@
 	}
 } /* End tw_free_device_extension() */
 
+/* Clean shutdown routine */
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+	int i;
+	
+	for (i=0;i<tw_device_extension_count;i++) {
+		printk(KERN_NOTICE "3w-xxxx: Notifying card #%d\n", i);
+		tw_shutdown_device(tw_device_extension_list[i]);
+	}
+	unregister_reboot_notifier(&tw_notifier);
+	
+	return NOTIFY_OK;
+} /* End tw_halt() */
+
 /* This function will send an initconnection command to controller */
-int tw_initconnection(TW_Device_Extension *tw_dev) 
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits) 
 {
 	u32 command_que_addr, command_que_value;
 	u32 status_reg_addr, status_reg_value;
@@ -784,7 +825,7 @@
 	command_packet->byte3.host_id = 0x0;
 	command_packet->status = 0x0;
 	command_packet->flags = 0x0;
-	command_packet->byte6.message_credits = TW_INIT_MESSAGE_CREDITS; 
+	command_packet->byte6.message_credits = message_credits; 
 	command_packet->byte8.init_connection.response_queue_pointer = 0x0;
 	command_que_value = tw_dev->command_packet_physical_address[request_id];
 
@@ -815,7 +856,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, flags = 0x%x.\n", command_packet->flags);
+				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				return 1;
 			}
 			break;	/* Response was okay, so we exit */
@@ -962,7 +1003,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, flags = 0x%x.\n", command_packet->flags);
+				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				return 1;
 			}
 			found = 1;
@@ -984,9 +1025,11 @@
 		if (is_unit_present[i] == 0) {
 			tw_dev->is_unit_present[i] = FALSE;
 		} else {
+		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
 			dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
 			tw_dev->is_unit_present[i] = TRUE;
 			num_units++;
+		  }
 		}
 	}
 	tw_dev->num_units = num_units;
@@ -1090,7 +1133,7 @@
 				request_id = response_que.u.response_id;
 				command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 				if (command_packet->status != 0) {
-					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, flags = 0x%x.\n", command_packet->flags);
+					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				}
 				if (tw_dev->state[request_id] != TW_S_POSTED) {
 					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
@@ -1186,7 +1229,7 @@
 	/* Initialize command packet */
 	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 	if (command_packet == NULL) {
-		printk(KERN_WARNING "3w-xxxx: twioctl(): Bad command packet virtual address.\n");
+		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
 		tw_dev->state[request_id] = TW_S_COMPLETED;
 		tw_state_request_finish(tw_dev, request_id);
 		tw_dev->srb[request_id]->result = (DID_OK << 16);
@@ -1256,6 +1299,12 @@
 			tw_dev->srb[request_id]->result = (DID_OK << 16);
 			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
 			return 0;
+		case TW_CMD_PACKET:
+		  memcpy(command_packet, ioctl->data, sizeof(TW_Command));
+		  command_packet->request_id = request_id;
+		  tw_post_command_packet(tw_dev, request_id);
+		
+		  return 0;
 		default:
 			printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
 			tw_dev->state[request_id] = TW_S_COMPLETED;
@@ -1480,7 +1529,7 @@
 		return 1;
 	}
 
-	error = tw_initconnection(tw_dev);
+	error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
 	if (error) {
 		printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
 		return 1;
@@ -1804,6 +1853,11 @@
 	/* Tell kernel scsi-layer we are gone */
 	scsi_unregister(tw_host);
 
+	/* Fake like we just shut down, so notify the card that
+	 * we "shut down cleanly".
+	 */
+	tw_halt(0, 0, 0);  // parameters aren't actually used
+
 	return 0;
 } /* End tw_scsi_release() */
 
@@ -1901,8 +1955,10 @@
 		if (is_unit_present[i] == 0) {
 			tw_dev->is_unit_present[i] = FALSE;
 		} else {
+		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
 			tw_dev->is_unit_present[i] = TRUE;
 			dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
+		  }
 		}
 	}
 
@@ -2125,6 +2181,92 @@
 	return 0;
 } /* End tw_scsiop_test_unit_ready() */
 
+/* Set a value in the features table */
+int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
+                  unsigned char *val)
+{
+	TW_Param *param;
+	TW_Command  *command_packet;
+	TW_Response_Queue response_queue;
+	int request_id = 0;
+	u32 command_que_value, command_que_addr;
+	u32 status_reg_addr, status_reg_value;
+	u32 response_que_addr;
+	u32 param_value;
+	int imax, i;
+
+	/* Initialize SetParam command packet */
+	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
+		return 1;
+	}
+	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+	memset(command_packet, 0, sizeof(TW_Sector));
+	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+
+	command_packet->byte0.opcode = TW_OP_SET_PARAM;
+	command_packet->byte0.sgl_offset  = 2;
+	param->table_id = 0x404;  /* Features table */
+	param->parameter_id = parm;
+	param->parameter_size_bytes = param_size;
+	memcpy(param->data, val, param_size);
+
+	param_value = tw_dev->alignment_physical_address[request_id];
+	if (param_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		tw_state_request_finish(tw_dev, request_id);
+		tw_dev->srb[request_id]->result = (DID_OK << 16);
+		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+	}
+	command_packet->byte8.param.sgl[0].address = param_value;
+	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+	command_packet->size = 4;
+	command_packet->request_id = request_id;
+	command_packet->byte6.parameter_count = 1;
+
+	command_que_value = tw_dev->command_packet_physical_address[request_id];
+	if (command_que_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
+		return 1;
+	}
+	command_que_addr = tw_dev->registers.command_que_addr;
+	status_reg_addr = tw_dev->registers.status_reg_addr;
+	response_que_addr = tw_dev->registers.response_que_addr;
+
+	/* Send command packet to the board */
+	outl(command_que_value, command_que_addr);
+
+	/* Poll for completion */
+	imax = TW_POLL_MAX_RETRIES;
+	for (i=0;i<imax;i++) {
+		mdelay(10);
+		status_reg_value = inl(status_reg_addr);
+		if (tw_check_bits(status_reg_value)) {
+			printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
+			return 1;
+		}
+		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+			response_queue.value = inl(response_que_addr);
+			request_id = (unsigned char)response_queue.u.response_id;
+			if (request_id != 0) {
+				/* unexpected request id */
+				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
+				return 1;
+			}
+			if (command_packet->status != 0) {
+				/* bad response */
+				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
+				return 1;
+			}
+			break; /* Response was okay, so we exit */
+		}
+	}
+
+	return 0;
+} /* End tw_setfeature() */
+
 /* This function will setup the interrupt handler */
 int tw_setup_irq(TW_Device_Extension *tw_dev)
 {
@@ -2140,6 +2282,29 @@
 	}
 	return 0;
 } /* End tw_setup_irq() */
+
+/* This function will tell the controller we're shutting down by sending
+   initconnection with a 1 */
+int tw_shutdown_device(TW_Device_Extension *tw_dev)
+{
+	int error;
+
+	/* Disable interrupts */
+	tw_disable_interrupts(tw_dev);
+
+	/* poke the board */
+	error = tw_initconnection(tw_dev, 1);
+	if (error) {
+		printk(KERN_WARNING "3w-xxxx: tw_shutdown_device(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
+	} else {
+		printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n");
+	}
+
+	/* Re-enable interrupts */
+	tw_enable_interrupts(tw_dev);
+
+	return 0;
+} /* End tw_shutdown_device() */
 
 /* This function will soft reset the controller */
 void tw_soft_reset(TW_Device_Extension *tw_dev) 
diff -urN linux-2.2.17-pre13/drivers/scsi/3w-xxxx.h linux/drivers/scsi/3w-xxxx.h
--- linux-2.2.17-pre13/drivers/scsi/3w-xxxx.h	Wed May  3 17:16:44 2000
+++ linux/drivers/scsi/3w-xxxx.h	Mon Dec  3 22:10:12 2001
@@ -2,7 +2,9 @@
    3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
    
    Written By: Adam Radford <linux@3ware.com>
-   Copyright (C) 1999 3ware Inc.
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
+   Copyright (C) 1999, 2000 3ware Inc.
 
    Kernel compatablity By:	Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
@@ -106,6 +108,7 @@
 #define TW_OP_SET_PARAM	      0x13
 #define TW_OP_SECTOR_INFO     0x1a
 #define TW_OP_AEN_LISTEN      0x1c
+#define TW_CMD_PACKET         0x1d
 
 /* Asynchronous Event Notification (AEN) Codes */
 #define TW_AEN_QUEUE_EMPTY       0x0000
@@ -135,7 +138,7 @@
 #define TW_BLOCK_SIZE			      0x200 /* 512-byte blocks */
 #define TW_IOCTL                              0x80
 #define TW_MAX_AEN_TRIES                      100
-
+#define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
 
 /* Macros */
@@ -305,7 +308,7 @@
 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
 int tw_findcards(Scsi_Host_Template *tw_host);
 void tw_free_device_extension(TW_Device_Extension *tw_dev);
-int tw_initconnection(TW_Device_Extension *tw_dev);
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits);
 int tw_initialize_device_extension(TW_Device_Extension *tw_dev);
 int tw_initialize_units(TW_Device_Extension *tw_dev);
 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id);
@@ -328,7 +331,9 @@
 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
+int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, unsigned char *val);
 int tw_setup_irq(TW_Device_Extension *tw_dev);
+int tw_shutdown_device(TW_Device_Extension *tw_dev);
 void tw_soft_reset(TW_Device_Extension *tw_dev);
 int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id);
 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
@@ -351,6 +356,8 @@
 	eh_strategy_handler : NULL,			\
 	eh_abort_handler : tw_scsi_eh_abort,		\
 	eh_device_reset_handler : NULL,			\
+        eh_bus_reset_handler : NULL,                    \
+        eh_host_reset_handler : tw_scsi_eh_reset,       \
 	abort : NULL,					\
 	reset : NULL,					\
 	slave_attach : NULL,				\
diff -urN linux-2.2.17-pre13/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- linux-2.2.17-pre13/drivers/scsi/eata.c	Tue Jan  4 10:12:19 2000
+++ linux/drivers/scsi/eata.c	Mon Dec  3 22:10:12 2001
@@ -915,7 +915,7 @@
    if (info.sign != EATA_SIGNATURE) return FALSE;
 
    if (DEV2H(info.data_len) < EATA_2_0A_SIZE) {
-      printk("%s: config structure size (%ld bytes) too short, detaching.\n",
+      printk("%s: config structure size (%d bytes) too short, detaching.\n",
              name, DEV2H(info.data_len));
       return FALSE;
       }
diff -urN linux-2.2.17-pre13/drivers/scsi/imm.c linux/drivers/scsi/imm.c
--- linux-2.2.17-pre13/drivers/scsi/imm.c	Fri May  7 10:57:42 1999
+++ linux/drivers/scsi/imm.c	Mon Dec  3 22:10:12 2001
@@ -32,6 +32,7 @@
 typedef struct {
     struct pardevice *dev;	/* Parport device entry         */
     int base;			/* Actual port address          */
+    int base_hi;		/* Hi Base address for ECP-ISA chipset */
     int mode;			/* Transfer mode                */
     int host;			/* Host number (for proc)       */
     Scsi_Cmnd *cur_cmd;		/* Current queued command       */
@@ -46,6 +47,7 @@
 #define IMM_EMPTY \
 {	dev:		NULL,		\
 	base:		-1,		\
+	base_hi:	0,		\
 	mode:		IMM_AUTODETECT,	\
 	host:		-1,		\
 	cur_cmd:	NULL,		\
@@ -63,6 +65,7 @@
 {IMM_EMPTY, IMM_EMPTY, IMM_EMPTY, IMM_EMPTY};
 
 #define IMM_BASE(x)	imm_hosts[(x)].base
+#define IMM_BASE_HI(x)     imm_hosts[(x)].base_hi
 
 int parbus_base[NO_HOSTS] =
 {0x03bc, 0x0378, 0x0278, 0x0000};
@@ -133,7 +136,7 @@
     }
   retry_entry:
     for (i = 0; pb; i++, pb = pb->next) {
-	int modes, ppb;
+	int modes, ppb, ppb_hi;
 
 	imm_hosts[i].dev =
 	    parport_register_device(pb, "imm", NULL, imm_wakeup,
@@ -158,6 +161,7 @@
 	    }
 	}
 	ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base;
+	ppb_hi = IMM_BASE_HI(i) = imm_hosts[i].dev->port->base_hi;
 	w_ctr(ppb, 0x0c);
 	modes = imm_hosts[i].dev->port->modes;
 
@@ -169,12 +173,12 @@
 	if (modes & PARPORT_MODE_PCPS2)
 	    imm_hosts[i].mode = IMM_PS2;
 
-	if (modes & PARPORT_MODE_PCECPPS2) {
-	    w_ecr(ppb, 0x20);
+	if (ppb_hi && modes & PARPORT_MODE_PCECPPS2) {
+	    w_ecr(ppb_hi, 0x20);
 	    imm_hosts[i].mode = IMM_PS2;
 	}
-	if (modes & PARPORT_MODE_PCECPEPP)
-	    w_ecr(ppb, 0x80);
+	if (ppb_hi && modes & PARPORT_MODE_PCECPEPP)
+	    w_ecr(ppb_hi, 0x80);
 
 	/* Done configuration */
 	imm_pb_release(i);
@@ -381,6 +385,9 @@
     return a;
 }
 
+/* 
+ * Clear EPP timeout bit. 
+ */
 static inline void epp_reset(unsigned short ppb)
 {
     int i;
@@ -390,19 +397,23 @@
     w_str(ppb, i & 0xfe);
 }
 
-static inline void ecp_sync(unsigned short ppb)
+/* 
+ * Wait for empty ECP fifo (if we are in ECP fifo mode only)
+ */
+static inline void ecp_sync(unsigned short hostno)
 {
-    int i;
+    int i, ppb_hi=IMM_BASE_HI(hostno);
 
-    if ((r_ecr(ppb) & 0xe0) != 0x80)
-	return;
+    if (ppb_hi == 0) return;
 
-    for (i = 0; i < 100; i++) {
-	if (r_ecr(ppb) & 0x01)
-	    return;
-	udelay(5);
+    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
+        for (i = 0; i < 100; i++) {
+	    if (r_ecr(ppb_hi) & 0x01)
+	        return;
+	    udelay(5);
+	}
+        printk("imm: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("imm: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int imm_byte_out(unsigned short base, const char *buffer, int len)
@@ -490,7 +501,7 @@
 	w_ctr(ppb, 0xc);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0xc);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     case IMM_NIBBLE:
@@ -552,7 +563,7 @@
 	w_ctr(ppb, 0x2c);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0x2c);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
@@ -1246,7 +1257,7 @@
 	    return 1;
 	}
 	imm_disconnect(host_no);
-	printk("imm: Communication established with ID %i using %s\n", loop,
+	printk("imm: Communication established at 0x%x with ID %i using %s\n", ppb, loop,
 	       IMM_MODE_STRING[imm_hosts[host_no].mode]);
 	imm_connect(host_no, CONNECT_EPP_MAYBE);
 	imm_reset_pulse(IMM_BASE(host_no));
diff -urN linux-2.2.17-pre13/drivers/scsi/imm.h linux/drivers/scsi/imm.h
--- linux-2.2.17-pre13/drivers/scsi/imm.h	Tue May 11 10:37:00 1999
+++ linux/drivers/scsi/imm.h	Mon Dec  3 22:10:12 2001
@@ -125,14 +125,15 @@
 #define r_str(x)        (unsigned char)inb((x)+1)
 #define r_ctr(x)        (unsigned char)inb((x)+2)
 #define r_epp(x)        (unsigned char)inb((x)+4)
-#define r_fifo(x)       (unsigned char)inb((x)+0x400)
-#define r_ecr(x)        (unsigned char)inb((x)+0x402)
+#define r_fifo(x)       (unsigned char)inb((x))   /* x must be base_hi */
+					/* On PCI is: base+0x400 != base_hi */
+#define r_ecr(x)        (unsigned char)inb((x)+2) /* x must be base_hi */
 
 #define w_dtr(x,y)      outb(y, (x))
 #define w_str(x,y)      outb(y, (x)+1)
 #define w_epp(x,y)      outb(y, (x)+4)
-#define w_fifo(x,y)     outb(y, (x)+0x400)
-#define w_ecr(x,y)      outb(y, (x)+0x402)
+#define w_fifo(x,y)     outb(y, (x))     /* x must be base_hi */
+#define w_ecr(x,y)      outb(y, (x)+0x2) /* x must be base_hi */
 
 #ifdef CONFIG_SCSI_IZIP_SLOW_CTR
 #define w_ctr(x,y)      outb_p(y, (x)+2)
diff -urN linux-2.2.17-pre13/drivers/scsi/ini9100u.h linux/drivers/scsi/ini9100u.h
--- linux-2.2.17-pre13/drivers/scsi/ini9100u.h	Mon Dec  3 22:10:06 2001
+++ linux/drivers/scsi/ini9100u.h	Mon Dec  3 22:10:12 2001
@@ -175,7 +175,9 @@
 #endif
 
 
+#ifndef VIRT_TO_BUS
 #define VIRT_TO_BUS(i)  (unsigned int) virt_to_bus((void *)(i))
+#endif
 #define ULONG   unsigned long
 #define USHORT  unsigned short
 #define UCHAR   unsigned char
diff -urN linux-2.2.17-pre13/drivers/scsi/inia100.h linux/drivers/scsi/inia100.h
--- linux-2.2.17-pre13/drivers/scsi/inia100.h	Mon Dec  3 22:10:06 2001
+++ linux/drivers/scsi/inia100.h	Mon Dec  3 22:10:12 2001
@@ -168,7 +168,9 @@
 #endif
 #endif
 
+#ifndef VIRT_TO_BUS
 #define VIRT_TO_BUS(i)  (unsigned int) virt_to_bus((void *)(i))
+#endif
 #define ULONG   unsigned long
 #define PVOID   void *
 #define USHORT  unsigned short
diff -urN linux-2.2.17-pre13/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
--- linux-2.2.17-pre13/drivers/scsi/ppa.c	Fri May  7 10:57:42 1999
+++ linux/drivers/scsi/ppa.c	Mon Dec  3 22:10:12 2001
@@ -125,7 +125,7 @@
     }
   retry_entry:
     for (i = 0; pb; i++, pb = pb->next) {
-	int modes, ppb;
+	int modes, ppb, ppb_hi;
 
 	ppa_hosts[i].dev =
 	    parport_register_device(pb, "ppa", NULL, ppa_wakeup,
@@ -150,6 +150,7 @@
 	    }
 	}
 	ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base;
+	ppb_hi =  ppa_hosts[i].dev->port->base_hi;
 	w_ctr(ppb, 0x0c);
 	modes = ppa_hosts[i].dev->port->modes;
 
@@ -162,11 +163,11 @@
 	    ppa_hosts[i].mode = PPA_PS2;
 
 	if (modes & PARPORT_MODE_PCECPPS2) {
-	    w_ecr(ppb, 0x20);
+	    w_ecr(ppb_hi, 0x20);
 	    ppa_hosts[i].mode = PPA_PS2;
 	}
 	if (modes & PARPORT_MODE_PCECPEPP)
-	    w_ecr(ppb, 0x80);
+	    w_ecr(ppb_hi, 0x80);
 
 	/* Done configuration */
 	ppa_pb_release(i);
@@ -322,8 +323,7 @@
 }
 
 /*
- * output a string, in whatever mode is available, according to the
- * PPA protocol. 
+ * Clear EPP Timeout Bit 
  */
 static inline void epp_reset(unsigned short ppb)
 {
@@ -334,19 +334,23 @@
     w_str(ppb, i & 0xfe);
 }
 
-static inline void ecp_sync(unsigned short ppb)
+/* 
+ * Wait for empty ECP fifo (if we are in ECP fifo mode only)
+ */
+static inline void ecp_sync(unsigned short hostno)
 {
-    int i;
+    int i, ppb_hi=ppa_hosts[hostno].dev->port->base_hi;
 
-    if ((r_ecr(ppb) & 0xe0) != 0x80)
-	return;
+    if (ppb_hi == 0) return;
 
-    for (i = 0; i < 100; i++) {
-	if (r_ecr(ppb) & 0x01)
-	    return;
-	udelay(5);
+    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
+        for (i = 0; i < 100; i++) {
+            if (r_ecr(ppb_hi) & 0x01)
+                return;
+            udelay(5);
+        }
+        printk("ppa: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("ppa: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int ppa_byte_out(unsigned short base, const char *buffer, int len)
@@ -421,7 +425,7 @@
 	w_ctr(ppb, 0xc);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0xc);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
@@ -474,7 +478,7 @@
 	w_ctr(ppb, 0x2c);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0x2c);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
diff -urN linux-2.2.17-pre13/drivers/scsi/ppa.h linux/drivers/scsi/ppa.h
--- linux-2.2.17-pre13/drivers/scsi/ppa.h	Tue May 11 10:36:59 1999
+++ linux/drivers/scsi/ppa.h	Mon Dec  3 22:10:12 2001
@@ -117,14 +117,15 @@
 #define r_str(x)        (unsigned char)inb((x)+1)
 #define r_ctr(x)        (unsigned char)inb((x)+2)
 #define r_epp(x)        (unsigned char)inb((x)+4)
-#define r_fifo(x)       (unsigned char)inb((x)+0x400)
-#define r_ecr(x)        (unsigned char)inb((x)+0x402)
+#define r_fifo(x)       (unsigned char)inb((x)) /* x must be base_hi */
+					/* On PCI is base+0x400 != base_hi */
+#define r_ecr(x)        (unsigned char)inb((x)+0x2) /* x must be base_hi */
 
 #define w_dtr(x,y)      outb(y, (x))
 #define w_str(x,y)      outb(y, (x)+1)
 #define w_epp(x,y)      outb(y, (x)+4)
-#define w_fifo(x,y)     outb(y, (x)+0x400)
-#define w_ecr(x,y)      outb(y, (x)+0x402)
+#define w_fifo(x,y)     outb(y, (x))	/* x must be base_hi */
+#define w_ecr(x,y)      outb(y, (x)+0x2)/* x must be base_hi */
 
 #ifdef CONFIG_SCSI_IZIP_SLOW_CTR
 #define w_ctr(x,y)      outb_p(y, (x)+2)
diff -urN linux-2.2.17-pre13/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- linux-2.2.17-pre13/drivers/scsi/scsi_ioctl.c	Tue Jan  4 10:12:21 2000
+++ linux/drivers/scsi/scsi_ioctl.c	Mon Dec  3 22:10:12 2001
@@ -403,6 +403,7 @@
 	return ioctl_probe(dev->host, arg);
     case SCSI_IOCTL_SEND_COMMAND:
 	if(!capable(CAP_SYS_ADMIN))  return -EACCES;
+	if(!capable(CAP_SYS_RAWIO))  return -EACCES;
 	return scsi_ioctl_send_command((Scsi_Device *) dev,
 				       (Scsi_Ioctl_Command *) arg);
     case SCSI_IOCTL_DOORLOCK:
diff -urN linux-2.2.17-pre13/drivers/scsi/tmscsim.c linux/drivers/scsi/tmscsim.c
--- linux-2.2.17-pre13/drivers/scsi/tmscsim.c	Fri Dec 25 16:41:39 1998
+++ linux/drivers/scsi/tmscsim.c	Mon Dec  3 22:10:12 2001
@@ -165,6 +165,7 @@
 #include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
+#include <scsi/scsicam.h>
 
 #include "dc390.h"
 
diff -urN linux-2.2.17-pre13/drivers/sound/Makefile linux/drivers/sound/Makefile
--- linux-2.2.17-pre13/drivers/sound/Makefile	Mon Dec  3 22:10:06 2001
+++ linux/drivers/sound/Makefile	Mon Dec  3 22:10:12 2001
@@ -61,7 +61,7 @@
 obj-$(CONFIG_SOUND_GUS)		+= gus.o ad1848.o
 obj-$(CONFIG_SOUND_MAD16)	+= mad16.o ad1848.o sb.o uart401.o
 obj-$(CONFIG_SOUND_VIA82CXXX)	+= via82cxxx.o sb.o uart401.o 
-obj-$(CONFIG_SOUND_YMPCI)	+= ymf_sb.o sb.o uart401.o ac97.o
+obj-$(CONFIG_SOUND_YMPCI)	+= ymfsb.o sb.o uart401.o ac97.o
 obj-$(CONFIG_SOUND_MAUI)	+= maui.o mpu401.o
 obj-$(CONFIG_SOUND_MPU401)	+= mpu401.o
 obj-$(CONFIG_SOUND_MSNDCLAS)	+= msnd.o msnd_classic.o
@@ -105,7 +105,7 @@
 # Declare multi-part drivers.
 
 list-multi	:= sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \
-    soundcore.o wavefront.o nm256.o via82cxxx.o \
+    soundcore.o wavefront.o nm256.o ymfsb.o via82cxxx.o \
 
 sound-objs	:= 							\
     dev_table.o soundcard.o sound_syms.o		\
@@ -123,7 +123,8 @@
 vidc_mod-objs	:= vidc.o vidc_audio.o vidc_fill.o vidc_mixer.o vidc_synth.o
 wavefront-objs  := wavfront.o wf_midi.o yss225.o
 nm256-objs	:= nm256_audio.o ac97.o
-via82cxxx-objs := via82cxxx_audio.o ac97.o
+via82cxxx-objs  := via82cxxx_audio.o ac97.o
+ymfsb-objs	:= ymf_sb.o ac97.o
 
 
 # Extract lists of the multi-part drivers.
@@ -214,6 +215,9 @@
 
 via82cxxx.o: $(via82cxxx-objs)
 	$(LD) -r -o $@ $(via82cxxx-objs)
+
+ymfsb.o: $(ymfsb-objs)
+	$(LD) -r -o $@ $(ymfsb-objs)
 
 # Firmware files that need translation
 #
diff -urN linux-2.2.17-pre13/drivers/sound/emu10k1/main.c linux/drivers/sound/emu10k1/main.c
--- linux-2.2.17-pre13/drivers/sound/emu10k1/main.c	Mon Dec  3 22:10:06 2001
+++ linux/drivers/sound/emu10k1/main.c	Mon Dec  3 22:10:12 2001
@@ -768,3 +768,10 @@
 
 module_init(emu10k1_init_module);
 module_exit(emu10k1_cleanup_module);
+
+#ifndef MODULE
+int __init init_emu10k1(void)
+{
+	return emu10k1_init_module();
+}
+#endif
diff -urN linux-2.2.17-pre13/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- linux-2.2.17-pre13/drivers/sound/i810_audio.c	Mon Dec  3 22:10:06 2001
+++ linux/drivers/sound/i810_audio.c	Mon Dec  3 22:10:12 2001
@@ -721,6 +721,9 @@
 	outl(virt_to_bus(&dmabuf->channel->sg[0]), state->card->iobase+dmabuf->channel->port+OFF_BDBAR);
 	outb(16, state->card->iobase+dmabuf->channel->port+OFF_LVI);
 	outb(0, state->card->iobase+dmabuf->channel->port+OFF_CIV);
+	
+	resync_dma_ptrs(state);
+	
 	if (rec) {
 		i810_rec_setup(state);
 	} else {
@@ -1561,7 +1564,7 @@
 		dmabuf->ossfragshift = 0;
 		dmabuf->ossmaxfrags  = 0;
 		dmabuf->subdivision  = 0;
-		i810_set_dac_rate(state, 48000);
+		i810_set_dac_rate(state, 8000);
 	}
 
 	if (file->f_mode & FMODE_READ) {
@@ -1570,7 +1573,7 @@
 		dmabuf->ossfragshift = 0;
 		dmabuf->ossmaxfrags  = 0;
 		dmabuf->subdivision  = 0;
-		i810_set_adc_rate(state, 48000);
+		i810_set_adc_rate(state, 8000);
 	}
 
 	state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
@@ -1733,6 +1736,8 @@
 		printk(KERN_ERR "i810_audio: AC'97 reset failed.\n");
 		return 0;
 	}
+	
+	udelay(500);
 	
 	inw(card->ac97base);
 
diff -urN linux-2.2.17-pre13/drivers/sound/maestro.c linux/drivers/sound/maestro.c
--- linux-2.2.17-pre13/drivers/sound/maestro.c	Wed Jun  7 14:26:43 2000
+++ linux/drivers/sound/maestro.c	Mon Dec  3 22:10:12 2001
@@ -3476,7 +3476,7 @@
 #ifdef MODULE
 int init_module(void)
 #else
-int SILLY_MAKE_INIT(init_maestro(void))
+SILLY_MAKE_INIT(int init_maestro(void))
 #endif
 {
 	struct pci_dev *pcidev = NULL;
diff -urN linux-2.2.17-pre13/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- linux-2.2.17-pre13/drivers/sound/sound_core.c	Mon Dec  3 22:10:06 2001
+++ linux/drivers/sound/sound_core.c	Mon Dec  3 22:10:12 2001
@@ -85,6 +85,9 @@
 #ifdef CONFIG_SOUND_FUSION
 extern int cs_probe(void);
 #endif
+#ifdef CONFIG_SOUND_EMU10K1
+extern int init_emu10k1(void);
+#endif
 
 /*
  *	Low level list operator. Scan the ordered list, find a hole and
@@ -448,6 +451,9 @@
 #endif
 #ifdef CONFIG_SOUND_FUSION
 	cs_probe();
+#endif
+#ifdef CONFIG_SOUND_EMU10K1
+	init_emu10k1();
 #endif
 	return 0;
 }
diff -urN linux-2.2.17-pre13/fs/isofs/dir.c linux/fs/isofs/dir.c
--- linux-2.2.17-pre13/fs/isofs/dir.c	Fri Apr 23 21:20:38 1999
+++ linux/fs/isofs/dir.c	Mon Dec  3 22:10:12 2001
@@ -7,6 +7,9 @@
  *
  *  Steve Beynon		       : Missing last directory entries fixed
  *  (stephen@askone.demon.co.uk)      : 21st June 1996
+ *
+ *  Go Taniguchi			: Move sector and boundarie error fixed
+ *  (go@turbolinux.co.jp)		: Jul 21 2000
  * 
  *  isofs directory handling functions
  */
@@ -160,9 +163,11 @@
 		de = (struct iso_directory_record *) (bh->b_data + offset);
 		if(first_de) inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
-		de_len = *(unsigned char *) de;
+		/* Check boundaries and get length. by GO! */
+		if (offset < bufsize) de_len = *(unsigned char *) de;
 #ifdef DEBUG
-		printk("de_len = %ld\n", de_len);
+		if (offset < bufsize) printk("de_len = %ld\n", de_len);
+		else printk("Move to next sector\n");
 #endif
 	    
 
@@ -170,15 +175,15 @@
 		   CDROM sector.  If we are at the end of the directory, we
 		   kick out of the while loop. */
 
-		if ((de_len == 0) || (offset >= bufsize) ) {
+		if ((offset >= bufsize) || (de_len == 0) ) {
 			brelse(bh);
-			if (de_len == 0) {
+			if (offset >= bufsize) {	/*Check first. by GO!*/
+				offset -= bufsize;
+				filp->f_pos += offset;
+			} else {
 				filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
 					       + ISOFS_BLOCK_SIZE);
 				offset = 0;
-			} else {
-				offset -= bufsize;
-				filp->f_pos += offset;
 			}
 
 			if (filp->f_pos >= inode->i_size)
diff -urN linux-2.2.17-pre13/fs/isofs/inode.c linux/fs/isofs/inode.c
--- linux-2.2.17-pre13/fs/isofs/inode.c	Wed Jun  7 14:26:43 2000
+++ linux/fs/isofs/inode.c	Mon Dec  3 22:10:12 2001
@@ -915,7 +915,7 @@
 	 * If we are beyond the end of this file, don't give out any
 	 * blocks.
 	 */
-	if( b_off > inode->i_size )
+	if( b_off >= inode->i_size )
 	  {
 	    off_t	max_legal_read_offset;
 
diff -urN linux-2.2.17-pre13/fs/ncpfs/ncplib_kernel.h linux/fs/ncpfs/ncplib_kernel.h
--- linux-2.2.17-pre13/fs/ncpfs/ncplib_kernel.h	Wed Jun  7 14:26:43 2000
+++ linux/fs/ncpfs/ncplib_kernel.h	Mon Dec  3 22:10:12 2001
@@ -130,7 +130,7 @@
 		nc[0] = toupperif(*np, case_trans);
 		nc[1] = 0x00;
 		nls_in->char2uni(nc, &len, &uc.uni2, &uc.uni1);
-		nls_out->uni2char(0x00, uc.uni2, np, 1, &len);
+		nls_out->uni2char(uc.uni1, uc.uni2, np, 1, &len);
 		np++;
 	}
 }
@@ -154,7 +154,7 @@
 		nc[0] = *np;
 		nc[1] = 0;
 		nls_in->char2uni(nc, &len, &uc.uni2, &uc.uni1);
-		nls_out->uni2char(0x00, uc.uni2, nc, 1, &len);
+		nls_out->uni2char(uc.uni1, uc.uni2, nc, 1, &len);
 		*np = tolowerif(nc[0], case_trans);
 		np++;
 	}
diff -urN linux-2.2.17-pre13/fs/smbfs/ChangeLog linux/fs/smbfs/ChangeLog
--- linux-2.2.17-pre13/fs/smbfs/ChangeLog	Wed Dec 31 16:00:00 1969
+++ linux/fs/smbfs/ChangeLog	Mon Dec  3 22:10:13 2001
@@ -0,0 +1,49 @@
+ChangeLog for smbfs.
+
+2000-07-20 Urban Widmark <urban@svenskatest.se>
+
+	* proc.c: fix 2 places where bad server responses could cause an Oops.
+
+2000-07-15 Urban Widmark <urban@svenskatest.se>
+
+	* *.c: more debug printk fixes
+
+2000-06-24: Matt Maynard <matthewm@corel.com>
+
+	* dir.c: dentry->d_inode->i_mtime isn't updated for all servers
+	  (NT?) and all operations (mv oldfile.txt newfile.txt) Removed for
+	  less efficient but better working directory cache.
+	* proc.c: included aDIR smbclient fix for renaming directories on
+	  OS/2 servers (win95/98?) (orig by John Janosik)
+
+2000-07-01 Urban Widmark <urban@svenskatest.se>
+
+	* *.c: replace ugly #ifdef's with less ugly debug macros.
+
+2000-03-?? Andrew Tridgell
+
+	* proc.c: removed support for old protocol levels. It didn't work
+	  anyway and was cluttering things up a lot.
+
+2000-01-?? cpg@aladdin.de
+
+	* proc.c: added posix semantics for unlink
+
+1999-11-16 Andrew Tridgell
+
+	* proc.c: use level 260 for most conns, or level 1 for <NT1
+	* proc.c: don't sleep every time with win95 on a FINDNEXT
+	* proc.c: fixed loop_count bug
+	* proc.c: got rid of resume_key
+
+[there are a few missing here :) ]
+
+1997-09-28 Riccardo Facchetti
+
+	* proc.c: Fixed smb_d_path [now smb_build_path()] to be non-recursive
+
+1996-06-28 Yuri Per
+
+	* proc.c: Fixed long file name support (smb_proc_readdir_long)
+
+You are in the wrong end for adding new entries. New entries at the top.
diff -urN linux-2.2.17-pre13/fs/smbfs/cache.c linux/fs/smbfs/cache.c
--- linux-2.2.17-pre13/fs/smbfs/cache.c	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/cache.c	Mon Dec  3 22:10:13 2001
@@ -6,6 +6,8 @@
  * Routines to support directory cacheing using the page cache.
  * Right now this only works for smbfs, but will be generalized
  * for use with other filesystems.
+ *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -17,9 +19,6 @@
 
 #include <asm/page.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 
@@ -40,8 +39,7 @@
 	struct inode * inode = dentry->d_inode;
 	struct cache_head * cachep;
 
-	VERBOSE("smb_get_dircache: finding cache for %s/%s\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name);
+	VERBOSE("finding cache for %s/%s\n", DENTRY_PATH(dentry));
 	cachep = (struct cache_head *) get_cached_page(inode, 0, 1);
 	if (!cachep)
 		goto out;
@@ -60,9 +58,8 @@
 		for (i = 0; i < cachep->pages; i++, index++) {
 #ifdef SMBFS_PARANOIA
 			if (index->block)
-				PARANOIA("smb_get_dircache: cache %s/%s has existing block!\n",
-					 dentry->d_parent->d_name.name,
-					 dentry->d_name.name);
+				PARANOIA("cache %s/%s has existing block!\n",
+					 DENTRY_PATH(dentry));
 #endif
 			offset = PAGE_SIZE + (i << PAGE_SHIFT);
 			block = (struct cache_block *) get_cached_page(inode,
@@ -86,7 +83,7 @@
 	struct cache_index * index = cachep->index;
 	int i;
 
-	VERBOSE("smb_free_cache_blocks: freeing %d blocks\n", cachep->pages);
+	VERBOSE("freeing %d blocks\n", cachep->pages);
 	for (i = 0; i < cachep->pages; i++, index++)
 	{
 		if (index->block)
@@ -103,7 +100,7 @@
 void
 smb_free_dircache(struct cache_head * cachep)
 {
-	VERBOSE("smb_free_dircache: freeing cache\n");
+	VERBOSE("freeing cache\n");
 	smb_free_cache_blocks(cachep);
 	put_cached_page((unsigned long) cachep);
 }
@@ -115,8 +112,7 @@
 void
 smb_init_dircache(struct cache_head * cachep)
 {
-	VERBOSE("smb_init_dircache: initializing cache, %d blocks\n", 
-		cachep->pages);
+	VERBOSE("initializing cache, %d blocks\n", cachep->pages);
 	smb_free_cache_blocks(cachep);
 	memset(cachep, 0, sizeof(struct cache_head));
 }
@@ -136,8 +132,8 @@
 	unsigned int nent, offset, len = entry->len;
 	unsigned int needed = len + sizeof(struct cache_entry);
 
-	VERBOSE("smb_add_to_cache: cache inode %p, status %d, adding %s at %ld\n",
-		inode, cachep->status, entry->name, fpos);
+	VERBOSE("cache inode %p, status %d, adding %.*s at %ld\n",
+		inode, cachep->status, entry->len, entry->name, fpos);
 	/*
 	 * Don't do anything if we've had an error ...
 	 */
@@ -163,8 +159,8 @@
 		block->cb_data.table[nent].offset = offset;
 		block->cb_data.table[nent].ino = entry->ino;
 		cachep->entries++;
-		VERBOSE("smb_add_to_cache: added entry %s, len=%d, pos=%ld, entries=%d\n",
-			entry->name, len, fpos, cachep->entries);
+		VERBOSE("added entry %.*s, len=%d, pos=%ld, entries=%d\n",
+			entry->len, entry->name, len, fpos, cachep->entries);
 		return;
 	}
 	/*
@@ -176,7 +172,7 @@
 	index++;
 #ifdef SMBFS_PARANOIA
 	if (index->block)
-		PARANOIA("smb_add_to_cache: new index already has block!\n");
+		PARANOIA("new index already has block!\n");
 #endif
 
 	/*
@@ -190,7 +186,7 @@
 	{
 		index->block = block;
 		index->space = PAGE_SIZE;
-		VERBOSE("smb_add_to_cache: inode=%p, pages=%d, block at %ld\n",
+		VERBOSE("inode=%p, pages=%d, block at %ld\n",
 			inode, cachep->pages, page_off);
 		goto add_entry;
 	}
@@ -212,8 +208,7 @@
 	unsigned int i, nent, offset = 0;
 	off_t next_pos = 2;
 
-	VERBOSE("smb_find_in_cache: cache %p, looking for pos=%ld\n", 
-		cachep, pos);
+	VERBOSE("cache %p, looking for pos=%ld\n", cachep, pos);
 	for (i = 0; i < cachep->pages; i++, index++)
 	{
 		if (pos < next_pos)
@@ -231,8 +226,8 @@
 		entry->len = block->cb_data.table[nent].namelen;
 		offset = block->cb_data.table[nent].offset;
 		entry->name = &block->cb_data.names[offset];
-		VERBOSE("smb_find_in_cache: found %s, len=%d, pos=%ld\n",
-			entry->name, entry->len, pos);
+		VERBOSE("found %.*s, len=%d, pos=%ld\n",
+			entry->len, entry->name, entry->len, pos);
 		break;
 	}
 	return offset;
@@ -244,9 +239,7 @@
 	struct inode * inode = dentry->d_inode;
 	int result;
 
-	VERBOSE("smb_refill_dircache: cache %s/%s, blocks=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name, 
-		cachep->pages);
+	VERBOSE("cache %s/%s, blocks=%d\n", DENTRY_PATH(dentry), cachep->pages);
 	/*
 	 * Fill the cache, starting at position 2.
 	 */
@@ -255,8 +248,7 @@
 	result = smb_proc_readdir(dentry, 2, cachep);
 	if (result < 0)
 	{
-		PARANOIA("smb_refill_dircache: readdir failed, result=%d\n", 
-			 result);
+		PARANOIA("readdir failed, result=%d\n", result);
 		goto out;
 	}
 
@@ -266,7 +258,7 @@
 	 */
 	if (!(inode->u.smbfs_i.cache_valid & SMB_F_CACHEVALID))
 	{
-		PARANOIA("smb_refill_dircache: cache invalidated, retrying\n");
+		PARANOIA("cache invalidated, retrying\n");
 		goto retry;
 	}
 
@@ -276,9 +268,8 @@
 		cachep->valid = 1;
 		cachep->mtime = dentry->d_inode->i_mtime;
 	}
-	VERBOSE("smb_refill_cache: cache %s/%s status=%d, entries=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
-		cachep->status, cachep->entries);
+	VERBOSE("cache %s/%s status=%d, entries=%d\n",
+		DENTRY_PATH(dentry), cachep->status, cachep->entries);
 
 out:
 	return result;
diff -urN linux-2.2.17-pre13/fs/smbfs/dir.c linux/fs/smbfs/dir.c
--- linux-2.2.17-pre13/fs/smbfs/dir.c	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/dir.c	Mon Dec  3 22:10:13 2001
@@ -4,18 +4,17 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/ctype.h>
 
 #include <linux/smb_fs.h>
 #include <linux/smbno.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 #define SMBFS_MAX_AGE 5*HZ
@@ -85,8 +84,7 @@
 	struct cache_head *cachep = NULL;
 	int result;
 
-	VERBOSE("smb_readdir: reading %s/%s, f_pos=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
+	VERBOSE("reading %s/%s, f_pos=%d\n", DENTRY_PATH(dentry),
 		(int) filp->f_pos);
 
 	result = 0;
@@ -118,10 +116,13 @@
 		goto out;
 	/*
 	 * Make sure the cache is up-to-date.
+	 *
+	 * To detect changes on the server we refill on each "new" access.
+	 *
+	 * Directory mtime would be nice to use for finding changes,
+	 * unfortunately some servers (NT4) doesn't update on local changes.
 	 */
-	if (!cachep->valid ||
-	    (cachep->mtime != dentry->d_inode->i_mtime &&
-	     filp->f_pos == 2))
+	if (!cachep->valid || filp->f_pos == 2)
 	{
 		result = smb_refill_dircache(cachep, dentry);
 		if (result)
@@ -176,7 +177,7 @@
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	int error = 0;
 
-	VERBOSE("smb_dir_open: (%s/%s)\n", dentry->d_parent->d_name.name, 
+	VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name, 
 		file->f_dentry->d_name.name);
 	if (server->conn_pid)
 		error = smb_revalidate_inode(dentry);
@@ -217,36 +218,23 @@
 	valid = (age <= SMBFS_MAX_AGE);
 #ifdef SMBFS_DEBUG_VERBOSE
 	if (!valid)
-		VERBOSE("smb_lookup_validate: %s/%s not valid, age=%lu\n", 
-			dentry->d_parent->d_name.name, dentry->d_name.name,
-			age);
+		VERBOSE("%s/%s not valid, age=%lu\n", DENTRY_PATH(dentry), age);
 #endif
 
-	if (inode)
-	{
-		if (is_bad_inode(inode))
-		{
-			PARANOIA("smb_lookup_validate: %s/%s has dud inode\n", 
-				 dentry->d_parent->d_name.name,
-				 dentry->d_name.name);
+	if (inode) {
+		if (is_bad_inode(inode)) {
+			PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry));
 			valid = 0;
 		} else if (!valid)
 			valid = (smb_revalidate_inode(dentry) == 0);
-	} else
-	{
-	/*
-	 * What should we do for negative dentries?
-	 */
+	} else {
+		/*
+		 * What should we do for negative dentries?
+		 */
 	}
 	return valid;
 }
 
-/*
- * XXX: It would be better to use the tolower from linux/ctype.h,
- * but _ctype is needed and it is not exported.
- */
-#define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-('A'-'a') : (c))
-
 static int 
 smb_hash_dentry(struct dentry *dir, struct qstr *this)
 {
@@ -285,19 +273,15 @@
 static void
 smb_delete_dentry(struct dentry * dentry)
 {
-	if (dentry->d_inode)
-	{
-		if (is_bad_inode(dentry->d_inode))
-		{
-			PARANOIA("smb_delete_dentry: bad inode, unhashing %s/%s\n", 
-				 dentry->d_parent->d_name.name,
-				 dentry->d_name.name);
+	if (dentry->d_inode) {
+		if (is_bad_inode(dentry->d_inode)) {
+			PARANOIA("bad inode, unhashing %s/%s\n", 
+				 DENTRY_PATH(dentry));
 			d_drop(dentry);
 		}
 		smb_close_dentry(dentry);
-	} else
-	{
-	/* N.B. Unhash negative dentries? */
+	} else {
+		/* N.B. Unhash negative dentries? */
 	}
 }
 
@@ -332,9 +316,8 @@
 	error = smb_proc_getattr(dentry, &finfo);
 #ifdef SMBFS_PARANOIA
 	if (error && error != -ENOENT)
-		PARANOIA("smb_lookup: find %s/%s failed, error=%d\n",
-			 dentry->d_parent->d_name.name, dentry->d_name.name,
-			 error);
+		PARANOIA("find %s/%s failed, error=%d\n",
+			 DENTRY_PATH(dentry), error);
 #endif
 
 	inode = NULL;
@@ -369,8 +352,7 @@
 	int error;
 	struct smb_fattr fattr;
 
-	VERBOSE("smb_instantiate: file %s/%s, fileid=%u\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name, fileid);
+	VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid);
 	error = smb_proc_getattr(dentry, &fattr);
 	if (error)
 		goto out_close;
@@ -396,9 +378,8 @@
 out_close:
 	if (have_id)
 	{
-		PARANOIA("smb_instantiate: %s/%s failed, error=%d, closing %u\n",
-			 dentry->d_parent->d_name.name, dentry->d_name.name,
-			 error, fileid);
+		PARANOIA("%s/%s failed, error=%d, closing %u\n",
+			 DENTRY_PATH(dentry), error, fileid);
 		smb_close_fileid(dentry, fileid);
 	}
 	goto out;
@@ -411,18 +392,14 @@
 	__u16 fileid;
 	int error;
 
-	VERBOSE("smb_create: creating %s/%s, mode=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name, mode);
+	VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
 
 	error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
-	if (!error)
-	{
+	if (!error) {
 		error = smb_instantiate(dentry, fileid, 1);
-	} else
-	{
-		PARANOIA("smb_create: %s/%s failed, error=%d\n",
-			 dentry->d_parent->d_name.name, dentry->d_name.name,
-			 error);
+	} else {
+		PARANOIA("%s/%s failed, error=%d\n",
+			 DENTRY_PATH(dentry), error);
 	}
 	return error;
 }
@@ -502,9 +479,8 @@
 		error = smb_proc_unlink(new_dentry);
 		if (error)
 		{
-			VERBOSE("smb_rename: unlink %s/%s, error=%d\n",
-				new_dentry->d_parent->d_name.name,
-				new_dentry->d_name.name, error);
+			VERBOSE("unlink %s/%s, error=%d\n",
+				DENTRY_PATH(new_dentry), error);
 			goto out;
 		}
 		/* FIXME */
diff -urN linux-2.2.17-pre13/fs/smbfs/file.c linux/fs/smbfs/file.c
--- linux-2.2.17-pre13/fs/smbfs/file.c	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/file.c	Mon Dec  3 22:10:13 2001
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -22,16 +23,8 @@
 #include <linux/smbno.h>
 #include <linux/smb_fs.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
-static inline int
-min(int a, int b)
-{
-	return a < b ? a : b;
-}
 
 static inline void
 smb_unlock_page(struct page *page)
@@ -43,8 +36,7 @@
 static int
 smb_fsync(struct file *file, struct dentry * dentry)
 {
-	VERBOSE("smb_fsync: sync file %s/%s\n", 
-		dentry->d_parent->d_name.name, dentry->d_name.name);
+	VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry));
 	return 0;
 }
 
@@ -62,15 +54,13 @@
 
 	clear_bit(PG_error, &page->flags);
 
-	VERBOSE("smb_readpage_sync: file %s/%s, count=%d@%ld, rsize=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name, count,
-		offset, rsize);
+	VERBOSE("file %s/%s, count=%d@%ld, rsize=%d\n",
+		DENTRY_PATH(dentry), count, offset, rsize);
 	result = smb_open(dentry, SMB_O_RDONLY);
 	if (result < 0)
 	{
-		PARANOIA("smb_readpage_sync: %s/%s open failed, error=%d\n",
-			 dentry->d_parent->d_name.name, dentry->d_name.name,
-			 result);
+		PARANOIA("%s/%s open failed, error=%d\n",
+			 DENTRY_PATH(dentry), result);
 		goto io_error;
 	}
 
@@ -109,7 +99,7 @@
 	DEBUG1("SMB: smb_readpage %08lx\n", page_address(page));
 #ifdef SMBFS_PARANOIA
 	if (test_bit(PG_locked, &page->flags))
-		DEBUG1("smb_readpage: page already locked!\n");
+		PARANOIA("page already locked!\n");
 #endif
 	set_bit(PG_locked, &page->flags);
 	atomic_inc(&page->count);
@@ -132,9 +122,8 @@
 	int result, written = 0;
 
 	offset += page->offset;
-	VERBOSE("smb_writepage_sync: file %s/%s, count=%d@%ld, wsize=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
-		count, offset, wsize);
+	VERBOSE("file %s/%s, count=%d@%ld, wsize=%d\n",
+		DENTRY_PATH(dentry), count, offset, wsize);
 
 	do {
 		if (count < wsize)
@@ -146,7 +135,8 @@
 		/* N.B. what if result < wsize?? */
 #ifdef SMBFS_PARANOIA
 		if (result < wsize)
-			printk(KERN_DEBUG "smb_writepage_sync: short write, wsize=%d, result=%d\n", wsize, result);
+			printk(KERN_DEBUG "short write, wsize=%d, result=%d\n",
+			       wsize, result);
 #endif
 		buffer += wsize;
 		offset += wsize;
@@ -175,7 +165,7 @@
 
 #ifdef SMBFS_PARANOIA
 	if (test_bit(PG_locked, &page->flags))
-		DEBUG1("smb_writepage: page already locked!\n");
+		PARANOIA("page already locked!\n");
 #endif
 	set_bit(PG_locked, &page->flags);
 	atomic_inc(&page->count);
@@ -190,9 +180,8 @@
 {
 	struct dentry *dentry = file->f_dentry;
 
-	DEBUG1("SMBFS: smb_updatepage(%s/%s %d@%ld, sync=%d)\n",
-	       dentry->d_parent->d_name.name, dentry->d_name.name,
-	       count, page->offset+offset, sync);
+	DEBUG1("(%s/%s %d@%ld, sync=%d)\n",
+	       DENTRY_PATH(dentry), count, page->offset+offset, sync);
 
 	return smb_writepage_sync(dentry, page, offset, count);
 }
@@ -203,23 +192,21 @@
 	struct dentry * dentry = file->f_dentry;
 	ssize_t	status;
 
-	VERBOSE("smb_file_read: file %s/%s, count=%lu@%lu\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
+	VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry),
 		(unsigned long) count, (unsigned long) *ppos);
 
 	status = smb_revalidate_inode(dentry);
 	if (status)
 	{
-		PARANOIA("smb_file_read: %s/%s validation failed, error=%d\n",
-			 dentry->d_parent->d_name.name, dentry->d_name.name,
-			 status);
+		PARANOIA("%s/%s validation failed, error=%d\n",
+			 DENTRY_PATH(dentry), status);
 		goto out;
 	}
 
-	VERBOSE("smb_file_read: before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n",
+	VERBOSE("before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n",
 		dentry->d_inode->i_size, dentry->d_inode->i_nrpages,
-		dentry->d_inode->i_flags,
-		dentry->d_inode->i_atime);
+		dentry->d_inode->i_flags, dentry->d_inode->i_atime);
+
 	status = generic_file_read(file, buf, count, ppos);
 out:
 	return status;
@@ -231,16 +218,14 @@
 	struct dentry * dentry = file->f_dentry;
 	int	status;
 
-	VERBOSE("smb_file_mmap: file %s/%s, address %lu - %lu\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
-		vma->vm_start, vma->vm_end);
+	VERBOSE("file %s/%s, address %lu - %lu\n",
+		DENTRY_PATH(dentry), vma->vm_start, vma->vm_end);
 
 	status = smb_revalidate_inode(dentry);
 	if (status)
 	{
-		PARANOIA("smb_file_mmap: %s/%s validation failed, error=%d\n",
-			 dentry->d_parent->d_name.name, dentry->d_name.name,
-			 status);
+		PARANOIA("%s/%s validation failed, error=%d\n",
+			 DENTRY_PATH(dentry), status);
 		goto out;
 	}
 	status = generic_file_mmap(file, vma);
@@ -257,18 +242,16 @@
 	struct dentry * dentry = file->f_dentry;
 	ssize_t	result;
 
-	VERBOSE("smb_file_write: file %s/%s, count=%lu@%lu, pages=%ld\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
+	VERBOSE("file %s/%s, count=%lu@%lu, pages=%ld\n", DENTRY_PATH(dentry),
 		(unsigned long) count, (unsigned long) *ppos,
 		dentry->d_inode->i_nrpages);
 
 	result = smb_revalidate_inode(dentry);
 	if (result)
 	{
-		PARANOIA("smb_file_write: %s/%s validation failed, error=%d\n",
-			 dentry->d_parent->d_name.name, dentry->d_name.name,
-			 result);
-			goto out;
+		PARANOIA("%s/%s validation failed, error=%d\n",
+			 DENTRY_PATH(dentry), result);
+		goto out;
 	}
 
 	result = smb_open(dentry, SMB_O_WRONLY);
@@ -278,7 +261,7 @@
 	if (count > 0)
 	{
 		result = generic_file_write(file, buf, count, ppos);
-		VERBOSE("smb_file_write: pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
+		VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
 			(long) file->f_pos, dentry->d_inode->i_size,
 			dentry->d_inode->i_mtime, dentry->d_inode->i_atime);
 	}
@@ -289,9 +272,8 @@
 static int
 smb_file_open(struct inode *inode, struct file * file)
 {
-	VERBOSE("smb_file_open: opening %s/%s, d_count=%d\n",
-		file->f_dentry->d_parent->d_name.name,
-		file->f_dentry->d_name.name, file->f_dentry->d_count);
+	VERBOSE("opening %s/%s, d_count=%d\n",
+		DENTRY_PATH(file->f_dentry), file->f_dentry->d_count);
 	return 0;
 }
 
@@ -300,14 +282,12 @@
 {
 	struct dentry * dentry = file->f_dentry;
 
-	VERBOSE("smb_file_release: closing %s/%s, d_count=%d\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
-		dentry->d_count);
-	
+	VERBOSE("closing %s/%s, d_count=%d\n",
+		DENTRY_PATH(dentry), dentry->d_count);
+
 	if (dentry->d_count == 1)
-	{
 		smb_close(inode);
-	}
+
 	return 0;
 }
 
@@ -322,7 +302,7 @@
 	int mode = inode->i_mode;
 	int error = 0;
 
-	VERBOSE("smb_file_permission: mode=%x, mask=%x\n", mode, mask);
+	VERBOSE("mode=%x, mask=%x\n", mode, mask);
 
 	/* Look at user permissions */
 	mode >>= 6;
diff -urN linux-2.2.17-pre13/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- linux-2.2.17-pre13/fs/smbfs/inode.c	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/inode.c	Mon Dec  3 22:10:13 2001
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/config.h>
@@ -28,9 +29,6 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 static void smb_read_inode(struct inode *);
@@ -76,7 +74,7 @@
 {
 	struct inode *result;
 
-	DEBUG1("smb_iget: %p\n", fattr);
+	DEBUG1("fattr @ %p\n", fattr);
 
 	result = get_empty_inode();
 	result->i_sb = sb;
@@ -169,7 +167,7 @@
 void
 smb_invalidate_inodes(struct smb_sb_info *server)
 {
-	VERBOSE("smb_invalidate_inodes\n");
+	VERBOSE("\n");
 	shrink_dcache_sb(SB_of(server));
 	invalidate_inodes(SB_of(server));
 }
@@ -204,9 +202,8 @@
 			 * To limit damage, mark the inode as bad so that
 			 * subsequent lookup validations will fail.
 			 */
-			PARANOIA("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
-				 dentry->d_parent->d_name.name,
-				 dentry->d_name.name,
+			PARANOIA("%s/%s changed mode, %07o to %07o\n",
+				 DENTRY_PATH(dentry),
 				 inode->i_mode, fattr.f_mode);
 
 			fattr.f_mode = inode->i_mode; /* save mode */
@@ -239,7 +236,7 @@
 	time_t last_time;
 	int error = 0;
 
-	DEBUG1("smb_revalidate_inode\n");
+	DEBUG1("\n");
 
 	/*
 	 * If this is a file opened with write permissions,
@@ -256,7 +253,7 @@
 	 */
 	if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10))
 	{
-		VERBOSE("smb_revalidate_inode: up-to-date, jiffies=%lu, oldtime=%lu\n",
+		VERBOSE("up-to-date, jiffies=%lu, oldtime=%lu\n",
 			jiffies, inode->u.smbfs_i.oldmtime);
 		goto out;
 	}
@@ -269,8 +266,8 @@
 	error = smb_refresh_inode(dentry);
 	if (error || inode->i_mtime != last_time)
 	{
-		VERBOSE("smb_revalidate: %s/%s changed, old=%ld, new=%ld\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
+		VERBOSE("%s/%s changed, old=%ld, new=%ld\n",
+			DENTRY_PATH(dentry),
 			(long) last_time, (long) inode->i_mtime);
 		if (!S_ISDIR(inode->i_mode))
 			invalidate_inode_pages(inode);
@@ -286,7 +283,7 @@
 static void
 smb_put_inode(struct inode *ino)
 {
-	DEBUG1("smb_put_inode: count = %d\n", ino->i_count);
+	DEBUG1("count = %d\n", ino->i_count);
 	if (ino->i_count == 1)
 		ino->i_nlink = 0;
 }
@@ -298,10 +295,9 @@
 static void
 smb_delete_inode(struct inode *ino)
 {
-	DEBUG1("smb_delete_inode\n");
+	DEBUG1("\n");
 	if (smb_close(ino))
-		PARANOIA("smb_delete_inode: could not close inode %ld\n",
-			 ino->i_ino);
+		PARANOIA("could not close inode %ld\n", ino->i_ino);
 	clear_inode(ino);
 }
 
@@ -317,7 +313,7 @@
 	}
 
 	if (server->conn_pid)
-	       kill_proc(server->conn_pid, SIGTERM, 1);
+		kill_proc(server->conn_pid, SIGTERM, 1);
 
 	kfree(server->mnt);
 	kfree(sb->u.smbfs_sb.temp_buf);
@@ -370,7 +366,7 @@
 	if (!mnt)
 		goto out_no_mount;
 	*mnt = *((struct smb_mount_data *) raw_data);
-	/* ** temp ** pass config flags in file mode */
+	/* FIXME: ** temp ** pass config flags in file mode */
 	mnt->version = (mnt->file_mode >> 9);
 	mnt->file_mode &= (S_IRWXU | S_IRWXG | S_IRWXO);
 	mnt->file_mode |= S_IFREG;
@@ -408,7 +404,7 @@
 	printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION);
 	goto out_fail;
 out_no_data:
-	printk(KERN_DEBUG "smb_read_super: missing data argument\n");
+	printk(KERN_ERR "smb_read_super: missing data argument\n");
 out_fail:
 	sb->s_dev = 0;
 	MOD_DEC_USE_COUNT;
@@ -459,8 +455,8 @@
 
 	if ((attr->ia_valid & ATTR_SIZE) != 0)
 	{
-		VERBOSE("smb_notify_change: changing %s/%s, old size=%ld, new size=%ld\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
+		VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
+			DENTRY_PATH(dentry),
 			(long) inode->i_size, (long) attr->ia_size);
 		error = smb_open(dentry, O_WRONLY);
 		if (error)
@@ -513,9 +509,8 @@
 	 */
 	if ((attr->ia_valid & ATTR_MODE) != 0)
 	{
-		VERBOSE("smb_notify_change: %s/%s mode change, old=%x, new=%lx\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,
-			fattr.f_mode,attr->ia_mode);
+		VERBOSE("%s/%s mode change, old=%x, new=%lx\n",
+			DENTRY_PATH(dentry), fattr.f_mode,attr->ia_mode);
 		changed = 0;
 		if (attr->ia_mode & S_IWUSR)
 		{
@@ -572,7 +567,7 @@
 int
 init_module(void)
 {
-	DEBUG1("smbfs: init_module called\n");
+	DEBUG1("registering ...\n");
 
 #ifdef DEBUG_SMB_MALLOC
 	smb_malloced = 0;
@@ -586,7 +581,7 @@
 void
 cleanup_module(void)
 {
-	DEBUG1("smbfs: cleanup_module called\n");
+	DEBUG1("unregistering ...\n");
 	unregister_filesystem(&smb_fs_type);
 #ifdef DEBUG_SMB_MALLOC
 	printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
diff -urN linux-2.2.17-pre13/fs/smbfs/ioctl.c linux/fs/smbfs/ioctl.c
--- linux-2.2.17-pre13/fs/smbfs/ioctl.c	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/ioctl.c	Mon Dec  3 22:10:13 2001
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/errno.h>
@@ -23,30 +24,25 @@
 	  unsigned int cmd, unsigned long arg)
 {
 	struct smb_sb_info *server = SMB_SERVER(inode);
+	struct smb_conn_opt opt;
 	int result = -EINVAL;
 
-	switch (cmd)
-	{
+	switch (cmd) {
 	case SMB_IOC_GETMOUNTUID:
 		result = put_user(server->mnt->mounted_uid, (uid_t *) arg);
 		break;
 
 	case SMB_IOC_NEWCONN:
-	{
-		struct smb_conn_opt opt;
-
 		/* require an argument == the mount data, else it is EINVAL */
 		if (!arg)
-			goto out;
+			break;
 
 		result = -EFAULT;
 		if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
 			result = smb_newconn(server, &opt);
 		break;
-	}
 	default:
 	}
 
-out:
 	return result;
 }
diff -urN linux-2.2.17-pre13/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- linux-2.2.17-pre13/fs/smbfs/proc.c	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/proc.c	Mon Dec  3 22:10:13 2001
@@ -4,19 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
- *  28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per
- *  28/09/97 - Fixed smb_d_path [now smb_build_path()] to be non-recursive
- *             by Riccardo Facchetti
- *  16/11/99 (tridge) 
- *           - use level 260 for most conns, or level 1 for <NT1
- *           - don't sleep every time with win95 on a FINDNEXT
- *           - fixed loop_count bug
- *           - got rid of resume_key
- *  Jan 2000, cpg@aladdin.de
- *           - added posix semantics for unlink
- *  March 2000, tridge
- *           - removed support for old protocol levels. It didn't work anyway 
- *             and was cluttering things up a lot. 
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/types.h>
@@ -39,10 +27,6 @@
    config option. */
 #define SMBFS_POSIX_UNLINK 1
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_TIMESTAMP 1 */
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 #define SMB_VWV(packet)  ((packet) + SMB_HEADER_LEN)
@@ -54,19 +38,15 @@
 #define SMB_DIRINFO_SIZE 43
 #define SMB_STATUS_SIZE  21
 
-/* This makes a dentry parent/child pair. Useful for debugging printk's */
-#define DENTRY_PATH(dentry) \
-	(dentry)->d_parent->d_name.name,(dentry)->d_name.name
-
-
 static int smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
 				struct smb_fattr *);
 static int
 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
 		      __u16 attr);
-
 static int
-smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,struct smb_sb_info *server);
+smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,
+		    struct smb_sb_info *server);
+
 
 /* reverse a string inline. This is used by the dircache walking routines */
 static void reverse_string(char *buf, int len) {
@@ -320,7 +300,7 @@
 {
 	int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
 	int size = smb_get_xmitsize(server, overhead);
-	VERBOSE("smb_get_rsize: packet=%d, xmit=%d, size=%d\n",
+	VERBOSE("packet=%d, xmit=%d, size=%d\n",
 		server->packet_size, server->opt.max_xmit, size);
 	return size;
 }
@@ -333,7 +313,7 @@
 {
 	int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
 	int size = smb_get_xmitsize(server, overhead);
-	VERBOSE("smb_get_wsize: packet=%d, xmit=%d, size=%d\n",
+	VERBOSE("packet=%d, xmit=%d, size=%d\n",
 		server->packet_size, server->opt.max_xmit, size);
 	return size;
 }
@@ -345,7 +325,7 @@
 	int error  = server->err;
 	char *class = "Unknown";
 
-	VERBOSE("smb_errno: errcls %d  code %d  from command 0x%x\n",
+	VERBOSE("errcls %d  code %d  from command 0x%x\n",
 		errcls, error, SMB_CMD(server->packet));
 
 	if (errcls == ERRDOS)
@@ -506,7 +486,7 @@
 		printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error);
 		goto out_restore;
 	}
-	VERBOSE("smb_retry: signalled pid %d, waiting for new connection\n",
+	VERBOSE("signalled pid %d, waiting for new connection\n",
 		server->conn_pid);
 
 	/*
@@ -514,14 +494,14 @@
 	 */
 	interruptible_sleep_on_timeout(&server->wait,  5*HZ);
 	if (signal_pending(current))
-		printk(KERN_INFO "smb_retry: caught signal\n");
+		printk(KERN_INFO "caught signal\n");
 
 	/*
 	 * Check for a valid connection.
 	 */
 	if (server->state == CONN_VALID)
 	{
-		PARANOIA("smb_retry: new pid=%d, generation=%d\n",
+		PARANOIA("sucessful, new pid=%d, generation=%d\n",
 			 server->conn_pid, server->generation);
 		result = 1;
 	}
@@ -564,7 +544,7 @@
 	}
 	if (smb_valid_packet(s->packet) != 0)
 	{
-		PARANOIA("smb_request_ok: invalid packet!\n");
+		PARANOIA("invalid packet!\n");
 		goto out;
 	}
 
@@ -605,7 +585,7 @@
 	struct file *filp;
 	int error;
 
-	VERBOSE("smb_newconn: fd=%d, pid=%d\n", opt->fd, current->pid);
+	VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);
 
 	/*
 	 * Make sure we don't already have a pid ...
@@ -654,7 +634,7 @@
 #endif
 	}
 
-	VERBOSE("smb_newconn: protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
+	VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
 		server->opt.protocol, server->opt.max_xmit, server->conn_pid,
 		server->opt.capabilities);
 
@@ -757,7 +737,7 @@
 		if (mode == read_write &&
 		    (error == -EACCES || error == -ETXTBSY || error == -EROFS))
 		{
-			VERBOSE("smb_proc_open: %s/%s R/W failed, error=%d, retrying R/O\n",
+			VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
 				DENTRY_PATH(dentry), error);
 			mode = read_only;
 			goto retry;
@@ -810,7 +790,7 @@
 		smb_unlock_server(server);
 		if (result)
 		{
-			PARANOIA("smb_open: %s/%s open failed, result=%d\n",
+			PARANOIA("%s/%s open failed, result=%d\n",
 				 DENTRY_PATH(dentry), result);
 			goto out;
 		}
@@ -827,7 +807,7 @@
 	if (inode->u.smbfs_i.access != wish && 
 	    inode->u.smbfs_i.access != SMB_O_RDWR)
 	{
-		PARANOIA("smb_open: %s/%s access denied, access=%x, wish=%x\n",
+		PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
 			 DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
 		result = -EACCES;
 	}
@@ -936,13 +916,13 @@
 			 */
 			if (dentry->d_count <= 1)
 			{
-				VERBOSE("smb_close_dentry: closing %s/%s, count=%d\n",
+				VERBOSE("closing %s/%s, count=%d\n",
 					DENTRY_PATH(dentry), dentry->d_count);
 				smb_proc_close_inode(server, ino);
 			}
 			smb_unlock_server(server);
 		}
-		VERBOSE("smb_close_dentry: closed %s/%s, count=%d\n",
+		VERBOSE("closed %s/%s, count=%d\n",
 			DENTRY_PATH(dentry), dentry->d_count);
 	}
 }
@@ -971,7 +951,7 @@
 {
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	__u16 returned_count, data_len;
-	char *buf;
+	unsigned char *buf;
 	int result;
 
 	smb_lock_server(server);
@@ -989,10 +969,19 @@
 
 	buf = SMB_BUF(server->packet);
 	data_len = WVAL(buf, 1);
+
+	/* we can NOT simply trust the data_len given by the server ... */
+	if (data_len > server->packet_size - (buf+3 - server->packet)) {
+		printk(KERN_ERR "smb_proc_read: invalid data length!! "
+		       "%d > %d - (%p - %p)\n",
+		       data_len, server->packet_size, buf+3, server->packet);
+		result = -EIO;
+		goto out;
+	}
+
 	memcpy(data, buf+3, data_len);
 
-	if (returned_count != data_len)
-	{
+	if (returned_count != data_len) {
 		printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
 		printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
 		       returned_count, data_len);
@@ -1000,7 +989,7 @@
 	result = data_len;
 
 out:
-	VERBOSE("smb_proc_read: file %s/%s, count=%d, result=%d\n",
+	VERBOSE("file %s/%s, count=%d, result=%d\n",
 		DENTRY_PATH(dentry), count, result);
 	smb_unlock_server(server);
 	return result;
@@ -1013,7 +1002,7 @@
 	int result;
 	__u8 *p;
 
-	VERBOSE("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
+	VERBOSE("file %s/%s, count=%d@%ld, packet_size=%d\n",
 		DENTRY_PATH(dentry), count, offset, server->packet_size);
 
 	smb_lock_server(server);
@@ -1078,7 +1067,7 @@
 
       retry:
 	p = smb_setup_header(server, SMBmv, 1, 0);
-	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
+	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
 	*p++ = 4;
 	p = smb_encode_path(server, p, old_dentry, NULL);
 	*p++ = 4;
@@ -1141,6 +1130,7 @@
 }
 
 
+#if SMBFS_POSIX_UNLINK
 /*
  * Note: called with the server locked.
  * removes readonly attribute from a file. Used by unlink to give posix semantics
@@ -1163,6 +1153,7 @@
         }
         return result;
 }
+#endif
 
 int
 smb_proc_unlink(struct dentry *dentry)
@@ -1313,15 +1304,16 @@
 
 	result = p + WVAL(p, 0);
 	len = DVAL(p, 60);
-	if (len > 255) len = 255;
+	if (len > SMB_MAXNAMELEN)
+		len = SMB_MAXNAMELEN;
 	/* NT4 null terminates */
 	entry->name = p + 94;
 	if (len && entry->name[len-1] == '\0')
 		len--;
 	entry->len = len;
 
-	VERBOSE("smb_decode_long_dirent: info 260 at %p, len=%d, name=%s\n",
-		p, entry->len, entry->name);
+	VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
+		p, entry->len, entry->len, entry->name);
 
 	return result;
 }
@@ -1343,7 +1335,8 @@
 smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
 		      void *cachep)
 {
-	char *p, *mask, *param = server->temp_buf;
+	unsigned char *p;
+	char *mask, *param = server->temp_buf;
 	__u16 command;
 	int first, entries, entries_seen;
 	int info_level = 260;
@@ -1370,8 +1363,7 @@
 	mask_len = smb_encode_path(server, mask, dir, &star) - mask;
 	first = 1;
 
-	VERBOSE("smb_proc_readdir_long: starting fpos=%d, mask=%s\n",
-		fpos, mask);
+	VERBOSE("starting fpos=%d, mask=%s\n", fpos, mask);
 
 	/*
 	 * We must reinitialize the dircache when retrying.
@@ -1381,19 +1373,16 @@
 	entries_seen = 2;
 	ff_eos = 0;
 
-	while (ff_eos == 0)
-	{
+	while (ff_eos == 0) {
 		loop_count += 1;
-		if (loop_count > 10)
-		{
+		if (loop_count > 10) {
 			printk(KERN_WARNING "smb_proc_readdir_long: "
 			       "Looping in FIND_NEXT??\n");
 			entries = -EIO;
 			break;
 		}
 
-		if (first != 0)
-		{
+		if (first != 0) {
 			command = TRANSACT2_FINDFIRST;
 			WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
 			WSET(param, 2, max_matches);	/* max count */
@@ -1401,15 +1390,14 @@
 			     SMB_CONTINUE_BIT|SMB_CLOSE_IF_END); 
 			WSET(param, 6, info_level);
 			DSET(param, 8, 0);
-		} else
-		{
+		} else {
 			/* we don't need the mask after the first bit */
 			mask_len = 0;
 			mask[0] = 0;
 
 			command = TRANSACT2_FINDNEXT;
 
-			VERBOSE("smb_proc_readdir_long: handle=0x%X, mask=%s\n",
+			VERBOSE("handle=0x%X, mask=%s\n",
 				ff_dir_handle, mask);
 
 			WSET(param, 0, ff_dir_handle);	/* search handle */
@@ -1425,14 +1413,12 @@
 					    &resp_data_len, &resp_data,
 					    &resp_param_len, &resp_param);
 
-		if (result < 0)
-		{
-			if (smb_retry(server))
-			{
-				PARANOIA("smb_proc_readdir_long: error=%d, retrying\n", result);
+		if (result < 0) {
+			if (smb_retry(server)) {
+				PARANOIA("error=%d, retrying\n", result);
 				goto retry;
 			}
-			PARANOIA("smb_proc_readdir_long: error=%d, breaking\n", result);
+			PARANOIA("error=%d, breaking\n", result);
 			entries = result;
 			break;
 		}
@@ -1446,64 +1432,68 @@
 			continue;
 		}
 
-		if (server->rcls != 0)
-		{ 
-			PARANOIA("smb_proc_readdir_long: name=%s, entries=%d, rcls=%d, err=%d\n",
+		if (server->rcls != 0) {
+			PARANOIA("name=%s, entries=%d, rcls=%d, err=%d\n",
 				 mask, entries, server->rcls, server->err);
 			entries = -smb_errno(server);
 			break;
 		}
 
 		/* parse out some important return info */
-		if (first != 0)
-		{
+		if (first != 0) {
 			ff_dir_handle = WVAL(resp_param, 0);
 			ff_searchcount = WVAL(resp_param, 2);
 			ff_eos = WVAL(resp_param, 4);
-		} else
-		{
+		} else {
 			ff_searchcount = WVAL(resp_param, 0);
 			ff_eos = WVAL(resp_param, 2);
 		}
 
 		if (ff_searchcount == 0)
-		{
 			break;
-		}
 
 		/* Now we are ready to parse smb directory entries. */
 
 		/* point to the data bytes */
 		p = resp_data;
-		for (i = 0; i < ff_searchcount; i++)
-		{
+		for (i = 0; i < ff_searchcount; i++) {
 			struct cache_dirent this_ent, *entry = &this_ent;
 
+			/* make sure we stay within the buffer */
+			if (p >= resp_data + resp_data_len) {
+				printk(KERN_ERR "smb_proc_readdir_long: "
+				       "dirent pointer outside buffer! "
+				       "%p  %d@%p  %d@%p\n",
+				       p, resp_data_len, resp_data,
+				       server->packet_size, server->packet);
+				result = -EIO; /* always a comm. error? */
+				goto unlock_return;
+			}
+
 			p = smb_decode_long_dirent(server, p, entry);
 
 			/* ignore . and .. from the server */
-			if (entries_seen == 2 && entry->name[0] == '.')
-			{
+			if (entries_seen == 2 && entry->name[0] == '.') {
 				if (entry->len == 1)
 					continue;
 				if (entry->name[1] == '.' && entry->len == 2)
 					continue;
 			}
-			if (entries_seen >= fpos)
-			{
+			if (entries_seen >= fpos) {
 				smb_add_to_cache(cachep, entry, entries_seen);
 				entries += 1;
 			}
  			entries_seen++;
 		}
 
-		VERBOSE("smb_proc_readdir_long: received %d entries, eos=%d\n",
+		VERBOSE("received %d entries, eos=%d\n",
 			ff_searchcount, ff_eos);
 
 		first = 0;
 		loop_count = 0;
 	}
 
+unlock_return:
 	smb_unlock_server(server);
 	return entries;
 }
@@ -1533,8 +1523,7 @@
 	p = smb_encode_path(server, p, dir, NULL);
 	smb_setup_bcc(server, p);
 
-	if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)
-	{
+	if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0) {
 		if (smb_retry(server))
 			goto retry;
 		goto out;
@@ -1599,7 +1588,7 @@
 	}
 	if (server->rcls != 0)
 	{
-		VERBOSE("smb_proc_getattr_trans2: for %s: result=%d, rcls=%d, err=%d\n",
+		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
 			&param[6], result, server->rcls, server->err);
 		result = -smb_errno(server);
 		goto out;
@@ -1607,7 +1596,7 @@
 	result = -ENOENT;
 	if (resp_data_len < 22)
 	{
-		PARANOIA("smb_proc_getattr_trans2: not enough data for %s, len=%d\n",
+		PARANOIA("not enough data for %s, len=%d\n",
 			 &param[6], resp_data_len);
 		goto out;
 	}
@@ -1649,7 +1638,8 @@
  * get the file attribute
  */
 static int
-smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,struct smb_sb_info *server)
+smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,
+		    struct smb_sb_info *server)
 {
 	int result;
 
@@ -1740,8 +1730,8 @@
 	struct smb_sb_info *server = server_from_dentry(dir);
 	int result;
 
-	VERBOSE("smb_proc_setattr: setting %s/%s, open=%d\n", 
-		DENTRY_PATH(dir), smb_is_open(dir->d_inode));
+	VERBOSE("setting %s/%s, open=%d\n", DENTRY_PATH(dir),
+		smb_is_open(dir->d_inode));
 
 	smb_lock_server(server);
 	result = smb_proc_setattr_core(server, dir, fattr->attr);
@@ -1872,26 +1862,23 @@
 	struct inode *inode = dentry->d_inode;
 	int result;
 
-	VERBOSE("smb_proc_settime: setting %s/%s, open=%d\n", 
-		DENTRY_PATH(dentry), smb_is_open(inode));
+	VERBOSE("setting %s/%s, open=%d\n", DENTRY_PATH(dentry),
+		smb_is_open(inode));
 
 	smb_lock_server(server);
 	/* setting the time on a Win95 server fails (tridge) */
-	if (!(server->mnt->version & SMB_FIX_WIN95))
-	{
+	if (!(server->mnt->version & SMB_FIX_WIN95)) {
 		if (smb_is_open(inode) &&
 		    inode->u.smbfs_i.access != SMB_O_RDONLY)
 			result = smb_proc_setattr_ext(server, inode, fattr);
 		else
 			result = smb_proc_setattr_trans2(server, dentry, fattr);
-	} else
-	{
+	} else {
 		/*
 		 * Fail silently on directories ... timestamp can't be set?
 		 */
 		result = 0;
-		if (S_ISREG(inode->i_mode))
-		{
+		if (S_ISREG(inode->i_mode)) {
 			/*
 			 * Set the mtime by opening and closing the file.
 			 * Note that the file is opened read-only, but this
@@ -1900,8 +1887,7 @@
 			result = -EACCES;
 			if (!smb_is_open(inode))
 				smb_proc_open(server, dentry, SMB_O_RDONLY);
-			if (smb_is_open(inode))
-			{
+			if (smb_is_open(inode)) {
 				inode->i_mtime = fattr->f_mtime;
 				result = smb_proc_close_inode(server, inode);
 			}
@@ -1924,8 +1910,7 @@
       retry:
 	smb_setup_header(server, SMBdskattr, 0, 0);
 
-	if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0)
-	{
+	if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
 		if (smb_retry(server))
 			goto retry;
 		goto out;
diff -urN linux-2.2.17-pre13/fs/smbfs/smb_debug.h linux/fs/smbfs/smb_debug.h
--- linux-2.2.17-pre13/fs/smbfs/smb_debug.h	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/smb_debug.h	Mon Dec  3 22:10:13 2001
@@ -2,19 +2,23 @@
  * Defines some debug macros for smbfs.
  */
 
+/* This makes a dentry parent/child pair. Useful for debugging printk's */
+#define DENTRY_PATH(dentry) \
+	(dentry)->d_parent->d_name.name,(dentry)->d_name.name
+
 /*
  * safety checks that should never happen ??? 
  * these are normally enabled.
  */
 #ifdef SMBFS_PARANOIA
-#define PARANOIA(x...) printk(KERN_NOTICE ## x);
+#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " ## x)
 #else
 #define PARANOIA(x...) do { ; } while(0)
 #endif
 
 /* lots of debug messages */
 #ifdef SMBFS_DEBUG_VERBOSE
-#define VERBOSE(x...) printk(KERN_DEBUG ## x);
+#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
 #else
 #define VERBOSE(x...) do { ; } while(0)
 #endif
@@ -24,7 +28,7 @@
  * too common name.
  */
 #ifdef SMBFS_DEBUG
-#define DEBUG1(x...) printk(KERN_DEBUG ## x);
+#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
 #else
 #define DEBUG1(x...) do { ; } while(0)
 #endif
diff -urN linux-2.2.17-pre13/fs/smbfs/sock.c linux/fs/smbfs/sock.c
--- linux-2.2.17-pre13/fs/smbfs/sock.c	Mon Dec  3 22:10:06 2001
+++ linux/fs/smbfs/sock.c	Mon Dec  3 22:10:13 2001
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -25,9 +26,6 @@
 
 #include <asm/uaccess.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 static int
@@ -120,7 +118,7 @@
 		result = -EIO;
 		if (job->sk->dead)
 		{
-			PARANOIA("smb_data_callback: sock dead!\n");
+			PARANOIA("sock dead!\n");
 			break;
 		}
 
@@ -135,7 +133,7 @@
 		result = _recvfrom(socket, (void *) peek_buf, 4,
 				   MSG_DONTWAIT);
 
-		DEBUG1("smb_data_callback: got SESSION KEEPALIVE\n");
+		DEBUG1("got SESSION KEEPALIVE\n");
 
 		if (result == -EAGAIN)
 			break;
@@ -154,7 +152,7 @@
 	struct data_callback* job;
 	job = kmalloc(sizeof(struct data_callback),GFP_ATOMIC);
 	if(job == 0) {
-		printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n");
+		printk("smb_data_ready: lost SESSION KEEPALIVE due to OOM.\n");
 		found_data(sk);
 		return;
 	}
@@ -182,7 +180,7 @@
 	{
 #ifdef SMBFS_PARANOIA
 		if (!smb_valid_socket(file->f_dentry->d_inode))
-			PARANOIA("smb_server_sock: bad socket!\n");
+			PARANOIA("bad socket!\n");
 #endif
 		return &file->f_dentry->d_inode->u.socket_i;
 	}
@@ -209,11 +207,11 @@
 	sk = socket->sk;
 	if (sk == NULL)
 	{
-		DEBUG1("smb_catch_keepalive: sk == NULL");
+		DEBUG1("sk == NULL");
 		server->data_ready = NULL;
 		goto out;
 	}
-	DEBUG1("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
+	DEBUG1("sk->d_r = %x, server->d_r = %x\n",
 	       (unsigned int) (sk->data_ready),
 	       (unsigned int) (server->data_ready));
 
@@ -261,9 +259,9 @@
 		       "server->data_ready == NULL\n");
 		goto out;
 	}
-	pr_debug("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
-		 (unsigned int) (sk->data_ready),
-		 (unsigned int) (server->data_ready));
+	DEBUG1("sk->d_r = %x, server->d_r = %x\n",
+	       (unsigned int) (sk->data_ready),
+	       (unsigned int) (server->data_ready));
 
 	/*
 	 * Restore the original callback atomically to avoid races ...
@@ -272,7 +270,7 @@
 	server->data_ready = NULL;
 	if (data_ready != smb_data_ready)
 	{
-		printk("smb_dont_catch_keepalive: "
+		printk(KERN_ERR "smb_dont_catch_keepalive: "
 		       "sk->data_ready != smb_data_ready\n");
 	}
 	error = 0;
@@ -288,13 +286,11 @@
 {
 	struct file * file = server->sock_file;
 
-	if (file)
-	{
-		VERBOSE("smb_close_socket: closing socket %p\n",
-			server_sock(server));
+	if (file) {
+		VERBOSE("closing socket %p\n", server_sock(server));
 #ifdef SMBFS_PARANOIA
 		if (server_sock(server)->sk->data_ready == smb_data_ready)
-			PARANOIA("smb_close_socket: still catching keepalives!\n");
+			PARANOIA("still catching keepalives!\n");
 #endif
 		server->sock_file = NULL;
 		fput(file);
@@ -319,7 +315,7 @@
 		}
 		if (result < 0)
 		{
-			DEBUG1("smb_send_raw: sendto error = %d\n", -result);
+			DEBUG1("sendto error = %d\n", -result);
 			return result;
 		}
 		already_sent += result;
@@ -345,8 +341,7 @@
 		}
 		if (result < 0)
 		{
-			DEBUG1("smb_receive_raw: recvfrom error = %d\n",
-			       -result);
+			DEBUG1("recvfrom error = %d\n", -result);
 			return result;
 		}
 		already_read += result;
@@ -369,7 +364,7 @@
 
 	if (result < 0)
 	{
-		PARANOIA("smb_get_length: recv error = %d\n", -result);
+		PARANOIA("recv error = %d\n", -result);
 		return result;
 	}
 	switch (peek_buf[0])
@@ -379,12 +374,11 @@
 		break;
 
 	case 0x85:
-		DEBUG1("smb_get_length: Got SESSION KEEP ALIVE\n");
+		DEBUG1("Got SESSION KEEP ALIVE\n");
 		goto re_recv;
 
 	default:
-		PARANOIA("smb_get_length: Invalid NBT packet, code=%x\n",
-			 peek_buf[0]);
+		PARANOIA("Invalid NBT packet, code=%x\n", peek_buf[0]);
 		return -EIO;
 	}
 
@@ -443,7 +437,7 @@
 	result = smb_receive_raw(socket, packet + 4, len);
 	if (result < 0)
 	{
-		VERBOSE("smb_receive: receive error: %d\n", result);
+		VERBOSE("receive error: %d\n", result);
 		goto out;
 	}
 	server->rcls = *(packet + smb_rcls);
@@ -451,8 +445,7 @@
 
 #ifdef SMBFS_DEBUG_VERBOSE
 	if (server->rcls != 0)
-		VERBOSE("smb_receive: rcls=%d, err=%d\n",
-			server->rcls, server->err);
+		VERBOSE("rcls=%d, err=%d\n", server->rcls, server->err);
 #endif
 out:
 	return result;
@@ -515,7 +508,7 @@
 			 */
 			if (parm_count == parm_tot && data_count == data_tot)
 			{
-				VERBOSE("smb_receive_trans2: fast track, parm=%u %u %u, data=%u %u %u\n",
+				VERBOSE("fast track, parm=%u %u %u, data=%u %u %u\n",
 					parm_disp, parm_offset, parm_count, 
 					data_disp, data_offset, data_count);
 
@@ -555,7 +548,7 @@
 		memcpy(*parm + parm_disp, base + parm_offset, parm_count);
 		memcpy(*data + data_disp, base + data_offset, data_count);
 
-		PARANOIA("smb_receive_trans2: copied, parm=%u of %u, data=%u of %u\n",
+		PARANOIA("copied, parm=%u of %u, data=%u of %u\n",
 			 parm_len, parm_tot, data_len, data_tot);
 
 		/*
@@ -577,9 +570,8 @@
 		server->packet_size = buf_len;
 		server->packet = rcv_buf;
 		rcv_buf = inbuf;
-	} else
-	{
-		PARANOIA("smb_receive_trans2: copying data, old size=%d, new size=%u\n",
+	} else {
+		PARANOIA("copying data, old size=%d, new size=%u\n",
 			 server->packet_size, buf_len);
 		memcpy(inbuf, rcv_buf, parm_len + data_len);
 	}
@@ -593,7 +585,7 @@
 	return result;
 
 out_no_mem:
-	PARANOIA("smb_receive_trans2: couldn't allocate data area\n");
+	printk(KERN_ERR "smb_receive_trans2: couldn't allocate data area\n");
 	result = -ENOMEM;
 	goto out;
 out_too_long:
@@ -640,7 +632,7 @@
 		goto bad_conn;
 
 	len = smb_len(buffer) + 4;
-	DEBUG1("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
+	DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
 
 	spin_lock_irqsave(&current->sigmask_lock, flags);
 	sigpipe = sigismember(&current->signal, SIGPIPE);
@@ -692,14 +684,14 @@
 	}
 
 out:
-	DEBUG1("smb_request: result = %d\n", result);
+	DEBUG1("result = %d\n", result);
 	return result;
 	
 bad_conn:
-	PARANOIA("smb_request: result %d, setting invalid\n", result);
+	PARANOIA("result %d, setting invalid\n", result);
 	server->state = CONN_INVALID;
 	smb_invalidate_inodes(server);
-	goto out;		
+	goto out;
 bad_no_packet:
 	printk(KERN_ERR "smb_request: no packet!\n");
 	goto out;
@@ -806,8 +798,7 @@
 	mm_segment_t fs;
 	int result;
 
-	DEBUG1("smb_trans2_request: com=%d, ld=%d, lp=%d\n",
-	       trans2_command, ldata, lparam);
+	DEBUG1("com=%d, ld=%d, lp=%d\n", trans2_command, ldata, lparam);
 
 	/*
 	 * These are initialized in smb_request_ok, but not here??
@@ -876,7 +867,7 @@
 	return result;
 
 bad_conn:
-	PARANOIA("smb_trans2_request: result=%d, setting invalid\n", result);
+	PARANOIA("result=%d, setting invalid\n", result);
 	server->state = CONN_INVALID;
 	smb_invalidate_inodes(server);
 	goto out;
diff -urN linux-2.2.17-pre13/fs/umsdos/README-WIP.txt linux/fs/umsdos/README-WIP.txt
--- linux-2.2.17-pre13/fs/umsdos/README-WIP.txt	Wed May  3 17:16:47 2000
+++ linux/fs/umsdos/README-WIP.txt	Mon Dec  3 22:10:13 2001
@@ -5,20 +5,16 @@
 There is no warning any more.
 Both read-only and read-write stuff is fixed, both in
 msdos-compatibile mode, and in umsdos EMD mode, and it seems stable.
-There are still few hardlink nuisances, but those are not fatal.
-
-I'd call it pre-release, and ask for as many people as possible to
-come and test it! See notes below for some more information, or if
-you are trying to use UMSDOS as root partition.
 
 Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
-will compile and work on 2.2.x kernels and glibc based systems may be found
-at http://cvs.linux.hr/
+will compile and work on 2.2.x+ kernels and glibc based systems, as well as
+kernel patches and other umsdos related information may be found at
+http://linux.voyager.hr/umsdos/
 
 Legend: those lines marked with '+' on the beggining of line indicates it
 passed all of my tests, and performed perfect in all of them.
 
-Current status (000123) - UMSDOS 0.85g:
+Current status (000729) - UMSDOS 0.85i:
 
 (1) pure MSDOS (no --linux-.--- EMD file):
 
@@ -29,7 +25,7 @@
 
 WRITE:
 + creat file			- works
-+ delete file			- works
++ unlink file			- works
 + write file			- works
 + rename file (same dir)	- works
 + rename file (dif. dir)	- works
@@ -49,7 +45,7 @@
 + read file			- works
 + switching MSDOS/UMSDOS	- works
 + switching UMSDOS/MSDOS	- works
-- pseudo root things		- works mostly. See notes below.
+- pseudo root things		- works. See notes below.
 + resolve symlink		- works
 + dereference symlink		- works
 + dangling symlink		- works
@@ -60,21 +56,21 @@
 
 WRITE:
 + create symlink		- works
-- create hardlink		- works for same DIR (see notes)
++ create hardlink		- works
 + create file			- works
 + create special file		- works
 + write to file			- works
 + rename file (same dir)	- works
 + rename file (dif. dir)	- works
 + rename hardlink (same dir)	- works
-- rename hardlink (dif. dir)	-
++ rename hardlink (dif. dir)	- works
 + rename symlink (same dir)	- works
 + rename symlink (dif. dir)	- works
 + rename dir (same dir)		- works
 + rename dir (dif. dir)		- works
 + delete file			- works
 + notify_change (chown,perms)	- works
-- delete hardlink		- works for same DIR (see notes)
++ delete hardlink		- works
 + mkdir				- works
 + rmdir 			- works
 + umssyncing (many ioctls)	- works
@@ -91,26 +87,13 @@
 Note: creating and using pseudo-hardlinks is always non-perfect, especially
 in filesystems that might be externally modified like umsdos. There is
 example is specs file about it. Specifically, moving directory which
-contains hardlinks will break them.
-
-Note: (about pseudoroot) If you are currently trying to use UMSDOS as root
-partition (with linux installed in c:\linux) it will boot, but there may be
-some problems. Volunteers ready to test pseudoroot are needed (preferably
-ones with working backups or unimportant data).  For example, '/DOS' pseudo
-directory is only partially re-implemented and buggy. It works most of the
-time, though. Update: should work ok in 0.84, although it still does not
-work correctly in combination with initrd featere. Working on this!
+contains hardlinks will break them in some cases.
 
 Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in
 pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice
 versa. Thanks to Sorin Iordachescu <sorin@rodae.ro> for providing fix.
-
-Warning: (about hardlinks) - modifying hardlinks (esp. if they are in
-different directories) are currently somewhat broken, I'm working on it.
-Problem seems to be that code uses and updates EMD of directory where 'real
-hardlink' is stored, not EMD of directory where our pseudo-hardlink is
-located! I'm looking for ideas how to work around this in clean way, since
-without it modifying hardlinks in any but most simple ways is broken!
+See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade
+procedure if you used broken versions...
 
 ------------------------------------------------------------------------------
 
@@ -124,6 +107,5 @@
 I'm unfortunately somewhat out of time to read linux-kernel@vger, but I do
 check for messages having "UMSDOS" in the subject, and read them.  I might
 miss some in all that volume, though.  I should reply to any direct e-mail
-in few days.  If I don't, probably I never got your message.  You can try
-mnalis-umsdos@voyager.hr; however mnalis@jagor.srce.hr is preferable.
+in few days.  If I don't, probably I never got your message.
 
diff -urN linux-2.2.17-pre13/fs/umsdos/emd.c linux/fs/umsdos/emd.c
--- linux-2.2.17-pre13/fs/umsdos/emd.c	Wed May  3 17:16:47 2000
+++ linux/fs/umsdos/emd.c	Mon Dec  3 22:10:13 2001
@@ -273,6 +273,16 @@
 	Printk ((KERN_DEBUG "umsdos_emd_dir_readentry /mn/: entering.\n"));
 
 	ret = umsdos_emd_dir_read (filp, (char *) entry, UMSDOS_REC_SIZE);
+
+	/* if this is an invalid entry (invalid name length), ignore it */
+	if( entry->name_len > UMSDOS_MAXNAME )
+	{
+		printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len);
+		entry->name_len = 0; 
+		ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */
+	}
+
+
 	if (ret == 0) {	/* if no error */
 		/* Variable size record. Maybe, we have to read some more */
 		int recsize = umsdos_evalrecsize (entry->name_len);
diff -urN linux-2.2.17-pre13/fs/umsdos/inode.c linux/fs/umsdos/inode.c
--- linux-2.2.17-pre13/fs/umsdos/inode.c	Wed May  3 17:16:47 2000
+++ linux/fs/umsdos/inode.c	Mon Dec  3 22:10:13 2001
@@ -56,8 +56,7 @@
 		 ,inode->i_count));
 
 	if (inode == pseudo_root) {
-		printk (KERN_ERR "Umsdos: Oops releasing pseudo_root."
-			" Notify jacques@solucorp.qc.ca\n");
+		printk (KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, inode->i_count);
 	}
 
 	if (inode->i_count == 1)
@@ -180,21 +179,6 @@
 }
 
 
-int umsdos_notify_change_locked(struct dentry *, struct iattr *);
-/*
- * lock the parent dir before starting ...
- */
-int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *dir = dentry->d_parent->d_inode;
-	int ret;
-
-	down(&dir->i_sem);
-	ret = umsdos_notify_change_locked(dentry, attr);
-	up(&dir->i_sem);
-	return ret;
-}
-
 /*
  * Must be called with the parent lock held.
  */
@@ -300,6 +284,65 @@
 
 
 /*
+ * lock the parent dir before starting ...
+ * also handles hardlink converting
+ */
+int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *dir;
+	struct umsdos_info info;
+	struct dentry *temp, *old_dentry = NULL;
+	int ret;
+
+	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
+				&info);
+	if (ret)
+		goto out;
+	ret = umsdos_findentry (dentry->d_parent, &info, 0);
+	if (ret) {
+printk("UMSDOS_notify_change: %s/%s not in EMD, ret=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, ret);
+		goto out;
+	}
+
+	if (info.entry.flags & UMSDOS_HLINK) {
+		/*
+		 * In order to get the correct (real) inode, we just drop
+		 * the original dentry.
+		 */ 
+		d_drop(dentry);
+Printk(("UMSDOS_notify_change: hard link %s/%s, fake=%s\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
+	
+		/* Do a real lookup to get the short name dentry */
+		temp = umsdos_covered(dentry->d_parent, info.fake.fname,
+						info.fake.len);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out;
+	
+		/* now resolve the link ... */
+		temp = umsdos_solve_hlink(temp);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out;
+		old_dentry = dentry;
+		dentry = temp;	/* so umsdos_notify_change_locked will operate on that */
+	}
+
+	dir = dentry->d_parent->d_inode;
+
+	down(&dir->i_sem);
+	ret = umsdos_notify_change_locked(dentry, attr);
+	up(&dir->i_sem);
+out:
+	if (old_dentry)
+		dput (dentry);	/* if we had to use fake dentry for hardlinks, dput() it now */
+	return ret;
+}
+
+
+/*
  * Update the disk with the inode content
  */
 void UMSDOS_write_inode (struct inode *inode)
@@ -332,11 +375,28 @@
 	UMSDOS_notify_change,	/* notify_change */
 	UMSDOS_put_super,	/* put_super */
 	NULL,			/* write_super */
-	fat_statfs,		/* statfs */
+	UMSDOS_statfs,		/* statfs */
 	NULL,			/* remount_fs */
 	fat_clear_inode,	/* clear_inode */
 };
 
+
+int UMSDOS_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
+{
+	int ret;
+	struct statfs tmp;
+	
+	ret = fat_statfs (sb, buf, bufsiz);
+	copy_from_user (&tmp, buf, bufsiz);
+	if (!ret) {
+		copy_from_user (&tmp, buf, bufsiz);
+		tmp.f_namelen = UMSDOS_MAXNAME;
+		copy_to_user (buf, &tmp, bufsiz);
+	}
+	return ret;
+}
+
+
 /*
  * Read the super block of an Extended MS-DOS FS.
  */
@@ -356,7 +416,7 @@
 	if (!res)
 		goto out_fail;
 
-	printk (KERN_INFO "UMSDOS 0.85g "
+	printk (KERN_INFO "UMSDOS 0.85i "
 		"(compatibility level %d.%d, fast msdos)\n", 
 		UMSDOS_VERSION, UMSDOS_RELEASE);
 
diff -urN linux-2.2.17-pre13/fs/umsdos/ioctl.c linux/fs/umsdos/ioctl.c
--- linux-2.2.17-pre13/fs/umsdos/ioctl.c	Tue Jan  4 10:12:24 2000
+++ linux/fs/umsdos/ioctl.c	Mon Dec  3 22:10:13 2001
@@ -179,6 +179,17 @@
 			struct umsdos_info info;
 
 			ret = umsdos_emd_dir_readentry (&new_filp, &entry);
+
+			if (ret == -ENAMETOOLONG) {
+				printk (KERN_INFO "Fixing EMD entry with invalid size -- zeroing out\n");
+				fill_new_filp (&new_filp, demd);
+				new_filp.f_pos = f_pos;
+				new_filp.f_reada = 0;
+				memset (&entry, 0, sizeof (entry));
+				ret = umsdos_emd_dir_write (&new_filp, (char *) &entry, UMSDOS_REC_SIZE);
+				continue;
+			}
+
 			if (ret)
 				break;
 			if (entry.name_len <= 0)
diff -urN linux-2.2.17-pre13/fs/umsdos/namei.c linux/fs/umsdos/namei.c
--- linux-2.2.17-pre13/fs/umsdos/namei.c	Wed May  3 17:16:47 2000
+++ linux/fs/umsdos/namei.c	Mon Dec  3 22:10:13 2001
@@ -715,17 +715,35 @@
 	if (ret == 0) {
 		struct iattr newattrs;
 
+		/* Do a real lookup to get the short name dentry */
+		temp = umsdos_covered(olddentry->d_parent,
+					old_info.fake.fname,
+					old_info.fake.len);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out_unlock2;
+
+		/* now resolve the link ... */
+		temp = umsdos_solve_hlink(temp);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out_unlock2;
+
 #ifdef UMSDOS_PARANOIA
 if (!oldinode->u.umsdos_i.i_is_hlink)
 printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino);
 #endif
-		oldinode->i_nlink++;
+		temp->d_inode->i_nlink++;
 Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name,
 oldinode->i_ino, oldinode->i_nlink));
 		newattrs.ia_valid = 0;
-		ret = umsdos_notify_change_locked(olddentry, &newattrs);
+		ret = umsdos_notify_change_locked(temp, &newattrs);
+ 		if (ret == 0)
+			mark_inode_dirty(temp->d_inode);
+		dput(temp);
+out_unlock2:	
 	}
 	if (olddir != dir)
 		up(&olddir->i_sem);
diff -urN linux-2.2.17-pre13/include/net/slhc_vj.h linux/include/net/slhc_vj.h
--- linux-2.2.17-pre13/include/net/slhc_vj.h	Sun Nov 30 14:00:39 1997
+++ linux/include/net/slhc_vj.h	Mon Dec  3 22:10:13 2001
@@ -115,6 +115,9 @@
 typedef __u8 byte_t;
 typedef __u32 int32;
 
+
+#include <linux/ip.h>
+#include <linux/tcp.h>
 /*
  * "state" data for each active tcp conversation on the wire.  This is
  * basically a copy of the entire IP/TCP header from the last packet
diff -urN linux-2.2.17-pre13/init/main.c linux/init/main.c
--- linux-2.2.17-pre13/init/main.c	Mon Dec  3 22:10:06 2001
+++ linux/init/main.c	Mon Dec  3 22:10:13 2001
@@ -58,6 +58,8 @@
 extern void nubus_init(void);
 #endif
 
+extern int irda_device_init(void);
+
 /*
  * Versions of gcc older than that listed below may actually compile
  * and link okay, but the end product can have subtle run time bugs.
diff -urN linux-2.2.17-pre13/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- linux-2.2.17-pre13/net/appletalk/ddp.c	Mon Dec  3 22:10:06 2001
+++ linux/net/appletalk/ddp.c	Mon Dec  3 22:10:13 2001
@@ -729,7 +729,7 @@
 
 	if(rt == NULL)
 	{
-		rt = (struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_KERNEL);
+		rt = (struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_ATOMIC);
 		if(rt == NULL) {
 			SOCKHASH_UNLOCK();
 			return (-ENOBUFS);
diff -urN linux-2.2.17-pre13/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- linux-2.2.17-pre13/net/ipv4/ip_fw.c	Tue Jan  4 10:12:26 2000
+++ linux/net/ipv4/ip_fw.c	Mon Dec  3 22:10:13 2001
@@ -740,7 +740,7 @@
 		for (; f; f = f->next) {
 			count++;
 			if (ip_rule_match(f,rif,ip,
-					  tcpsyn,src_port,dst_port,offset)) {
+					  tcpsyn,src_port,dst_port,offset!=0)) {
 				if (!testing
 				    && !ip_fw_domatch(f, ip, rif, chain->label,
 						      skb, slot, 
diff -urN linux-2.2.17-pre13/net/irda/irda_device.c linux/net/irda/irda_device.c
--- linux-2.2.17-pre13/net/irda/irda_device.c	Wed May  3 17:16:54 2000
+++ linux/net/irda/irda_device.c	Mon Dec  3 22:10:13 2001
@@ -63,6 +63,8 @@
 extern int tekram_init(void);
 extern int actisys_init(void);
 extern int girbil_init(void);
+extern int toshoboe_init(void);
+extern int litelink_init(void);
 
 static void __irda_task_delete(struct irda_task *task);
 
diff -urN linux-2.2.17-pre13/net/irda/irmod.c linux/net/irda/irmod.c
--- linux-2.2.17-pre13/net/irda/irmod.c	Wed May  3 17:16:54 2000
+++ linux/net/irda/irmod.c	Mon Dec  3 22:10:13 2001
@@ -73,7 +73,7 @@
 
 #ifdef CONFIG_IRDA_COMPRESSION
 #ifdef CONFIG_IRDA_DEFLATE
-extern irda_deflate_init();
+extern irda_deflate_init(void);
 #endif /* CONFIG_IRDA_DEFLATE */
 #endif /* CONFIG_IRDA_COMPRESSION */
 
diff -urN linux-2.2.17-pre13/net/irda/irttp.c linux/net/irda/irttp.c
--- linux-2.2.17-pre13/net/irda/irttp.c	Wed May  3 17:16:54 2000
+++ linux/net/irda/irttp.c	Mon Dec  3 22:10:13 2001
@@ -1528,9 +1528,9 @@
 			       self->remote_credit);
 		len += sprintf(buf+len, "send credit: %d\n",
 			       self->send_credit);
-		len += sprintf(buf+len, "  tx packets: %d, ",
+		len += sprintf(buf+len, "  tx packets: %ld, ",
 			       self->stats.tx_packets);
-		len += sprintf(buf+len, "rx packets: %d, ",
+		len += sprintf(buf+len, "rx packets: %ld, ",
 			       self->stats.rx_packets);
 		len += sprintf(buf+len, "tx_queue len: %d ", 
 			       skb_queue_len(&self->tx_queue));
