Linux 1.0-pre1
diff --git a/Makefile b/Makefile
index ff25f83..c806bf0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-VERSION = 0.99
-PATCHLEVEL = 15
-ALPHA = j
+VERSION = pre-1
+PATCHLEVEL = 0
+ALPHA =
 
 all:	Version zImage
 
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index bc0dfc5..c1e022a 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -37,9 +37,6 @@
 ifdef CONFIG_SBPCD
 OBJS := $(OBJS) sbpcd.o
 SRCS := $(SRCS) sbpcd.c
-ifdef PATCHLEVEL
-CFLAGS := $(CFLAGS) -DPATCHLEVEL=$(PATCHLEVEL) 
-endif
 endif #CONFIG_SBPCD
 
 ifdef CONFIG_BLK_DEV_HD
diff --git a/drivers/block/README.sbpcd b/drivers/block/README.sbpcd
index 5b5dd1c..b34c06a 100644
--- a/drivers/block/README.sbpcd
+++ b/drivers/block/README.sbpcd
@@ -1,4 +1,4 @@
-This is release 1.2 of the SoundBlaster Pro (Matsushita, Kotobuki,
+This is release 1.3 of the SoundBlaster Pro (Matsushita, Kotobuki,
 Panasonic, CreativeLabs, Aztech) CD-ROM driver for Linux.
 
 The driver is able to drive the whole family of IDE-style
@@ -6,10 +6,10 @@
 like CR-562 and CR-563, too), and it will work with the soundcard
 interfaces (SB Pro, SB 16, Galaxy, SoundFX, ...) and/or with
 the "no-sound" cards (Panasonic CI-101P, LaserMate, Aztech, ...).
-The interface type has to get configured, because the behavior 
-is different.
+The interface type has to get configured in /usr/include/linux/sbpcd.h, 
+because the behavior is different.
 
-The driver respects different drive firmware releases - my drive
+The driver respects different drive firmware releases - my old drive
 is a 2.11, but it should work with "old" drives <2.01 ... >3.00
 and with "new" drives (which count the releases around 0.75 or
 1.00).
@@ -23,20 +23,14 @@
 to it's drive ID. The drive IDs may be selected freely from 0 to 3 -
 they must not be in consecutive order.
 
-If this driver doesn't work with your equipment, mail me a
-description, please.
-
 The driver supports reading of data from the CD and playing of
 audio tracks. The audio part should run with WorkMan, xcdplayer,
 with the "non-X11" products CDplayer and WorkBone - tell me if
 it is not compatible with other software.
 
 MultiSession is supported, "ManySession" (see below) alternatively.
-Photo CDs should work, too. At ftp.gwdg.de:/pub/linux/hpcdtoppm
-is a package to convert photo CD image files.
-
-I did not have a chance to play with XA or mixed mode CDs yet.
-Send one over, if you would like sbpcd to support that.
+Photo CDs work, too. At ftp.gwdg.de:/pub/linux/hpcdtoppm/ is a package 
+to convert photo CD image files.
 
 The transfer rate will reach 150 kB/sec with standard drives and
 the full 300 kB/sec with double-speed drives.
@@ -127,7 +121,7 @@
 drop me a mail and some food for the soul. :-)
 Those "many-session" CDs can get made by CDROM writers like
 Philips CDD 521.
-With this feature enabled, it is impossible to read true
+If you enable this feature, it is impossible to read true
 multisession CDs.
 
 
@@ -194,10 +188,6 @@
 Currently, the detection of disk change or removal does not
 work as good as it should.
 
-Further, I do not know if this driver can live together with a
-SCSI CD-ROM driver and/or device, but I hope so. 
-
-
 
 Bug reports, comments, wishes, donations (technical information
 is a donation, too :-) etc. to
diff --git a/drivers/block/mcd.c b/drivers/block/mcd.c
index 44119ea..b3e3ccb 100644
--- a/drivers/block/mcd.c
+++ b/drivers/block/mcd.c
@@ -852,7 +852,10 @@
 			       mcd_port);
 			return mem_start;
 		}	
-					
+
+	if (result[0] == result[1] && result[1] == result[2])
+		return mem_start;
+
 	printk("mcd: Mitsumi version : %02X %c %x\n",
 	       result[0],result[1],result[2]);
 
diff --git a/drivers/block/sbpcd.c b/drivers/block/sbpcd.c
index 3312e7f..189d410 100644
--- a/drivers/block/sbpcd.c
+++ b/drivers/block/sbpcd.c
@@ -5,7 +5,7 @@
  *            and for "no-sound" interfaces like Lasermate and the
  *            Panasonic CI-101P.
  *
- *  NOTE:     This is release 1.2.
+ *  NOTE:     This is release 1.3.
  *            It works with my SbPro & drive CR-521 V2.11 from 2/92
  *            and with the new CR-562-B V0.75 on a "naked" Panasonic
  *            CI-101P interface. And vice versa. 
@@ -13,8 +13,8 @@
  *
  *  VERSION HISTORY
  *
- *  0.1  initial release, April/May 93, after mcd.c
- *  
+ *  0.1  initial release, April/May 93, after mcd.c (Martin Harriss)
+ *
  *  0.2  the "repeat:"-loop in do_sbpcd_request did not check for
  *       end-of-request_queue (resulting in kernel panic).
  *       Flow control seems stable, but throughput is not better.  
@@ -60,7 +60,8 @@
  *  1.2  Found the "workman with double-speed drive" bug: use the driver's
  *       audio_state, not what the drive is reporting with ReadSubQ.
  *
- *
+ *  1.3  Minor cleanups.
+ *       Refinements regarding Workman.
  *
  *     special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
  *     elaborated speed-up experiments (and the fabulous results!), for
@@ -92,17 +93,10 @@
  *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-#ifndef PATCHLEVEL
-#define PATCHLEVEL 9
-#endif
 
 #include <linux/config.h>
 #include <linux/errno.h>
 
-#if SBPCD_USE_IRQ
-#include <linux/signal.h>
-#endif SBPCD_USE_IRQ
-
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/fs.h>
@@ -111,13 +105,12 @@
 #include <linux/ioport.h>
 #include <linux/sbpcd.h>
 
