diff -u --recursive --new-file v2.1.23/linux/MAINTAINERS linux/MAINTAINERS
--- v2.1.23/linux/MAINTAINERS	Thu Jan 23 21:06:45 1997
+++ linux/MAINTAINERS	Mon Jan 27 11:14:37 1997
@@ -261,7 +261,7 @@
 
 PPP PROTOCOL DRIVERS AND COMPRESSORS
 P:	Al Longyear
-M:	longyear@netcom.com, Cc: longyear@sii.com
+M:	longyear@pobox.com
 L:	linux-ppp@vger.rutgers.edu
 S:	Maintained
 
diff -u --recursive --new-file v2.1.23/linux/Makefile linux/Makefile
--- v2.1.23/linux/Makefile	Tue Jan 28 18:49:45 1997
+++ linux/Makefile	Sun Jan 26 19:45:48 1997
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 23
+SUBLEVEL = 24
 
 ARCH = i386
 
diff -u --recursive --new-file v2.1.23/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c
--- v2.1.23/linux/arch/i386/boot/compressed/misc.c	Thu Jan 23 21:06:46 1997
+++ linux/arch/i386/boot/compressed/misc.c	Mon Jan 27 11:24:21 1997
@@ -356,7 +356,11 @@
 void setup_output_buffer_if_we_run_high(struct moveparams *mv)
 {
 	high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+#ifdef STANDARD_MEMORY_BIOS_CALL
 	if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
+#else
+	if (EXT_MEM_K*64 < (3*1024)) error("Less than 4MB of memory.\n");
+#endif	
 	mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
 	high_loaded = 1;
 	free_mem_end_ptr = (long)high_buffer_start;
diff -u --recursive --new-file v2.1.23/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.1.23/linux/arch/i386/kernel/smp.c	Tue Jan 28 18:49:47 1997
+++ linux/arch/i386/kernel/smp.c	Tue Jan 28 09:28:40 1997
@@ -638,11 +638,11 @@
 	load_ldt(0);
 	local_flush_tlb();
 	
-	while(!task[cpuid] || current_set[cpuid] != task[cpuid])
+	while (cpu_number_map[cpuid] == -1)
 		barrier();
 
-	if (cpu_number_map[cpuid] == -1)
-		while(1);
+	while(!task[cpuid] || current_set[cpuid] != task[cpu_number_map[cpuid]])
+		barrier();
 
 	local_flush_tlb();
 	load_TR(cpu_number_map[cpuid]);
diff -u --recursive --new-file v2.1.23/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.1.23/linux/drivers/block/floppy.c	Tue Jan 28 18:49:55 1997
+++ linux/drivers/block/floppy.c	Tue Jan 28 10:02:45 1997
@@ -4128,7 +4128,6 @@
 extern char *get_options(char *str, int *ints);
 
 char *floppy=NULL;
-MODULE_PARM(floppy, "s");
 
 static void parse_floppy_cfg_string(char *cfg)
 {
diff -u --recursive --new-file v2.1.23/linux/drivers/block/triton.c linux/drivers/block/triton.c
--- v2.1.23/linux/drivers/block/triton.c	Sun Nov 10 20:12:10 1996
+++ linux/drivers/block/triton.c	Tue Jan 28 09:32:47 1997
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/block/triton.c	Version 1.13  Aug 12, 1996
+ *  linux/drivers/block/triton.c	Version 1.20  Jan 27, 1997
  *
- *  Copyright (c) 1995-1996  Mark Lord
+ *  Copyright (c) 1995-1997  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
  */
 
@@ -95,6 +95,9 @@
  * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe
  * (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this).
  *
+ * Thanks to "Christopher J. Reimer" <reimer@doe.carleton.ca> for fixing the
+ * problem with some (all?) ACER motherboards/BIOSs.
+ *
  * And, yes, Intel Zappa boards really *do* use the Triton IDE ports.
  */
 #include <linux/types.h>
@@ -143,7 +146,11 @@
  */
 #define PRD_BYTES	8
 #define PRD_ENTRIES	(PAGE_SIZE / (2 * PRD_BYTES))
-#define DEFAULT_BMIBA	0xe800	/* in case BIOS did not init it */
+
+/*
+ * Interface to access piix registers
+ */
+static unsigned int piix_key;
 
 /*
  * dma_intr() is the handler for disk read/write DMA interrupts
@@ -366,6 +373,53 @@
 	printk("\n");
 }
 
+/* The next two functions were stolen from cmd640.c, with
+   a few modifications  */
+
+static void put_piix_reg (unsigned short reg, long val)
+{
+  unsigned long flags;
+
+  save_flags(flags);
+  cli();
+  outl_p((reg & 0xfc) | piix_key, 0xcf8);
+  outl_p(val, (reg & 3) | 0xcfc);
+  restore_flags(flags);
+}
+
+static long get_piix_reg (unsigned short reg)
+{
+  long b;
+  unsigned long flags;
+
+  save_flags(flags);
+  cli();
+  outl_p((reg & 0xfc) | piix_key, 0xcf8);
+  b = inl_p((reg & 3) | 0xcfc);
+  restore_flags(flags);
+  return b;
+}
+
+/*
+ * Search for an (apparently) unused block of I/O space
+ * of "size" bytes in length.
+ */
+static short find_free_region (unsigned short size)
+{
+	unsigned short i, base = 0xe800;
+	for (base = 0xe800; base > 0; base -= 0x800) {
+		if (!check_region(base,size)) {
+			for (i = 0; i < size; i++) {
+				if (inb(base+i) != 0xff)
+					goto next;
+			}
+			return base;	/* success */
+		}
+	next:
+	}
+	return 0;	/* failure */
+}
+
 /*
  * ide_init_triton() prepares the IDE driver for DMA operation.
  * This routine is called once, from ide.c during driver initialization,
@@ -379,8 +433,9 @@
 	unsigned int bmiba, timings;
 
 	printk("ide: i82371 PIIX (Triton) on PCI bus %d function %d\n", bus, fn);
+
 	/*
-	 * See if IDE and BM-DMA features are enabled:
+	 * See if IDE ports are enabled
 	 */
 	if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))
 		goto quit;
@@ -388,42 +443,44 @@
 		printk("ide: ports are not enabled (BIOS)\n");
 		goto quit;
 	}
