diff -u --recursive --new-file v1.2.8/linux/Makefile linux/Makefile
--- v1.2.8/linux/Makefile	Mon May 29 11:16:03 1995
+++ linux/Makefile	Thu May  4 20:43:31 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 2
-SUBLEVEL = 8
+SUBLEVEL = 9
 
 ARCH = i386
 
diff -u --recursive --new-file v1.2.8/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v1.2.8/linux/arch/i386/kernel/process.c	Wed Mar  1 08:43:07 1995
+++ linux/arch/i386/kernel/process.c	Fri May 26 08:25:32 1995
@@ -45,13 +45,15 @@
 asmlinkage int sys_idle(void)
 {
 	int i;
+	pmd_t * pmd;
 
 	if (current->pid != 0)
 		return -EPERM;
 
 	/* Map out the low memory: it's no longer needed */
+	pmd = pmd_offset(swapper_pg_dir, 0);
 	for (i = 0 ; i < 768 ; i++)
-		pgd_clear(swapper_pg_dir + i);
+		pmd_clear(pmd++);
 
 	/* endless idle loop with no priority at all */
 	current->counter = -100;
diff -u --recursive --new-file v1.2.8/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- v1.2.8/linux/arch/i386/kernel/ptrace.c	Sat Feb 25 15:36:18 1995
+++ linux/arch/i386/kernel/ptrace.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /* ptrace.c */
 /* By Ross Biro 1/23/92 */
 /* edited by Linus Torvalds */
diff -u --recursive --new-file v1.2.8/linux/drivers/block/README.ide linux/drivers/block/README.ide
--- v1.2.8/linux/drivers/block/README.ide	Sat Mar 18 12:45:45 1995
+++ linux/drivers/block/README.ide	Thu Jun  1 11:23:04 1995
@@ -21,16 +21,34 @@
 	- support for interrupt unmasking during I/O (better than hd.c)
 	- improved handshaking and error detection/recovery
 	- can co-exist with hd.c to control only the secondary interface
+NEW!	- support for reliable operation of buggy CMD-640 interfaces
+		- use kernel command line option:   hda=serialize
+NEW!	- experimental support for DTC-2278D interfaces
+		- use kernel command line option:  hda=dtc2278
+NEW!	- run-time selectible 32bit interface support (using hdparm-2.3)
 
 Under construction:
 
+	- improved CMD support:  tech info is supposedly "in the mail"
 	- support for interface speed selection on jumperless interfaces
 	- improved detection of non-standard IDE ATAPI cdrom drives
 	- support for non-standard 3rd/4th drive interface on Promise cards
 
+***
+
+IMPORTANT NOTICE:  "CMD" EIDE Interfaces will not (by default) work *reliably*
+when drives are attached to the second interface.  To "fix" this, supply the
+special kernel "command line" parameter to LILO:    hda=serialize
+Failure to do so can cause severe data corruption!
+
+***
+
 To access devices on the second interface, device entries must first be
 created in /dev for them.  To create such entries, simply run the included
 shell script:   MAKEDEV.ide1
+
+Apparently the early releases of Slackware 2.2 have incorrect entries
+in /dev for hdc* and hdd* -- this can also be corrected by running MAKEDEV.ide1
 
 ide.c automatically probes for the primary and secondary interfaces,
 for the drives/geometries attached to those interfaces, and for the
diff -u --recursive --new-file v1.2.8/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v1.2.8/linux/drivers/block/genhd.c	Thu Jan  5 13:55:40 1995
+++ linux/drivers/block/genhd.c	Fri May 26 08:23:33 1995
@@ -90,6 +90,7 @@
 			    !(hd->part[current_minor].nr_sects = p->nr_sects))
 				goto done;  /* no more logicals in this partition */
 			hd->part[current_minor].start_sect = first_sector + p->start_sect;
+			hd->sizes[current_minor] = p->nr_sects >> (BLOCK_SIZE_BITS - 9);
 			this_sector = first_sector + p->start_sect;
 			dev = ((hd->major) << 8) | current_minor;
 			brelse(bh);
diff -u --recursive --new-file v1.2.8/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- v1.2.8/linux/drivers/block/ide-cd.c	Sat Apr 29 12:42:21 1995
+++ linux/drivers/block/ide-cd.c	Thu Jun  1 11:23:04 1995
@@ -24,7 +24,7 @@
  *                       Thanks to Nick Saw <cwsaw@pts7.pts.mot.com> for
  *                       help in figuring this out.  Ditto for Acer and
  *                       Aztech drives, which seem to have the same problem.
- *                       
+ * 2.04b May 30, 1995 -- Fix to match changes in ide.c version 3.16 -ml
  *
  * ATAPI cd-rom driver.  To be used with ide.c.
  *
@@ -41,8 +41,13 @@
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 
+#if 1	/* "old" method */
 #define OUT_WORDS(b,n)  outsw (IDE_PORT (HD_DATA, dev->hwif), (b), (n))
 #define IN_WORDS(b,n)   insw  (IDE_PORT (HD_DATA, dev->hwif), (b), (n))
+#else	/* "new" method -- should really fix each instance instead of this */
+#define OUT_WORDS(b,n)	output_ide_data(dev,b,(n)/2)
+#define IN_WORDS(b,n)	input_ide_data(dev,b,(n)/2)
+#endif
 
 /* special command codes for strategy routine. */
 #define PACKET_COMMAND 4315
@@ -196,7 +201,7 @@
   stat = GET_STAT (dev->hwif);
   *stat_ret = stat;
 
-  if (OK_STAT (stat, good_stat, BAD_RW_STAT))
+  if (OK_STAT (stat, good_stat, BAD_R_STAT))
     return 0;
 
   /* Got an error. */
diff -u --recursive --new-file v1.2.8/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.2.8/linux/drivers/block/ide.c	Tue Apr  4 09:05:34 1995
+++ linux/drivers/block/ide.c	Thu Jun  1 11:23:04 1995
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide.c	Version 3.14  March 7, 1995
+ *  linux/drivers/block/ide.c	Version 3.16  May 30, 1995
  *
  *  Copyright (C) 1994, 1995  Linus Torvalds & authors (see below)
  */
@@ -107,8 +107,22 @@
  *  Version 3.14	fix ide_error() handling of BUSY_STAT
  *			fix byte-swapped cdrom strings (again.. arghh!)
  *			ignore INDEX bit when checking the ALTSTATUS reg
+ *  Version 3.15	add SINGLE_THREADED flag for use with dual-CMD i/f
+ *			ignore WRERR_STAT for non-write operations
+ *			added VLB_SYNC support for DC-2000A & others,
+ *			 (incl. some Promise chips), courtesy of Frank Gockel
+ *  Version 3.16	convert VLB_32BIT and VLB_SYNC into runtime flags
+ *			add ioctls to get/set VLB flags (HDIO_[SG]ET_CHIPSET)
+ *			rename SINGLE_THREADED to SUPPORT_SERIALIZE,
+ *			add boot flag to "serialize" operation for CMD i/f
+ *			add optional support for DTC2278 interfaces,
+ *			 courtesy of andy@cercle.cts.com (Dyan Wile).
+ *			add boot flag to enable "dtc2278" probe
+ *			add probe to avoid EATA (SCSI) interfaces,
+ *			 courtesy of neuffer@goofy.zdv.uni-mainz.de.
  *
  *  To do:
+ *	- improved CMD support:  tech info is supposedly "in the mail"
  *	- special 32-bit controller-type detection & support
  *	- figure out how to support oddball "intelligent" caching cards
  *	- reverse-engineer 3/4 drive support on fancy "Promise" cards
@@ -142,12 +156,15 @@
 #include <asm/io.h>
 
 #undef	REALLY_FAST_IO			/* define if ide ports are perfect */
-#define INITIAL_MULT_COUNT	0	/* use zero to disable block mode */
-#ifndef VLB_32BIT_IDE			/* 0 for safety, 1 for 32-bit chipset:*/
-#define VLB_32BIT_IDE		0	/*   Winbond 83759F or OPTi 82C621 */
+#define INITIAL_MULT_COUNT	0	/* off=0; on=2,4,8,16,32, etc.. */
+#ifndef SUPPORT_VLB_32BIT		/* 1 to support 32bit I/O on VLB */
+#define SUPPORT_VLB_32BIT	1	/* 0 to reduce kernel size */
 #endif
-#ifndef DISK_RECOVERY_TIME		/* min. delay between IO for hardware */
-#define DISK_RECOVERY_TIME	0	/*  that needs it. */
+#ifndef SUPPORT_VLB_SYNC		/* 1 to support weird 32-bit chips */
+#define SUPPORT_VLB_SYNC	1	/* 0 to reduce kernel size */
+#endif
+#ifndef DISK_RECOVERY_TIME		/* off=0; on=access_delay_time */
+#define DISK_RECOVERY_TIME	0	/*  for hardware that needs it */
 #endif
 #ifndef OK_TO_RESET_CONTROLLER		/* 1 needed for good error recovery */
 #define OK_TO_RESET_CONTROLLER	1	/* 0 for use with AH2372A/B interface */
@@ -158,9 +175,15 @@
 #ifndef OPTIMIZE_IRQS			/* 1 for slightly faster code */
 #define OPTIMIZE_IRQS		1	/* 0 to reduce kernel size */
 #endif
+#ifndef SUPPORT_SERIALIZE		/* 1 to support CMD dual interfaces */
+#define SUPPORT_SERIALIZE	1	/* 0 to reduce kernel size */
+#endif
 #ifndef SUPPORT_SHARING_IRQ		/* 1 to allow two IDE i/f on one IRQ */
 #define SUPPORT_SHARING_IRQ	1	/* 0 to reduce kernel size */
 #endif
+#ifndef SUPPORT_DTC2278			/* 1 to support DTC2278 chipset */
+#define SUPPORT_DTC2278		1	/* 0 to reduce kernel size */
+#endif
 #ifndef FANCY_STATUS_DUMPS		/* 1 for human-readable drive errors */
 #define FANCY_STATUS_DUMPS	1	/* 0 to reduce kernel size */
 #endif
@@ -194,10 +217,17 @@
 #undef  SUPPORT_TWO_INTERFACES
 #define SUPPORT_TWO_INTERFACES	0
 #endif	/* CONFIG_BLK_DEV_HD */
+
 #if SUPPORT_TWO_INTERFACES
 #define HWIF			hwif
 #define DEV_HWIF		(dev->hwif)
+#if SUPPORT_SERIALIZE
+#undef	SUPPORT_SHARING_IRQ
+#define	SUPPORT_SHARING_IRQ	1
+#endif
 #else
+#undef	SUPPORT_SERIALIZE
+#define SUPPORT_SERIALIZE		0
 #undef	OPTIMIZE_IRQS
 #define OPTIMIZE_IRQS		0
 #undef	SUPPORT_SHARING_IRQ
@@ -224,19 +254,22 @@
 #define IN_BYTE(p,hwif)		(byte)inb_p(IDE_PORT(p,hwif))
 #endif /* REALLY_FAST_IO */
 
-#if VLB_32BIT_IDE
-#define OUT_SECTORS(b,n)	outsl(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<7)
-#define IN_SECTORS(b,n)		insl(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<7)
-#else
-#define OUT_SECTORS(b,n)	outsw(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<8)
-#define IN_SECTORS(b,n)		insw(IDE_PORT(HD_DATA,DEV_HWIF),(b),(n)<<8)
-#endif	/* VLB_32BIT_IDE */
+#if SUPPORT_VLB_32BIT
+#if SUPPORT_VLB_SYNC
+#define VLB_SYNC __asm__ __volatile__ ("pusha\n movl $0x01f2,%edx\n inb (%dx),%al\n inb (%dx),%al\n inb (%dx),%al\n popa\n")
+#endif	/* SUPPORT_VLB_SYNC */
+#endif	/* SUPPORT_VLB_32BIT */
+
+#if SUPPORT_DTC2278
+static uint probe_dtc2278 = 0;
+#endif
 
 #define GET_ERR(hwif)		IN_BYTE(HD_ERROR,hwif)
 #define GET_STAT(hwif)		IN_BYTE(HD_STATUS,hwif)
 #define OK_STAT(stat,good,bad)	(((stat)&((good)|(bad)))==(good))
-#define BAD_RW_STAT		(BUSY_STAT   | ERR_STAT  | WRERR_STAT)
-#define BAD_STAT		(BAD_RW_STAT | DRQ_STAT)
+#define BAD_R_STAT		(BUSY_STAT   | ERR_STAT)
+#define BAD_W_STAT		(BUSY_STAT   | ERR_STAT | WRERR_STAT)
+#define BAD_STAT		(BAD_R_STAT  | DRQ_STAT)
 #define DRIVE_READY		(READY_STAT  | SEEK_STAT)
 #define DATA_READY		(DRIVE_READY | DRQ_STAT)
 
@@ -248,6 +281,7 @@
 #define PARTN_BITS	6	/* number of minor dev bits for partitions */
 #define PARTN_MASK	((1<<PARTN_BITS)-1)	/* a useful bit mask */
 #define MAX_DRIVES	2	/* per interface; 2 assumed by lots of code */
+#define SECTOR_WORDS	(512 / 4)	/* number of 32bit words per sector */
 
 /*
  * Timeouts for various operations:
@@ -296,10 +330,12 @@
 	unsigned dont_probe 	: 1;	/* from:  hdx=noprobe */
 	unsigned keep_settings  : 1;	/* restore settings after drive reset */
 	unsigned busy		: 1;	/* mutex for ide_open, revalidate_.. */