-#if PATCHLEVEL>13
+#if SBPCD_USE_IRQ
+#include <linux/signal.h>
+#endif SBPCD_USE_IRQ
+
 #include <linux/ddi.h>
 #include <linux/major.h> 
-#else
-#define DDIOCSDBG 0x9000
-#define MATSUSHITA_CDROM_MAJOR 25  
-#endif
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -127,14 +120,10 @@
 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
 #include "blk.h"
 
-#define VERSION "1.2"
+#define VERSION "1.3 Eberhard Moenkeberg <emoenke@gwdg.de>"
 
 #define SBPCD_DEBUG
 
-#ifndef CONFIG_SBPCD
-#error "SBPCD: \"make config\" again. Enable Matsushita/Panasonic CDROM support"
-#endif
-
 #ifndef CONFIG_ISO9660_FS
 #error "SBPCD: \"make config\" again. File system iso9660 is necessary."
 #endif
@@ -145,7 +134,7 @@
 #define MANY_SESSION 0
 #define CDMKE
 #undef  FUTURE
-#define WORKMAN 0 /* some testing stuff to make it better */
+#define WORKMAN 1 /* some testing stuff to make it better */
 
 /*==========================================================================*/
 /*==========================================================================*/
@@ -154,17 +143,16 @@
  * inspired by Adam J. Richter from Yggdrasil
  *
  * still not good enough - can cause a hang.
- *   example: a NE 2000 ehernet card at 300 will cause a hang probing 310.
+ *   example: a NE 2000 ethernet card at 300 will cause a hang probing 310.
  * if that happens, reboot and use the LILO (kernel) command line.
- * the conflicting possible ethernet card addresses get probed last - to
- * minimize the hang possibilities. 
+ * The possibly conflicting ethernet card addresses get NOT probed 
+ * by default - to minimize the hang possibilities. 
  *
  * The SB Pro addresses get "mirrored" at 0x6xx - to avoid a type error,
  * the 0x2xx-addresses must get checked before 0x6xx.
  *
- * what are other cards' default and range ???
- * what about ESCOM PowerSound???
- * what about HighScreen???
+ * send mail to emoenke@gwdg.de if your interface card is not FULLY
+ * represented here.
  */
 static int autoprobe[] = 
 {
@@ -181,11 +169,14 @@
   0x650, 0, /* "sound card #9" */
   0x670, 0, /* "sound card #9" */
   0x690, 0, /* "sound card #9" */
+#if 0
+/* some "hazardous" locations (ethernet cards) */
   0x330, 0, /* Lasermate, CI-101P */
   0x350, 0, /* Lasermate, CI-101P */
   0x370, 0, /* Lasermate, CI-101P */
   0x290, 1, /* Soundblaster 16 */
   0x310, 0, /* Lasermate, CI-101P */
+#endif
 };
 
 #define NUM_AUTOPROBE  (sizeof(autoprobe) / sizeof(int))
@@ -221,6 +212,8 @@
  * (1<<DBG_DID)  drive ID test
  * (1<<DBG_RES)  drive reset info
  * (1<<DBG_SPI)  SpinUp test info
+ * (1<<DBG_IOS)  ioctl trace: "subchannel"
+ * (1<<DBG_IO2)  ioctl trace: general
  * (1<<DBG_000)  unnecessary information
  */
 #if 1
@@ -228,6 +221,7 @@
 #else
 static int sbpcd_debug =  (1<<DBG_INF) |
                           (1<<DBG_TOC) |
+                          (1<<DBG_IOC) |
                           (1<<DBG_IOX);
 #endif
 static int sbpcd_ioaddr = CDROM_PORT;	/* default I/O base address */