+	if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
+		goto quit;
+	if (!(timings & 0x80008000)) {
+		printk("ide: neither port is enabled\n");
+		goto quit;
+	}
+
+	/*
+	 * See if Bus-Mastered DMA is enabled
+	 */
 	if ((pcicmd & 4) == 0) {
 		printk("ide: BM-DMA feature is not enabled (BIOS)\n");
 	} else {
 		/*
 		 * Get the bmiba base address
 		 */
-		int try_again = 1;
-		do {
-			if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
-				goto quit;
-			bmiba &= 0xfff0;	/* extract port base address */
-			if (bmiba) {
-				dma_enabled = 1;
-				break;
-			} else {
-				printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
-				if (inb(DEFAULT_BMIBA) != 0xff || !try_again)
-					break;
-				printk("ide: setting BM-DMA base register to 0x%04x\n", DEFAULT_BMIBA);
-				if ((rc = pcibios_write_config_word(bus, fn, 0x04, pcicmd&~1)))
-					goto quit;
-				rc = pcibios_write_config_dword(bus, fn, 0x20, DEFAULT_BMIBA|1);
-				if (pcibios_write_config_word(bus, fn, 0x04, pcicmd|5) || rc)
-					goto quit;
+		if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
+			goto quit;
+		bmiba &= 0xfff0;	/* extract port base address */
+		if (bmiba) {
+			dma_enabled = 1;
+		} else {
+			unsigned short base;
+		        printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
+			base = find_free_region(16);
+		        if (base) {
+				printk("ide: bypassing BIOS; setting BMIBA to 0x%04x\n", base);
+				piix_key = 0x80000000 + (fn * 0x100);
+				put_piix_reg(0x04,get_piix_reg(0x04)&~5);
+				put_piix_reg(0x20,(get_piix_reg(0x20)&0xFFFF000F)|base|1);
+				put_piix_reg(0x04,get_piix_reg(0x04)|5);
+				bmiba = get_piix_reg(0x20)&0x0000FFF0;
+				if (bmiba == base && (get_piix_reg(0x04) & 5) == 5)
+					dma_enabled = 1;
+				else
+					printk("ide: no such luck; DMA disabled\n");
 			}
-		} while (try_again--);
-	}
-
-	/*
-	 * See if ide port(s) are enabled
-	 */
-	if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
-		goto quit;
-	if (!(timings & 0x80008000)) {
-		printk("ide: neither port is enabled\n");
-		goto quit;
+		}
 	}
 
 	/*
diff -u --recursive --new-file v2.1.23/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.1.23/linux/drivers/char/rtc.c	Tue Jan 28 18:50:01 1997
+++ linux/drivers/char/rtc.c	Mon Jan 27 11:24:28 1997
@@ -54,6 +54,7 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/poll.h>
 
 /*
  *	We sponge a minor off of the misc major. No need slurping
diff -u --recursive --new-file v2.1.23/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v2.1.23/linux/drivers/char/softdog.c	Thu Dec 12 19:37:02 1996
+++ linux/drivers/char/softdog.c	Tue Jan 28 10:02:45 1997
@@ -46,6 +46,7 @@
  
 struct timer_list watchdog_ticktock;
 static int timer_alive = 0;
+static int in_use = 0;
 
 
 /*
@@ -70,8 +71,9 @@
  
 static int softdog_open(struct inode *inode, struct file *file)
 {
-	if(timer_alive)
+	if(in_use)
 		return -EBUSY;
+	in_use = 1;
 	MOD_INC_USE_COUNT;
 	/*
 	 *	Activate timer
@@ -94,6 +96,7 @@
 	MOD_DEC_USE_COUNT;
 	timer_alive=0;
 #endif	
+	in_use = 0;
 }
 
 static void softdog_ping(void)
diff -u --recursive --new-file v2.1.23/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v2.1.23/linux/drivers/net/ppp.c	Tue Jan 28 18:50:02 1997
+++ linux/drivers/net/ppp.c	Mon Jan 27 11:14:37 1997
@@ -6,7 +6,7 @@
  *  Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
  *  ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
  *
- *  ==FILEVERSION 960528==
+ *  ==FILEVERSION 970126==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the number above to the
@@ -138,7 +138,6 @@
 
 static int rcv_proto_ip		(struct ppp *, __u16, __u8 *, int);
 static int rcv_proto_ipx	(struct ppp *, __u16, __u8 *, int);
-static int rcv_proto_ipv6	(struct ppp *, __u16, __u8 *, int);
 static int rcv_proto_vjc_comp	(struct ppp *, __u16, __u8 *, int);
 static int rcv_proto_vjc_uncomp (struct ppp *, __u16, __u8 *, int);
 static int rcv_proto_unknown	(struct ppp *, __u16, __u8 *, int);
@@ -266,7 +265,6 @@
 ppp_proto_type proto_list[] = {
 	{ PPP_IP,	  rcv_proto_ip	       },
 	{ PPP_IPX,	  rcv_proto_ipx	       },
-	{ PPP_IPV6,	  rcv_proto_ipv6       },
 	{ PPP_VJC_COMP,	  rcv_proto_vjc_comp   },
 	{ PPP_VJC_UNCOMP, rcv_proto_vjc_uncomp },
 	{ PPP_LQR,	  rcv_proto_lqr	       },
@@ -1230,18 +1228,6 @@
 }
 
 /*
- * Process the receipt of an IPV6 frame
- */
-
-static int
-rcv_proto_ipv6 (struct ppp *ppp, __u16 proto, __u8 * data, int count)
-{
-	if (((ppp2dev (ppp)->flags & IFF_UP) != 0) && (count > 0))
-		return ppp_rcv_rx (ppp, htons (ETH_P_IPV6), data, count);
-	return 0;
-}
-
-/*
  * Process the receipt of an VJ Compressed frame
  */
 
@@ -3074,10 +3060,6 @@
 
 	case ETH_P_IP:
 		answer = ppp_dev_xmit_ip (dev, ppp, data);
-		break;
-
-	case ETH_P_IPV6:
-		answer = ppp_dev_xmit_ipx (dev, ppp, data, len, PPP_IPV6);
 		break;
 
 	default: /* All others have no support at this time. */
diff -u --recursive --new-file v2.1.23/linux/drivers/sbus/char/sunkeymap.c linux/drivers/sbus/char/sunkeymap.c
--- v2.1.23/linux/drivers/sbus/char/sunkeymap.c	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/sunkeymap.c	Mon Jan 27 10:42:54 1997
@@ -65,7 +65,7 @@
 u_short ctrl_map[NR_KEYS] = {
 	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf100,	0xf101,	0xf109,
 	0xf102,	0xf10a,	0xf103,	0xf10b,	0xf104,	0xf701,	0xf105,	0xf200,
-	0xf107,	0xf200,	0xf108,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf204,
+	0xf106,	0xf107,	0xf108,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf204,
 	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf200,	0xf200,	0xf000,
 	0xf01b,	0xf01c,	0xf01d,	0xf01e,	0xf01f,	0xf07f,	0xf200,	0xf200,
 	0xf01f,	0xf200,	0xf000,	0xf008,	0xf115,	0xf200,	0xf30d,	0xf30c,
@@ -103,7 +103,7 @@
 u_short alt_map[NR_KEYS] = {
 	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf500,	0xf501,	0xf509,
 	0xf502,	0xf50a,	0xf503,	0xf50b,	0xf504,	0xf701,	0xf505,	0xf200,
-	0xf507,	0xf200,	0xf508,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf209,
+	0xf506,	0xf507,	0xf508,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf209,
 	0xf210,	0xf200,	0xf200,	0xf600,	0xf211,	0xf81b,	0xf831,	0xf832,
 	0xf833,	0xf834,	0xf835,	0xf836,	0xf837,	0xf838,	0xf839,	0xf830,
 	0xf82d,	0xf83d,	0xf860,	0xf87f,	0xf115,	0xf200,	0xf30d,	0xf30c,
@@ -122,7 +122,7 @@
 u_short ctrl_alt_map[NR_KEYS] = {
 	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf500,	0xf501,	0xf509,
 	0xf502,	0xf50a,	0xf503,	0xf50b,	0xf504,	0xf701,	0xf505,	0xf200,
-	0xf507,	0xf200,	0xf508,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf200,
+	0xf506,	0xf507,	0xf508,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf200,
 	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf200,	0xf200,	0xf200,
 	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
 	0xf200,	0xf200,	0xf200,	0xf200,	0xf115,	0xf200,	0xf30d,	0xf30c,
diff -u --recursive --new-file v2.1.23/linux/drivers/sbus/char/sunkeymap.map linux/drivers/sbus/char/sunkeymap.map
--- v2.1.23/linux/drivers/sbus/char/sunkeymap.map	Wed Dec 18 15:58:48 1996
+++ linux/drivers/sbus/char/sunkeymap.map	Mon Jan 27 10:42:54 1997
@@ -51,13 +51,13 @@
 # BLANK KEY on type 5 keyboards
 keycode 0x0f =
 keycode 0x10 = F7			F17	Console_19
-	control	Keycode			0x10 = F7
+	control	keycode			0x10 = F7
 	alt	keycode			0x10 = Console_7
 	control	alt	keycode		0x10 = Console_7
 keycode 0x11 = F8			F18	Console_20
-	control	keycode			0x10 = F8
-	alt	keycode			0x10 = Console_8
-	control	alt	keycode		0x10 = Console_8
+	control	keycode			0x11 = F8
+	alt	keycode			0x11 = Console_8
+	control	alt	keycode		0x11 = Console_8
 keycode 0x12 = F9			F19	Console_21
 	control	keycode			0x12 = F9
 	alt	keycode			0x12 = Console_9
diff -u --recursive --new-file v2.1.23/linux/drivers/scsi/AM53C974.h linux/drivers/scsi/AM53C974.h
--- v2.1.23/linux/drivers/scsi/AM53C974.h	Sat Oct  5 16:58:34 1996
+++ linux/drivers/scsi/AM53C974.h	Mon Jan 27 10:42:54 1997
@@ -194,12 +194,12 @@
 #define CNTLREG2	    	0x2C	/* rw	control register two		   */
 #define CNTLREG2_ENF		0x40	/* enable features			   */
 
-#define CNTLREG3	    	0x30	/* rw	control register three		   */ 
+#define CNTLREG3	    	0x30	/* rw	control register three		   */
 #define CNTLREG3_ADIDCHK	0x80	/* additional ID check			   */
 #define CNTLREG3_FASTSCSI	0x10	/* fast SCSI				   */
 #define CNTLREG3_FASTCLK	0x08	/* fast SCSI clocking			   */
 
-#define CNTLREG4	    	0x34	/* rw	control register four		   */ 
+#define CNTLREG4	    	0x34	/* rw	control register four		   */
 #define CNTLREG4_GLITCH		0xC0	/* glitch eater				   */
 #define CNTLREG4_PWD		0x20	/* reduced power feature		   */
 #define CNTLREG4_RAE		0x08	/* write only, active negot. ctrl.	   */
@@ -268,7 +268,7 @@
 
 #define AM53C974 { \
     NULL,              		/* pointer to next in list                      */  \
-    NULL,			/* long * usage_count				*/  \
+    NULL,			/* struct module *module			*/  \
     &proc_scsi_am53c974,        /* struct proc_dir_entry *proc_dir              */ \
     NULL,                       /* int (*proc_info)(char *, char **, off_t, int, int, int); */ \
     "AM53C974",        		/* name                                         */  \
diff -u --recursive --new-file v2.1.23/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog
--- v2.1.23/linux/drivers/scsi/ChangeLog	Tue Jan 28 18:50:10 1997
+++ linux/drivers/scsi/ChangeLog	Mon Jan 27 10:36:13 1997
@@ -1,4 +1,4 @@
-Sat Jan 18 15:51:45 1997  Richard Henderson  <richard@twiddle.rth.home>
+Sat Jan 18 15:51:45 1997  Richard Henderson  <rth@tamu.edu>
 
 	* Don't play with usage_count directly, instead hand around
 	the module header and use the module macros.
diff -u --recursive --new-file v2.1.23/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
--- v2.1.23/linux/drivers/sound/audio.c	Tue Oct 29 19:58:14 1996
+++ linux/drivers/sound/audio.c	Tue Jan 28 10:02:45 1997
@@ -12,7 +12,7 @@
  * for more info.
  */
 #include <linux/config.h>
-
+#include <linux/poll.h>
 
 #include "sound_config.h"
 
@@ -542,44 +542,31 @@
    */
 }
 
-int
-audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+audio_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
   char           *dma_buf;
+  unsigned int	  mask = 0;
   int             buf_no, buf_ptr, buf_size;
 
   dev = dev >> 4;
 
-  switch (sel_type)
-    {
-    case SEL_IN:
-      if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
-	{
-	  return 0;		/* Not recording */
-	}
-
-      return DMAbuf_select (dev, file, sel_type, wait);
-      break;
-
-    case SEL_OUT:
-      if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX))
-	{
-	  return 0;		/* Wrong direction */
-	}
-
-      if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
-	{
-	  return 1;		/* There is space in the current buffer */
-	}
-
-      return DMAbuf_select (dev, file, sel_type, wait);
-      break;
+  mask = DMAbuf_poll (dev, file, wait);
 
-    case SEL_EX:
-      return 0;
-    }
+/* sel_in */
+  if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
+    mask &= ~(POLLIN | POLLRDNORM); /* Wrong direction */
+
+/* sel_out */
+  if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX)) {
+    mask &= ~(POLLOUT | POLLWRNORM); /* Wrong direction */
+    goto sel_ex;
+  }
+  if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
+    mask |= POLLOUT | POLLWRNORM;
 
-  return 0;
+ sel_ex:
+  return mask;
 }
 
 
diff -u --recursive --new-file v2.1.23/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c
--- v2.1.23/linux/drivers/sound/dmabuf.c	Thu Dec 12 17:02:44 1996
+++ linux/drivers/sound/dmabuf.c	Tue Jan 28 10:02:45 1997
@@ -11,7 +11,7 @@
  * for more info.
  */
 #include <linux/config.h>
-
+#include <linux/poll.h>
 
 #include "sound_config.h"
 
@@ -1834,109 +1834,70 @@
 {
 }
 
-int
-DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+DMAbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
+  unsigned int mask = 0;
   struct dma_buffparms *dmap;
   unsigned long   flags;
 
-  switch (sel_type)
-    {
-    case SEL_IN:
-      if (!(audio_devs[dev]->open_mode))
-	return 0;
-
-      dmap = audio_devs[dev]->dmap_in;
-
-      if (dmap->mapping_flags & DMA_MAP_MAPPED)
-	{
-	  if (dmap->qlen)
-	    return 1;
-
-	  save_flags (flags);
-	  cli ();
-
-	  in_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&in_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-
-      if (dmap->dma_mode != DMODE_INPUT)
-	{
-	  if (dmap->dma_mode == DMODE_NONE &&
-	      audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
-	      !dmap->qlen &&
-	      audio_devs[dev]->go)
-	    {
-	      unsigned long   flags;
-
-	      save_flags (flags);
-	      cli ();
-	      activate_recording (dev, dmap);
-	      restore_flags (flags);
-	    }
-	  return 0;
-	}
-
-      if (!dmap->qlen)
-	{
-	  save_flags (flags);
-	  cli ();
-
-	  in_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&in_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      return 1;
-      break;
-
-    case SEL_OUT:
-      dmap = audio_devs[dev]->dmap_out;
-
-      if (dmap->mapping_flags & DMA_MAP_MAPPED)
-	{
-	  if (dmap->qlen)
-	    return 1;
+  save_flags (flags);
+  cli ();
 
-	  save_flags (flags);
-	  cli ();
+  in_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&in_sleeper[dev], wait);
+  out_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&out_sleeper[dev], wait);
 
-	  out_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&out_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-
-      if (dmap->dma_mode == DMODE_INPUT)
-	{
-	  return 0;
-	}
+  restore_flags (flags);
 
-      if (dmap->dma_mode == DMODE_NONE)
-	{
-	  return 1;
-	}
+/* sel_in */
+  dmap = audio_devs[dev]->dmap_in;
+  if (!(audio_devs[dev]->open_mode))
+    goto sel_out;
+  if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+    if (dmap->qlen)
+      mask |= POLLIN | POLLRDNORM;
+    goto sel_out;
+  }
+  if (dmap->dma_mode != DMODE_INPUT) {
+    if (dmap->dma_mode == DMODE_NONE &&
+	audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
+	!dmap->qlen &&
+	audio_devs[dev]->go) {
+      unsigned long   flags;
 
-      if (!space_in_queue (dev))
-	{
-	  save_flags (flags);
-	  cli ();
+      save_flags (flags);
+      cli ();
+      activate_recording (dev, dmap);
+      restore_flags (flags);
+    }
+    goto sel_out;
+  }
+  if (!dmap->qlen)
+    goto sel_out;
+  mask |= POLLIN | POLLRDNORM;
 
-	  out_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&out_sleeper[dev], wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      return 1;
-      break;
+ sel_out:
+  dmap = audio_devs[dev]->dmap_out;
 
-    case SEL_EX:
-      return 0;
-    }
+  if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+    if (dmap->qlen)
+      mask |= POLLOUT | POLLWRNORM;
+    goto sel_ex;
+  }
+  if (dmap->dma_mode == DMODE_INPUT)
+    goto sel_ex;
+  if (dmap->dma_mode == DMODE_NONE) {
+    mask |= POLLOUT | POLLWRNORM;
+    goto sel_ex;
+  }
+  if (!space_in_queue (dev))
+    goto sel_ex;
+  mask |= POLLOUT | POLLWRNORM;
 
-  return 0;
+sel_ex:
+  return mask;
 }
 
 
diff -u --recursive --new-file v2.1.23/linux/drivers/sound/midibuf.c linux/drivers/sound/midibuf.c
--- v2.1.23/linux/drivers/sound/midibuf.c	Tue Oct 29 19:58:15 1996
+++ linux/drivers/sound/midibuf.c	Tue Jan 28 10:02:45 1997
@@ -11,6 +11,7 @@
  * for more info.
  */
 #include <linux/config.h>
+#include <linux/poll.h>
 
 
 #include "sound_config.h"