-	unsigned reserved0	: 3;	/* unused */
+	unsigned vlb_32bit	: 1;	/* use 32bit in/out for data */
+	unsigned vlb_sync	: 1;	/* needed for some 32bit chip sets */
+	unsigned reserved0	: 1;	/* unused */
 	special_t special;		/* special action flags */
 	select_t  select;		/* basic drive/head select reg value */
-	byte mult_count, reserved1, reserved2;
+	byte mult_count, chipset, reserved2;
 	byte usage, mult_req, wpcom, ctl;
 	byte head, sect, bios_head, bios_sect;
 	unsigned short cyl, bios_cyl;
@@ -329,9 +365,10 @@
 	{{HD_NAME "a", HD_NAME "b"}, {HD_NAME "c", HD_NAME "d"}};
 static const char	*unsupported = " not supported by this kernel\n";
 
+static byte		single_threaded    = 0;
 #if SUPPORT_SHARING_IRQ
 static byte		sharing_single_irq = 0;	/* for two i/f on one IRQ */
-static volatile byte 	current_hwif = 0;	/* for two i/f on one IRQ */
+static volatile byte 	current_hwif = 0;	/* for single_threaded==1 */
 #endif /* SUPPORT_SHARING_IRQ */
 
 /*
@@ -429,6 +466,50 @@
 }
 
 /*
+ * This is used for all data transfers *from* the IDE interface
+ */
+void input_ide_data (ide_dev_t *dev, void *buffer, uint wcount)
+{
+#if SUPPORT_VLB_32BIT
+	if (dev->vlb_32bit) {
+#if SUPPORT_VLB_SYNC
+		if (dev->vlb_sync) {
+			cli();
+			VLB_SYNC;
+			insl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
+			if (dev->unmask)
+				sti();
+		} else
+#endif /* SUPPORT_VLB_SYNC */
+			insl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
+	} else
+#endif /* SUPPORT_VLB_32BIT */
+		insw(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount<<1);
+}
+
+/*
+ * This is used for all data transfers *to* the IDE interface
+ */
+void output_ide_data (ide_dev_t *dev, void *buffer, uint wcount)
+{
+#if SUPPORT_VLB_32BIT
+	if (dev->vlb_32bit) {
+#if SUPPORT_VLB_SYNC
+		if (dev->vlb_sync) {
+			cli();
+			VLB_SYNC;
+			outsl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
+			if (dev->unmask)
+				sti();
+		} else
+			outsl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount);
+#endif /* SUPPORT_VLB_SYNC */
+	} else
+#endif /* SUPPORT_VLB_32BIT */
+		outsw(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount<<1);
+}
+
+/*
  * This should get invoked on every exit path from the driver.
  */
 static inline void start_ide_timer (byte hwif)
@@ -652,7 +733,7 @@
 	unsigned int msect, nsect;
 	struct request *rq;
 
-	if (!OK_STAT(stat=GET_STAT(DEV_HWIF),DATA_READY,BAD_RW_STAT)) {
+	if (!OK_STAT(stat=GET_STAT(DEV_HWIF),DATA_READY,BAD_R_STAT)) {
 		sti();
 		ide_error(dev, "read_intr", stat);
 		DO_REQUEST;
@@ -667,7 +748,7 @@
 		msect -= nsect;
 	} else
 		nsect = 1;
-	IN_SECTORS(rq->buffer,nsect);
+	input_ide_data(dev, rq->buffer, nsect * SECTOR_WORDS);
 #ifdef DEBUG
 	printk("%s:  read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n",
 		dev->name, rq->sector, rq->sector+nsect-1,
@@ -695,7 +776,7 @@
 	int i;
 	struct request *rq = ide_cur_rq[DEV_HWIF];
 
-	if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_RW_STAT)) {
+	if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_W_STAT)) {
 #ifdef DEBUG
 		printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n",
 			dev->name, rq->sector, (unsigned long) rq->buffer,
@@ -711,7 +792,7 @@
 				end_request(1, DEV_HWIF);
 			if (i > 0) {
 				ide_handler[DEV_HWIF] = &write_intr;
-				OUT_SECTORS(rq->buffer,1);
+				output_ide_data(dev, rq->buffer, SECTOR_WORDS);
 				return;
 			}
 			DO_REQUEST;
@@ -734,7 +815,7 @@
 			nsect = mcount;
 		mcount -= nsect;
 
-		OUT_SECTORS(rq->buffer,nsect);
+		output_ide_data(dev, rq->buffer, nsect<<7);
 #ifdef DEBUG
 		printk("%s: multwrite: sector %ld, buffer=0x%08lx, count=%d, remaining=%ld\n",
 			dev->name, rq->sector, (unsigned long) rq->buffer,
@@ -762,7 +843,7 @@
 	int i;
 	struct request *rq = &ide_write_rq[DEV_HWIF];
 
-	if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_RW_STAT)) {
+	if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,BAD_W_STAT)) {
 		if (stat & DRQ_STAT) {
 			if (rq->nr_sectors) {
 				if (dev->mult_count)
@@ -814,7 +895,7 @@
 			printk ("  %s: enabled %d-sector multiple mode\n",
 				dev->name, dev->mult_count);
 		else
-			printk ("  %s: disabled multiple mode\n", dev->name);
+			printk ("  %s: multiple mode turned off\n", dev->name);
 	}
 	DO_REQUEST;
 }
@@ -865,16 +946,24 @@
 	} else {
 		ide_handler[HWIF] = NULL;
 		disable_irq(ide_irq[HWIF]);
+#if SUPPORT_SERIALIZE
+		if (single_threaded && ide_irq[HWIF] != ide_irq[HWIF^1])
+			disable_irq(ide_irq[HWIF^1]);
+#endif /* SUPPORT_SERIALIZE */
 		sti();
 		ide_error(ide_cur_dev[HWIF], "timeout", GET_STAT(HWIF));
 		do_request(HWIF);
 #if SUPPORT_SHARING_IRQ
-		if (sharing_single_irq)	/* this line is indeed necessary */
+		if (single_threaded)	/* this line is indeed necessary */
 			hwif = current_hwif;
 #endif /* SUPPORT_SHARING_IRQ */
 		cli();
 		start_ide_timer(HWIF);
 		enable_irq(ide_irq[HWIF]);
+#if SUPPORT_SERIALIZE
+		if (single_threaded && ide_irq[HWIF] != ide_irq[HWIF^1])
+			enable_irq(ide_irq[HWIF^1]);
+#endif /* SUPPORT_SERIALIZE */
 	}
 	restore_flags(flags);
 }