@@ -1992,9 +1986,17 @@
 {
   int i, st;
 
-  DPRINTF((DBG_IOC,"SBPCD: ioctl(%d, 0x%08lX, 0x%08lX)\n",
+  DPRINTF((DBG_IO2,"SBPCD: ioctl(%d, 0x%08lX, 0x%08lX)\n",
 				MINOR(inode->i_rdev), cmd, arg));
   if (!inode) return (-EINVAL);
+  i=MINOR(inode->i_rdev);
+  if ( (i<0) || (i>=NR_SBPCD) )
+    {
+      printk("SBPCD: ioctl: bad device: %d\n", i);
+      return (-ENODEV);             /* no such drive */
+    }
+  switch_drive(i);
+
   st=GetStatus();
   if (st<0) return (-EIO);
   
@@ -2004,16 +2006,7 @@
       if (i<0) return (-EIO);	/* error reading TOC */
     }
   
-  i=MINOR(inode->i_rdev);
-  if ( (i<0) || (i>=NR_SBPCD) )
-    {
-      DPRINTF((DBG_INF,"SBPCD: ioctl: bad device: %d\n", i));
-      return (-ENODEV);             /* no such drive */
-    }
-  switch_drive(i);
-
-
-  DPRINTF((DBG_IOC,"SBPCD: ioctl: device %d, request %04X\n",i,cmd));
+  DPRINTF((DBG_IO2,"SBPCD: ioctl: device %d, request %04X\n",i,cmd));
   switch (cmd) 		/* Sun-compatible */
     {
     case DDIOCSDBG:		/* DDI Debug */
@@ -2194,7 +2187,7 @@
       return (0);
 
     case CDROMSUBCHNL:   /* Get subchannel info */
-      DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSUBCHNL entered.\n"));
+      DPRINTF((DBG_IOS,"SBPCD: ioctl: CDROMSUBCHNL entered.\n"));
       if ((st_spinning)||(!subq_valid)) { i=xx_ReadSubQ();
 					  if (i<0) return (-EIO);
 					}
@@ -2235,7 +2228,7 @@
 	  SC.cdsc_reladdr.msf.frame=DS[d].SubQ_run_trk&0x00FF;
 	}
       memcpy_tofs((void *) arg, &SC, sizeof(struct cdrom_subchnl));
-      DPRINTF((DBG_IOC,"SBPCD: CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
+      DPRINTF((DBG_IOS,"SBPCD: CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
 	       SC.cdsc_format,SC.cdsc_audiostatus,
 	       SC.cdsc_adr,SC.cdsc_ctrl,
 	       SC.cdsc_trk,SC.cdsc_ind,
@@ -2251,7 +2244,7 @@
       return (-EINVAL);
       
     default:
-      DPRINTF((DBG_IOX,"SBPCD: ioctl: unknown function request %04X\n", cmd));
+      DPRINTF((DBG_IOC,"SBPCD: ioctl: unknown function request %04X\n", cmd));
       return (-EINVAL);
     } /* end switch(cmd) */
 }
@@ -2353,7 +2346,7 @@
   dev = MINOR(CURRENT->dev);
   if ( (dev<0) || (dev>=NR_SBPCD) )
     {
-      DPRINTF((DBG_INF,"SBPCD: do_request: bad device: %d\n", dev));
+      printk("SBPCD: do_request: bad device: %d\n", dev);
       return;
     }
   switch_drive(dev);
@@ -2364,7 +2357,7 @@
 
   if (CURRENT->cmd != READ)
     {
-      DPRINTF((DBG_INF,"SBPCD: bad cmd %d\n", CURRENT->cmd));
+      printk("SBPCD: bad cmd %d\n", CURRENT->cmd);
       end_request(0);
       goto request_loop;
     }
@@ -2556,8 +2549,8 @@
       if (j&s_not_data_ready)
 	{
 	  if ((DS[d].ored_ctl_adr&0x40)==0)
-	    DPRINTF((DBG_INF,"SBPCD: CD contains no data tracks.\n"));
-	  else DPRINTF((DBG_INF,"SBPCD: sbp_data: DATA_READY timeout.\n"));
+	    printk("SBPCD: CD contains no data tracks.\n");
+	  else printk("SBPCD: sbp_data: DATA_READY timeout.\n");
 	  error_flag++;
 	  break;
 	}
@@ -2665,7 +2658,7 @@
   i = MINOR(ip->i_rdev);
   if ( (i<0) || (i>=NR_SBPCD) )
     {
-      DPRINTF((DBG_INF,"SBPCD: open: bad device: %d\n", i));
+      printk("SBPCD: open: bad device: %d\n", i);
       return (-ENODEV);             /* no such drive */
     }
   switch_drive(i);
@@ -2683,7 +2676,7 @@
   DPRINTF((DBG_STA,"SBPCD: sbpcd_open: status %02X\n", DS[d].status_byte));
   if (!st_door_closed||!st_caddy_in)
     {
-      DPRINTF((DBG_INF,"SBPCD: sbpcd_open: no disk in drive\n"));
+      printk("SBPCD: sbpcd_open: no disk in drive\n");
       return (-EIO);
     }
 
@@ -2716,7 +2709,7 @@
   i = MINOR(ip->i_rdev);
   if ( (i<0) || (i>=NR_SBPCD) ) 
     {
-      DPRINTF((DBG_INF,"SBPCD: release: bad device: %d\n", i));
+      printk("SBPCD: release: bad device: %d\n", i);
       return;
     }
   switch_drive(i);
@@ -2840,19 +2833,25 @@
       DPRINTF((DBG_INI,"SBPCD: check_drives done.\n"));
       sti(); /* to avoid possible "printk" bug */
       if (i>=0) break; /* drive found */
-      printk ("\n");
+      DPRINTF((DBG_INF,"\n"));
       sti(); /* to avoid possible "printk" bug */
     } /* end of cycling through the set of possible I/O port addresses */
 
   if (ndrives==0)
     {
-      DPRINTF((DBG_INF,"SBPCD: No drive found.\n"));
+      printk("SBPCD: No drive found.\n");
       sti();
       return (mem_start);
     }
 
-  DPRINTF((DBG_INF,"SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n",
-	   ndrives, type, CDo_command));
+  if (port_index>0)
+    {
+      printk("SBPCD: You should configure sbpcd.h for your hardware.\n");
+      sti();
+    }
+
+  printk("SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n",
+	   ndrives, type, CDo_command);
   sti(); /* to avoid possible "printk" bug */
   check_datarate();
   DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n"));
@@ -2908,8 +2907,8 @@
   
   if (register_blkdev(MATSUSHITA_CDROM_MAJOR, "sbpcd", &sbpcd_fops) != 0)
     {
-      DPRINTF((DBG_INF,"SBPCD: Can't get MAJOR %d for Matsushita CDROM\n",
-	       MATSUSHITA_CDROM_MAJOR));
+      printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n",
+	       MATSUSHITA_CDROM_MAJOR);
       sti(); /* to avoid possible "printk" bug */
       return (mem_start);
     }
@@ -2921,8 +2920,7 @@
 #if SBPCD_USE_IRQ
   if (irqaction(SBPCD_INTR_NR, &sbpcd_sigaction))
     {
-      DPRINTF((DBG_INF,"SBPCD: Can't get IRQ%d for sbpcd driver\n",
-	       SBPCD_INTR_NR));
+      printk("SBPCD: Can't get IRQ%d for sbpcd driver\n", SBPCD_INTR_NR);
       sti(); /* to avoid possible "printk" bug */
     }
 #endif SBPCD_USE_IRQ
@@ -2954,7 +2952,7 @@
 
   if (MAJOR(full_dev) != MATSUSHITA_CDROM_MAJOR) 
     {
-      DPRINTF((DBG_INF,"SBPCD: media_check: invalid device.\n"));
+      printk("SBPCD: media_check: invalid device.\n");
       return (-1);
     }
   
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 4ef9f62..cec5449 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -29,6 +29,9 @@
 
 #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
 
+#define KBD_REPORT_ERR
+#define KBD_REPORT_UNKN
+
 #ifndef KBD_DEFMODE
 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
 #endif
@@ -209,6 +212,17 @@
 	} else if (scancode == 0xfe) {
 		resend = 1;
 		goto end_kbd_intr;
+	} else if (scancode == 0) {
+#ifdef KBD_REPORT_ERR
+	        printk("keyboard buffer overflow\n");
+#endif
+		goto end_kbd_intr;
+	} else if (scancode == 0xff) {
+#ifdef KBD_REPORT_ERR
+	        printk("keyboard error\n");
+#endif
+	        prev_scancode = 0;
+	        goto end_kbd_intr;
 	}
 	tty = TTY_TABLE(0);
  	kbd = kbd_table + fg_console;
@@ -267,13 +281,17 @@
 	      if (e0_keys[scancode])
 		scancode = e0_keys[scancode];
 	      else if (!raw_mode) {
+#ifdef KBD_REPORT_UNKN
 		  printk("keyboard: unknown scancode e0 %02x\n", scancode);
+#endif
 		  goto end_kbd_intr;
 	      }
 	  }
 	} else if (scancode >= E0_BASE && !raw_mode) {
+#ifdef KBD_REPORT_UNKN
 	  printk("keyboard: scancode (%02x) not in range 00 - %2x\n",
 		 scancode, E0_BASE - 1);
+#endif
 	  goto end_kbd_intr;
  	}
   
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index d0141b0..8fadbd0 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -17,7 +17,7 @@
 */
 
 static char *version =