@@ -497,40 +498,21 @@
       }
 }
 
-int
-MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+MIDIbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
-  dev = dev >> 4;
-
-  switch (sel_type)
-    {
-    case SEL_IN:
-      if (!DATA_AVAIL (midi_in_buf[dev]))
-	{
-
-	  input_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&input_sleeper[dev], wait);
-	  return 0;
-	}
-      return 1;
-      break;
-
-    case SEL_OUT:
-      if (SPACE_AVAIL (midi_out_buf[dev]))
-	{
-
-	  midi_sleep_flag[dev].opts = WK_SLEEP;
-	  select_wait (&midi_sleeper[dev], wait);
-	  return 0;
-	}
-      return 1;
-      break;
-
-    case SEL_EX:
-      return 0;
-    }
+  unsigned int mask = 0;
 
-  return 0;
+  input_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&input_sleeper[dev], wait);
+  midi_sleep_flag[dev].opts = WK_SLEEP;
+  poll_wait (&midi_sleeper[dev], wait);
+
+  if (DATA_AVAIL (midi_in_buf[dev]))
+    mask |= POLLIN | POLLRDNORM;
+  if (!SPACE_AVAIL (midi_out_buf[dev]))
+    mask |= POLLOUT | POLLWRNORM;
+  return mask;
 }
 
 
diff -u --recursive --new-file v2.1.23/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c
--- v2.1.23/linux/drivers/sound/sequencer.c	Sat Nov 30 12:03:11 1996
+++ linux/drivers/sound/sequencer.c	Tue Jan 28 10:02:45 1997
@@ -11,6 +11,7 @@
  * for more info.
  */
 #include <linux/config.h>
+#include <linux/poll.h>
 
 
 #define SEQUENCER_C
@@ -1768,50 +1769,28 @@
   return -EINVAL;
 }
 
-int
-sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+sequencer_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
 {
+  unsigned int	  mask = 0;
   unsigned long   flags;
 
-  dev = dev >> 4;
-
-  switch (sel_type)
-    {
-    case SEL_IN:
-      save_flags (flags);
-      cli ();
-      if (!iqlen)
-	{
-
-	  midi_sleep_flag.opts = WK_SLEEP;
-	  select_wait (&midi_sleeper, wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      restore_flags (flags);
-      return 1;
-      break;
+  save_flags (flags);
+  cli ();
 
-    case SEL_OUT:
-      save_flags (flags);
-      cli ();
-      if ((SEQ_MAX_QUEUE - qlen) < output_threshold)
-	{
+  midi_sleep_flag.opts = WK_SLEEP;
+  poll_wait (&midi_sleeper, wait);
+  seq_sleep_flag.opts = WK_SLEEP;
+  poll_wait (&seq_sleeper, wait);
 
-	  seq_sleep_flag.opts = WK_SLEEP;
-	  select_wait (&seq_sleeper, wait);
-	  restore_flags (flags);
-	  return 0;
-	}
-      restore_flags (flags);
-      return 1;
-      break;
+  restore_flags (flags);
 
-    case SEL_EX:
-      return 0;
-    }
+  if (iqlen)
+    mask |= POLLIN | POLLRDNORM;
+  if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+    mask |= POLLOUT | POLLWRNORM;
 
-  return 0;
+  return mask;
 }
 
 
diff -u --recursive --new-file v2.1.23/linux/drivers/sound/sound_calls.h linux/drivers/sound/sound_calls.h
--- v2.1.23/linux/drivers/sound/sound_calls.h	Sat Nov 30 12:03:11 1996
+++ linux/drivers/sound/sound_calls.h	Tue Jan 28 10:02:45 1997
@@ -18,7 +18,7 @@
 void DMAbuf_reset_dma (int dev);
 void DMAbuf_inputintr(int dev);
 void DMAbuf_outputintr(int dev, int underflow_flag);
-int DMAbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int DMAbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 void DMAbuf_start_device(int dev);
 void DMAbuf_start_devices(unsigned int devmask);
 void DMAbuf_reset (int dev);
@@ -36,7 +36,7 @@
 	   unsigned int cmd, caddr_t arg);
 void audio_init_devices (void);
 
-int audio_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int audio_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 
 /*
  *	System calls for the /dev/sequencer
@@ -56,7 +56,7 @@
 void seq_input_event(unsigned char *event, int len);
 void seq_copy_to_input (unsigned char *event, int len);
 
-int sequencer_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int sequencer_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 
 /*
  *	System calls for the /dev/midi
@@ -72,7 +72,7 @@
 void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
 void MIDIbuf_init(void);
 
-int MIDIbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int MIDIbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
 
 /*
  *
diff -u --recursive --new-file v2.1.23/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v2.1.23/linux/drivers/sound/soundcard.c	Tue Jan 28 18:50:15 1997
+++ linux/drivers/sound/soundcard.c	Tue Jan 28 10:02:45 1997
@@ -192,29 +192,29 @@
   return err;
 }
 
-static int
-sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
+static unsigned int
+sound_poll (struct file *file, poll_table * wait)
 {
   int             dev;
 
-  dev = MINOR (inode->i_rdev);
+  dev = MINOR (file->f_inode->i_rdev);
 
   files[dev].flags = file->f_flags;
 
-  DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
+  DEB (printk ("sound_poll(dev=%d)\n", dev));
 
   switch (dev & 0x0f)
     {
 #ifdef CONFIG_SEQUENCER
     case SND_DEV_SEQ:
     case SND_DEV_SEQ2:
-      return sequencer_select (dev, &files[dev], sel_type, wait);
+      return sequencer_poll (dev, &files[dev], wait);
       break;
 #endif
 
 #ifdef CONFIG_MIDI
     case SND_DEV_MIDIN:
-      return MIDIbuf_select (dev, &files[dev], sel_type, wait);
+      return MIDIbuf_poll (dev, &files[dev], wait);
       break;
 #endif
 
@@ -222,7 +222,7 @@
     case SND_DEV_DSP:
     case SND_DEV_DSP16:
     case SND_DEV_AUDIO:
-      return audio_select (dev, &files[dev], sel_type, wait);
+      return audio_poll (dev, &files[dev], wait);
       break;
 #endif
 
@@ -327,7 +327,7 @@
   sound_read,
   sound_write,
   NULL,				/* sound_readdir */
-  sound_select,
+  sound_poll,
   sound_ioctl,
   sound_mmap,
   sound_open,
diff -u --recursive --new-file v2.1.23/linux/fs/binfmt_script.c linux/fs/binfmt_script.c
--- v2.1.23/linux/fs/binfmt_script.c	Tue Jan 28 18:50:16 1997
+++ linux/fs/binfmt_script.c	Tue Jan 28 10:02:45 1997
@@ -76,7 +76,6 @@
 	/*
 	 * OK, now restart the process with the interpreter's inode.
 	 */
-	bprm->filename = interp;
 	retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
 	if (retval)
 		return retval;
diff -u --recursive --new-file v2.1.23/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.1.23/linux/fs/proc/array.c	Tue Jan 28 18:50:19 1997
+++ linux/fs/proc/array.c	Tue Jan 28 10:02:45 1997
@@ -1011,6 +1011,7 @@
 extern int get_md_status (char *);
 extern int get_rtc_status (char *);
 extern int get_locks_status (char *);
+extern int get_swaparea_info (char *);
 #ifdef __SMP_PROF__
 extern int get_smp_prof_list(char *);
 #endif
@@ -1088,6 +1089,9 @@
 
                 case PROC_MTAB:
                        return get_filesystem_info( page );
+
+                case PROC_SWAP:
+                       return get_swaparea_info(page);
 #ifdef CONFIG_RTC
 		case PROC_RTC:
 			return get_rtc_status(page);
diff -u --recursive --new-file v2.1.23/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.1.23/linux/fs/proc/root.c	Tue Jan 28 18:50:22 1997
+++ linux/fs/proc/root.c	Tue Jan 28 10:02:45 1997
@@ -510,6 +510,10 @@
 	PROC_MTAB, 6, "mounts",
 	S_IFREG | S_IRUGO, 1, 0, 0,
 };