@@ -983,7 +1072,7 @@
 	if (rq->cmd == WRITE) {
 		OUT_BYTE(dev->wpcom,HD_PRECOMP);	/* for ancient drives */
 		OUT_BYTE(dev->mult_count ? WIN_MULTWRITE : WIN_WRITE, HD_COMMAND);
-		WAIT_STAT(dev, DATA_READY, BAD_RW_STAT, WAIT_DRQ, "DRQ", error);
+		WAIT_STAT(dev, DATA_READY, BAD_W_STAT, WAIT_DRQ, "DRQ", error);
 		if (!dev->unmask)
 			cli();
 		if (dev->mult_count) {
@@ -991,7 +1080,7 @@
 			multwrite(dev);
 			ide_handler[DEV_HWIF] = &multwrite_intr;
 		} else {
-			OUT_SECTORS(rq->buffer,1);
+			output_ide_data(dev, rq->buffer, SECTOR_WORDS);
 			ide_handler[DEV_HWIF] = &write_intr;
 		}
 		return 0;
@@ -1040,14 +1129,14 @@
 repeat:
 	sti();
 #if SUPPORT_SHARING_IRQ
-	current_hwif = hwif;	/* used *only* when sharing_single_irq==1 */
+	current_hwif = hwif;	/* used *only* when single_threaded==1 */
 #endif /* SUPPORT_SHARING_IRQ */
 	if ((rq = ide_cur_rq[HWIF]) == NULL) {
 		rq = blk_dev[ide_major[HWIF]].current_request;
 		if ((rq == NULL) || (rq->dev < 0)) {
 #if SUPPORT_SHARING_IRQ
-			if (sharing_single_irq) {
-				if ((dev = ide_cur_dev[hwif])) /* disable irq */
+			if (single_threaded) {
+				if (sharing_single_irq && (dev = ide_cur_dev[hwif])) /* disable irq */
 					OUT_BYTE(dev->ctl|2,HD_CMD);
 				rq = blk_dev[ide_major[hwif^=1]].current_request;
 				if ((rq != NULL) && (rq->dev >= 0))
@@ -1121,10 +1210,14 @@
 {						\
 	if (ide_handler[hwif] == NULL) {	\
 		disable_irq(ide_irq[hwif]);	\
+		if (single_threaded && ide_irq[hwif] != ide_irq[hwif^1]) \
+			disable_irq(ide_irq[hwif^1]); \
 		do_request(hwif);		\
 		cli();				\
 		start_ide_timer(hwif);		\
 		enable_irq(ide_irq[hwif]);	\
+		if (single_threaded && ide_irq[hwif] != ide_irq[hwif^1]) \
+			enable_irq(ide_irq[hwif^1]); \
 	}					\
 }
 
@@ -1169,10 +1262,12 @@
 
 	if (!OK_STAT(stat=GET_STAT(HWIF), DRIVE_READY, BAD_STAT))
 		(void) dump_status(HWIF, "unexpected_intr", stat);
+	outb_p(2,IDE_PORT(HD_CMD,hwif));	/* disable device irq */
 #if SUPPORT_SHARING_IRQ
-	if (sharing_single_irq) {
+	if (single_threaded && ide_irq[hwif] == ide_irq[hwif^1]) {
 		if (!OK_STAT(stat=GET_STAT(hwif^1), DRIVE_READY, BAD_STAT))
 			(void) dump_status(hwif^1, "unexpected_intr", stat);
+		outb_p(2,IDE_PORT(HD_CMD,hwif^1));	/* disable device irq */
 	}
 #endif /* SUPPORT_SHARING_IRQ */
 }
@@ -1197,21 +1292,32 @@
 	} else						\
 		unexpected_intr(hwif);			\
 	cli();						\
-	start_ide_timer(hwif);				\
 }
 
+#if SUPPORT_SERIALIZE
+/* entry point for all interrupts when single_threaded==1 */
+static void ide_seq_intr (int irq, struct pt_regs *regs)
+{
+	byte hwif = (irq != ide_irq[0]);
+	IDE_INTR(HWIF);
+	start_ide_timer(current_hwif);
+}
+#endif /* SUPPORT_SERIALIZE */
+
 #if OPTIMIZE_IRQS
 
-/* entry point for all interrupts on ide0 when sharing_single_irq==0 */
+/* entry point for all interrupts on ide0 when single_threaded==0 */
 static void ide0_intr (int irq, struct pt_regs *regs)
 {
 	IDE_INTR(0);
+	start_ide_timer(0);
 }
 
-/* entry point for all interrupts on ide1 when sharing_single_irq==0 */
+/* entry point for all interrupts on ide1 when single_threaded==0 */
 static void ide1_intr (int irq, struct pt_regs *regs)
 {
 	IDE_INTR(1);
+	start_ide_timer(1);
 }
 
 #else	/* OPTIMIZE_IRQS */
@@ -1219,13 +1325,14 @@
 #define ide0_intr	ide_intr
 #define ide1_intr	ide_intr
 
-/* entry point for all interrupts when sharing_single_irq==0 */
+/* entry point for all interrupts when single_threaded==0 */
 static void ide_intr (int irq, struct pt_regs *regs)
 {
 #if SUPPORT_TWO_INTERFACES
 	byte hwif = (irq != ide_irq[0]);
 #endif	/* SUPPORT_TWO_INTERFACES */
 	IDE_INTR(HWIF);
+	start_ide_timer(HWIF);
 }
 
 #endif	/* OPTIMIZE_IRQS */
@@ -1235,6 +1342,7 @@
 static void ide_shared_intr (int irq, struct pt_regs * regs)
 {
 	IDE_INTR(current_hwif);
+	start_ide_timer(current_hwif);
 }
 #endif /* SUPPORT_SHARING_IRQ */
 
@@ -1454,6 +1562,9 @@
                 case HDIO_GET_UNMASKINTR:
 			return write_fs_long(arg, dev->unmask);
 
+                case HDIO_GET_CHIPSET:
+			return write_fs_long(arg, dev->chipset);
+
                 case HDIO_GET_MULTCOUNT:
 			return write_fs_long(arg, dev->mult_count);
 
@@ -1468,22 +1579,28 @@
 			return 0;
 
 		case HDIO_SET_KEEPSETTINGS:
+		case HDIO_SET_UNMASKINTR:
 			if (!suser()) return -EACCES;
 			if ((arg > 1) || (MINOR(inode->i_rdev) & PARTN_MASK))
 				return -EINVAL;
 			save_flags(flags);
 			cli();
-			dev->keep_settings = arg;
+			if (cmd == HDIO_SET_KEEPSETTINGS)
+				dev->keep_settings = arg;
+			else
+				dev->unmask = arg;
 			restore_flags(flags);
 			return 0;
 
-		case HDIO_SET_UNMASKINTR:
+		case HDIO_SET_CHIPSET:
 			if (!suser()) return -EACCES;
-			if ((arg > 1) || (MINOR(inode->i_rdev) & PARTN_MASK))
+			if ((arg > 3) || (MINOR(inode->i_rdev) & PARTN_MASK))
 				return -EINVAL;
 			save_flags(flags);
 			cli();
-			dev->unmask = arg;
+			dev->chipset   = arg;
+			dev->vlb_sync  = (arg & 2) >> 1;
+			dev->vlb_32bit = (arg & 1);
 			restore_flags(flags);
 			return 0;
 
@@ -1614,10 +1731,20 @@
 
 	id = dev->id = (struct hd_driveid *) probe_mem_start; /* kmalloc() */
 	probe_mem_start += 512;
-	IN_SECTORS(id,1);	/* read 512 bytes of id info */
+	input_ide_data(dev, id, SECTOR_WORDS);	/* read 512 bytes of id info */
 	sti();
 
 	/*
+	 * EATA SCSI controllers do a hardware ATA emulation:  ignore them
+	 */
+	if ((id->model[0] == 'P' && id->model[1] == 'M')
+	 || (id->model[0] == 'S' && id->model[1] == 'K')) {
+		printk("%s: EATA SCSI HBA %.10s\n", dev->name, id->model);
+		dev->present = 0;
+		return;
+	}
+
+	/*
 	 *  WIN_IDENTIFY returns little-endian info,
 	 *  WIN_PIDENTIFY *usually* returns little-endian info.
 	 */
@@ -1769,7 +1896,7 @@
 		delay_10ms();		/* give drive a breather */
 	} while (IN_BYTE(hd_status,DEV_HWIF) & BUSY_STAT);
 	delay_10ms();		/* wait for IRQ and DRQ_STAT */
-	if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_RW_STAT)) {
+	if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_R_STAT)) {
 		cli();			/* some systems need this */
 		do_identify(dev, cmd);	/* drive returned ID */
 		rc = 0;			/* success */
@@ -1957,8 +2084,22 @@
 	if (dev->present)
 		printk("(redefined) ");
 	if (ints[0] == 0) {
+#if SUPPORT_DTC2278
+		if (!strcmp(str,"dtc2278")) {
+			printk("%s\n",str);
+			probe_dtc2278 = 1;	/* try to init DTC-2278 at boot */
+			return;
+		}
+#endif /* SUPPORT_DTC2278 */
+#if SUPPORT_SERIALIZE
+		if (!strcmp(str,"serialize") || !strcmp(str,"cmd")) {
+			printk("%s\n",str);
+			single_threaded = 1;	/* serialize all drive access */
+			return;
+		}
+#endif /* SUPPORT_SERIALIZE */
 		if (!strcmp(str,"noprobe")) {
-			printk("noprobe\n");
+			printk("%s\n",str);
 			dev->dont_probe = 1;	/* don't probe for this drive */
 			return;
 		}
@@ -2070,6 +2211,8 @@
 		dev->mult_count			= 0; /* set by do_identify() */
 		dev->mult_req			= 0; /* set by do_identify() */
 		dev->usage			= 0;
+		dev->vlb_32bit			= 0;
+		dev->vlb_sync			= 0;
 		dev->id				= NULL;
 		dev->ctl			= 0x08;
 		dev->wqueue			= NULL;
@@ -2103,6 +2246,13 @@
 		}
 		handler = &ide_shared_intr;
 	}