-    "3c501.c:v13.13 1993 Donald Becker (becker@super.org).\n";
+    "3c501.c: 3/3/94 Donald Becker (becker@super.org).\n";
 
 /*
   Braindamage remaining:
@@ -302,9 +302,6 @@
     if (skb->len <= 0)
 	return 0;
 
-    if (el_debug > 2)
-	printk("%s: el_start_xmit(%d)...", dev->name, skb->len);
-
     /* Avoid timer-based retransmission conflicts. */
     if (set_bit(0, (void*)&dev->tbusy) != 0)
 	printk("%s: Transmitter access conflict.\n", dev->name);
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index bf86c6f..f46f3b1 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -16,7 +16,7 @@
 */
 
 static char *version =
-    "3c503.c:v0.99.13 8/30/93 Donald Becker (becker@super.org)\n";
+    "3c503.c:v0.99.15k 3/3/93 Donald Becker (becker@super.org)\n";
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -200,9 +200,6 @@
 	dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE;
 	dev->rmem_start = TX_PAGES*256 + dev->mem_start;
     }
-    if (ei_debug > 2)
-	printk("\n3c503: memory params start=%#5x rstart=%#5x end=%#5x rend=%#5x.\n",
-	       dev->mem_start, dev->rmem_start, dev->mem_end, dev->rmem_end);
 
     /* Finish setting the board's parameters. */
     ei_status.name = "3C503";
@@ -228,7 +225,7 @@
     dev->stop = &el2_close;
 
     if (dev->mem_start)
-	printk("\n%s: %s with shared memory at %#6x-%#6x,\n",
+	printk("\n%s: %s with shared memory at %#6lx-%#6lx,\n",
 	       dev->name, ei_status.name, dev->mem_start, dev->mem_end-1);
     else
 	printk("\n%s: %s using programmed I/O (REJUMPER for SHARED MEMORY).\n",
@@ -352,9 +349,6 @@
 	if (ei_debug > 2  &&  memcmp(dest_addr, buf, count))
 	    printk("%s: 3c503 send_packet() bad memory copy @ %#5x.\n",
 		   dev->name, (int) dest_addr);
-	else if (ei_debug > 4)
-	    printk("%s: 3c503 send_packet() good memory copy @ %#5x.\n",
-		   dev->name, (int) dest_addr);
 	return;
     }
     /* No shared memory, put the packet out the slow way. */
@@ -395,19 +389,11 @@
 	if (dev->mem_start + ring_offset + count > end_of_ring) {
 	    /* We must wrap the input move. */
 	    int semi_count = end_of_ring - (dev->mem_start + ring_offset);
-	    if (ei_debug > 4)
-		printk("%s: 3c503 block_input() @ %#5x+%x=%5x.\n",
-		       dev->name, dev->mem_start, ring_offset,
-		       dev->mem_start + ring_offset);
 	    memcpy(buf, (char *)dev->mem_start + ring_offset, semi_count);
 	    count -= semi_count;
 	    memcpy(buf + semi_count, (char *)dev->rmem_start, count);
 	    return dev->rmem_start + count;
 	}
-	if (ei_debug > 4)
-	    printk("%s: 3c503 block_input() @ %#5x+%x=%5x.\n",
-		   dev->name, dev->mem_start, ring_offset,
-		   dev->mem_start + ring_offset);
 	memcpy(buf, (char *)dev->mem_start + ring_offset, count);
 	return ring_offset + count;
     }
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index 8ee16f6..4c6221e 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -394,7 +394,7 @@
 	dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
 	dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 