+static struct proc_dir_entry proc_root_swaps = {
+	PROC_MTAB, 5, "swaps",
+	S_IFREG | S_IRUGO, 1, 0, 0,
+};
 static struct proc_dir_entry proc_root_profile = {
 	PROC_PROFILE, 7, "profile",
 	S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
@@ -572,6 +576,7 @@
 	proc_register(&proc_root, &proc_root_locks);
 
 	proc_register(&proc_root, &proc_root_mounts);
+	proc_register(&proc_root, &proc_root_swaps);
 
 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
 #ifdef CONFIG_SUN_OPENPROMFS
diff -u --recursive --new-file v2.1.23/linux/include/asm-sparc/namei.h linux/include/asm-sparc/namei.h
--- v2.1.23/linux/include/asm-sparc/namei.h	Sun Dec 22 16:37:40 1996
+++ linux/include/asm-sparc/namei.h	Mon Jan 27 10:42:54 1997
@@ -1,4 +1,4 @@
-/* $Id: namei.h,v 1.1 1996/12/13 14:48:20 jj Exp $
+/* $Id: namei.h,v 1.3 1997/01/26 23:36:36 davem Exp $
  * linux/include/asm-sparc/namei.h
  *
  * Routines to handle famous /usr/gnemul/s*.
@@ -11,8 +11,7 @@
 #define SPARC_BSD_EMUL "usr/gnemul/sunos/"
 #define SPARC_SOL_EMUL "usr/gnemul/solaris/"
 
-#if 1
-#define gnemul_namei(pathname, base, follow_links, res_inode) ({					\
+#define translate_namei(pathname, base, follow_links, res_inode) ({					\
 	if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') {			\
 		struct inode *emul_ino;									\
 		int namelen;										\
@@ -31,11 +30,8 @@
 		base->i_count++;									\
 	}												\
 })
-#else
-#define gnemul_namei(pathname, base, follow_links, res_inode) do { } while (0)
-#endif
 
-#define gnemul_open_namei(pathname, flag, mode, res_inode, base) ({					\
+#define translate_open_namei(pathname, flag, mode, res_inode, base) ({					\
 	if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') {			\
 		struct inode *emul_ino;									\
 		int namelen;										\
diff -u --recursive --new-file v2.1.23/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.1.23/linux/include/linux/proc_fs.h	Tue Jan 28 18:50:56 1997
+++ linux/include/linux/proc_fs.h	Tue Jan 28 19:07:43 1997
@@ -43,6 +43,7 @@
 	PROC_CMDLINE,
 	PROC_SYS,
 	PROC_MTAB,
+	PROC_SWAP,
 	PROC_MD,
 	PROC_RTC,
 	PROC_LOCKS,
diff -u --recursive --new-file v2.1.23/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.1.23/linux/include/linux/sched.h	Tue Jan 28 18:50:56 1997
+++ linux/include/linux/sched.h	Tue Jan 28 19:07:32 1997
@@ -154,7 +154,7 @@
 #define INIT_MM { \
 		1, \
 		swapper_pg_dir, \
-		-1, \
+		0, \
 		0, 0, 0, 0, \
 		0, 0, 0, 0, \
 		0, 0, 0, 0, \
diff -u --recursive --new-file v2.1.23/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.1.23/linux/include/linux/swap.h	Sat Nov 30 12:03:11 1996
+++ linux/include/linux/swap.h	Tue Jan 28 10:02:45 1997
@@ -19,6 +19,7 @@
 struct swap_info_struct {
 	unsigned int flags;
 	kdev_t swap_device;
+	char *swap_filename;
 	struct inode * swap_file;
 	unsigned char * swap_map;
 	unsigned char * swap_lockmap;
diff -u --recursive --new-file v2.1.23/linux/include/net/sock.h linux/include/net/sock.h
--- v2.1.23/linux/include/net/sock.h	Tue Jan 28 18:50:56 1997
+++ linux/include/net/sock.h	Tue Jan 28 19:09:50 1997
@@ -293,6 +293,14 @@
  *	}
  */
 
+/* Define this to get the sk->debug debugging facility. */
+#define SOCK_DEBUGGING
+#ifdef SOCK_DEBUGGING
+#define SOCK_DEBUG(sk, msg...) if((sk) && ((sk)->debug)) printk(KERN_DEBUG ## msg)
+#else
+#define SOCK_DEBUG(sk, msg...) do { } while (0)
+#endif
+
 /*
  *  TCP will start to use the new protinfo while *still using the old* fields 
  */
diff -u --recursive --new-file v2.1.23/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.1.23/linux/include/net/tcp.h	Tue Jan 28 18:50:56 1997
+++ linux/include/net/tcp.h	Tue Jan 28 19:13:07 1997
@@ -432,8 +432,7 @@
 	sk->state = state;
 
 #ifdef STATE_TRACE
-	if(sk->debug)
-		printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
+	SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
 #endif	
 
 	switch (state) {
diff -u --recursive --new-file v2.1.23/linux/kernel/sched.c linux/kernel/sched.c
--- v2.1.23/linux/kernel/sched.c	Tue Jan 28 18:50:57 1997
+++ linux/kernel/sched.c	Tue Jan 28 18:41:42 1997
@@ -6,6 +6,7 @@
  *  1996-04-21	Modified by Ulrich Windl to make NTP work
  *  1996-12-23  Modified by Dave Grothe to fix bugs in semaphores and
  *              make semaphores SMP safe
+ *  1997-01-28  Modified by Finn Arne Gangstad to make timers scale better.
  */
 
 /*
@@ -630,73 +631,173 @@
 	__sleep_on(p,TASK_UNINTERRUPTIBLE);
 }
 
-/*
- * The head for the timer-list has a "expires" field of MAX_UINT,
- * and the sorting routine counts on this..
- */
-static struct timer_list timer_head = { &timer_head, &timer_head, ~0, 0, NULL };
+
+#define TVN_BITS 6
+#define TVR_BITS 8
+#define TVN_SIZE (1 << TVN_BITS)
+#define TVR_SIZE (1 << TVR_BITS)
+#define TVN_MASK (TVN_SIZE - 1)
+#define TVR_MASK (TVR_SIZE - 1)
+
 #define SLOW_BUT_DEBUGGING_TIMERS 0
 
-void add_timer(struct timer_list * timer)
+struct timer_vec {
+        int index;
+        struct timer_list *vec[TVN_SIZE];
+};
+
+struct timer_vec_root {
+        int index;
+        struct timer_list *vec[TVR_SIZE];
+};
+
+static struct timer_vec tv5 = { 0 };
+static struct timer_vec tv4 = { 0 };
+static struct timer_vec tv3 = { 0 };
+static struct timer_vec tv2 = { 0 };
+static struct timer_vec_root tv1 = { 0 };
+
+static struct timer_vec * const tvecs[] = {
+	(struct timer_vec *)&tv1, &tv2, &tv3, &tv4, &tv5
+};
+
+#define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
+
+static unsigned long timer_jiffies = 0;
+
+static inline void insert_timer(struct timer_list *timer,
+				struct timer_list **vec, int idx)
 {
-	unsigned long flags;
-	struct timer_list *p;
+	if ((timer->next = vec[idx]))
+		vec[idx]->prev = timer;
+	vec[idx] = timer;
+	timer->prev = (struct timer_list *)&vec[idx];
+}
 
-#if SLOW_BUT_DEBUGGING_TIMERS
-	if (timer->next || timer->prev) {
-		printk("add_timer() called with non-zero list from %p\n",
-			__builtin_return_address(0));
-		return;
+static inline void internal_add_timer(struct timer_list *timer)
+{
+	/*
+	 * must be cli-ed when calling this
+	 */
+	unsigned long expires = timer->expires;
+	unsigned long idx = expires - timer_jiffies;
+
+	if (idx < TVR_SIZE) {
+		int i = expires & TVR_MASK;
+		insert_timer(timer, tv1.vec, i);
+	} else if (idx < 1 << (TVR_BITS + TVN_BITS)) {
+		int i = (expires >> TVR_BITS) & TVN_MASK;
+		insert_timer(timer, tv2.vec, i);
+	} else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) {
+		int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK;
+		insert_timer(timer, tv3.vec, i);
+	} else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) {
+		int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
+		insert_timer(timer, tv4.vec, i);
+	} else if ((idx + 1UL) == 0UL) {
+		/* can happen if you add a timer with expires == jiffies */
+		insert_timer(timer, tv1.vec, tv1.index);
+	} else if (idx < 0xffffffffUL) {
+		int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
+		insert_timer(timer, tv5.vec, i);
+	} else {
+		/* Can only get here on architectures with 64-bit jiffies */
+		timer->next = timer->prev = timer;
 	}
-#endif
-	p = &timer_head;
+}
+
+void add_timer(struct timer_list *timer)
+{
+	unsigned long flags;
 	save_flags(flags);
 	cli();
-	do {
-		p = p->next;
-	} while (timer->expires > p->expires);
-	timer->next = p;
-	timer->prev = p->prev;
-	p->prev = timer;
-	timer->prev->next = timer;
+#if SLOW_BUT_DEBUGGING_TIMERS
+        if (timer->next || timer->prev) {
+                printk("add_timer() called with non-zero list from %p\n",
+		       __builtin_return_address(0));
+		goto out;
+        }
+#endif
+	internal_add_timer(timer);
+#if SLOW_BUT_DEBUGGING_TIMERS
+out:
+#endif
 	restore_flags(flags);
 }
 
-int del_timer(struct timer_list * timer)
+static inline int detach_timer(struct timer_list *timer)
 {
 	int ret = 0;
-	if (timer->next) {
-		unsigned long flags;
-		struct timer_list * next;
-		save_flags(flags);
-		cli();
-		if ((next = timer->next) != NULL) {
-			(next->prev = timer->prev)->next = next;
-			timer->next = timer->prev = NULL;
-			ret = 1;
-		}
-		restore_flags(flags);
+	struct timer_list *next, *prev;
+	next = timer->next;
+	prev = timer->prev;
+	if (next) {
+		next->prev = prev;
+	}
+	if (prev) {
+		ret = 1;
+		prev->next = next;
 	}
 	return ret;
 }
 
-static inline void run_timer_list(void)
+
+int del_timer(struct timer_list * timer)
+{
+	int ret;
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	ret = detach_timer(timer);
+	timer->next = timer->prev = 0;
+	restore_flags(flags);
+	return ret;
+}
+
+static inline void cascade_timers(struct timer_vec *tv)
 {
-	struct timer_list * timer;
+        /* cascade all the timers from tv up one level */
+        struct timer_list *timer;
+        timer = tv->vec[tv->index];
+        /*
+         * We are removing _all_ timers from the list, so we don't  have to
+         * detach them individually, just clear the list afterwards.
+         */
+        while (timer) {
+                struct timer_list *tmp = timer;
+                timer = timer->next;
+                internal_add_timer(tmp);
+        }
+        tv->vec[tv->index] = NULL;
+        tv->index = (tv->index + 1) & TVN_MASK;
+}
 
+static inline void run_timer_list(void)
+{
 	cli();
-	while ((timer = timer_head.next) != &timer_head && timer->expires <= jiffies) {
-		void (*fn)(unsigned long) = timer->function;
-		unsigned long data = timer->data;
-		timer->next->prev = timer->prev;
-		timer->prev->next = timer->next;
-		timer->next = timer->prev = NULL;
-		sti();
-		fn(data);
-		cli();
+	while ((long)(jiffies - timer_jiffies) >= 0) {
+		struct timer_list *timer;
+		if (!tv1.index) {
+			int n = 1;
+			do {
+				cascade_timers(tvecs[n]);
+			} while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
+		}
+		while ((timer = tv1.vec[tv1.index])) {
+			void (*fn)(unsigned long) = timer->function;
+			unsigned long data = timer->data;
+			detach_timer(timer);
+			timer->next = timer->prev = NULL;
+			sti();
+			fn(data);
+			cli();
+		}
+		++timer_jiffies; 
+		tv1.index = (tv1.index + 1) & TVR_MASK;
 	}
 	sti();
 }
+
 
 static inline void run_old_timers(void)
 {
diff -u --recursive --new-file v2.1.23/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.1.23/linux/mm/swapfile.c	Tue Jan 28 18:50:58 1997
+++ linux/mm/swapfile.c	Tue Jan 28 10:02:45 1997
@@ -18,6 +18,7 @@
 #include <linux/swap.h>
 #include <linux/fs.h>
 #include <linux/swapctl.h>
+#include <linux/malloc.h>
 #include <linux/blkdev.h> /* for blk_size */
 #include <linux/vmalloc.h>
 
@@ -393,6 +394,8 @@
 
 	nr_swap_pages -= p->pages;
 	iput(p->swap_file);
+	if (p->swap_filename)
+		kfree(p->swap_filename);
 	p->swap_file = NULL;
 	p->swap_device = 0;
 	vfree(p->swap_map);
@@ -406,6 +409,37 @@
 	return err;
 }
 
+int get_swaparea_info(char *buf)
+{
+	struct swap_info_struct *ptr = swap_info;
+	int i, j, len = 0, usedswap;
+
+	len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
+	for (i = 0 ; i < nr_swapfiles ; i++, ptr++)
+		if (ptr->flags & SWP_USED) {
+			if (ptr->swap_filename)
+				len += sprintf(buf + len, "%-31s ", ptr->swap_filename);
+			else
+				len += sprintf(buf + len, "(null)\t\t\t");
+			if (ptr->swap_file)
+				len += sprintf(buf + len, "file\t\t");
+			else
+				len += sprintf(buf + len, "partition\t");
+			usedswap = 0;
+			for (j = 0; j < ptr->max; ++j)
+				switch (ptr->swap_map[j]) {
+					case 128:
+					case 0:
+						continue;
+					default:
+						usedswap++;
+				}
+			len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10), 
+				usedswap << (PAGE_SHIFT - 10), ptr->prio);
+		}
+	return len;
+}
+
 /*
  * Written 01/25/92 by Simmule Turner, heavily changed by Linus.
  *
@@ -418,6 +452,7 @@
 	unsigned int type;
 	int i, j, prev;
 	int error = -EPERM;
+	char *tmp;
 	struct file filp;
 	static int least_priority = 0;
 
@@ -434,6 +469,7 @@
 	if (type >= nr_swapfiles)
 		nr_swapfiles = type+1;
 	p->flags = SWP_USED;
+	p->swap_filename = NULL;
 	p->swap_file = NULL;
 	p->swap_device = 0;
 	p->swap_map = NULL;
@@ -541,6 +577,12 @@
 		prev = i;
 	}
 	p->next = i;
+	if (!getname(specialfile, &tmp)) {
+		if ((p->swap_filename =
+		    (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
+			strcpy(p->swap_filename, tmp);
+		putname(tmp);
+	}
 	if (prev < 0) {
 		swap_list.head = swap_list.next = p - swap_info;
 	} else {
diff -u --recursive --new-file v2.1.23/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v2.1.23/linux/net/appletalk/ddp.c	Tue Jan 28 18:50:58 1997
+++ linux/net/appletalk/ddp.c	Mon Jan 27 11:04:48 1997
@@ -1484,8 +1484,7 @@
 
 	/* Build a packet */
 
-	if(sk->debug)
-		printk("SK %p: Got address.\n",sk);
+	SOCK_DEBUG(sk, "SK %p: Got address.\n",sk);
 
 	size=sizeof(struct ddpehdr)+len+ddp_dl->header_length;	/* For headers */
 
@@ -1507,8 +1506,7 @@
 		dev=rt->dev;
 	}
 
-	if(sk->debug)
-		printk("SK %p: Size needed %d, device %s\n", sk, size, dev->name);
+	SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name);
 
 	size += dev->hard_header_len;
 
@@ -1523,8 +1521,7 @@
 
 	skb->dev=dev;
 
-	if(sk->debug)
-		printk("SK %p: Begin build.\n", sk);
+	SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
 
 	ddp=(struct ddpehdr *)skb_put(skb,sizeof(struct ddpehdr));
 	ddp->deh_pad=0;
@@ -1544,8 +1541,7 @@
 	ddp->deh_dport=usat->sat_port;
 	ddp->deh_sport=sk->protinfo.af_at.src_port;
 
-	if(sk->debug)
-		printk("SK %p: Copy user data (%d bytes).\n", sk, len);
+	SOCK_DEBUG(sk, "SK %p: Copy user data (%d bytes).\n", sk, len);
 
 	err = memcpy_fromiovec(skb_put(skb,len),msg->msg_iov,len);
 	if (err)