+#if SUPPORT_SERIALIZE
+	else if (single_threaded) {
+		handler = &ide_seq_intr;
+		if (HWIF != 0)
+			msg = " (single-threaded with ide0)";
+	}
+#endif /* SUPPORT_SERIALIZE */
 #endif /* SUPPORT_SHARING_IRQ */
 	save_flags(flags);
 	cli();
@@ -2160,6 +2310,54 @@
 #endif CONFIG_BLK_DEV_IDECD
 };
 
+
+#if SUPPORT_DTC2278
+/*
+ * From: andy@cercle.cts.com (Dyan Wile)
+ *
+ * Below is a patch for DTC-2278 - alike software-programmable controllers
+ * The code enables the secondary IDE controller and the PIO4 (3?) timings on
+ * the primary (EIDE). You may probably have to enable the 32-bit support to
+ * get the full speed. You better get the disk interrupts disabled ( hdparm -u0 
+ * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my 
+ * filesystem  corrupted with -u 1, but under heavy disk load only :-)  
+ */
+
+static void sub22 (char b, char c)
+{
+	int i;
+
+	for(i = 0; i < 3; i++) {
+		__inb(0x3f6);
+		outb_p(b,0xb0);
+		__inb(0x3f6);
+		outb_p(c,0xb4);
+		__inb(0x3f6);
+		if(__inb(0xb4) == c) {
+			outb_p(7,0xb0);
+			__inb(0x3f6);
+			return;	/* success */
+		}
+	}
+}
+
+static void try_to_init_dtc2278 (void)
+{
+/* This (presumably) enables PIO mode4 (3?) on the first interface */
+	cli();
+	sub22(1,0xc3);
+	sub22(0,0xa0);
+	sti();
+
+/* This enables the second interface */
+
+	outb_p(4,0xb0);
+	__inb(0x3f6);
+	outb_p(0x20,0xb4);
+	__inb(0x3f6);
+}
+#endif /* SUPPORT_DTC2278 */
+
 /*
  * This is gets invoked once during initialization, to set *everything* up
  */