-	printk(", IRQ %d, %sternal xcvr, memory %#x-%#x.\n", dev->irq,
+	printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
 		   dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
 
 	if (net_debug)
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 288693b..f89581c 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -12,7 +12,7 @@
 */
 
 static char *version =
-	"at1700.c:v0.05 2/9/94  Donald Becker (becker@super.org)\n";
+	"at1700.c:v0.06 3/3/94  Donald Becker (becker@super.org)\n";
 
 #include <linux/config.h>
 
@@ -412,7 +412,7 @@
 
 	/* For ethernet, fill in the header.  This should really be done by a
 	   higher level, rather than duplicated for each ethernet adaptor. */
-	if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+	if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
 		skb->dev = dev;
 		arp_queue (skb);
 		return 0;
@@ -425,11 +425,7 @@
 		printk("%s: Transmitter access conflict.\n", dev->name);
 	else {
 		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-		unsigned char *buf = (void *)(skb+1);
-
-		if (net_debug > 4)
-			printk("%s: Transmitting a packet of length %d.\n", dev->name,
-				   skb->len);
+		unsigned char *buf = skb->data;
 
 		/* Turn off the possible Tx interrupts. */
 		outb(0x00, ioaddr + TX_INTR);
@@ -561,14 +557,13 @@
 			skb->len = pkt_len;
 			skb->dev = dev;
 
-			/* 'skb+1' points to the start of sk_buff data area. */
-			insw(ioaddr + DATAPORT, (void *)(skb+1), (pkt_len + 1) >> 1);
+			insw(ioaddr + DATAPORT, skb->data, (pkt_len + 1) >> 1);
 
 			if (net_debug > 5) {
 				int i;
 				printk("%s: Rxed packet of length %d: ", dev->name, pkt_len);
 				for (i = 0; i < 14; i++)
-					printk(" %02x", ((unsigned char*)(skb + 1))[i]);
+					printk(" %02x", skb->data[i]);
 				printk(".\n");
 			}
 
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 38c779a..3178159 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -782,7 +782,7 @@
     }
 
     /* Fill in the ethernet header. */
-    if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+    if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
 	skb->dev = dev;
 	arp_queue (skb);
 	return 0;
@@ -814,7 +814,7 @@
       int entry = lp->cur_tx++;
       int len;
       long skbL = skb->len;
-      char *p = (char *)(skb + 1);
+      char *p = (char *) skb->data;
 
       entry &= lp->rmask;  		    /* Ring around buffer number. */
       buf = (unsigned char *)(lp->tx_ring[entry].base & 0x00ffffff);
@@ -835,7 +835,7 @@
       lp->tx_ring[entry].misc = 0x0000;
 
       /* copy the data from the socket buffer to the net memory */
-      memcpy((unsigned char *)(buf), (unsigned char *)(skb + 1), len);
+      memcpy((unsigned char *)(buf), skb->data, len);
 
       /* Hand over buffer ownership to the LANCE */
       if (skbL <= 0) lp->tx_ring[entry].base |= (T_ENP);
@@ -859,7 +859,7 @@
 	dev->tbusy=0;
 
 	/* Copy ethernet header to the new buffer */
-	memcpy((unsigned char *)buf, (unsigned char *)(skb + 1), PKT_HDR_LEN);
+	memcpy((unsigned char *)buf, skb->data, PKT_HDR_LEN);
 
 	/* Determine length of data buffer */
 	len = ((skbL > DAT_SZ) ? DAT_SZ : skbL); /* skbL too long */
@@ -998,7 +998,7 @@
 	    skb->mem_addr = skb;
 	    skb->len = pkt_len;
 	    skb->dev = dev;
-	    memcpy((unsigned char *)(skb + 1),
+	    memcpy(skb->data,
 		   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
 		   pkt_len);
 	    /* 
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index d658e50..5372fa1 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -278,7 +278,7 @@
 #endif
 
 	/* 0x0056: A continuous transmit command, only here for testing. */
-	0, CmdTx, DUMP_DATA, DUMP_DATA+8, 0x803ff, -1, DUMP_DATA, 0,
+	0, CmdTx, DUMP_DATA, DUMP_DATA+8, 0x83ff, -1, DUMP_DATA, 0,
 };
 
 /* Index to functions, as function prototypes. */
@@ -513,7 +513,7 @@
 
 	/* For ethernet, fill in the header.  This should really be done by a
 	   higher level, rather than duplicated for each ethernet adaptor. */
-	if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+	if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
 		skb->dev = dev;
 		arp_queue (skb);
 		return 0;
@@ -525,7 +525,7 @@
 		printk("%s: Transmitter access conflict.\n", dev->name);
 	else {
 		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-		unsigned char *buf = (void *)(skb+1);
+		unsigned char *buf = skb->data;
 
 		/* Disable the 82586's input to the interrupt line. */
 		outb(irqrmap[dev->irq], ioaddr + SET_IRQ);
@@ -982,7 +982,7 @@
 
 			outw(data_buffer_addr + 10, ioaddr + READ_PTR);
 
-			insw(ioaddr, (void *)(skb+1), (pkt_len + 1) >> 1);
+			insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
 		
 #ifdef HAVE_NETIF_RX
 			netif_rx(skb);
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index 68e4823..845226c 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -13,7 +13,7 @@
 */
 
 static char *version =
-	"hp.c:v0.99.15c 2/11/94 Donald Becker (becker@super.org)\n";
+	"hp.c:v0.99.15k 3/3/94 Donald Becker (becker@super.org)\n";
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -177,31 +177,22 @@
 {
 	int hp_base = dev->base_addr - NIC_OFFSET;
 	int saved_config = inb_p(hp_base + HP_CONFIGURE);
-	int reset_start_time = jiffies;
 
-	if (ei_debug > 1) printk("resetting the 8390 time=%d...", jiffies);
+	if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
 	outb_p(0x00, hp_base + HP_CONFIGURE);
 	ei_status.txing = 0;
-
-	sti();
-	/* We shouldn't use the boguscount for timing, but this hasn't been
-	   checked yet, and you could hang your machine if jiffies break... */
-	{
-		int boguscount = 150000;
-		while(jiffies - reset_start_time < 2)
-			if (boguscount-- < 0) {
-				printk("jiffy failure (t=%d)...", jiffies);
-				break;
-			}
-	}
+	/* Pause just a few cycles for the hardware reset to take place. */
+	SLOW_DOWN_IO;
+	SLOW_DOWN_IO;
 
 	outb_p(saved_config, hp_base + HP_CONFIGURE);
-	while ((inb_p(hp_base+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
-		if (jiffies - reset_start_time > 2) {
-			printk("%s: hp_reset_8390() did not complete.\n", dev->name);
-			return;
-		}
-	if (ei_debug > 1) printk("8390 reset done (%d).", jiffies);
+	SLOW_DOWN_IO; SLOW_DOWN_IO;
+	
+	if ((inb_p(hp_base+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
+		printk("%s: hp_reset_8390() did not complete.\n", dev->name);
+
+	if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
+	return;
 }
 
 /* Block input and output, similar to the Crynwr packet driver.	 If you
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 39e6339..674011e 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -512,7 +512,7 @@
     }
 
     /* Fill in the ethernet header. */
-    if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+    if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
 	skb->dev = dev;
 	arp_queue (skb);
 	return 0;
@@ -553,11 +553,11 @@
 
     /* If any part of this buffer is >16M we must copy it to a low-memory
        buffer. */
-    if ((int)(skb+1) + skb->len > 0x01000000) {
+    if ((int)(skb->data) + skb->len > 0x01000000) {
 	if (lance_debug > 5)
 	    printk("%s: bouncing a high-memory packet (%#x).\n",
-		   dev->name, (int)(skb+1));
-	memcpy(&lp->tx_bounce_buffs[entry], skb+1, skb->len);
+		   dev->name, (int)(skb->data));
+	memcpy(&lp->tx_bounce_buffs[entry], skb->data, skb->len);
 	lp->tx_ring[entry].base =
 	    (int)(lp->tx_bounce_buffs + entry) | 0x83000000;
 	if (skb->free)
@@ -567,7 +567,7 @@
 	   code that we are still using it. */
     	if(skb->free==0)
     		skb_kept_by_device(skb);
-	lp->tx_ring[entry].base = (int)(skb+1) | 0x83000000;
+	lp->tx_ring[entry].base = (int)(skb->data) | 0x83000000;
     }
     lp->cur_tx++;
 
@@ -733,7 +733,7 @@
 	    skb->mem_addr = skb;
 	    skb->len = pkt_len;
 	    skb->dev = dev;
-	    memcpy((unsigned char *) (skb + 1),
+	    memcpy(skb->data,
 		   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
 		   pkt_len);
 #ifdef HAVE_NETIF_RX
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index a69754a..d37042f 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -17,7 +17,7 @@
 /* Routines for the NatSemi-based designs (NE[12]000). */
 
 static char *version =
-    "ne.c:v0.99-15b 2/8/94 Donald Becker (becker@super.org)\n";
+    "ne.c:v0.99-15k 3/3/94 Donald Becker (becker@super.org)\n";
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -156,7 +156,6 @@
 
     if (wordlength == 2) {
 	/* We must set the 8390 for word mode. */
-	int tmp;
 	outb_p(0x49, ioaddr + EN0_DCFG);
 	/* We used to reset the ethercard here, but it doesn't seem
 	   to be necessary. */
@@ -265,7 +264,7 @@
     int tmp = inb_p(NE_BASE + NE_RESET);
     int reset_start_time = jiffies;
 
-    if (ei_debug > 1) printk("resetting the 8390 t=%d...", jiffies);
+    if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
     ei_status.txing = 0;
 
     outb_p(tmp, NE_BASE + NE_RESET);
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 863e3b6..2e9b2e1 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -20,6 +20,7 @@
  *		Alan Cox	:	KISS AX.25 and AXUI IP support
  *		Michael Riepe	:	Automatic CSLIP recognition added
  *		Charles Hedrick :	CSLIP header length problem fix.
+ *		Alan Cox	:	Corrected non-IP cases of the above.
  */
  
 #include <asm/segment.h>
@@ -552,37 +553,35 @@
   /* We were not, so we are now... :-) */
   if (skb != NULL) {
 #ifdef CONFIG_AX25  
-  	if(sl->mode & SL_MODE_AX25)
-  	{
-  		if(!skb->arp && dev->rebuild_header(skb->data,dev))
-  		{
-  			skb->dev=dev;
-  			arp_queue(skb);
-  			return 0;
-  		}
-  		skb->arp=1;
-  	}
+	if(sl->mode & SL_MODE_AX25)
+	{
+		if(!skb->arp && dev->rebuild_header(skb->data,dev))
+		{
+			skb->dev=dev;
+			arp_queue(skb);
+			return 0;
+		}
+		skb->arp=1;
+	}
 #endif  	
 	sl_lock(sl);
-	
-	size=skb->len;
-	if(size<sizeof(struct iphdr))
-	{
-		printk("Runt IP frame fed to slip!\n");
+	size = skb->len;
+	if (!(sl->mode & SL_MODE_AX25)) {
+		if (size < sizeof(struct iphdr)) {
+			printk("Runt IP frame fed to slip!\n");
+		} else {
+			size = ((struct iphdr *)(skb->data))->tot_len;
+			size = ntohs(size);
+		}
 	}
-	else
-	{
-		size=((struct iphdr *)(skb->data))->tot_len;
-		size=ntohs(size);
 	/*	sl_hex_dump(skb->data,skb->len);*/
-		sl_encaps(sl, skb->data, size);
-	}
-	if (skb->free) kfree_skb(skb, FREE_WRITE);
+	sl_encaps(sl, skb->data, size);
+	if (skb->free)
+		kfree_skb(skb, FREE_WRITE);
   }
   return(0);
 }
 
-
 /* Return the frame type ID.  This is normally IP but maybe be AX.25. */
 static unsigned short
 sl_type_trans (struct sk_buff *skb, struct device *dev)
diff --git a/fs/exec.c b/fs/exec.c
index efa15a7..db46a74 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -692,6 +692,7 @@
 		retval = fn(&bprm, regs);
 		if (retval == 0) {
 			iput(bprm.inode);
+			current->did_exec = 1;
 			return 0;
 		}
 		fmt++;
diff --git a/include/linux/keyboard.h b/include/linux/keyboard.h
index b956435..583b975 100644
--- a/include/linux/keyboard.h
+++ b/include/linux/keyboard.h
@@ -5,6 +5,10 @@
 #define KG_CTRL		2
 #define KG_ALT		3
 #define KG_ALTGR	1
+#define KG_SHIFTL       4
+#define KG_SHIFTR       5
+#define KG_CTRLL        6
+#define KG_CTRLR        7
 
 #define NR_KEYS 128
 #define NR_KEYMAPS 16
@@ -115,6 +119,10 @@
 #define K_CTRL		K(KT_SHIFT,KG_CTRL)
 #define K_ALT		K(KT_SHIFT,KG_ALT)
 #define K_ALTGR		K(KT_SHIFT,KG_ALTGR)
+#define K_SHIFTL        K(KT_SHIFT,KG_SHIFTL)
+#define K_SHIFTR        K(KT_SHIFT,KG_SHIFTR)
+#define K_CTRLL         K(KT_SHIFT,KG_CTRLL)
+#define K_CTRLR         K(KT_SHIFT,KG_CTRLR)
 
 #define NR_SHIFT	4
 
diff --git a/include/linux/msg.h b/include/linux/msg.h
index da02269..d345466 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -52,7 +52,7 @@
 };
 
 #define MSGMNI   128   /* <= 1K */     /* max # of msg queue identifiers */
-#define MSGMAX  4080   /* <= 4080 */   /* max size of message (bytes) */
+#define MSGMAX  4056   /* <= 4056 */   /* max size of message (bytes) */
 #define MSGMNB 16384   /* ? */        /* default max size of a message queue */
 
 /* unused */
diff --git a/include/linux/sbpcd.h b/include/linux/sbpcd.h
index 880781f..5e7513a 100644
--- a/include/linux/sbpcd.h
+++ b/include/linux/sbpcd.h
@@ -35,12 +35,8 @@
  * LASERMATE (CI-101P) adresses typically are 0x0300, 0x0310, ...
  * there are some soundcards on the market with 0x0630, 0x0650, ...
  *
- * obey! changed against v0.4 !!!
- * for SBPRO cards, specify the CDROM address - no longer the audio address! 
  * example: if your SBPRO audio address is 0x220, specify 0x230.
  *
- * a fill-in is not always necessary - the driver does auto-probing now,
- * with the here specified address first...
  */
 #define CDROM_PORT 0x0230
 
@@ -73,7 +69,9 @@
 #define DBG_DID		16	/* drive ID test */
 #define DBG_RES		17	/* drive reset info */
 #define DBG_SPI		18	/* SpinUp test */
-#define DBG_000		19	/* unnecessary information */
+#define DBG_IOS		19	/* ioctl trace: "subchannel" */
+#define DBG_IO2		20	/* ioctl trace: general */
+#define DBG_000		21	/* unnecessary information */
 
 /*==========================================================================*/
 /*==========================================================================*/
@@ -420,12 +418,7 @@
 /*
  * use "REP INSB" for strobing the data in:
  */
-#if PATCHLEVEL<15
-#define READ_DATA(port, buf, nr) \
-__asm__("cld;rep;insb": :"d" (port),"D" (buf),"c" (nr):"cx","dx","di")
-#else
 #define READ_DATA(port, buf, nr) insb(port, buf, nr)
-#endif
 
 /*==========================================================================*/
 /*
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 92aa261..2834379 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -183,6 +183,7 @@
 	int elf_executable:1;
 	int dumpable:1;
 	int swappable:1;
+	int did_exec:1;
 	unsigned long start_code,end_code,end_data,start_brk,brk,start_stack,start_mmap;
 	unsigned long arg_start, arg_end, env_start, env_end;
 	int pid,pgrp,session,leader;
@@ -263,7 +264,7 @@
 /* schedlink */	&init_task,&init_task, \
 /* signals */	{{ 0, },}, \
 /* stack */	0,(unsigned long) &init_kernel_stack, \
-/* ec,brk... */	0,0,0,0,0,0,0,0,0,0,0,0, \
+/* ec,brk... */	0,0,0,0,0,0,0,0,0,0,0,0,0, \
 /* argv.. */	0,0,0,0, \
 /* pid etc.. */	0,0,0,0, \
 /* suppl grps*/ {NOGROUP,}, \
diff --git a/include/linux/timex.h b/include/linux/timex.h
index bf4b390..565043d 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -25,8 +25,6 @@
 #ifndef _LINUX_TIMEX_H
 #define _LINUX_TIMEX_H
 
-#include <linux/unistd.h>
-
 /*
  * The following defines establish the engineering parameters of the PLL
  * model. The HZ variable establishes the timer interrupt frequency, 100 Hz 
diff --git a/kernel/fork.c b/kernel/fork.c
index 306ddab..7e4d4da 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -136,6 +136,7 @@
 		goto bad_fork_free;
 	task[nr] = p;
 	*p = *current;
+	p->did_exec = 0;
 	p->kernel_stack_page = 0;
 	p->state = TASK_UNINTERRUPTIBLE;
 	p->flags &= ~(PF_PTRACED|PF_TRACESYS);
diff --git a/kernel/sys.c b/kernel/sys.c
index a158393..4d3e296 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -461,32 +461,49 @@
  * OK, I think I have the protection semantics right.... this is really
  * only important on a multi-user system anyway, to make sure one user
  * can't send a signal to a process owned by another.  -TYT, 12/12/91
+ *
+ * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
+ * LBT 04.03.94
  */
 asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
 {
-	int i; 
+	struct task_struct * p;
 
 	if (!pid)
 		pid = current->pid;
 	if (!pgid)
-		pgid = current->pid;
+		pgid = pid;
 	if (pgid < 0)
 		return -EINVAL;
-	for (i=0 ; i<NR_TASKS ; i++)
-		if (task[i] && (task[i]->pid == pid) &&
-		    ((task[i]->p_pptr == current) || 
-		     (task[i]->p_opptr == current) || 
-		     (task[i] == current))) {
-			if (task[i]->leader)
-				return -EPERM;
-			if ((task[i]->session != current->session) ||
-			    ((pgid != pid) && 
-			     (session_of_pgrp(pgid) != current->session)))
-				return -EPERM;
-			task[i]->pgrp = pgid;
-			return 0;
-		}
+	for_each_task(p) {
+		if (p->pid == pid)
+			goto found_task;
+	}
 	return -ESRCH;
+
+found_task:
+	if (p->p_pptr == current || p->p_opptr == current) {
+		if (p->session != current->session)
+			return -EPERM;
+		if (p->did_exec)
+			return -EACCES;
+	} else if (p != current)
+		return -ESRCH;
+	if (p->leader)
+		return -EPERM;
+	if (pgid != pid) {
+		struct task_struct * tmp;
+		for_each_task (tmp) {
+			if (tmp->pgrp == pgid &&
+			 tmp->session == current->session)
+				goto ok_pgid;
+		}
+		return -EPERM;
+	}
+
+ok_pgid:
+	p->pgrp = pgid;
+	return 0;
 }
 
 asmlinkage int sys_getpgid(pid_t pid)
diff --git a/net/inet/ip.c b/net/inet/ip.c
index c8954c4..944d1ed 100644
--- a/net/inet/ip.c
+++ b/net/inet/ip.c
@@ -36,7 +36,7 @@
  *		Alan Cox	:	Use ip_tos/ip_ttl settings
  *		Alan Cox	:	Fragmentation bogosity removed
  *					(Thanks to Mark.Bush@prg.ox.ac.uk)
- *		Dmitry Gordchanin :	Send of a raw packet crash fix.
+ *		Dmitry Gorodchanin :	Send of a raw packet crash fix.
  *		Alan Cox	:	Silly ip bug when an overlength
  *					fragment turns up. Now frees the
  *					queue.
diff --git a/net/inet/tcp.c b/net/inet/tcp.c
index faf1903..b29f444 100644
--- a/net/inet/tcp.c
+++ b/net/inet/tcp.c
@@ -592,14 +592,15 @@
 static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
 {
 	int size;
+	struct tcphdr * th = skb->h.th;
 
 	/* length of packet (not counting length of pre-tcp headers) */
-	size = skb->len - ((unsigned char *) skb->h.th - skb->data);
+	size = skb->len - ((unsigned char *) th - skb->data);
 
 	/* sanity check it.. */
 	if (size < sizeof(struct tcphdr) || size > skb->len) {
 		printk("tcp_send_skb: bad skb (skb = %p, data = %p, th = %p, len = %lu)\n",
-			skb, skb->data, skb->h.th, skb->len);
+			skb, skb->data, th, skb->len);
 		kfree_skb(skb, FREE_WRITE);
 		return;
 	}
@@ -607,7 +608,7 @@
 	/* If we have queued a header size packet.. */
 	if (size == sizeof(struct tcphdr)) {
 		/* If its got a syn or fin its notionally included in the size..*/
-		if(!skb->h.th->syn && !skb->h.th->fin) {
+		if(!th->syn && !th->fin) {
 			printk("tcp_send_skb: attempt to queue a bogon.\n");
 			kfree_skb(skb,FREE_WRITE);
 			return;
@@ -615,10 +616,10 @@
 	}
   
 	/* We need to complete and send the packet. */
-	tcp_send_check(skb->h.th, sk->saddr, sk->daddr, size, sk);
+	tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
 
-	skb->h.seq = sk->write_seq;
-	if (after(sk->write_seq , sk->window_seq) ||
+	skb->h.seq = ntohl(th->seq) + size - 4*th->doff;
+	if (after(skb->h.seq, sk->window_seq) ||
 	    (sk->retransmits && sk->timeout == TIME_WRITE) ||
 	     sk->packets_out >= sk->cong_window) {
 		DPRINTF((DBG_TCP, "sk->cong_window = %d, sk->packets_out = %d\n",
diff --git a/net/unix/proc.c b/net/unix/proc.c
index 8a80ad5..2ec7f8d 100644
--- a/net/unix/proc.c
+++ b/net/unix/proc.c
@@ -16,6 +16,7 @@
  *		Fred Baumgarten, <dc6iq@insu1.etec.uni-kalrsruhe.de>
  *
  * Fixes:
+ *		Dmitry Gorodchanin	:	/proc locking fix
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -43,7 +44,7 @@
   pos += sprintf(pos, "Num RefCount Protocol Flags    Type St Path\n");
 
   for(i = 0; i < NSOCKETS; i++) {
-	if (unix_datas[i].refcnt) {
+	if (unix_datas[i].refcnt>0) {
 		pos += sprintf(pos, "%2d: %08X %08X %08lX %04X %02X", i,
 			unix_datas[i].refcnt,
 			unix_datas[i].protocol,
diff --git a/net/unix/sock.c b/net/unix/sock.c
index 6ab4e83..ae264e3 100644
--- a/net/unix/sock.c
+++ b/net/unix/sock.c
@@ -13,11 +13,12 @@
  * Fixes:
  *		Alan Cox	:	Verify Area
  *		NET2E Team	:	Page fault locks
+ *	Dmitry Gorodchanin	:	/proc locking
  *
  * To Do:
- *
- *	Change to the NET2E3 code for Unix domain sockets in general. The
- *	read/write logic is much better and cleaner.
+ *	Some nice person is looking into Unix sockets done properly. NET3
+ *	will replace all of this and include datagram sockets and socket
+ *	options - so please stop asking me for them 8-)
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -237,7 +238,7 @@
   struct unix_proto_data *upd;
 
   for(upd = unix_datas; upd <= last_unix_data; ++upd) {
-	if (upd->refcnt && upd->socket &&
+	if (upd->refcnt > 0 && upd->socket &&
 	    upd->socket->state == SS_UNCONNECTED &&
 	    upd->sockaddr_un.sun_family == sockun->sun_family &&
 	    upd->inode == inode) return(upd);
@@ -254,7 +255,7 @@
   cli();
   for(upd = unix_datas; upd <= last_unix_data; ++upd) {
 	if (!upd->refcnt) {
-		upd->refcnt = 1;
+		upd->refcnt = -1;	/* unix domain socket not yet initialised - bgm */
 		sti();
 		upd->socket = NULL;
 		upd->sockaddr_len = 0;
@@ -328,6 +329,7 @@
   upd->protocol = protocol;
   upd->socket = sock;
   UN_DATA(sock) = upd;
+  upd->refcnt = 1;	/* Now its complete - bgm */
   dprintf(1, "UNIX: create: allocated data 0x%x\n", upd);
   return(0);
 }
diff --git a/net/unix/unix.h b/net/unix/unix.h
index 74b1777..4ad032a 100644
--- a/net/unix/unix.h
+++ b/net/unix/unix.h
@@ -15,6 +15,9 @@
  *		Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  *
+ * Fixes:
+ *		Dmitry Gorodchanin	-	proc locking
+ *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
  *		as published by the Free Software Foundation; either version
@@ -27,6 +30,7 @@
 
 struct unix_proto_data {
 	int		refcnt;		/* cnt of reference 0=free	*/
+					/* -1=not initialised	-bgm	*/
 	struct socket	*socket;	/* socket we're bound to	*/
 	int		protocol;
 	struct sockaddr_un	sockaddr_un;