@@ -1582,8 +1578,7 @@
 			if(skb2)
 			{
 				loopback=1;
-				if(sk->debug)
-					printk("SK %p: send out(copy).\n", sk);
+				SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
 				if(aarp_send_ddp(dev,skb2,&usat->sat_addr, NULL)==-1)
 					kfree_skb(skb2, FREE_WRITE);
 				/* else queued/sent above in the aarp queue */
@@ -1593,8 +1588,7 @@
 
 	if((dev->flags&IFF_LOOPBACK) || loopback)
 	{
-		if(sk->debug)
-			printk("SK %p: Loop back.\n", sk);
+		SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk);
 		/* loop back */
 		skb_orphan(skb);
 		ddp_dl->datalink_header(ddp_dl, skb, dev->dev_addr);
@@ -1606,9 +1600,7 @@
 	}
 	else
 	{
-		if(sk->debug)
-			printk("SK %p: send out.\n", sk);
-
+		SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
 		if ( rt->flags & RTF_GATEWAY ) {
 		    gsat.sat_addr = rt->gateway;
 		    usat = &gsat;
@@ -1618,8 +1610,7 @@
 			kfree_skb(skb, FREE_WRITE);
 		/* else queued/sent above in the aarp queue */
 	}
-	if(sk->debug)
-		printk("SK %p: Done write (%d).\n", sk, len);
+	SOCK_DEBUG(sk, "SK %p: Done write (%d).\n", sk, len);
 	return len;
 }
 
diff -u --recursive --new-file v2.1.23/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- v2.1.23/linux/net/ax25/af_ax25.c	Tue Jan 28 18:50:58 1997
+++ linux/net/ax25/af_ax25.c	Mon Jan 27 11:04:48 1997
@@ -1374,41 +1374,32 @@
 	else
 		sk->protinfo.ax25->source_addr = *call;
 
-	if (sk->debug)
-		printk("AX25: source address set to %s\n", ax2asc(&sk->protinfo.ax25->source_addr));
+	SOCK_DEBUG(sk, "AX25: source address set to %s\n", ax2asc(&sk->protinfo.ax25->source_addr));
 
 	if (addr_len == sizeof(struct full_sockaddr_ax25) && addr->fsa_ax25.sax25_ndigis == 1) {
 		if (ax25cmp(&addr->fsa_digipeater[0], &null_ax25_address) == 0) {
 			dev = NULL;
-			if (sk->debug)
-				printk("AX25: bound to any device\n");
+			SOCK_DEBUG(sk, "AX25: bound to any device\n");
 		} else {
 			if ((dev = ax25rtr_get_dev(&addr->fsa_digipeater[0])) == NULL) {
-				if (sk->debug)
-					printk("AX25: bind failed - no device\n");
+				SOCK_DEBUG(sk, "AX25: bind failed - no device\n");
 				return -EADDRNOTAVAIL;
 			}
-			if (sk->debug)
-				printk("AX25: bound to device %s\n", dev->name);
+			SOCK_DEBUG(sk, "AX25: bound to device %s\n", dev->name);
 		}
 	} else {
 		if ((dev = ax25rtr_get_dev(&addr->fsa_ax25.sax25_call)) == NULL) {
-			if (sk->debug)
-				printk("AX25: bind failed - no device\n");
+			SOCK_DEBUG(sk, "AX25: bind failed - no device\n");
 			return -EADDRNOTAVAIL;
 		}
-		if (sk->debug)
-			printk("AX25: bound to device %s\n", dev->name);
+		SOCK_DEBUG(sk, "AX25: bound to device %s\n", dev->name);
 	}
 
 	ax25_fillin_cb(sk->protinfo.ax25, dev);
 	ax25_insert_socket(sk->protinfo.ax25);
 
 	sk->zapped = 0;
-
-	if (sk->debug)
-		printk("AX25: socket is bound\n");
-
+	SOCK_DEBUG(sk, "AX25: socket is bound\n");
 	return 0;
 }
 
@@ -2028,12 +2019,10 @@
 		dp = sk->protinfo.ax25->digipeat;
 	}
 
-	if (sk->debug)
-		printk("AX.25: sendto: Addresses built.\n");
+	SOCK_DEBUG(sk, "AX.25: sendto: Addresses built.\n");
 
 	/* Build a packet */
-	if (sk->debug)
-		printk("AX.25: sendto: building packet.\n");
+	SOCK_DEBUG(sk, "AX.25: sendto: building packet.\n");
 
 	/* Assume the worst case */
 	size = len + 3 + size_ax25_addr(dp) + AX25_BPQ_HEADER_LEN;
@@ -2045,8 +2034,7 @@
 
 	skb_reserve(skb, size - len);
 
-	if (sk->debug)
-		printk("AX.25: Appending user data\n");
+	SOCK_DEBUG(sk, "AX.25: Appending user data\n");
 
 	/* User data follows immediately after the AX.25 data */
 	memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
@@ -2055,8 +2043,7 @@
 	asmptr  = skb_push(skb, 1);
 	*asmptr = sk->protocol;
 
-	if (sk->debug)
-		printk("AX.25: Transmitting buffer\n");
+	SOCK_DEBUG(sk, "AX.25: Transmitting buffer\n");
 
 	if (sk->type == SOCK_SEQPACKET) {
 		/* Connected mode sockets go via the LAPB machine */
@@ -2071,22 +2058,18 @@
 	} else {
 		asmptr = skb_push(skb, 1 + size_ax25_addr(dp));
 
-		if (sk->debug) {
-			printk("Building AX.25 Header (dp=%p).\n", dp);
-			if (dp != 0)
-				printk("Num digipeaters=%d\n", dp->ndigi);
-		}
+		SOCK_DEBUG(sk, "Building AX.25 Header (dp=%p).\n", dp);
+		if(dp != 0)
+			SOCK_DEBUG(sk, "Num digipeaters=%d\n", dp->ndigi);
 
 		/* Build an AX.25 header */
 		asmptr += (lv = build_ax25_addr(asmptr, &sk->protinfo.ax25->source_addr, &sax.sax25_call, dp, AX25_COMMAND, AX25_MODULUS));
 
-		if (sk->debug)
-			printk("Built header (%d bytes)\n",lv);
+		SOCK_DEBUG(sk, "Built header (%d bytes)\n",lv);
 
 		skb->h.raw = asmptr;
 
-		if (sk->debug)
-			printk("base=%p pos=%p\n", skb->data, asmptr);
+		SOCK_DEBUG(sk, "base=%p pos=%p\n", skb->data, asmptr);
 
 		*asmptr = AX25_UI;
 
diff -u --recursive --new-file v2.1.23/linux/net/ax25/ax25_subr.c linux/net/ax25/ax25_subr.c
--- v2.1.23/linux/net/ax25/ax25_subr.c	Thu Jan 23 21:06:54 1997
+++ linux/net/ax25/ax25_subr.c	Mon Jan 27 11:04:48 1997
@@ -528,8 +528,7 @@
 void ax25_dama_on(ax25_cb *ax25)
 {
 	if (ax25_dev_is_dama_slave(ax25->device) == 0) {
-		if (ax25->sk != NULL && ax25->sk->debug)
-			printk("ax25_dama_on: DAMA on\n");
+		SOCK_DEBUG(ax25->sk, "ax25_dama_on: DAMA on\n");
 		ax25_kiss_cmd(ax25, 5, 1);
 	}
 }
@@ -541,8 +540,7 @@
 
 	ax25->dama_slave = 0;
 	if (ax25_dev_is_dama_slave(ax25->device) == 0) {
-		if (ax25->sk != NULL && ax25->sk->debug)
-			printk("ax25_dama_off: DAMA off\n");
+		SOCK_DEBUG(ax25->sk, "ax25_dama_off: DAMA off\n");
 		ax25_kiss_cmd(ax25, 5, 0);
 	}
 }
diff -u --recursive --new-file v2.1.23/linux/net/ax25/ax25_timer.c linux/net/ax25/ax25_timer.c
--- v2.1.23/linux/net/ax25/ax25_timer.c	Thu Jan 23 21:06:54 1997
+++ linux/net/ax25/ax25_timer.c	Mon Jan 27 11:04:48 1997
@@ -149,8 +149,7 @@
 
 			ax25->state = AX25_STATE_0;
 			if (ax25->sk != NULL) {
-				if (ax25->sk->debug)
-					printk(KERN_DEBUG "AX.25 T3 Timeout\n");
+				SOCK_DEBUG(ax25->sk, "AX.25 T3 Timeout\n");
 				ax25->sk->state     = TCP_CLOSE;
 				ax25->sk->err       = ETIMEDOUT;
 				ax25->sk->shutdown |= SEND_SHUTDOWN;
@@ -298,8 +297,7 @@
 				ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
 				ax25->state = AX25_STATE_0;
 				if (ax25->sk != NULL) {
-					if (ax25->sk->debug)
-						printk(KERN_DEBUG "AX.25 link Failure\n");
+					SOCK_DEBUG(ax25->sk, "AX.25 link Failure\n");
 					ax25->sk->state     = TCP_CLOSE;
 					ax25->sk->err       = ETIMEDOUT;
 					ax25->sk->shutdown |= SEND_SHUTDOWN;
diff -u --recursive --new-file v2.1.23/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.1.23/linux/net/ipv4/tcp.c	Tue Jan 28 18:50:58 1997
+++ linux/net/ipv4/tcp.c	Mon Jan 27 11:05:37 1997
@@ -524,16 +524,13 @@
 	int sum;
 	unsigned long flags;
 
-	if(sk && sk->debug)
-	  	printk("tcp_readable: %p - ",sk);
-
+	SOCK_DEBUG(sk, "tcp_readable: %p - ",sk);
 	save_flags(flags);
 	cli();
 	if (sk == NULL || (skb = skb_peek(&sk->receive_queue)) == NULL)
 	{
 		restore_flags(flags);
-	  	if(sk && sk->debug)
-	  		printk("empty\n");
+		SOCK_DEBUG(sk, "empty\n");
 	  	return(0);
 	}
 
@@ -592,8 +589,7 @@
 	while(skb != (struct sk_buff *)&sk->receive_queue);
 
 	restore_flags(flags);
-	if(sk->debug)
-	  	printk("got %lu bytes.\n",amount);
+	SOCK_DEBUG(sk, "got %lu bytes.\n",amount);
 	return(amount);
 }
 
@@ -1043,9 +1039,6 @@
 			sk->write_seq += copy;
 		
 			tcp_send_skb(sk, skb);
-
-			release_sock(sk);
-			lock_sock(sk);
 		}
 	}
 
@@ -1159,7 +1152,7 @@
 
 static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb)
 {
-	sk->ack_backlog++;
+	sk->delayed_acks++;
 
 	__skb_unlink(skb, &sk->receive_queue);
 	kfree_skb(skb, FREE_READ);
@@ -1169,41 +1162,36 @@
 static void cleanup_rbuf(struct sock *sk)
 {
 	struct sk_buff *skb;
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	unsigned long pspace, rspace;
 
 	/*
 	 * NOTE! The socket must be locked, so that we don't get
 	 * a messed-up receive queue.
 	 */
 
-	pspace = sock_rspace(sk);
-	
 	while ((skb=skb_peek(&sk->receive_queue)) != NULL) {
 		if (!skb->used || skb->users>1)
 			break;
 		tcp_eat_skb(sk, skb);
 	}
-       
-	if(sk->debug)
-		printk("sk->rspace = %lu\n", sock_rspace(sk));
-	
+
+	SOCK_DEBUG(sk, "sk->rspace = %lu\n", sock_rspace(sk));
+
 	/*
 	 *  We send a ACK if the sender is blocked
 	 *  else let tcp_data deal with the acking policy.
 	 */
 
-	rspace = sock_rspace(sk);
-
-	if ((rspace > pspace) &&
-	    (rspace > tp->rcv_wnd - (tp->rcv_nxt - tp->rcv_wup)) && 
-	    (tp->rcv_wnd - (tp->rcv_nxt - tp->rcv_wup) < sk->mss)) 
+	if (sk->delayed_acks)
 	{
-		/* Send an ack right now. */
-		sk->delayed_acks++;
-		tcp_read_wakeup(sk);
-	}	
-} 
+		struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+		__u32 rcv_wnd;
+
+		rcv_wnd = tp->rcv_wnd - (tp->rcv_nxt - tp->rcv_wup);
+
+		if ((rcv_wnd < sk->mss) && (sock_rspace(sk) > rcv_wnd))
+			tcp_read_wakeup(sk);
+	}
+}
 
 
 /*
@@ -1413,7 +1401,8 @@
 			 */
 			*seq -= err;
 			atomic_dec(&skb->users);