@@ -2167,6 +2365,11 @@
 {
 	byte hwif;
 
+#if SUPPORT_DTC2278
+	if (probe_dtc2278)
+		try_to_init_dtc2278();
+#endif /* SUPPORT_DTC2278 */
+	/* single_threaded = 0; */	/* zero by default, override at boot */
 	for (hwif = 0; hwif < 2; hwif++) {
 		init_ide_data (hwif);
 		if (SUPPORT_TWO_INTERFACES || hwif == HWIF) {
@@ -2191,6 +2394,7 @@
 		} else {
 #if SUPPORT_SHARING_IRQ
 			sharing_single_irq = 1;
+			single_threaded = 1;
 #else /* SUPPORT_SHARING_IRQ */
 			printk("%s: ide irq-sharing%s", ide_name[1], unsupported);
 			return mem_start;
@@ -2218,7 +2422,7 @@
 				timer_table[ide_timer[HWIF]].fn
 					= HWIF ? ide1_timer_expiry : ide0_timer_expiry;
 #if SUPPORT_SHARING_IRQ
-				if (sharing_single_irq)
+				if (single_threaded)
 					blk_dev[major].request_fn = &do_shared_request;
 				else
 #endif /* SUPPORT_SHARING_IRQ */
diff -u --recursive --new-file v1.2.8/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v1.2.8/linux/drivers/char/cyclades.c	Wed Mar 29 06:52:57 1995
+++ linux/drivers/char/cyclades.c	Tue May 30 14:33:31 1995
@@ -1,5 +1,5 @@
 static char rcsid[] =
-"$Revision: 1.36.1.3 $$Date: 1995/03/23 22:15:35 $";
+"$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $";
 /*
  *  linux/kernel/cyclades.c
  *
@@ -18,6 +18,9 @@
  *   int  cy_open(struct tty_struct *tty, struct file *filp);
  *
  * $Log: cyclades.c,v $
+ * Revision 1.36.1.4  1995/03/29  06:14:14  bentson
+ * disambiguate between Cyclom-16Y and Cyclom-32Ye;
+ *
  * Revision 1.36.1.3  1995/03/23  22:15:35  bentson
  * add missing break in modem control block in ioctl switch statement
  * (discovered by Michael Edward Chastain <mec@jobe.shell.portal.com>);
@@ -2637,6 +2640,17 @@
 
         base_addr[CyGFRCR] = 0;
         udelay(10L);
+
+        /* The Cyclom-16Y does not decode address bit 9 and therefore
+           cannot distinguish between references to chip 0 and a non-
+           existent chip 4.  If the preceeding clearing of the supposed
+           chip 4 GFRCR register appears at chip 0, there is no chip 4
+           and this must be a Cyclom-16Y, not a Cyclom-32Ye.
+        */
+        if (chip_number == 4
+        && *(true_base_addr + cy_chip_offset[0] + CyGFRCR) == 0){
+	    return chip_number;
+        }
 
         base_addr[CyCCR] = CyCHIP_RESET;
         udelay(1000L);
diff -u --recursive --new-file v1.2.8/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- v1.2.8/linux/drivers/net/loopback.c	Wed Jan  4 21:16:05 1995
+++ linux/drivers/net/loopback.c	Mon May 29 11:15:01 1995
@@ -71,12 +71,6 @@
 
   dev->tbusy = 0;
 
-  if (!intr_count && (bh_active & bh_mask)) {
-	start_bh_atomic();
-	do_bottom_half();
-	end_bh_atomic();
-  }
-
   return(0);
 }
 
diff -u --recursive --new-file v1.2.8/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog
--- v1.2.8/linux/drivers/scsi/ChangeLog	Sat Apr 29 12:42:22 1995
+++ linux/drivers/scsi/ChangeLog	Thu May  4 10:55:24 1995
@@ -2,7 +2,7 @@
 
 	* Linux 1.2.5 released.
 
-	* buslogic.c: Update to version 1.15 (From Dave G, I expect).
+	* buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff).
 	Fixed interrupt routine to avoid races when handling multiple
 	complete commands per interrupt.  Seems to come up with faster
 	cards.
diff -u --recursive --new-file v1.2.8/linux/drivers/scsi/buslogic.c linux/drivers/scsi/buslogic.c
--- v1.2.8/linux/drivers/scsi/buslogic.c	Mon May 29 11:16:08 1995
+++ linux/drivers/scsi/buslogic.c	Tue May 30 14:33:32 1995
@@ -1555,7 +1555,7 @@
 	    bases[setup_idx] = 0;
 	    return;
 	}
-    buslogic_printk("invalid base 0x%X specified.\n", ints[i]);
+    buslogic_printk("invalid base 0x%X specified.\n", ints[1]);
 }
 
 #ifdef MODULE
diff -u --recursive --new-file v1.2.8/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v1.2.8/linux/drivers/scsi/st.c	Fri Apr 14 12:02:43 1995
+++ linux/drivers/scsi/st.c	Tue May 30 14:33:31 1995
@@ -124,22 +124,22 @@
 	   SCpnt->request_bufflen);
     if (driver_byte(result) & DRIVER_SENSE)
       print_sense("st", SCpnt);
-  } else
+  }
 #endif
-    scode = sense[2] & 0x0f;
-    if (!(driver_byte(result) & DRIVER_SENSE) ||
-	((sense[0] & 0x70) == 0x70 &&
-	 scode != NO_SENSE &&
-	 scode != RECOVERED_ERROR &&
-	 scode != UNIT_ATTENTION &&
-	 scode != BLANK_CHECK &&
-	 scode != VOLUME_OVERFLOW)) {  /* Abnormal conditions for tape */
-      printk("st%d: Error %x. ", dev, result);
-      if (driver_byte(result) & DRIVER_SENSE)
-	print_sense("st", SCpnt);
-      else
-	printk("\n");
-    }
+  scode = sense[2] & 0x0f;
+  if (!(driver_byte(result) & DRIVER_SENSE) ||
+      ((sense[0] & 0x70) == 0x70 &&
+       scode != NO_SENSE &&
+       scode != RECOVERED_ERROR &&
+       scode != UNIT_ATTENTION &&
+       scode != BLANK_CHECK &&
+       scode != VOLUME_OVERFLOW)) {  /* Abnormal conditions for tape */
+    printk("st%d: Error %x. ", dev, result);
+    if (driver_byte(result) & DRIVER_SENSE)
+      print_sense("st", SCpnt);
+    else
+      printk("\n");
+  }
 
   if ((sense[0] & 0x70) == 0x70 &&
       scode == RECOVERED_ERROR
diff -u --recursive --new-file v1.2.8/linux/drivers/sound/.blurb linux/drivers/sound/.blurb
--- v1.2.8/linux/drivers/sound/.blurb	Sun Nov 20 21:50:47 1994
+++ linux/drivers/sound/.blurb	Tue May 30 13:20:32 1995
@@ -1,28 +1,3 @@
-NOTE!
-
-	This is an ALPHA TEST VERSION (pre 3.0). The latest
-	released version of this driver is now part of
-	Linux kernel distribution. For other operating systems
-	use the snd-driv-2.5.tar.gz package.
-
-	This particular version contains lots of new features
-	BUT THERE ARE NO APPLICATIONS WHICH USE THEM. So there
-	is no need to install this version as long as you are
-	not developing the driver or applications which use it.
-	All new features are in the /dev/sequencer and /dev/midi
-	parts of the driver.
-
-	
-	This version is little bit incomplete. Some features have
-	not been implemented for each soundcards yet. All features
-	of v2.4 should work OK.
-
-CAUTION!
-	This version of driver works with applications written and
-	compiled for v2.*. The problem is that APPLICATIONS COMPILED
-	WITH soundcard.h OF THIS VERSION WILL NOT WORK WITH OLDER DRIVER.
-	Be careful when distributing applications compiled with this
-	version (just the apps using /dev/sequencer are incompatible).
 
 	*********************************************************
 	* IF YOU HAVE ANY PROBLEMS WITH THE SOUND DRIVER,	*
@@ -30,5 +5,3 @@
 	* NEAREST LINUX FTP SITE AND CONTAINS ANSWER TO YOUR	*
 	* PROBLEM.						*
 	*********************************************************
-
-Hannu
diff -u --recursive --new-file v1.2.8/linux/fs/buffer.c linux/fs/buffer.c
--- v1.2.8/linux/fs/buffer.c	Sat Apr 29 12:42:22 1995
+++ linux/fs/buffer.c	Mon May 29 13:50:16 1995
@@ -973,7 +973,7 @@
 	}
 	if (bhnum)
 		ll_rw_block(READ, bhnum, bhr);