-			return -EFAULT;
+			copied = -EFAULT;
+			break;
 		}
 
 		copied += used;
@@ -1467,7 +1456,7 @@
 					       msg->msg_name);       
 	}
 	if(addr_len)
-		*addr_len= tp->af_specific->sockaddr_len;
+		*addr_len = tp->af_specific->sockaddr_len;
 
 	remove_wait_queue(sk->sleep, &wait);
 	current->state = TASK_RUNNING;
@@ -1583,10 +1572,10 @@
 	/*
 	 *	FIN if needed
 	 */
-	 
+
 	if (tcp_close_state(sk,0))
 		tcp_send_fin(sk);
-		
+
 	release_sock(sk);
 }
 
diff -u --recursive --new-file v2.1.23/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.1.23/linux/net/ipv4/tcp_input.c	Thu Jan  2 15:55:27 1997
+++ linux/net/ipv4/tcp_input.c	Mon Jan 27 11:14:01 1997
@@ -301,7 +301,7 @@
  *  See draft-stevens-tcpca-spec-01 for documentation.
  */
 
-static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
+static void tcp_fast_retrans(struct sock *sk, u32 seq, u32 ack, int not_dup)
 {
 	struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp);
 
@@ -316,24 +316,24 @@
 	 *     The packet acked data after high_seq;
 	 */
 
-	if (ack == tp->snd_una && sk->packets_out && (not_dup == 0) &&
-	    after(ack, tp->high_seq))
+	if (ack == tp->snd_una && sk->packets_out && (not_dup == 0))
 	{
-		
-		sk->dup_acks++;	
-		
-
 		/*
 		 * 1. When the third duplicate ack is received, set ssthresh 
 		 * to one half the current congestion window, but no less 
 		 * than two segments. Retransmit the missing segment.
 		 */
-	
-		if (sk->dup_acks == 3) 
+
+		if (tp->high_seq == 0 || after(seq, tp->high_seq))
 		{
-			sk->ssthresh = max(sk->cong_window >> 1, 2);
-			sk->cong_window = sk->ssthresh + 3;
-			tcp_do_retransmit(sk, 0);
+			sk->dup_acks++;
+
+			if (sk->dup_acks == 3)
+			{
+				sk->ssthresh = max(sk->cong_window >> 1, 2);
+				sk->cong_window = sk->ssthresh + 3;
+				tcp_do_retransmit(sk, 0);
+			}
 		}
 
 		/*
@@ -343,9 +343,10 @@
 		 * Packet transmission will be done on normal flow processing
 		 * since we're not in "retransmit mode"
 		 */
-		
-		if (sk->dup_acks > 3) 
+
+		if (sk->dup_acks >= 3)
 		{
+			sk->dup_acks++;
 			sk->cong_window++;
 		}
 	}
@@ -358,13 +359,13 @@
 
 		if (sk->dup_acks >= 3)
 		{
-			sk->tp_pinfo.af_tcp.retrans_head = NULL;
+			tp->retrans_head = NULL;
 			sk->cong_window = sk->ssthresh;
 			sk->retransmits = 0;
 		}
 		sk->dup_acks = 0;
+		tp->high_seq = 0;
 	}
-	
 }
 
 /*
@@ -536,9 +537,11 @@
 		/* Check for a bug. */
 
 		if (skb->next != (struct sk_buff*) &sk->write_queue &&
-		    after(skb->end_seq, skb->next->seq)) 
-			printk("INET: tcp_input.c: *** "
+		    after(skb->end_seq, skb->next->seq))
+		{
+			printk(KERN_DEBUG "INET: tcp_input.c: *** "
 			       "bug send_list out of order.\n");
+		}
 #endif								
 		/*
 		 *	If our packet is before the ack sequence we can
@@ -549,12 +552,7 @@
 		if (after(skb->end_seq, ack))
 			break;
 		
-		if (sk->debug)
-		{
-			printk(KERN_DEBUG "removing seg %x-%x from "
-			       "retransmit queue\n", skb->seq, skb->end_seq);
-		}
-		
+		SOCK_DEBUG(sk, "removing seg %x-%x from retransmit queue\n", skb->seq, skb->end_seq);
 		acked = FLAG_DATA_ACKED;
 		
 		atomic_dec(&sk->packets_out);
@@ -624,19 +622,18 @@
 	if(sk->zapped)
 		return(1);	/* Dead, can't ack any more so why bother */
 
-	 
 	if (tp->pending == TIME_KEEPOPEN) 
 	{
 	  	tp->probes_out = 0;
 	}
 
 	tp->rcv_tstamp = jiffies;
-		
+
 	/*
 	 *	If the ack is newer than sent or older than previous acks
 	 *	then we can probably ignore it.
 	 */
-	 
+
 	if (after(ack, tp->snd_nxt) || before(ack, tp->snd_una))
 		goto uninteresting_ack;
 
@@ -660,27 +657,30 @@
 	 *	segments from shrinking the window 
 	 */
 
-	if ((tp->snd_wl1 == 0) || before(tp->snd_wl1, ack_seq) ||
+	if (before(tp->snd_wl1, ack_seq) ||
 	    (tp->snd_wl1 == ack_seq && !after(tp->snd_wl2, ack)))
 	{
-		tp->snd_wnd = ntohs(th->window);
-		tp->snd_wl1 = ack_seq;
-		tp->snd_wl2 = ack;
-
-		flag |= FLAG_WIN_UPDATE;
+		unsigned long nwin;
 
-		if (tp->snd_wnd > sk->max_window)
+		nwin = ntohs(th->window);
+		if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd))
 		{
-			sk->max_window = tp->snd_wnd;
+			flag |= FLAG_WIN_UPDATE;
+			tp->snd_wnd = nwin;
+
+			tp->snd_wl1 = ack_seq;
+			tp->snd_wl2 = ack;
+
+			if (nwin > sk->max_window)
+				sk->max_window = nwin;
 		}
 	}
 
-	
 	/*
 	 *	We passed data and got it acked, remove any soft error
 	 *	log. Something worked...
 	 */
-	 
+
 	sk->err_soft = 0;
 
 	/*
@@ -702,8 +702,8 @@
 		flag |= FLAG_DATA_ACKED;
 
 
-	/* 
-	 * if we where retransmiting don't count rtt estimate
+	/*
+	 *	if we where retransmiting don't count rtt estimate
 	 */
 
 	if (sk->retransmits)
@@ -728,38 +728,22 @@
 		if (flag & FLAG_DATA_ACKED)
 		{
 			tcp_rtt_estimator(tp, seq_rtt);
-			
+
 			(*tcp_sys_cong_ctl_f)(sk, seq, ack, seq_rtt);
 		}
 	}
 
-			
-#ifdef TCP_DEBUG
-
-	/* Sanity check out packets_out counter */
-	if (skb_queue_len(&sk->write_queue) == 0 || 
-	    ack == tp->snd_nxt ) 
-	{
-		if (sk->packets_out) 
-		{
-			printk(KERN_DEBUG "tcp_ack: packets_out %d\n",
-			       sk->packets_out);
-                        sk->packets_out = 0;
-                }
-	}
-#endif
-
 	if (sk->packets_out)
 	{
 		if (flag & FLAG_DATA_ACKED)
 		{
 			long when;
-				
+
 			skb = skb_peek(&sk->write_queue);
-		
+
 			when = tp->rto - (jiffies - skb->when);
-		
-			if (when <= 0) 
+
+			if (when <= 0)
 			{
 				tp->retrans_head = NULL;
 				/* 
@@ -770,32 +754,27 @@
 				tcp_reset_xmit_timer(sk, TIME_RETRANS,
 						     tp->rto);
 			}
-			else 
+			else
 				tcp_reset_xmit_timer(sk, TIME_RETRANS, when);
 		}
 	}
 	else
 		tcp_clear_xmit_timer(sk, TIME_RETRANS);
-	
+
+
+	tcp_fast_retrans(sk, ack_seq, ack, (flag & (FLAG_DATA|FLAG_WIN_UPDATE)));
 
 	/*
 	 *	Remember the highest ack received.
 	 */
-	 
-	tp->snd_una = ack;
-
-	tcp_fast_retrans(sk, ack, (flag & (FLAG_DATA|FLAG_WIN_UPDATE)));
 
+	tp->snd_una = ack;
 
 	return 1;
 
 uninteresting_ack:
 
-	tcp_fast_retrans(sk, ack, 0);
-
-	if(sk->debug)
-		printk("Ack ignored %u %u\n",ack,tp->snd_nxt);
-			
+	SOCK_DEBUG(sk, "Ack ignored %u %u\n", ack, tp->snd_nxt);
 	return 0;
 }
 
@@ -914,18 +893,13 @@
 			break;
 
 		if (!after(skb->end_seq, tp->rcv_nxt)) {
-
-			if (sk->debug)
-				printk("ofo packet was allready received \n");
-
+			SOCK_DEBUG(sk, "ofo packet already received \n");
 			skb_unlink(skb);
 			kfree_skb(skb, FREE_READ);
 			
 			continue;
 		}
-
-		if (sk->debug) 
-			printk("ofo requeuing : rcv_next %X seq %X - %X\n", 
+		SOCK_DEBUG(sk, "ofo requeuing : rcv_next %X seq %X - %X\n",
 			       tp->rcv_nxt, skb->seq, skb->end_seq);
 		
 		skb_unlink(skb);
@@ -982,10 +956,7 @@
 		 * 2nd most common case.
 		 * force an imediate ack
 		 */
-
-		if (sk->debug) 
-			printk("retransmit received: seq %X\n", skb->seq);
-
+		SOCK_DEBUG(sk, "retransmit received: seq %X\n", skb->seq);
 		sk->delayed_acks = MAX_DELAY_ACK;
 		kfree_skb(skb, FREE_READ);
 
@@ -999,13 +970,10 @@
 		 * Partial packet
 		 * seq < rcv_next < end_seq
 		 */
-
-		if (sk->debug) 
-			printk("partial packet: rcv_next %X seq %X - %X\n", 
+		SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n",
 			       tp->rcv_nxt, skb->seq, skb->end_seq);
-		
-		skb_queue_tail(&sk->receive_queue, skb);
 
+		skb_queue_tail(&sk->receive_queue, skb);
 
 		tp->rcv_nxt = skb->end_seq;
 
@@ -1014,15 +982,15 @@
 		if (skb_queue_len(&sk->out_of_order_queue) == 0)
 			tp->pred_flags = htonl((0x5010 << 16) | tp->snd_wnd);
 
-		return;		
+		return;
 	}
 
-	/* 
-	 * Ok. This is an out_of_order segment 
+	/*
+	 *	Ok. This is an out_of_order segment
 	 */
-	
+
 	/* Force an ack */
-	
+
 	sk->delayed_acks = MAX_DELAY_ACK;
 
 	/*
@@ -1031,8 +999,7 @@
 
 	tp->pred_flags = 0;
 
-	if (sk->debug) 
-		printk("out of order segment: rcv_next %X seq %X - %X\n", 
+	SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
 		       tp->rcv_nxt, skb->seq, skb->end_seq);
 
 	if (skb_peek(&sk->out_of_order_queue) == NULL) {
@@ -1055,7 +1022,7 @@
 				skb_append(skb1,skb);
 				break;
 			}
-			
+
                         /*
 			 *	See if we've hit the start. If so insert.
 			 */
@@ -1064,7 +1031,6 @@
 				break;
 			}
 		}
-			
 }
 
 
@@ -1096,9 +1062,9 @@
 	 *	The bytes in the receive read/assembly queue has increased. 
 	 *	Needed for the low memory discard algorithm 
 	 */
-	   
+
 	sk->bytes_rcv += skb->len;
-		
+
 	/*
 	 *	We no longer have anyone receiving data on this connection.
 	 */
@@ -1107,23 +1073,21 @@
 
 	if (before(tp->rcv_nxt, sk->copied_seq)) 
 	{
-		printk("*** tcp.c:tcp_data bug acked < copied\n");
+		printk(KERN_DEBUG "*** tcp.c:tcp_data bug acked < copied\n");
 		tp->rcv_nxt = sk->copied_seq;
 	}
 
 	sk->delayed_acks++;
-	
 
 	/*
 	 *	Now tell the user we may have some data. 
 	 */
-	 
-	if (!sk->dead) 
+
+	if (!sk->dead)
 	{
-        	if(sk->debug)
-        		printk("Data wakeup.\n");
+		SOCK_DEBUG(sk, "Data Wakeup.\n");
 		sk->data_ready(sk,0);
-	} 
+	}
 	return(1);
 }
 
@@ -1132,7 +1096,7 @@
 	struct sk_buff *skb;
 	struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp);
 
-	if ((skb = tp->send_head)) 
+	if ((skb = tp->send_head))
 	{
 		if (!after(skb->end_seq, tp->snd_una + tp->snd_wnd) &&
 		    sk->packets_out < sk->cong_window )
@@ -1151,9 +1115,9 @@
  			 *	Data to queue but no room.
  			 */
  			tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto);
- 		}		
+ 		}
 	}
-}	
+}
 
 static __inline__ void tcp_ack_snd_check(struct sock *sk)
 {
@@ -1168,15 +1132,20 @@
 	 */
 
 	if (sk->delayed_acks == 0)
+	{
+		/*
+		 *	We sent a data segment already
+		 */
 		return;
+	}
 
-	if (sk->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk)) 
+	if (sk->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk))
 	{
 		tcp_send_ack(sk);
 	}
-	else 
-	{	
-		tcp_send_delayed_ack(sk, HZ/2);		
+	else
+	{
+		tcp_send_delayed_ack(sk, HZ/2);
 	}
 }
 
@@ -1319,13 +1288,11 @@
 			if (len == sizeof(struct tcphdr))
 			{
 				tcp_ack(sk, th, skb->seq, skb->ack_seq, len);
+				tcp_data_snd_check(sk);
 			}
 
-			tcp_data_snd_check(sk);
-
 			kfree_skb(skb, FREE_READ);
 			return 0;
-			
 		}
 		else if (skb->ack_seq == tp->snd_una)
 		{
@@ -1342,12 +1309,14 @@
 			sk->data_ready(sk, 0);
 			tcp_delack_estimator(tp);
 
-			if (sk->delayed_acks++)
+			if (sk->delayed_acks++ == 0)
 			{
 				tcp_send_delayed_ack(sk, HZ/2);
 			}
 			else
+			{
 				tcp_send_ack(sk);
+			}
 
 			return 0;
 		}
@@ -1516,6 +1485,8 @@
 	   
 		if(th->ack)
 		{
+			tp->snd_wl1 = skb->seq;
+
 			/* We got an ack, but it's not a good ack */
 			if(!tcp_ack(sk,th, skb->seq, skb->ack_seq, len))
 			{
@@ -1730,19 +1701,19 @@
 			break;
 
 		case TCP_FIN_WAIT1:
-			
+
 			if (tp->snd_una == sk->write_seq) 
 			{
 				sk->shutdown |= SEND_SHUTDOWN;
 				tcp_set_state(sk, TCP_FIN_WAIT2);
-				if (!sk->dead) 
+				if (!sk->dead)
 					sk->state_change(sk);
 			}
 			break;
 
-		case TCP_CLOSING:			
+		case TCP_CLOSING:	
 
-			if (tp->snd_una == sk->write_seq) 
+			if (tp->snd_una == sk->write_seq)
 			{
 				tcp_time_wait(sk);
 			}
@@ -1750,7 +1721,7 @@
 
 		case TCP_LAST_ACK:
 
-			if (tp->snd_una == sk->write_seq) 
+			if (tp->snd_una == sk->write_seq)
 			{
 				sk->shutdown = SHUTDOWN_MASK;
 				tcp_set_state(sk,TCP_CLOSE);
@@ -1839,9 +1810,9 @@
 {
 	int val = sysctl_tcp_cong_avoidance;
 	int retv;
-	
-	retv  = proc_dointvec(ctl, write, filp, buffer, lenp);
-	
+
+	retv = proc_dointvec(ctl, write, filp, buffer, lenp);
+
 	if (write)
 	{
 		switch (sysctl_tcp_cong_avoidance) {
@@ -1856,13 +1827,6 @@
 				sysctl_tcp_cong_avoidance = val;
 		}
 	}
-	
+
 	return retv;
 }
-
-/*
- * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe -m486 -DCPU=486 -c -o tcp_input.o tcp_input.c"
- * c-file-style: "Linux"
- * End:
- */
diff -u --recursive --new-file v2.1.23/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.1.23/linux/net/ipv4/tcp_ipv4.c	Tue Jan 28 18:50:58 1997
+++ linux/net/ipv4/tcp_ipv4.c	Mon Jan 27 11:04:48 1997
@@ -346,7 +346,6 @@
 	struct tcphdr *th = (struct tcphdr*)(dp+(iph->ihl<<2));
 	int type = skb->h.icmph->type;
 	int code = skb->h.icmph->code;
-	struct tcp_opt *tp;
 	struct sock *sk;
 
 	sk = get_sock(&tcp_prot, th->source, iph->daddr, th->dest, iph->saddr);
@@ -356,19 +355,12 @@
 
 	if (type == ICMP_SOURCE_QUENCH)
 	{
-		/*
-		 * FIXME:
-		 * Follow BSD for now and just reduce cong_window to 1 again.
-		 * It is possible that we just want to reduce the
-		 * window by 1/2, or that we want to reduce ssthresh by 1/2
-		 * here as well.
-		 */
-
-		tp = &sk->tp_pinfo.af_tcp;
+		struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
 
-		sk->cong_window = 1;
+		sk->ssthresh = max(sk->cong_window >> 1, 2);
+		sk->cong_window = sk->ssthresh + 3;
 		tp->high_seq = tp->snd_nxt;
-		
+
 		return;
 	}
 
@@ -629,10 +621,7 @@
 	/* If the socket is dead, don't accept the connection.	*/
 	if (sk->dead)
 	{
-		if(sk->debug)
-		{
-			printk("Reset on %p: Connect on dead socket.\n",sk);
-		}
+		SOCK_DEBUG(sk, "Reset on %p: Connect on dead socket.\n",sk);
 		tcp_statistics.TcpAttemptFails++;
 		return -ENOTCONN;		
 	}
@@ -1229,10 +1218,3 @@
 	0, 0,
 	NULL
 };
-
-/*
- * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe -m486 -DCPU=486 -c -o tcp_ipv4.o tcp_ipv4.c"
- * c-file-style: "Linux"
- * End:
- */
diff -u --recursive --new-file v2.1.23/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.1.23/linux/net/ipv4/tcp_output.c	Thu Dec 12 19:37:30 1996
+++ linux/net/ipv4/tcp_output.c	Mon Jan 27 11:04:48 1997
@@ -377,7 +377,7 @@
 	 *	c) not retransmiting [Nagle]
 	 */
 
-	start_bh_atomic();
+	lock_sock(sk);
 
 	rcv_wnd = htons(tcp_select_window(sk));
 	
@@ -456,7 +456,7 @@
 		tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
 	}
 
-	end_bh_atomic();
+	release_sock(sk);
 }
 
 
@@ -637,7 +637,7 @@
 	int ct=0;
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 
-	start_bh_atomic();
+	lock_sock(sk);
 
 	if (tp->retrans_head == NULL)
 		tp->retrans_head = skb_peek(&sk->write_queue);
@@ -693,9 +693,7 @@
 			break;
 		}
 
-		if (sk->debug)
-			printk("retransmit sending\n");
-
+		SOCK_DEBUG(sk, "retransmit sending\n");
 		/*
 		 *	update ack and window
 		 */
@@ -705,13 +703,13 @@
 
 		size = skb->tail - (unsigned char *) th;
 		tp->af_specific->send_check(sk, th, size, skb);
-		
+
 		skb->when = jiffies;
 		buff = skb_clone(skb, GFP_ATOMIC);
 		skb_set_owner_w(buff, sk);
-		
+
 		clear_delayed_acks(sk);
-		
+
 		tp->af_specific->queue_xmit(buff);
 		
 		/*
@@ -722,14 +720,8 @@
 		sk->prot->retransmits ++;
 		tcp_statistics.TcpRetransSegs++;
 
-		/*
-		 * Record the high sequence number to help avoid doing
-		 * to much fast retransmission.
-		 */
+		tp->high_seq = tp->snd_nxt;
 
-		if (sk->retransmits)
-		       tp->high_seq = tp->snd_nxt;
-		
 		/*
 		 *	Only one retransmit requested.
 		 */
@@ -756,7 +748,7 @@
 		}
 	}
 
-	end_bh_atomic();
+	release_sock(sk);
 }
 
 /*
@@ -1035,12 +1027,8 @@
 
 	tp->af_specific->send_check(sk, th, sizeof(struct tcphdr), buff);
 
-  	if (sk->debug)
-  		 printk("\rtcp_send_ack: seq %x ack %x\n", 
-			tp->snd_nxt, tp->rcv_nxt);
-
+	SOCK_DEBUG(sk, "\rtcp_send_ack: seq %x ack %x\n", tp->snd_nxt, tp->rcv_nxt);
 	tp->af_specific->queue_xmit(buff);
-
   	tcp_statistics.TcpOutSegs++;
 }
 
diff -u --recursive --new-file v2.1.23/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.1.23/linux/net/ipv6/tcp_ipv6.c	Tue Jan 28 18:50:59 1997
+++ linux/net/ipv6/tcp_ipv6.c	Mon Jan 27 11:04:48 1997
@@ -477,10 +477,7 @@
 	/* If the socket is dead, don't accept the connection.	*/
 	if (sk->dead)
 	{
-		if(sk->debug)
-		{
-			printk("Reset on %p: Connect on dead socket.\n",sk);
-		}
+		SOCK_DEBUG(sk, "Reset on %p: Connect on dead socket.\n",sk);
 		tcp_statistics.TcpAttemptFails++;
 		return -ENOTCONN;		
 	}
diff -u --recursive --new-file v2.1.23/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v2.1.23/linux/net/ipx/af_ipx.c	Tue Jan 28 18:50:59 1997
+++ linux/net/ipx/af_ipx.c	Mon Jan 27 11:04:48 1997
@@ -1895,9 +1895,7 @@
 			sk->protinfo.af_ipx.node,
 			sk->protinfo.af_ipx.port) != NULL)
 		{
-			if(sk->debug)
-				printk("IPX: bind failed because port %X in"
-				       " use.\n", (int)addr->sipx_port);
+			SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port);
 			return -EADDRINUSE;
 		}
 	}
@@ -1912,9 +1910,7 @@
 			IPX_NODE_LEN);
 
 		if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
-			if(sk->debug)
-				printk("IPX: bind failed because port %X in"
-				       " use.\n", (int)addr->sipx_port);
+			SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port);
 			return -EADDRINUSE;
 		}
 	}
@@ -1925,9 +1921,7 @@
 	   an interface routed to IPX with the ipx routing ioctl() */
 
 	if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
-		if(sk->debug)
-			printk("IPX: bind failed because port %X in use.\n",
-				(int)addr->sipx_port);
+		SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port);
 		return -EADDRINUSE;
 	}
 
@@ -1935,8 +1929,7 @@
 
 	ipxitf_insert_socket(intrfc, sk);
 	sk->zapped=0;
-	if(sk->debug)
-		printk("IPX: socket is bound.\n");
+	SOCK_DEBUG(sk, "IPX: socket is bound.\n");
 	return 0;
 }
 
diff -u --recursive --new-file v2.1.23/linux/net/netbeui/netbeui.c linux/net/netbeui/netbeui.c
--- v2.1.23/linux/net/netbeui/netbeui.c	Tue Jan 28 18:50:59 1997
+++ linux/net/netbeui/netbeui.c	Mon Jan 27 11:04:48 1997
@@ -510,10 +510,7 @@
 	}
 
 	/* Build a packet */