-	for (i = 0 ; i < nrbuf ; i++) {
+	for (i = nrbuf ; --i >= 0 ; ) {
 		if (bh[i]) {
 			wait_on_buffer(bh[i]);
 		}
diff -u --recursive --new-file v1.2.8/linux/fs/open.c linux/fs/open.c
--- v1.2.8/linux/fs/open.c	Wed Feb 15 09:31:56 1995
+++ linux/fs/open.c	Tue May 30 14:33:31 1995
@@ -277,6 +277,8 @@
 		return -ENOENT;
 	if (IS_RDONLY(inode))
 		return -EROFS;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
@@ -299,6 +301,10 @@
 		iput(inode);
 		return -EROFS;
 	}
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+		iput(inode);
+		return -EPERM;
+	}
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
@@ -322,6 +328,8 @@
 		return -ENOENT;
 	if (IS_RDONLY(inode))
 		return -EROFS;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
 	if (user == (uid_t) -1)
 		user = inode->i_uid;
 	if (group == (gid_t) -1)
@@ -361,6 +369,10 @@
 	if (IS_RDONLY(inode)) {
 		iput(inode);
 		return -EROFS;
+	}
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+		iput(inode);
+		return -EPERM;
 	}
 	if (user == (uid_t) -1)
 		user = inode->i_uid;
diff -u --recursive --new-file v1.2.8/linux/fs/proc/array.c linux/fs/proc/array.c
--- v1.2.8/linux/fs/proc/array.c	Sun Apr  9 11:59:57 1995
+++ linux/fs/proc/array.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  *  linux/fs/proc/array.c
  *
diff -u --recursive --new-file v1.2.8/linux/fs/proc/mem.c linux/fs/proc/mem.c
--- v1.2.8/linux/fs/proc/mem.c	Mon Feb 20 21:29:53 1995
+++ linux/fs/proc/mem.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  *  linux/fs/proc/mem.c
  *
diff -u --recursive --new-file v1.2.8/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h
--- v1.2.8/linux/include/asm-i386/processor.h	Fri Feb 24 16:41:01 1995
+++ linux/include/asm-i386/processor.h	Mon May 29 11:13:40 1995
@@ -21,12 +21,6 @@
 extern char wp_works_ok;		/* doesn't work on a 386 */
 extern char hlt_works_ok;	/* problems on some 486Dx4's and old 386's */
 
-#define start_bh_atomic() \
-__asm__ __volatile__("incl _intr_count")
-
-#define end_bh_atomic() \
-__asm__ __volatile__("decl _intr_count")
-
 /*
  * Bus types (default is ISA, but people can check others with these..)
  * MCA_bus hardcoded to 0 for now.
diff -u --recursive --new-file v1.2.8/linux/include/linux/hdreg.h linux/include/linux/hdreg.h
--- v1.2.8/linux/include/linux/hdreg.h	Thu Jan  5 13:47:08 1995
+++ linux/include/linux/hdreg.h	Thu Jun  1 11:23:04 1995
@@ -78,12 +78,14 @@
 #define HDIO_GET_MULTCOUNT	0x304	/* get current IDE blockmode setting */
 #define HDIO_GET_IDENTITY 	0x307	/* get IDE identification info */
 #define HDIO_GET_KEEPSETTINGS 	0x308	/* get keep-settings-on-reset flag */
+#define HDIO_GET_CHIPSET	0x309	/* get current interface type setting */
 #define HDIO_DRIVE_CMD		0x31f	/* execute a special drive command */
 
 /* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x32n/0x33n */
 #define HDIO_SET_MULTCOUNT	0x321	/* set IDE blockmode */
 #define HDIO_SET_UNMASKINTR	0x322	/* permit other irqs during I/O */
 #define HDIO_SET_KEEPSETTINGS	0x323	/* keep ioctl settings on reset */
+#define HDIO_SET_CHIPSET	0x324	/* optimise driver for interface type */
 
 /* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */
 struct hd_driveid {
diff -u --recursive --new-file v1.2.8/linux/include/linux/interrupt.h linux/include/linux/interrupt.h
--- v1.2.8/linux/include/linux/interrupt.h	Thu Jan 26 07:38:17 1995
+++ linux/include/linux/interrupt.h	Mon May 29 11:13:51 1995
@@ -45,6 +45,18 @@
 	set_bit(nr, &bh_mask);
 }
 
+extern inline void start_bh_atomic(void)
+{
+	intr_count++;
+}
+
+extern inline void end_bh_atomic(void)
+{
+	if (intr_count == 1 && (bh_active & bh_mask))
+		do_bottom_half();
+	intr_count--;
+}
+
 /*
  * Autoprobing for irqs:
  *
diff -u --recursive --new-file v1.2.8/linux/include/linux/pci.h linux/include/linux/pci.h
--- v1.2.8/linux/include/linux/pci.h	Sun Apr  9 11:59:57 1995
+++ linux/include/linux/pci.h	Tue May 30 14:33:31 1995
@@ -388,7 +388,7 @@
 	{PCI_VENDOR_ID_CONTAQ,		"Contaq"}, \
 	{PCI_VENDOR_ID_NS,		"NS"}, \
 	{PCI_VENDOR_ID_VIA,		"VIA Technologies"}, \
-	{PCI_VENDOR_ID_SI,		"Silicon Integrated"}, \
+	{PCI_VENDOR_ID_SI,		"Silicon Integrated Systems"}, \
 	{PCI_VENDOR_ID_LEADTEK,		"Leadtek Research"}, \
 	{PCI_VENDOR_ID_IMS,		"IMS"}, \
 	{PCI_VENDOR_ID_ZEINET,		"ZeiNet"}, \
diff -u --recursive --new-file v1.2.8/linux/ipc/shm.c linux/ipc/shm.c
--- v1.2.8/linux/ipc/shm.c	Wed Mar 29 06:53:00 1995
+++ linux/ipc/shm.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  * linux/ipc/shm.c
  * Copyright (C) 1992, 1993 Krishna Balasubramanian
diff -u --recursive --new-file v1.2.8/linux/kernel/module.c linux/kernel/module.c
--- v1.2.8/linux/kernel/module.c	Tue Jan 31 09:36:21 1995
+++ linux/kernel/module.c	Fri May 26 08:23:33 1995
@@ -745,7 +745,7 @@
 		link && (link != &kernel_module);
 		link = link->next) {
 
-		if (link->ref->module == mp)
+		if (link->ref && (link->ref->module == mp))
 			link->ref = newref++;
 	}
 
diff -u --recursive --new-file v1.2.8/linux/kernel/resource.c linux/kernel/resource.c
--- v1.2.8/linux/kernel/resource.c	Fri Jan 13 09:20:31 1995
+++ linux/kernel/resource.c	Thu Jun  1 08:49:37 1995
@@ -13,7 +13,7 @@
 #include <linux/types.h>
 #include <linux/ioport.h>
 
-#define IOTABLE_SIZE 32
+#define IOTABLE_SIZE 64
 
 typedef struct resource_entry_t {
 	u_long from, num;
diff -u --recursive --new-file v1.2.8/linux/mm/filemap.c linux/mm/filemap.c
--- v1.2.8/linux/mm/filemap.c	Tue Feb 14 08:39:06 1995
+++ linux/mm/filemap.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  *	linux/mm/filemmap.c
  *
diff -u --recursive --new-file v1.2.8/linux/mm/memory.c linux/mm/memory.c
--- v1.2.8/linux/mm/memory.c	Sun Apr  9 11:59:57 1995
+++ linux/mm/memory.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  *  linux/mm/memory.c
  *
diff -u --recursive --new-file v1.2.8/linux/mm/mprotect.c linux/mm/mprotect.c
--- v1.2.8/linux/mm/mprotect.c	Tue Feb 14 08:39:06 1995
+++ linux/mm/mprotect.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  *	linux/mm/mprotect.c
  *
diff -u --recursive --new-file v1.2.8/linux/mm/swap.c linux/mm/swap.c
--- v1.2.8/linux/mm/swap.c	Fri Apr 28 11:10:56 1995
+++ linux/mm/swap.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  *  linux/mm/swap.c
  *
diff -u --recursive --new-file v1.2.8/linux/mm/vmalloc.c linux/mm/vmalloc.c
--- v1.2.8/linux/mm/vmalloc.c	Thu Feb  9 18:22:18 1995
+++ linux/mm/vmalloc.c	Tue May 30 12:17:18 1995
@@ -1,4 +1,3 @@
-#define THREE_LEVEL
 /*
  *  linux/mm/vmalloc.c
  *
diff -u --recursive --new-file v1.2.8/linux/net/inet/af_inet.c linux/net/inet/af_inet.c
--- v1.2.8/linux/net/inet/af_inet.c	Thu Mar  9 20:37:36 1995
+++ linux/net/inet/af_inet.c	Fri May 26 08:23:32 1995
@@ -815,8 +815,8 @@
 	sk->inuse = 1;
 
 	/* This will destroy it. */