-
-	if(sk->debug)
-		printk("SK %p: Got address.\n",sk);
-
+	SOCK_DEBUG(sk, "SK %p: Got address.\n",sk);
 	size=sizeof(struct ddpehdr)+len+nb_dl->header_length;	/* For headers */
 
 	if(usat->sat_addr.s_net!=0 || usat->sat_addr.s_node == ATADDR_ANYNODE)
@@ -533,12 +530,8 @@
 			return -ENETUNREACH;
 		dev=rt->dev;
 	}
-
-	if(sk->debug)
-		printk("SK %p: Size needed %d, device %s\n", sk, size, dev->name);
-
+	SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name);
 	size += dev->hard_header_len;
-
 	skb = sock_alloc_send_skb(sk, size, 0, 0 , &err);
 	if(skb==NULL)
 		return err;
@@ -548,12 +541,8 @@
 	skb->arp=1;
 	skb_reserve(skb,nb_dl->header_length);
 	skb_reserve(skb,dev->hard_header_len);
-
 	skb->dev=dev;
-
-	if(sk->debug)
-		printk("SK %p: Begin build.\n", sk);
-
+	SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
 	ddp=(struct ddpehdr *)skb_put(skb,sizeof(struct ddpehdr));
 	ddp->deh_pad=0;
 	ddp->deh_hops=0;
@@ -571,10 +560,7 @@
 	ddp->deh_snode=sk->protinfo.af_at.src_node;
 	ddp->deh_dport=usat->sat_port;
 	ddp->deh_sport=sk->protinfo.af_at.src_port;
-
-	if(sk->debug)
-		printk("SK %p: Copy user data (%d bytes).\n", sk, len);
-
+	SOCK_DEBUG(sk, "SK %p: Copy user data (%d bytes).\n", sk, len);
 	err = memcpy_fromiovec(skb_put(skb,len),msg->msg_iov,len);
 	if (err)
 	{
@@ -610,8 +596,7 @@
 			if(skb2)
 			{
 				loopback=1;
-				if(sk->debug)
-					printk("SK %p: send out(copy).\n", sk);
+				SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
 				if(aarp_send_ddp(dev,skb2,&usat->sat_addr, NULL)==-1)
 					kfree_skb(skb2, FREE_WRITE);
 				/* else queued/sent above in the aarp queue */
@@ -621,8 +606,7 @@
 
 	if((dev->flags&IFF_LOOPBACK) || loopback)
 	{
-		if(sk->debug)
-			printk("SK %p: Loop back.\n", sk);
+		SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk);
 		/* loop back */
 		atomic_sub(skb->truesize, &sk->wmem_alloc);
 		nb_dl->datalink_header(nb_dl, skb, dev->dev_addr);
@@ -635,9 +619,7 @@
 	}
 	else
 	{
-		if(sk->debug)
-			printk("SK %p: send out.\n", sk);
-
+		SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
 		if ( rt->flags & RTF_GATEWAY ) {
 		    gsat.sat_addr = rt->gateway;
 		    usat = &gsat;
@@ -647,8 +629,7 @@
 			kfree_skb(skb, FREE_WRITE);
 		/* else queued/sent above in the aarp queue */
 	}
-	if(sk->debug)
-		printk("SK %p: Done write (%d).\n", sk, len);
+	SOCK_DEBUG(sk, "SK %p: Done write (%d).\n", sk, len);
 	return len;
 }
 
diff -u --recursive --new-file v2.1.23/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- v2.1.23/linux/net/netrom/af_netrom.c	Tue Jan 28 18:50:59 1997
+++ linux/net/netrom/af_netrom.c	Mon Jan 27 11:04:48 1997
@@ -735,8 +735,7 @@
 		return -EINVAL;
 
 	if ((dev = nr_dev_get(&addr->fsa_ax25.sax25_call)) == NULL) {
-		if (sk->debug)
-			printk("NET/ROM: bind failed: invalid node callsign\n");
+		SOCK_DEBUG(sk, "NET/ROM: bind failed: invalid node callsign\n");
 		return -EADDRNOTAVAIL;
 	}
 
@@ -765,10 +764,7 @@
 	nr_insert_socket(sk);
 
 	sk->zapped = 0;
-
-	if (sk->debug)
-		printk("NET/ROM: socket is bound\n");
-
+	SOCK_DEBUG(sk, "NET/ROM: socket is bound\n");
 	return 0;
 }
 
@@ -1105,14 +1101,10 @@
 		sax.sax25_family = AF_NETROM;
 		sax.sax25_call   = sk->protinfo.nr->dest_addr;
 	}
-
-	if (sk->debug)
-		printk("NET/ROM: sendto: Addresses built.\n");
+	SOCK_DEBUG(sk, "NET/ROM: sendto: Addresses built.\n");
 
 	/* Build a packet */
-	if (sk->debug)
-		printk("NET/ROM: sendto: building packet.\n");
-
+	SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n");
 	size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
 
 	if ((skb = sock_alloc_send_skb(sk, size, 0, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
@@ -1127,9 +1119,7 @@
 	 */
 
 	asmptr = skb_push(skb, NR_TRANSPORT_LEN);
-
-	if (sk->debug)
-		printk("Building NET/ROM Header.\n");
+	SOCK_DEBUG(sk, "Building NET/ROM Header.\n");
 
 	/* Build a NET/ROM Transport header */
 
@@ -1138,9 +1128,7 @@
 	*asmptr++ = 0;		/* To be filled in later */
 	*asmptr++ = 0;		/*      Ditto            */
 	*asmptr++ = NR_INFO;
-
-	if (sk->debug)
-		printk("Built header.\n");
+	SOCK_DEBUG(sk, "Built header.\n");
 
 	/*
 	 *	Put the data on the end
@@ -1149,15 +1137,11 @@
 	skb->h.raw = skb_put(skb, len);
 
 	asmptr = skb->h.raw;
-
-	if (sk->debug)
-		printk("NET/ROM: Appending user data\n");
+	SOCK_DEBUG(sk, "NET/ROM: Appending user data\n");
 
 	/* User data follows immediately after the NET/ROM transport header */
 	memcpy_fromiovec(asmptr, msg->msg_iov, len);
-
-	if (sk->debug)
-		printk("NET/ROM: Transmitting buffer\n");
+	SOCK_DEBUG(sk, "NET/ROM: Transmitting buffer\n");
 
 	if (sk->state != TCP_ESTABLISHED) {
 		kfree_skb(skb, FREE_WRITE);
diff -u --recursive --new-file v2.1.23/linux/net/rose/af_rose.c linux/net/rose/af_rose.c
--- v2.1.23/linux/net/rose/af_rose.c	Tue Jan 28 18:50:59 1997
+++ linux/net/rose/af_rose.c	Mon Jan 27 11:04:48 1997
@@ -797,8 +797,7 @@
 		return -EINVAL;
 
 	if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) {
-		if (sk->debug)
-			printk("Rose: bind failed: invalid address\n");
+		SOCK_DEBUG(sk, "Rose: bind failed: invalid address\n");
 		return -EADDRNOTAVAIL;
 	}
 
@@ -822,10 +821,7 @@
 	rose_insert_socket(sk);
 
 	sk->zapped = 0;
-
-	if (sk->debug)
-		printk("Rose: socket is bound\n");
-
+	SOCK_DEBUG(sk, "Rose: socket is bound\n");
 	return 0;
 }
 
@@ -1134,14 +1130,10 @@
 			srose.srose_digi   = sk->protinfo.rose->dest_digi;
 		}
 	}
-
-	if (sk->debug)
-		printk("Rose: sendto: Addresses built.\n");
+	SOCK_DEBUG(sk, "Rose: sendto: Addresses built.\n");
 
 	/* Build a packet */
-	if (sk->debug)
-		printk("Rose: sendto: building packet.\n");
-
+	SOCK_DEBUG(sk, "Rose: sendto: building packet.\n");
 	size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
 
 	if ((skb = sock_alloc_send_skb(sk, size, 0, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
@@ -1156,18 +1148,14 @@
 	 */
 
 	asmptr = skb_push(skb, ROSE_MIN_LEN);
-
-	if (sk->debug)
-		printk("Building Rose Header.\n");
+	SOCK_DEBUG(sk, "Building Rose Header.\n");
 
 	/* Build a Rose Transport header */
 
 	*asmptr++ = ((sk->protinfo.rose->lci >> 8) & 0x0F) | ROSE_GFI;
 	*asmptr++ = (sk->protinfo.rose->lci >> 0) & 0xFF;
 	*asmptr++ = ROSE_DATA;
-
-	if (sk->debug)
-		printk("Built header.\n");
+	SOCK_DEBUG(sk, "Built header.\n");
 
 	/*
 	 *	Put the data on the end
@@ -1176,15 +1164,11 @@
 	skb->h.raw = skb_put(skb, len);
 
 	asmptr = skb->h.raw;
-
-	if (sk->debug)
-		printk("Rose: Appending user data\n");
+	SOCK_DEBUG(sk, "Rose: Appending user data\n");
 
 	/* User data follows immediately after the Rose transport header */
 	memcpy_fromiovec(asmptr, msg->msg_iov, len);
-
-	if (sk->debug)
-		printk("Rose: Transmitting buffer\n");
+	SOCK_DEBUG(sk, "Rose: Transmitting buffer\n");
 
 	if (sk->state != TCP_ESTABLISHED) {
 		kfree_skb(skb, FREE_WRITE);
diff -u --recursive --new-file v2.1.23/linux/net/x25/af_x25.c linux/net/x25/af_x25.c
--- v2.1.23/linux/net/x25/af_x25.c	Tue Jan 28 18:50:59 1997
+++ linux/net/x25/af_x25.c	Mon Jan 27 11:04:49 1997
@@ -652,10 +652,7 @@
 	x25_insert_socket(sk);
 
 	sk->zapped = 0;
-
-	if (sk->debug)
-		printk(KERN_DEBUG "x25_bind: socket is bound\n");
-
+	SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
 	return 0;
 }
 
@@ -937,14 +934,10 @@
 		sx25.sx25_family = AF_X25;
 		sx25.sx25_addr   = sk->protinfo.x25->dest_addr;
 	}
-
-	if (sk->debug)
-		printk(KERN_DEBUG "x25_sendmsg: sendto: Addresses built.\n");
+	SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n");
 
 	/* Build a packet */
-	if (sk->debug)
-		printk(KERN_DEBUG "x25_sendmsg: sendto: building packet.\n");
-
+	SOCK_DEBUG(sk, "x25_sendmsg: sendto: building packet.\n");
 	if ((msg->msg_flags & MSG_OOB) && len > 32)
 		len = 32;
 
@@ -958,9 +951,7 @@
 	/*
 	 *	Put the data on the end
 	 */
-	if (sk->debug)
-		printk(KERN_DEBUG "x25_sendmsg: Copying user data\n");
-
+	SOCK_DEBUG(sk, "x25_sendmsg: Copying user data\n");
 	skb->h.raw = skb_put(skb, len);
 	asmptr = skb->h.raw;
 
@@ -978,9 +969,7 @@
 	/*
 	 *	Push down the X.25 header
 	 */
- 	if (sk->debug)
-		printk(KERN_DEBUG "x25_sendmsg: Building X.25 Header.\n");
-
+	SOCK_DEBUG(sk, "x25_sendmsg: Building X.25 Header.\n");
 	if (msg->msg_flags & MSG_OOB) {
 		if (sk->protinfo.x25->neighbour->extended) {
 			asmptr    = skb_push(skb, X25_STD_MIN_LEN);
@@ -1012,12 +1001,8 @@
 		if (qbit)
 			skb->data[0] |= X25_Q_BIT;
 	}
-
-	if (sk->debug)
-		printk(KERN_DEBUG "x25_sendmsg: Built header.\n");
-
-	if (sk->debug)
-		printk(KERN_DEBUG "x25_sendmsg: Transmitting buffer\n");
+	SOCK_DEBUG(sk, "x25_sendmsg: Built header.\n");
+	SOCK_DEBUG(sk, "x25_sendmsg: Transmitting buffer\n");
 
 	if (sk->state != TCP_ESTABLISHED) {
 		kfree_skb(skb, FREE_WRITE);