-	release_sock(sk);
 	sock->data = NULL;
+	release_sock(sk);
 	sk->socket = NULL;
 	return(0);
 }
@@ -939,8 +939,12 @@
 		return 0;	/* Rock and roll */
 	}
 
-	if (sock->state == SS_CONNECTING && sk->protocol == IPPROTO_TCP && (flags & O_NONBLOCK))
-		return -EALREADY;	/* Connecting is currently in progress */
+	if (sock->state == SS_CONNECTING && sk->protocol == IPPROTO_TCP && (flags & O_NONBLOCK)) {
+		if (sk->err != 0)
+			return -sk->err;	/* Connection must have failed */
+		else
+			return -EALREADY;	/* Connecting is currently in progress */
+	}
   	
 	if (sock->state != SS_CONNECTING) 
 	{
diff -u --recursive --new-file v1.2.8/linux/net/inet/dev.c linux/net/inet/dev.c
--- v1.2.8/linux/net/inet/dev.c	Thu Mar  9 20:37:37 1995
+++ linux/net/inet/dev.c	Mon May 29 11:10:05 1995
@@ -337,7 +337,9 @@
 		 *	Make sure we haven't missed an interrupt. 
 		 */
 		printk("dev_queue_xmit: worked around a missed interrupt\n");
+		start_bh_atomic();
 		dev->hard_start_xmit(NULL, dev);
+		end_bh_atomic();
 		return;
   	}
 
@@ -409,12 +411,15 @@
 			}
 		}
 	}
+	start_bh_atomic();
 	if (dev->hard_start_xmit(skb, dev) == 0) {
+		end_bh_atomic();
 		/*
 		 *	Packet is now solely the responsibility of the driver
 		 */
 		return;
 	}
+	end_bh_atomic();
 
 	/*
 	 *	Transmission failed, put skb back into a list. Once on the list it's safe and
diff -u --recursive --new-file v1.2.8/linux/net/inet/ip.c linux/net/inet/ip.c
--- v1.2.8/linux/net/inet/ip.c	Sun Apr  9 11:59:58 1995
+++ linux/net/inet/ip.c	Tue May 30 14:33:31 1995
@@ -1489,7 +1489,8 @@
 	 *	(4.	We ought to check for IP multicast addresses and undefined types.. does this matter ?)
 	 */
 
-	if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0)
+	if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 ||
+		skb->len<ntohs(iph->tot_len) || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0)
 	{
 		ip_statistics.IpInHdrErrors++;
 		kfree_skb(skb, FREE_WRITE);
@@ -2090,8 +2091,6 @@
 			unsigned char ucval;
 
 			ucval=get_fs_byte((unsigned char *)optval);
-			if(ucval<1||ucval>255)
-                                return -EINVAL;
 			sk->ip_mc_ttl=(int)ucval;
 	                return 0;
 		}
diff -u --recursive --new-file v1.2.8/linux/net/inet/tcp.c linux/net/inet/tcp.c
--- v1.2.8/linux/net/inet/tcp.c	Mon May 29 11:16:09 1995
+++ linux/net/inet/tcp.c	Fri May 26 08:23:33 1995
@@ -934,6 +934,8 @@
 		break;
 
 	case SEL_OUT:
+		if (sk->err)
+			return 1;
 		if (sk->shutdown & SEND_SHUTDOWN) 
 			return 0;
 		if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)
@@ -948,7 +950,7 @@
 		return 1;
 
 	case SEL_EX:
-		if (sk->err || sk->urg_data)
+		if (sk->urg_data)
 			return 1;
 		break;
 	}
diff -u --recursive --new-file v1.2.8/linux/net/unix/sock.c linux/net/unix/sock.c
--- v1.2.8/linux/net/unix/sock.c	Thu Mar  9 20:37:37 1995
+++ linux/net/unix/sock.c	Tue May 30 12:23:57 1995
@@ -481,7 +481,7 @@
 	fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
 	old_fs = get_fs();
 	set_fs(get_ds());
-	i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
+	i = open_namei(fname, 2, S_IFSOCK, &inode, NULL);
 	set_fs(old_fs);
 	if (i < 0) 
 	{
diff -u --recursive --new-file v1.2.8/linux/versions.mk linux/versions.mk
--- v1.2.8/linux/versions.mk	Mon Jan 23 10:38:28 1995
+++ linux/versions.mk	Thu Jun  1 11:53:40 1995
@@ -11,11 +11,14 @@
 .SUFFIXES: .ver
 
 .c.ver:
-	$(CC) $(CFLAGS) -E -D__GENKSYMS__ $< | genksyms -w $(TOPINCL)/modules
+	@if [ ! -x /sbin/genksyms ]; then echo "Please read: README.modules"; fi
+	$(CC) $(CFLAGS) -E -DCONFIG_MODVERSIONS -D__GENKSYMS__ $< | /sbin/genksyms -w $(TOPINCL)/modules
 	@ln -sf $(TOPINCL)/modules/$@ .
 
 $(SYMTAB_OBJS):
 	$(CC) $(CFLAGS) -DEXPORT_SYMTAB -c $(@:.o=.c)
+
+$(SYMTAB_OBJS:.o=.ver): $(TOPINCL)/autoconf.h
 
 $(TOPINCL)/modversions.h: $(SYMTAB_OBJS:.o=.ver)
 	@echo updating $(TOPINCL)/modversions.h
