diff -u --recursive --new-file v1.3.75/linux/CREDITS linux/CREDITS
--- v1.3.75/linux/CREDITS	Fri Mar 15 16:03:09 1996
+++ linux/CREDITS	Tue Mar 19 09:05:23 1996
@@ -432,12 +432,13 @@
 S: USA
 
 N: Kai Harrekilde-Petersen
-E: khp@pip.dknet.dk
+E: khp@dolphinics.no
 W: http://www.pip.dknet.dk/~pip93
 D: ftape-HOWTO, i82078 fdc detection code, various ftape related stuff.
-S: Studsgade 40, 2tv
-S: DK-8000 Aarhus C
-S: Denmark
+S: Dolphin Interconnect Solutions A/S
+S: P.O. Box 70, Borgerud
+S: N-0621 Oslo
+S: Norway
 
 N: Andrew Haylett
 E: ajh@primag.co.uk
@@ -716,6 +717,7 @@
 D: BIOS video mode handling code
 D: Miscellaneous kernel fixes
 D: MOXA C-218 serial board driver
+D: BOOTP support
 S: Kankovskeho 1241
 S: 182 00 Praha 8
 S: Czech Republic 
diff -u --recursive --new-file v1.3.75/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v1.3.75/linux/Documentation/Configure.help	Sun Mar 17 09:04:03 1996
+++ linux/Documentation/Configure.help	Tue Mar 19 09:05:22 1996
@@ -168,6 +168,12 @@
   or something similar.  Be sure to consult the drivers/block/ide-tape.c
   and README.ide files for usage information.
 
+Support removeable IDE interfaces (PCMCIA)
+CONFIG_BLK_DEV_IDE_PCMCIA
+  This option adds code to the IDE driver to handle hot insertion
+  and removal of IDE interfaces and drives, under direction of an
+  external utility (?).  Normally, just say N here.
+
 CMD640 chipset bugfix/support
 CONFIG_BLK_DEV_CMD640
   The CMD-Technologies CMD640 chip is used on many common 486 and
@@ -248,7 +254,7 @@
   card.  This driver is known to incur timeouts/retries during heavy
   I/O to drives attached to the secondary interface.  CDROM and
   TAPE devices are not supported yet.
-  See the README.ide and ali14xx.c files for more info.
+  See the README.ide and promise.c files for more info.
 
 XT harddisk support
 CONFIG_BLK_DEV_XD
@@ -2486,6 +2492,27 @@
   pass options to the kernel. The lilo procedure is also explained in
   the SCSI-HOWTO, available via ftp (user: anonymous) in
   sunsite.unc.edu:/pub/Linux/docs/HOWTO.) Most people say N here.
+
+BOOTP support
+CONFIG_RNFS_BOOTP
+  If you want your Linux box to mount its whole root filesystem from
+  some other computer over the net via NFS and you want the address
+  of your computer to be discovered automatically using the BOOTP
+  protocol (a special protocol designed for doing this job), say Y
+  here. In case the boot ROM of your network card was designed for
+  booting Linux and does BOOTP itself, providing all necessary
+  information on the kernel command line, you can say N here.
+  If unsure, say Y. Note that in case you want to use BOOTP, a BOOTP
+  server must be operating on your network.
+
+RARP support
+CONFIG_RNFS_RARP
+  If you want your Linux box to mount its whole root filesystem from
+  some other computer over the net via NFS and you want the address
+  of your computer to be discovered automatically using the RARP
+  protocol (an older protocol which is being obsoleted by BOOTP), say
+  Y here. Note that in case you want to use RARP, a RARP server must be
+  operating on your network.
 
 ISO9660 cdrom filesystem support
 CONFIG_ISO9660_FS
diff -u --recursive --new-file v1.3.75/linux/Documentation/svga.txt linux/Documentation/svga.txt
--- v1.3.75/linux/Documentation/svga.txt	Sun Mar 17 09:04:03 1996
+++ linux/Documentation/svga.txt	Tue Mar 19 09:05:22 1996
@@ -1,4 +1,4 @@
-			Video Mode Selection Support 2.2
+			Video Mode Selection Support 2.4
 	      (c) 1995, 1996 Martin Mares, <mj@k332.feld.cvut.cz>
 --------------------------------------------------------------------------------
 
@@ -148,7 +148,8 @@
 -- in this case turn this switch off to see the rest.
 
    CONFIG_VIDEO_RETAIN - enables retaining of screen contents when switching
-video modes. Useful and probably harmless.
+video modes. Works only with some boot loaders leaving enough room for the
+buffer.
 
    CONFIG_VIDEO_LOCAL - enables inclusion of "local modes" in the list. The
 local modes are added automatically to the beginning of the list not depending
@@ -216,3 +217,8 @@
 		flag, 0xffff and 0xfffe became aliases instead of real ID's.
 		Screen contents retained during mode changes.
 2.3 (15-Mar-96)	Changed to work with 1.3.74 kernel.
+2.4 (18-Mar-96)	Added patches by Hans Lermen fixing a memory overwrite problem
+		with some boot loaders. Memory management rewritten to reflect
+		these changes. Unfortunately, screen contents retaining works
+		only with some loaders now.
+		Added a Tseng 132x60 mode.
diff -u --recursive --new-file v1.3.75/linux/MAINTAINERS linux/MAINTAINERS
--- v1.3.75/linux/MAINTAINERS	Sun Mar 17 09:04:03 1996
+++ linux/MAINTAINERS	Tue Mar 19 09:05:23 1996
@@ -97,7 +97,7 @@
 
 FTAPE/QIC-117:
 P:	Kai Harrekilde-Petersen
-M:	khp@pip.dknet.dk [from 960401: khp@dolphinics.no]
+M:	khp@@dolphinics.no
 L:	linux-tape@vger.rutgers.edu
 S:	Maintained
 
@@ -165,6 +165,12 @@
 P:	David S. Miller
 M:	davem@caip.rutgers.edu
 L:	sparclinux@vger.rutgers.edu
+S:	Maintained
+
+SVGA HANDLING:
+P:	Martin Mares
+M:	mj@k332.feld.cvut.cz
+L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
 REST:
diff -u --recursive --new-file v1.3.75/linux/Makefile linux/Makefile
--- v1.3.75/linux/Makefile	Sun Mar 17 09:04:03 1996
+++ linux/Makefile	Sun Mar 17 08:26:51 1996
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 75
+SUBLEVEL = 76
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.75/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v1.3.75/linux/arch/alpha/defconfig	Wed Mar 13 10:09:09 1996
+++ linux/arch/alpha/defconfig	Tue Mar 19 09:50:58 1996
@@ -121,6 +121,7 @@
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_AM53C974 is not set
 
 #
diff -u --recursive --new-file v1.3.75/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- v1.3.75/linux/arch/i386/boot/setup.S	Sun Mar 17 09:04:04 1996
+++ linux/arch/i386/boot/setup.S	Tue Mar 19 09:05:22 1996
@@ -61,7 +61,7 @@
 ! SETUP-header, must start at CS:2 (old 0x9020:2)
 !
 		.ascii	"HdrS"		! Signature for SETUP-header
-		.word	0x0200		! Version number of header format
+		.word	0x0201		! Version number of header format
 					! (must be >= 0x0105
 					! else old loadlin-1.5 will fail)
 realmode_swtch:	.word	0,0		! default_switch,SETUPSEG
@@ -80,6 +80,10 @@
 loadflags:	.byte	0	! unused bits =0 (reserved for future development)
 LOADED_HIGH	= 1		! bit within loadflags,
 				! if set, then the kernel is loaded high
+CAN_USE_HEAP	= 0x80		! if set, the loader also has set heap_end_ptr
+				! to tell how much space behind setup.S
+				| can be used for heap purposes.
+				! Only the loader knows what is free!
 setup_move_size: .word  0x8000	! size to move, when we (setup) are not
 				! loaded at 0x90000. We will move ourselves
 				! to 0x90000 then just before jumping into
@@ -97,6 +101,9 @@
 ramdisk_size:	.long	0	! its size in bytes
 bootsect_kludge:
 		.word   bootsect_helper,SETUPSEG
+heap_end_ptr:	.word	modelist+1024	! space from here (exclusive) down to
+				! end of setup code can be used by setup
+				! for local heap purposes.
 ! ------------------------ end of header ----------------------------------
 
 start_of_setup:
@@ -229,7 +236,7 @@
 ! Check for video adapter and its parameters and allow the
 ! user to browse video modes.
 
-	call	video
+	call	video	! NOTE: we need DS pointing to bootsector
 
 ! Get hd0 data
 
diff -u --recursive --new-file v1.3.75/linux/arch/i386/boot/video.S linux/arch/i386/boot/video.S
--- v1.3.75/linux/arch/i386/boot/video.S	Sun Mar 17 09:04:04 1996
+++ linux/arch/i386/boot/video.S	Tue Mar 19 09:05:22 1996
@@ -1,5 +1,5 @@
 !
-!	Display adapter & video mode setup, version 2.3 (15-Mar-96)
+!	Display adapter & video mode setup, version 2.4 (18-Mar-96)
 !
 !	Copyright (C) 1995, 1996 Martin Mares <mj@k332.feld.cvut.cz>
 !	Based on the original setup.S code (C) Linus Torvalds
@@ -66,6 +66,8 @@
 !
 ! This is the main entry point called by setup.S
 !
+! Input:
+!	DS pointing to the bootsector
 
 video:	push	ds		! We use different segments
 	push	ds		! FS contains original DS
@@ -543,26 +545,35 @@
 store_screen:
 	cmpb	[do_restore],#0		! Already stored?
 	jnz	stsr
+	testb	[loadflags],#CAN_USE_HEAP	! Have we space for storing?
+	jz	stsr
 	push	ax
 	push	bx
-	incb	[do_restore]		! Screen will be restored later
 	mov	al,[def_mode]		! "Default mode" flag overriden
 	push	ax
 	movb	[def_mode],#0
-	call	mode_params		! Obtain and store basic parameters
+	call	mode_params		! Obtain params of current mode
 	pop	ax
 	mov	[def_mode],al
-	seg	fs			! of the current mode.
-	mov	ax,[PARAM_CURSOR_POS]
-	lea	di,modelist+8192
-	stosw
+
 	seg	fs
 	mov	ah,[PARAM_VIDEO_LINES]
 	seg	fs
 	mov	al,[PARAM_VIDEO_COLS]
-	stosw
+	mov	bx,ax			! BX=dimensions
 	mul	ah
 	mov	cx,ax			! CX=number of characters to store
+	add	ax,ax			! Calculate image size
+	add	ax,modelist+1024+4
+	cmp	ax,[heap_end_ptr]
+	jnc	sts1			! Unfortunately, out of memory
+
+	seg	fs			! Store mode params
+	mov	ax,[PARAM_CURSOR_POS]
+	lea	di,modelist+1024
+	stosw
+	mov	ax,bx
+	stosw
 
 	push	ds			! Store the screen
 	mov	ds,[video_segment]
@@ -570,7 +581,8 @@
 	rep
 	movsw
 	pop	ds
-	pop	bx
+	incb	[do_restore]		! Screen will be restored later
+sts1:	pop	bx
 	pop	ax
 stsr:	ret
 
@@ -586,7 +598,7 @@
 	mov	cl,[PARAM_VIDEO_LINES]
 	seg	fs
 	mov	ch,[PARAM_VIDEO_COLS]
-	lea	si,modelist+8192	! Screen buffer
+	lea	si,modelist+1024	! Screen buffer
 	lodsw				! Set cursor position
 	mov	dx,ax
 	cmp	dh,cl
@@ -735,7 +747,7 @@
 	cmpb	[adapter],#2	! VGA only
 	jnz	ret0
 	mov	bp,di		! BP=original mode table end
-	add	di,#0x400	! Buffer space
+	add	di,#0x200	! Buffer space
 	mov	ax,#0x4f00	! VESA Get card info call
 	int	#0x10
 	mov	di,bp
@@ -1423,6 +1435,7 @@
 	.byte	0x23, 0x19, 0x84
 	.byte	0x24, 0x1c, 0x84
 	.byte	0x22, 0x2c, 0x84
+	.byte	0x21, 0x3c, 0x84
 	.byte	0
 	.ascii	"Tseng"
 	.byte	0
diff -u --recursive --new-file v1.3.75/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S
--- v1.3.75/linux/arch/i386/kernel/head.S	Mon Dec 11 15:42:00 1995
+++ linux/arch/i386/kernel/head.S	Mon Mar 18 13:15:00 1996
@@ -133,6 +133,7 @@
 	je is486
 isnew:	pushl %ecx		# restore original EFLAGS
 	popfl
+	incl SYMBOL_NAME(have_cpuid)	# we have CPUID
 	/* get processor type */
 	movl $1, %eax		# Use the CPUID instruction to 
 	.byte 0x0f, 0xa2	# check the processor type
diff -u --recursive --new-file v1.3.75/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v1.3.75/linux/arch/i386/kernel/irq.c	Sun Mar 17 09:04:04 1996
+++ linux/arch/i386/kernel/irq.c	Sun Mar 17 09:01:02 1996
@@ -212,16 +212,15 @@
 #endif
 
 /*
- * IRQ0 is timer, IRQ2 is cascade interrupt to second interrupt controller
+ * IRQ2 is cascade interrupt to second interrupt controller
  */
-extern struct irqaction irq0;
 static struct irqaction irq2  = { no_action, 0, 0, "cascade", NULL, NULL};
 
 static struct irqaction *irq_action[16] = {
-	&irq0, NULL, &irq2, NULL,
 	NULL, NULL, NULL, NULL,
 	NULL, NULL, NULL, NULL,
-	NULL, &irq13 , NULL, NULL
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL
 };
 
 int get_irq_list(char *buf)
@@ -385,59 +384,39 @@
 	}
 }
 
-int request_irq(unsigned int irq, 
-		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
+int setup_x86_irq(int irq, struct irqaction * new)
 {
 	int shared = 0;
-	struct irqaction * action, **p;
+	struct irqaction *old, **p;
 	unsigned long flags;
 
-	if (irq > 15)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
 	p = irq_action + irq;
-	action = *p;
-	if (action) {
+	if ((old = *p) != NULL) {
 		/* Can't share interrupts unless both agree to */
-		if (!(action->flags & irqflags & SA_SHIRQ))
+		if (!(old->flags & new->flags & SA_SHIRQ))
 			return -EBUSY;
 
 		/* Can't share interrupts unless both are same type */
-		if ((action->flags ^ irqflags) & SA_INTERRUPT)
+		if ((old->flags ^ new->flags) & SA_INTERRUPT)
 			return -EBUSY;
 
 		/* add new interrupt at end of irq queue */
 		do {
-			p = &action->next;
-			action = *p;
-		} while (action);
+			p = &old->next;
+			old = *p;
+		} while (old);
 		shared = 1;
 	}
 
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	if (irqflags & SA_SAMPLE_RANDOM)
+	if (new->flags & SA_SAMPLE_RANDOM)
 		rand_initialize_irq(irq);
 
-	action->handler = handler;
-	action->flags = irqflags;
-	action->mask = 0;
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
 	save_flags(flags);
 	cli();
-	*p = action;
+	*p = new;
 
 	if (!shared) {
-		if (action->flags & SA_INTERRUPT)
+		if (new->flags & SA_INTERRUPT)
 			set_intr_gate(0x20+irq,fast_interrupt[irq]);
 		else
 			set_intr_gate(0x20+irq,interrupt[irq]);
@@ -446,6 +425,38 @@
 	restore_flags(flags);
 	return 0;
 }
+
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+	if (irq > 15)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_x86_irq(irq, action);
+
+	if (retval)
+		kfree(action);
+	return retval;
+}
 		
 void free_irq(unsigned int irq, void *dev_id)
 {
@@ -535,6 +546,6 @@
 #endif	
 	request_region(0x20,0x20,"pic1");
 	request_region(0xa0,0x20,"pic2");
-	enable_irq(2);
-	enable_irq(13);
+	setup_x86_irq(2, &irq2);
+	setup_x86_irq(13, &irq13);
 } 
diff -u --recursive --new-file v1.3.75/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v1.3.75/linux/arch/i386/kernel/setup.c	Wed Mar 13 10:09:11 1996
+++ linux/arch/i386/kernel/setup.c	Mon Mar 18 13:15:00 1996
@@ -36,14 +36,15 @@
 /*
  * Tell us the machine setup..
  */
-char hard_math = 0;		/* set by boot/head.S */
-char x86 = 0;			/* set by boot/head.S to 3 or 4 */
-char x86_model = 0;		/* set by boot/head.S */
-char x86_mask = 0;		/* set by boot/head.S */
-int x86_capability = 0;		/* set by boot/head.S */
+char hard_math = 0;		/* set by kernel/head.S */
+char x86 = 0;			/* set by kernel/head.S to 3..6 */
+char x86_model = 0;		/* set by kernel/head.S */
+char x86_mask = 0;		/* set by kernel/head.S */
+int x86_capability = 0;		/* set by kernel/head.S */
 int fdiv_bug = 0;		/* set if Pentium(TM) with FP bug */
+int have_cpuid = 0;             /* set if CPUID instruction works */
 
-char x86_vendor_id[13] = "Unknown";
+char x86_vendor_id[13] = "unknown";
 
 char ignore_irq13 = 0;		/* set if exception 16 works */
 char wp_works_ok = -1;		/* set if paging hardware honours WP */ 
@@ -211,7 +212,7 @@
 	};
 	if (nr < sizeof(model)/sizeof(char *))
 		return model[nr];
-	return "Unknown";
+	return NULL;
 }
 
 static const char * i586model(unsigned int nr)
@@ -221,144 +222,96 @@
 	};
 	if (nr < sizeof(model)/sizeof(char *))
 		return model[nr];
-	return "Unknown";
+	return NULL;
 }
 
 static const char * getmodel(int x86, int model)
 {
+        const char *p = NULL;
+        static char nbuf[12];
 	switch (x86) {
 		case 4:
-			return i486model(model);
+			p = i486model(model);
 		case 5:
-			return i586model(model);
+			p = i586model(model);
 	}
-	return "Unknown";
+        if (p)
+                return p;
+
+        sprintf(nbuf, "%d", model);
+        return nbuf;
 }
 
 int get_cpuinfo(char * buffer)
 {
-	char mask[2];
-#ifndef __SMP__	
-	mask[0] = x86_mask+'@';
-	mask[1] = '\0';
-	return sprintf(buffer,"cpu\t\t: %c86\n"
-			      "model\t\t: %s\n"
-			      "mask\t\t: %s\n"
-			      "vid\t\t: %s\n"
-			      "fdiv_bug\t: %s\n"
-			      "math\t\t: %s\n"
-			      "hlt\t\t: %s\n"
-			      "wp\t\t: %s\n"
-			      "Integrated NPU\t: %s\n"
-			      "Enhanced VM86\t: %s\n"
-			      "IO Breakpoints\t: %s\n"
-			      "4MB Pages\t: %s\n"
-			      "TS Counters\t: %s\n"
-			      "Pentium MSR\t: %s\n"
-			      "Mach. Ch. Exep.\t: %s\n"
-			      "CMPXCHGB8B\t: %s\n"
-		              "BogoMips\t: %lu.%02lu\n",
-			      x86+'0', 
-			      getmodel(x86, x86_model),
-			      x86_mask ? mask : "Unknown",
-			      x86_vendor_id,
-			      fdiv_bug ? "yes" : "no",
-			      hard_math ? "yes" : "no",
-			      hlt_works_ok ? "yes" : "no",
-			      wp_works_ok ? "yes" : "no",
-			      x86_capability & 1 ? "yes" : "no",
-			      x86_capability & 2 ? "yes" : "no",
-			      x86_capability & 4 ? "yes" : "no",
-			      x86_capability & 8 ? "yes" : "no",
-			      x86_capability & 16 ? "yes" : "no",
-			      x86_capability & 32 ? "yes" : "no",
-			      x86_capability & 128 ? "yes" : "no",
-			      x86_capability & 256 ? "yes" : "no",
-		              loops_per_sec/500000, (loops_per_sec/5000) % 100
-			      );
+        int i, len = 0;
+        static const char *x86_cap_flags[] = {
+                "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+                "cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov",
+                "16", "17", "18", "19", "20", "21", "22", "mmx",
+                "24", "25", "26", "27", "28", "29", "30", "31"
+        };
+        
+#ifdef __SMP__
+        int n;
+
+#define CD(X) (cpu_data[n].(X))
+#define CPUN n
+
+        for ( n = 0 ; n < 32 ; n++ ) {
+                if ( cpu_present_map & (1<<n) ) {
+                        if (len) buffer[len++] = '\n'; 
+
 #else
-	char *bp=buffer;
-	int i;	
-	bp+=sprintf(bp,"cpu\t\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%c86             ",cpu_data[i].x86+'0');
-	bp+=sprintf(bp,"\nmodel\t\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s",getmodel(cpu_data[i].x86,cpu_data[i].x86_model));
-	bp+=sprintf(bp,"\nmask\t\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-		{
-			mask[0] = cpu_data[i].x86_mask+'@';
-			mask[1] = '\0';		
-			bp+=sprintf(bp,"%-16s", cpu_data[i].x86_mask ? mask : "Unknown");
-		}
-	bp+=sprintf(bp,"\nvid\t\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", cpu_data[i].x86_vendor_id);
-	bp+=sprintf(bp,"\nfdiv_bug\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", cpu_data[i].fdiv_bug?"yes":"no");
-	bp+=sprintf(bp,"\nmath\t\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", cpu_data[i].hard_math?"yes":"no");
-	bp+=sprintf(bp,"\nhlt\t\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", cpu_data[i].hlt_works_ok?"yes":"no");
-	bp+=sprintf(bp,"\nwp\t\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", cpu_data[i].wp_works_ok?"yes":"no");
-	bp+=sprintf(bp,"\nIntegrated NPU\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", cpu_data[i].x86_capability&1?"yes":"no");
-	bp+=sprintf(bp,"\nEnhanced VM86\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", cpu_data[i].x86_capability&2?"yes":"no");
-	bp+=sprintf(bp,"\nIO Breakpoints\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&4)?"yes":"no");
-	bp+=sprintf(bp,"\n4MB Pages\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability)&8?"yes":"no");
-	bp+=sprintf(bp,"\nTS Counters\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&16)?"yes":"no");
-	bp+=sprintf(bp,"\nPentium MSR\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&32)?"yes":"no");
-	bp+=sprintf(bp,"\nMach. Ch. Exep.\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&128)?"yes":"no");
-	bp+=sprintf(bp,"\nCMPXCHG8B\t: ");
-	for(i=0;i<32;i++)
-		if(cpu_present_map&(1<<i))
-			bp+=sprintf(bp,"%-16s", (cpu_data[i].x86_capability&256)?"yes":"no");
-	bp+=sprintf(bp,"\nBogoMips\t: ");
-	for(i=0;i<32;i++)
-	{
-		char tmp[17];
-		if(cpu_present_map&(1<<i))
-		{
-			sprintf(tmp,"%lu.%02lu",cpu_data[i].udelay_val/500000L,
-						   (cpu_data[i].udelay_val/5000L)%100);
-			bp+=sprintf(bp,"%-16s",tmp);
-		}
-	}
-	*bp++='\n';
-	return bp-buffer;
-#endif			      
+#define CD(X) (X)
+#define CPUN 0
+#endif
+
+                        len += sprintf(buffer+len,"processor\t: %d\n"
+                                       "cpu\t\t: %c86\n"
+                                       "model\t\t: %s\n"
+                                       "vendor_id\t: %s\n",
+                                       CPUN,
+                                       CD(x86)+'0',
+                                       CD(have_cpuid) ? 
+                                         getmodel(CD(x86), CD(x86_model)) :
+                                         "unknown",
+                                       CD(x86_vendor_id));
+        
+                        if (CD(x86_mask))
+                                len += sprintf(buffer+len,
+                                               "stepping\t: %d\n",
+                                               CD(x86_mask));
+                        else
+                                len += sprintf(buffer+len, 
+                                               "stepping\t: unknown\n");
+        
+                        len += sprintf(buffer+len,
+                                       "fdiv_bug\t: %s\n"
+                                       "hlt_bug\t\t: %s\n"
+                                       "fpu\t\t: %s\n"
+                                       "cpuid\t\t: %s\n"
+                                       "wp\t\t: %s\n"
+                                       "flags\t\t:",
+                                       CD(fdiv_bug) ? "yes" : "no",
+                                       CD(hlt_works_ok) ? "no" : "yes",
+                                       CD(hard_math) ? "yes" : "no",
+                                       CD(have_cpuid) ? "yes" : "no",
+                                       CD(wp_works_ok) ? "yes" : "no");
+        
+                        for ( i = 0 ; i < 32 ; i++ ) {
+                                if ( CD(x86_capability) & (1 << i) ) {
+                                        len += sprintf(buffer+len, " %s",
+                                                       x86_cap_flags[i]);
+                                }
+                        }
+                        len += sprintf(buffer+len,
+                                       "\nbogomips:\t: %lu.%02lu\n",
+                                       CD(loops_per_sec)/500000,
+                                       (CD(loops_per_sec)/5000) % 100);
+#ifdef __SMP__
+                }
+        }
+#endif
+        return len;
 }
diff -u --recursive --new-file v1.3.75/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v1.3.75/linux/arch/i386/kernel/smp.c	Sun Mar 17 09:04:04 1996
+++ linux/arch/i386/kernel/smp.c	Mon Mar 18 13:15:00 1996
@@ -494,6 +494,7 @@
 	c->fdiv_bug=fdiv_bug;
 	c->wp_works_ok=wp_works_ok;		/* Always assumed the same currently */
 	c->hlt_works_ok=hlt_works_ok;
+	c->have_cpuid=have_cpuid;
 	c->udelay_val=loops_per_sec;
 	strcpy(c->x86_vendor_id, x86_vendor_id);
 }
diff -u --recursive --new-file v1.3.75/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- v1.3.75/linux/arch/i386/kernel/time.c	Wed Mar 13 10:09:12 1996
+++ linux/arch/i386/kernel/time.c	Sun Mar 17 08:54:33 1996
@@ -27,6 +27,8 @@
 #include <linux/timex.h>
 #include <linux/config.h>
 
+extern int setup_x86_irq(int, struct irqaction *);
+
 /* Cycle counter value at the previous timer interrupt.. */
 static unsigned long long last_timer_cc = 0;
 static unsigned long long init_timer_cc = 0;
@@ -353,7 +355,7 @@
 	return mktime(year, mon, day, hour, min, sec);
 }
 
-struct irqaction irq0  = { timer_interrupt, 0, 0, "timer", NULL, NULL};
+static struct irqaction irq0  = { timer_interrupt, 0, 0, "timer", NULL, NULL};
 
 void time_init(void)
 {
@@ -374,5 +376,5 @@
 		irq0.handler = pentium_timer_interrupt;
 	}
 #endif
-	enable_irq(0);
+	setup_x86_irq(0, &irq0);
 }
diff -u --recursive --new-file v1.3.75/linux/arch/i386/math-emu/reg_constant.c linux/arch/i386/math-emu/reg_constant.c
--- v1.3.75/linux/arch/i386/math-emu/reg_constant.c	Thu Jun  2 10:28:27 1994
+++ linux/arch/i386/math-emu/reg_constant.c	Tue Mar 19 13:45:01 1996
@@ -3,9 +3,9 @@
  |                                                                           |
  | All of the constant FPU_REGs                                              |
  |                                                                           |
- | Copyright (C) 1992,1993,1994                                              |
- |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
- |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ | Copyright (C) 1992,1993,1994,1996                                         |
+ |                     W. Metzenthen, 22 Parker St, Ormond, Vic 3163,        |
+ |                     Australia.  E-mail   billm@jacobi.maths.monash.edu.au |
  |                                                                           |
  |                                                                           |
  +---------------------------------------------------------------------------*/
@@ -14,6 +14,7 @@
 #include "fpu_emu.h"
 #include "status_w.h"
 #include "reg_constant.h"
+#include "control_w.h"
 
 
 FPU_REG const CONST_1    = { SIGN_POS, TW_Valid, EXP_BIAS,
@@ -56,7 +57,7 @@
 
 
 
-static void fld_const(FPU_REG const *c)
+static void fld_const(FPU_REG const *c, int adj)
 {
   FPU_REG *st_new_ptr;
 
@@ -67,50 +68,58 @@
     }
   push();
   reg_move(c, st_new_ptr);
+  st_new_ptr->sigl += adj;  /* For all our fldxxx constants, we don't need to
+			       borrow or carry. */
   clear_C1();
 }
 
+/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
+   (and not one of RC_RND or RC_UP).
+   */
+#define DOWN_OR_CHOP(x)  (x & RC_DOWN)
 
-static void fld1(void)
+static void fld1(int rc)
 {
-  fld_const(&CONST_1);
+  fld_const(&CONST_1, 0);
 }
 
-static void fldl2t(void)
+static void fldl2t(int rc)
 {
-  fld_const(&CONST_L2T);
+  fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0);
 }
 
-static void fldl2e(void)
+static void fldl2e(int rc)
 {
-  fld_const(&CONST_L2E);
+  fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0);
 }
 
-static void fldpi(void)
+static void fldpi(int rc)
 {
-  fld_const(&CONST_PI);
+  fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0);
 }
 
-static void fldlg2(void)
+static void fldlg2(int rc)
 {
-  fld_const(&CONST_LG2);
+  fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0);
 }
 
-static void fldln2(void)
+static void fldln2(int rc)
 {
-  fld_const(&CONST_LN2);
+  fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0);
 }
 
-static void fldz(void)
+static void fldz(int rc)
 {
-  fld_const(&CONST_Z);
+  fld_const(&CONST_Z, 0);
 }
 
-static FUNC constants_table[] = {
-  fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, FPU_illegal
+typedef void (*FUNC_RC)(int);
+
+static FUNC_RC constants_table[] = {
+  fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC)FPU_illegal
 };
 
 void fconst(void)
 {
-  (constants_table[FPU_rm])();
+  (constants_table[FPU_rm])(control_word & CW_RC);
 }
diff -u --recursive --new-file v1.3.75/linux/arch/i386/math-emu/version.h linux/arch/i386/math-emu/version.h
--- v1.3.75/linux/arch/i386/math-emu/version.h	Mon Aug  1 08:19:16 1994
+++ linux/arch/i386/math-emu/version.h	Tue Mar 19 13:45:02 1996
@@ -2,11 +2,11 @@
  |  version.h                                                                |
  |                                                                           |
  |                                                                           |
- | Copyright (C) 1992,1993,1994                                              |
- |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
- |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ | Copyright (C) 1992,1993,1994,1996                                         |
+ |                     W. Metzenthen, 22 Parker St, Ormond, Vic 3163,        |
+ |                     Australia.  E-mail   billm@jacobi.maths.monash.edu.au |
  |                                                                           |
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
-#define FPU_VERSION "wm-FPU-emu version 1.20"
+#define FPU_VERSION "wm-FPU-emu version 1.21"
diff -u --recursive --new-file v1.3.75/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v1.3.75/linux/drivers/block/floppy.c	Fri Mar 15 16:03:10 1996
+++ linux/drivers/block/floppy.c	Sat Mar 16 23:13:55 1996
@@ -175,7 +175,7 @@
 {
 	int order;
 
-	size >>= (PAGE_SHIFT-1);
+	size = (size-1) >> (PAGE_SHIFT-1);
 	order = -1;
 	do {
 		size >>= 1;
diff -u --recursive --new-file v1.3.75/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.3.75/linux/drivers/block/ide.c	Sun Mar 17 09:04:05 1996
+++ linux/drivers/block/ide.c	Sun Mar 17 09:58:23 1996
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide.c	Version 5.33  Mar 15, 1996
+ *  linux/drivers/block/ide.c	Version 5.34  Mar 16, 1996
  *
  *  Copyright (C) 1994-1996  Linus Torvalds & authors (see below)
  */
@@ -218,7 +218,9 @@
  *			add config option for PCMCIA baggage
  *			try to make PCMCIA support safer to use
  *			improve security on ioctls(): all are suser() only
- * Version 5.33			improve handling of HDIO_DRIVE_CMDs that read data
+ * Version 5.33		improve handling of HDIO_DRIVE_CMDs that read data
+ * Version 5.34		fix irq-sharing problem from 5.33
+ *			fix cdrom ioctl problem from 5.33
  *
  *  Some additional driver compile-time options are in ide.h
  *
@@ -1893,8 +1895,6 @@
 	unsigned long flags;
 	struct request rq;
 
-	if (!suser())
-		return -EACCES;
 	if (!inode || !(inode->i_rdev))
 		return -EINVAL;
 	if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
@@ -1915,11 +1915,13 @@
 			return 0;
 		}
 		case BLKFLSBUF:
+			if (!suser()) return -EACCES;
 			fsync_dev(inode->i_rdev);
 			invalidate_buffers(inode->i_rdev);
 			return 0;
 
 		case BLKRASET:
+			if (!suser()) return -EACCES;
 			if(arg > 0xff) return -EINVAL;
 			read_ahead[MAJOR(inode->i_rdev)] = arg;
 			return 0;
@@ -1930,6 +1932,7 @@
 	 	case BLKGETSIZE:   /* Return device size */
 			return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects);
 		case BLKRRPART: /* Re-read partition tables */
+			if (!suser()) return -EACCES;
 			return revalidate_disk(inode->i_rdev);
 
 		case HDIO_GET_KEEPSETTINGS:
@@ -1961,6 +1964,7 @@
 			return write_fs_long(arg, drive->bad_wstat == BAD_R_STAT);
 
 		case HDIO_SET_DMA:
+			if (!suser()) return -EACCES;
 #ifdef CONFIG_BLK_DEV_IDECD
 			if (drive->media == ide_cdrom)
 				return -EPERM;
@@ -1973,6 +1977,7 @@
 			if (arg > 1)
 				return -EINVAL;
 		case HDIO_SET_32BIT:
+			if (!suser()) return -EACCES;
 			if ((MINOR(inode->i_rdev) & PARTN_MASK))
 				return -EINVAL;
 			save_flags(flags);
@@ -2012,6 +2017,7 @@
 			return 0;
 
 		case HDIO_SET_MULTCOUNT:
+			if (!suser()) return -EACCES;
 			if (MINOR(inode->i_rdev) & PARTN_MASK)
 				return -EINVAL;
 			if (drive->id && arg > drive->id->max_multsect)
@@ -2032,6 +2038,7 @@
 		{
 			byte args[4], *argbuf = args;
 			int argsize = 4;
+			if (!suser()) return -EACCES;
 			if (NULL == (void *) arg) {
 				err = ide_do_drive_cmd(drive, &rq, ide_wait);
 			} else if (!(err = verify_area(VERIFY_READ,(void *)arg, 4))) {
@@ -2057,6 +2064,7 @@
 			return err;
 		}
 		case HDIO_SET_PIO_MODE:
+			if (!suser()) return -EACCES;
 			if (MINOR(inode->i_rdev) & PARTN_MASK)
 				return -EINVAL;
 			if (!HWIF(drive)->tuneproc)
@@ -2973,22 +2981,20 @@
 	 * Handle serialization, regardless of init sequence
 	 */
 	mate_hwif = &ide_hwifs[hwif->index ^ 1];
-	if (hwif->serialized && mate_hwif->present) {
-		hwgroup = mate_hwif->hwgroup;
+	if (hwif->serialized && mate_hwif->present)
 		mate_irq = mate_hwif->irq;
-	}
 
 	/*
-	 * If another hwif is sharing our irq, then join its hwgroup.
+	 * Group up with any other hwifs that share our irq(s)
 	 */
-	if (hwgroup == NULL) {
-		for (index = 0; index < MAX_HWIFS; index++) {
-			if (index != hwif->index) {
-				ide_hwif_t *g = &ide_hwifs[index];
-				if (g->irq == hwif->irq || g->irq == mate_irq) {
-					hwgroup = ide_hwifs[index].hwgroup;
-					break;
-				}
+	for (index = 0; index < MAX_HWIFS; index++) {
+		if (index != hwif->index) {
+			ide_hwif_t *g = &ide_hwifs[index];
+			if (g->irq == hwif->irq || g->irq == mate_irq) {
+				if (hwgroup && !g->hwgroup)
+					g->hwgroup = hwgroup;
+				else if (!hwgroup)
+					hwgroup = g->hwgroup;
 			}
 		}
 	}
@@ -3001,7 +3007,10 @@
 		hwgroup->hwif 	 = hwgroup->next_hwif = hwif->next = hwif;
 		hwgroup->rq      = NULL;
 		hwgroup->handler = NULL;
-		hwgroup->drive   = &hwif->drives[0];
+		if (hwif->drives[0].present)
+			hwgroup->drive   = &hwif->drives[0];
+		else
+			hwgroup->drive   = &hwif->drives[1];
 		hwgroup->poll_timeout = 0;
 		init_timer(&hwgroup->timer);
 		hwgroup->timer.function = &timer_expiry;
@@ -3016,7 +3025,11 @@
 			restore_flags(flags);
 			return 1;
 		}
-		hwif->got_irq = 1;
+		for (index = 0; index < MAX_HWIFS; index++) {
+			ide_hwif_t *g = &ide_hwifs[index];
+			if (g->irq == hwif->irq)
+				g->got_irq = 1;
+		}
 	}
 
 	/*
diff -u --recursive --new-file v1.3.75/linux/drivers/block/promise.c linux/drivers/block/promise.c
--- v1.3.75/linux/drivers/block/promise.c	Sun Mar 17 09:04:05 1996
+++ linux/drivers/block/promise.c	Sun Mar 17 09:58:23 1996
@@ -25,6 +25,7 @@
  *  Version 0.04        Updated for ide.c version 5.30
  *                      Changed initialization strategy
  *  Version 0.05	Kernel integration.  -ml
+ *  Version 0.06	Ooops. Add hwgroup to direct call of ide_intr() -ml
  */
 
 
@@ -58,6 +59,7 @@
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include "ide.h"
 #include "promise.h"
 
@@ -319,7 +321,13 @@
 	    do {
 		stat=GET_STAT();
 		if(stat & DRQ_STAT) {
-		    ide_intr(HWIF(drive)->irq,NULL,NULL);
+                    unsigned long flags;
+                    save_flags(flags);
+                    cli();
+                    disable_irq(HWIF(drive)->irq);
+		    ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL);
+                    enable_irq(HWIF(drive)->irq);
+                    restore_flags(flags);
 		    return;
 		}
 		if(IN_BYTE(io_base+IDE_SELECT_OFFSET) & 0x01)
diff -u --recursive --new-file v1.3.75/linux/drivers/char/ftape/kernel-interface.c linux/drivers/char/ftape/kernel-interface.c
--- v1.3.75/linux/drivers/char/ftape/kernel-interface.c	Sun Mar 17 09:04:06 1996
+++ linux/drivers/char/ftape/kernel-interface.c	Sat Mar 16 23:13:55 1996
@@ -89,7 +89,7 @@
 {
 	int order;
 
-	size >>= (PAGE_SHIFT-1);
+	size = (size-1) >> (PAGE_SHIFT-1);
 	order = -1;
 	do {
 		size >>= 1;
diff -u --recursive --new-file v1.3.75/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v1.3.75/linux/drivers/net/eexpress.c	Fri Mar 15 16:03:14 1996
+++ linux/drivers/net/eexpress.c	Sun Mar 17 09:58:21 1996
@@ -730,10 +730,13 @@
 		outb(0,ioaddr+SET_IRQ);
 	}
 
-	eexp_hw_ASICrst(dev);
-
 	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+	if (!dev->priv) 
+		return -ENOMEM;
+
 	memset(dev->priv, 0, sizeof(struct net_local));
+
+	eexp_hw_ASICrst(dev);
 
 	{
 		unsigned short i586mso = 0x023e;
diff -u --recursive --new-file v1.3.75/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.3.75/linux/drivers/scsi/scsi.c	Sun Mar 10 09:49:55 1996
+++ linux/drivers/scsi/scsi.c	Tue Mar 19 10:00:49 1996
@@ -271,6 +271,7 @@
 {"INSITE","I325VM","*", BLIST_KEY},
 {"PIONEER","CD-ROM DRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
 {"PIONEER","CD-ROM DRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
+{"EMULEX","MD21/S2     ESDI","*",BLIST_FORCELUN | BLIST_SINGLELUN},
 /*
  * Must be at end of list...
  */
@@ -768,8 +769,10 @@
    * If this device is known to support multiple units, override the other
    * settings, and scan all of them.
    */
-  if (bflags & BLIST_FORCELUN)
+  if (bflags & BLIST_FORCELUN) {
     *max_dev_lun = 8;
+    return 1;
+  }
   /*
    * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI
    * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1
@@ -1037,17 +1040,32 @@
 	    restore_flags(flags);
 	    return NULL;
 	}
-	if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE)  /* Might have changed */
+	if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE)	/* Might have changed */
 	{
-	    restore_flags(flags);
-	    if(!wait) return NULL;
-	    if (!SCwait) {
-		printk("Attempt to allocate device channel %d, target %d, "
-		       "lun %d\n", device->channel, device->id, device->lun);
-		panic("No device found in allocate_device\n");
-	    }
-	    SCSI_SLEEP(&device->device_wait,
-		       (SCwait->request.rq_status != RQ_INACTIVE));
+#if 1	/* NEW CODE */
+		if (wait && SCwait && SCwait->request.rq_status != RQ_INACTIVE) {
+ 			sleep_on(&device->device_wait);
+ 			restore_flags(flags);
+	 	} else {
+ 			restore_flags(flags);
+	 		if (!wait) return NULL;
+ 			if (!SCwait) {
+	 			printk("Attempt to allocate device target %d, lun %d\n",
+ 					device->id ,device->lun);
+ 				panic("No device found in allocate_device\n");
+	 		}
+ 		}
+#else	/* ORIGINAL CODE */
+		    restore_flags(flags);
+		    if(!wait) return NULL;
+		    if (!SCwait) {
+			printk("Attempt to allocate device channel %d, target %d, "
+			       "lun %d\n", device->channel, device->id, device->lun);
+			panic("No device found in allocate_device\n");
+		    }
+		    SCSI_SLEEP(&device->device_wait,
+			       (SCwait->request.rq_status != RQ_INACTIVE));
+#endif
 	} else {
 	    if (req) {
 		memcpy(&SCpnt->request, req, sizeof(struct request));
diff -u --recursive --new-file v1.3.75/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v1.3.75/linux/drivers/scsi/sd.c	Wed Dec 13 09:02:47 1995
+++ linux/drivers/scsi/sd.c	Mon Mar 18 13:15:00 1996
@@ -1126,10 +1126,10 @@
 	 */
 	rscsi_disks[i].ready = 1;
 
-	rscsi_disks[i].capacity = (buffer[0] << 24) |
-	    (buffer[1] << 16) |
-		(buffer[2] << 8) |
-		    buffer[3];
+	rscsi_disks[i].capacity = 1 + ((buffer[0] << 24) |
+				       (buffer[1] << 16) |
+				       (buffer[2] << 8) |
+				       buffer[3]);
 	
 	rscsi_disks[i].sector_size = (buffer[4] << 24) |
 	    (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
diff -u --recursive --new-file v1.3.75/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v1.3.75/linux/drivers/scsi/sr.c	Sat Feb 17 16:02:52 1996
+++ linux/drivers/scsi/sr.c	Mon Mar 18 11:54:26 1996
@@ -1020,18 +1020,27 @@
 	    (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
 	scsi_CDs[i].sector_size = (buffer[4] << 24) |
 	    (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
-	if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
-	/* Work around bug/feature in HP 4020i CD-Recorder... */
-	if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
-	if(scsi_CDs[i].sector_size != 2048 && 
-	   scsi_CDs[i].sector_size != 512) {
-	    printk ("scd%d : unsupported sector size %d.\n",
-		    i, scsi_CDs[i].sector_size);
-	    scsi_CDs[i].capacity = 0;
-	    scsi_CDs[i].needs_sector_size = 1;
-	};
-	if(scsi_CDs[i].sector_size == 2048)
-	    scsi_CDs[i].capacity *= 4;
+	switch (scsi_CDs[i].sector_size) {
+		/*
+		 * HP 4020i CD-Recorder reports 2340 byte sectors
+		 * Philips CD-Writers report 2352 byte sectors
+		 *
+		 * Use 2k sectors for them..
+		 */
+		case 0: case 2340: case 2352:
+			scsi_CDs[i].sector_size = 2048;
+			/* fall through */
+		case 2048:
+			scsi_CDs[i].capacity *= 4;
+			/* fall through */
+		case 512:
+			break;
+		default:
+			printk ("scd%d : unsupported sector size %d.\n",
+				i, scsi_CDs[i].sector_size);
+			scsi_CDs[i].capacity = 0;
+			scsi_CDs[i].needs_sector_size = 1;
+	}
 	scsi_CDs[i].needs_sector_size = 0;
 	sr_sizes[i] = scsi_CDs[i].capacity;
     };
diff -u --recursive --new-file v1.3.75/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v1.3.75/linux/drivers/scsi/sr_ioctl.c	Sat Nov 11 17:41:33 1995
+++ linux/drivers/scsi/sr_ioctl.c	Tue Mar 19 08:58:59 1996
@@ -378,6 +378,44 @@
 	return result;
     }
 	
+    case CDROMVOLREAD:
+    {
+	char * buffer;
+	struct cdrom_volctrl volctrl;
+	
+        err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_volctrl));
+        if (err) return err;
+	
+	/* Get the current params */
+	
+	sr_cmd[0] = MODE_SENSE;
+	sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
+	sr_cmd[2] = 0xe;    /* Want mode page 0xe, CDROM audio params */
+	sr_cmd[3] = 0;
+	sr_cmd[4] = 28;
+	sr_cmd[5] = 0;
+	
+	buffer = (unsigned char *) scsi_malloc(512);
+	if(!buffer) return -ENOMEM;
+	
+	if ((result = do_ioctl (target, sr_cmd, buffer, 28))) {
+	    printk ("(CDROMVOLREAD) Hosed while obtaining audio mode page\n");
+	    scsi_free(buffer, 512);
+	    return result;
+	}
+
+	volctrl.channel0 = buffer[21];
+	volctrl.channel1 = buffer[23];
+	volctrl.channel2 = buffer[25];
+	volctrl.channel3 = buffer[27];
+
+	memcpy_tofs ((void *) arg, &volctrl, sizeof (struct cdrom_volctrl));
+
+	scsi_free(buffer, 512);
+
+	return 0;
+    }
+	
     case CDROMSUBCHNL:
     {
 	struct cdrom_subchnl subchnl;
diff -u --recursive --new-file v1.3.75/linux/drivers/sound/configure.c linux/drivers/sound/configure.c
--- v1.3.75/linux/drivers/sound/configure.c	Sun Mar 17 09:04:07 1996
+++ linux/drivers/sound/configure.c	Sun Mar 17 09:58:21 1996
@@ -778,7 +778,7 @@
 		  "Check from manual of the card");
 
   ask_int_choice (B (OPT_SB), "SB_MPU_IRQ",
-		  "SB MPU401 IRQ (SB16, Jazz16 and ES1688)",
+		  "SB MPU401 IRQ (Jazz16 and ES1688)",
 		  FMT_INT,
 		  -1,
 		  "Check from manual of the card");
diff -u --recursive --new-file v1.3.75/linux/fs/Config.in linux/fs/Config.in
--- v1.3.75/linux/fs/Config.in	Fri Feb 16 11:34:09 1996
+++ linux/fs/Config.in	Tue Mar 19 09:05:23 1996
@@ -21,6 +21,10 @@
   tristate 'NFS filesystem support' CONFIG_NFS_FS
   if [ "$CONFIG_NFS_FS" = "y" ]; then
     bool 'Root file system on NFS' CONFIG_ROOT_NFS
+    if [ "$CONFIG_ROOT_NFS" = "y" ]; then
+      bool 'BOOTP support' CONFIG_RNFS_BOOTP
+      bool 'RARP support' CONFIG_RNFS_RARP
+    fi
   fi
   tristate 'SMB filesystem support (to mount WfW shares etc..)' CONFIG_SMB_FS
 fi
diff -u --recursive --new-file v1.3.75/linux/fs/inode.c linux/fs/inode.c
--- v1.3.75/linux/fs/inode.c	Wed Mar 13 10:09:19 1996
+++ linux/fs/inode.c	Mon Mar 18 10:38:59 1996
@@ -12,6 +12,25 @@
 
 #include <asm/system.h>
 
+#define NR_IHASH 512
+
+/*
+ * Be VERY careful when you access the inode hash table. There
+ * are some rather scary race conditions you need to take care of:
+ *  - P1 tries to open file "xx", calls "iget()" with the proper
+ *    inode number, but blocks because it's not on the list.
+ *  - P2 deletes file "xx", gets the inode (which P1 has just read,
+ *    but P1 hasn't woken up to the fact yet)
+ *  - P2 iput()'s the inode, which now has i_nlink = 0
+ *  - P1 wakes up and has the inode, but now P2 has made that
+ *    inode invalid (but P1 has no way of knowing that).
+ *
+ * The "updating" counter makes sure that when P1 blocks on the
+ * iget(), P2 can't delete the inode from under it because P2
+ * will wait until P1 has been able to update the inode usage
+ * count so that the inode will stay in use until everybody has
+ * closed it..
+ */
 static struct inode_hash_entry {
 	struct inode * inode;
 	int updating;
@@ -563,6 +582,13 @@
 		if (inode->i_dev == sb->s_dev && inode->i_ino == nr)
 			goto found_it;
 	if (!empty) {
+		/*
+		 * If we sleep here before we have found an inode
+		 * we need to make sure nobody does anything bad
+		 * to the inode while we sleep, because otherwise
+		 * we may return an inode that is not valid any
+		 * more when we wake up..
+		 */
 		h->updating++;
 		empty = get_empty_inode();
 		if (!--h->updating)
diff -u --recursive --new-file v1.3.75/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
--- v1.3.75/linux/fs/nfs/nfsroot.c	Sun Mar 17 09:04:07 1996
+++ linux/fs/nfs/nfsroot.c	Tue Mar 19 09:05:23 1996
@@ -1,5 +1,5 @@
 /*
- *  linux/fs/nfs/nfsroot.c -- version 2.0
+ *  linux/fs/nfs/nfsroot.c -- version 2.1
  *
  *  Copyright (C) 1995  Gero Kuhlmann <gero@gkminix.han.de>
  *  Copyright (C) 1996  Martin Mares <mj@k332.feld.cvut.cz>
@@ -25,6 +25,8 @@
  *	Martin Mares	:	Randomized timer with exponential backoff
  *				installed to minimize network congestion.
  *	Martin Mares	:	Code cleanup.
+ *	Martin Mares	: (2.1)	BOOTP and RARP made configuration options.
+ *	Martin Mares	:	Server hostname generation fixed.
  *
  *
  *	Known bugs and caveats:
@@ -40,10 +42,6 @@
 #undef NFSROOT_DEBUG
 #undef NFSROOT_MORE_DEBUG
 
-/* Choose default protocol(s) */
-#define CONFIG_USE_BOOTP
-#define CONFIG_USE_RARP
-
 /* Define the timeout for waiting for a RARP/BOOTP reply */
 #define CONF_BASE_TIMEOUT	(HZ*5)	/* Initial timeout: 5 seconds */
 #define CONF_RETRIES	 	10	/* 10 retries */
@@ -106,14 +104,19 @@
 static struct sockaddr_in netmask;	/* Netmask for local subnet */
 
 /* BOOTP/RARP variables */
+
 static int bootp_flag;			/* User said: Use BOOTP! */
 static int rarp_flag;			/* User said: Use RARP! */
 static int bootp_dev_count = 0;		/* Number of devices allowing BOOTP */
 static int rarp_dev_count = 0;		/* Number of devices allowing RARP */
+
+#if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
+#define CONFIG_RNFS_DYNAMIC		/* Enable dynamic IP config */
 volatile static int pkt_arrived;	/* BOOTP/RARP packet detected */
 
 #define ARRIVED_BOOTP 1
 #define ARRIVED_RARP 2
+#endif
 
 /* NFS-related data */
 static struct nfs_mount_data nfs_data;	/* NFS mount info */
@@ -212,6 +215,8 @@
 
  ***************************************************************************/
 
+#ifdef CONFIG_RNFS_RARP
+
 extern void arp_send(int type, int ptype, unsigned long target_ip,
 		     struct device *dev, unsigned long src_ip,
 		     unsigned char *dest_hw, unsigned char *src_hw,
@@ -350,6 +355,7 @@
 	}
 }
 
+#endif
 
 /***************************************************************************
 
@@ -357,6 +363,8 @@
 
  ***************************************************************************/
 
+#ifdef CONFIG_RNFS_BOOTP
+
 static struct device *bootp_dev = NULL;	/* Device selected as best BOOTP target */
 
 static int bootp_xmit_fd = -1;		/* Socket descriptor for transmit */
@@ -827,6 +835,7 @@
 	}
 }
 
+#endif
 
 /***************************************************************************
 
@@ -834,6 +843,8 @@
 
  ***************************************************************************/
 
+#ifdef CONFIG_RNFS_DYNAMIC
+
 /*
  *  Determine client and server IP numbers and appropriate device by using
  *  the RARP and BOOTP protocols.
@@ -843,24 +854,43 @@
 	int retries;
 	u32 timeout, jiff;
 	u32 start_jiffies;
+	int selected = 0;
 
 	/* Check devices */
-	if (bootp_flag && !bootp_dev_count) {
-		printk(KERN_ERR "BOOTP: No suitable device found.\n");
-		bootp_flag = 0;
+
+#ifdef CONFIG_RNFS_BOOTP
+	if (bootp_flag) {
+		if (bootp_dev_count)
+			selected = 1;
+		else {
+			printk(KERN_ERR "BOOTP: No suitable device found.\n");
+			bootp_flag = 0;
 		}
-	if (rarp_flag && !rarp_dev_count) {
-		printk(KERN_ERR "RARP: No suitable device found.\n");
-		rarp_flag = 0;
+	}
+#else
+	bootp_flag = 0;
+#endif
+
+#ifdef CONFIG_RNFS_RARP
+	if (rarp_flag) {
+		if (rarp_dev_count)
+			selected = 1;
+		else {
+			printk(KERN_ERR "RARP: No suitable device found.\n");
+			rarp_flag = 0;
 		}
+	}
+#else
+	rarp_flag = 0;
+#endif
 
 	/* If neither BOOTP nor RARP was selected manually, use both of them */
-	if (!bootp_flag && !rarp_flag) {
-#ifdef CONFIG_USE_BOOTP
+	if (!selected) {
+#ifdef CONFIG_RNFS_BOOTP
 		if (bootp_dev_count)
 			bootp_flag = 1;
 #endif
-#ifdef CONFIG_USE_RARP
+#ifdef CONFIG_RNFS_RARP
 		if (rarp_dev_count)
 			rarp_flag = 1;
 #endif
@@ -869,12 +899,16 @@
 	}
 
 	/* Setup RARP and BOOTP protocols */
+#ifdef CONFIG_RNFS_RARP
 	if (rarp_flag)
 		root_rarp_open();
+#endif
+#ifdef CONFIG_RNFS_BOOTP
 	if (bootp_flag && root_bootp_open()) {
 		root_bootp_close();
 		return -1;
 	}
+#endif
 
 	/*
 	 * Send requests and wait, until we get an answer. This loop
@@ -893,6 +927,7 @@
 	get_random_bytes(&timeout, sizeof(timeout));
 	timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
 	for(;;) {
+#ifdef CONFIG_RNFS_BOOTP
 		if (bootp_flag && root_bootp_send(jiffies - start_jiffies)) {
 			printk("...BOOTP failed!\n");
 			root_bootp_close();
@@ -900,12 +935,19 @@
 			if (!rarp_flag)
 				break;
 		}
+#endif
+#ifdef CONFIG_RNFS_RARP
 		if (rarp_flag)
 			root_rarp_send();
+#endif
 		printk(".");
 		jiff = jiffies + timeout;
 		while (jiffies < jiff && !pkt_arrived)
+#ifdef CONFIG_RNFS_BOOTP
 			root_bootp_recv();
+#else
+			;
+#endif
 		if (pkt_arrived)
 			break;
 		if (! --retries) {
@@ -917,10 +959,14 @@
 			timeout = CONF_TIMEOUT_MAX;
 	}
 
+#ifdef CONFIG_RNFS_RARP
 	if (rarp_flag)
 		root_rarp_close();
+#endif
+#ifdef CONFIG_RNFS_BOOTP
 	if (bootp_flag)
 		root_bootp_close();
+#endif
 
 	if (!pkt_arrived)
 		return -1;
@@ -934,6 +980,7 @@
 	return 0;
 }
 
+#endif
 
 /***************************************************************************
 
@@ -999,10 +1046,6 @@
 		name = cp;
 	}
 
-	/* Setup the server hostname */
-	cp = in_ntoa(server.sin_addr.s_addr);
-	strncpy(nfs_data.hostname, cp, 255);
-
 	/* Set the name of the directory to mount */
 	cp = in_ntoa(myaddr.sin_addr.s_addr);
 	strncpy(buf, name, 255);
@@ -1186,6 +1229,9 @@
 		system_utsname.nodename[__NEW_UTS_LEN] = '\0';
 	}
 
+	/* Setup the server hostname */
+	strncpy(nfs_data.hostname, in_ntoa(server.sin_addr.s_addr), 255);
+
 	/* Set the correct netmask */
 	if (netmask.sin_addr.s_addr == INADDR_NONE)
 		netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
@@ -1273,8 +1319,11 @@
 	 */
 	if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
 	     server.sin_addr.s_addr == INADDR_NONE ||
-	     (open_base != NULL && open_base->next != NULL)) &&
-	     root_auto_config() < 0) {
+	     (open_base != NULL && open_base->next != NULL))
+#ifdef CONFIG_RNFS_DYNAMIC
+		&& root_auto_config() < 0
+#endif
+	   ) {
 		root_dev_close();
 		return -1;
 	}
diff -u --recursive --new-file v1.3.75/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v1.3.75/linux/include/asm-i386/smp.h	Sun Mar 17 09:04:07 1996
+++ linux/include/asm-i386/smp.h	Mon Mar 18 13:15:00 1996
@@ -161,6 +161,7 @@
 	char x86_vendor_id[16];
 	int  x86_capability;
 	int  fdiv_bug;
+	int  have_cpuid;
 	char wp_works_ok;
 	char hlt_works_ok;
 	unsigned long udelay_val;
diff -u --recursive --new-file v1.3.75/linux/include/asm-i386/string.h linux/include/asm-i386/string.h
--- v1.3.75/linux/include/asm-i386/string.h	Wed Feb 28 11:50:11 1996
+++ linux/include/asm-i386/string.h	Mon Mar 18 10:52:08 1996
@@ -6,8 +6,11 @@
  * byte string operations. But on a 386 or a PPro the
  * byte string ops are faster than doing it by hand
  * (MUCH faster on a Pentium).
+ *
+ * Also, the byte strings actually work correctly. Forget
+ * the i486 routines for now as they may be broken..
  */
-#if CPU == 486 || CPU == 586
+#if FIXED_486_STRING && (CPU == 486 || CPU == 586)
 #include <asm/string-486.h>
 #else
 
diff -u --recursive --new-file v1.3.75/linux/include/linux/fs.h linux/include/linux/fs.h
--- v1.3.75/linux/include/linux/fs.h	Fri Mar 15 16:03:20 1996
+++ linux/include/linux/fs.h	Tue Mar 19 14:34:18 1996
@@ -30,7 +30,6 @@
 #define NR_OPEN 256
 
 #define NR_SUPER 64
-#define NR_IHASH 131
 #define BLOCK_SIZE 1024
 #define BLOCK_SIZE_BITS 10
 
diff -u --recursive --new-file v1.3.75/linux/include/linux/module.h linux/include/linux/module.h
--- v1.3.75/linux/include/linux/module.h	Sun Jan 14 16:30:14 1996
+++ linux/include/linux/module.h	Sun Mar 17 16:15:05 1996
@@ -74,9 +74,6 @@
 	void (*cleanup)(void);		/* cleanup routine */
 };
 
-/* rename_module_symbol(old_name, new_name)  WOW! */
-extern int rename_module_symbol(char *, char *);
-
 /* insert new symbol table */
 extern int register_symtab(struct symbol_table *);
 
diff -u --recursive --new-file v1.3.75/linux/include/linux/symtab_begin.h linux/include/linux/symtab_begin.h
--- v1.3.75/linux/include/linux/symtab_begin.h	Sat Feb 17 16:02:54 1996
+++ linux/include/linux/symtab_begin.h	Sun Mar 17 16:15:05 1996
@@ -3,19 +3,37 @@
 #ifdef MODVERSIONS
 # undef _set_ver
 # undef X
+/*
+ * These two macros _will_ get enough arguments from the X* macros
+ * since "sym" expands to "symaddr, symstr" from the #define in *.ver
+ */
+# define _basic_version(symaddr,symstr)  symaddr, symstr
+# define _alias_version(really,symaddr,symstr)  (void *) & really , symstr
 
 # ifndef __GENKSYMS__
 #  ifdef MODULE
 #    define _set_ver(sym,ver) \
-	{ (void *) & sym ## _R ## ver, SYMBOL_NAME_STR(sym) "_R" #ver }
+	(void *) & sym ## _R ## ver, SYMBOL_NAME_STR(sym) "_R" #ver
 #  else /* !MODULE */
 #    define _set_ver(sym,ver) \
-	{ (void *) & sym, SYMBOL_NAME_STR(sym) "_R" #ver }
+	(void *) & sym, SYMBOL_NAME_STR(sym) "_R" #ver
 #  endif /* !MODULE */
-#  define X(a) a
+#  define X(sym) { _basic_version(sym) }
+/*
+ * For _really_ stacked modules:
+ *
+ * Use "Xalias(local_symbol, symbol_from_other_module)"
+ * to make subsequent modules really use "local_symbol"
+ * when they think that they are using "symbol_from_other_module"
+ *
+ * The "aliasing" module can still use "symbol_from_other_module",
+ * but can now replace and/or modify the behaviour of that symbol.
+ */
+#  define Xalias(really,sym) { _alias_version(really,sym) }
 # endif /* !__GENKSYMS__ */
 #else /* !MODVERSIONS */
 # define X(sym) { (void *) & sym, SYMBOL_NAME_STR(sym)}
+# define Xalias(really,sym) { (void *) & really, SYMBOL_NAME_STR(sym)}
 #endif /* MODVERSIONS */
 /*
  * Some symbols always need to be unversioned.  This includes
diff -u --recursive --new-file v1.3.75/linux/include/net/sock.h linux/include/net/sock.h
--- v1.3.75/linux/include/net/sock.h	Wed Feb 28 11:50:14 1996
+++ linux/include/net/sock.h	Tue Mar 19 15:06:27 1996
@@ -236,7 +236,7 @@
 						   'timed out' */
 	unsigned char		protocol;
 	volatile unsigned char	state;
-	volatile unsigned char	ack_backlog;
+	unsigned char		ack_backlog;
 	unsigned char		max_ack_backlog;
 	unsigned char		priority;
 	unsigned char		debug;
diff -u --recursive --new-file v1.3.75/linux/include/net/tcp.h linux/include/net/tcp.h
--- v1.3.75/linux/include/net/tcp.h	Sun Mar 17 09:04:08 1996
+++ linux/include/net/tcp.h	Tue Mar 19 14:34:36 1996
@@ -107,9 +107,16 @@
 
 static __inline__ int min(unsigned int a, unsigned int b)
 {
-	if (a < b) 
-		return(a);
-	return(b);
+	if (a > b)
+		a = b;
+	return a;
+}
+
+static __inline__ int max(unsigned int a, unsigned int b)
+{
+	if (a < b)
+		a = b;
+	return a;
 }
 
 extern struct proto tcp_prot;
diff -u --recursive --new-file v1.3.75/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.75/linux/kernel/ksyms.c	Sun Mar 17 09:04:08 1996
+++ linux/kernel/ksyms.c	Sun Mar 17 16:15:05 1996
@@ -116,7 +116,6 @@
 #endif
 
 	/* stackable module support */
-	X(rename_module_symbol),
 	X(register_symtab),
 #ifdef CONFIG_KERNELD
 	X(kerneld_send),
diff -u --recursive --new-file v1.3.75/linux/kernel/module.c linux/kernel/module.c
--- v1.3.75/linux/kernel/module.c	Sun Jan 14 16:30:15 1996
+++ linux/kernel/module.c	Sun Mar 17 16:15:05 1996
@@ -81,62 +81,6 @@
 	kernel_module.name = "";
 }
 
-int
-rename_module_symbol(char *old_name, char *new_name)
-{
-	struct internal_symbol *sym;
-	int i = 0; /* keep gcc silent */
-
-	if (module_list->symtab) {
-		sym = module_list->symtab->symbol;
-		for (i = module_list->symtab->n_symbols; i > 0; ++sym, --i) {
-			if (strcmp(sym->name, old_name) == 0) { /* found it! */
-				sym->name = new_name; /* done! */
-				PRINTK(("renamed %s to %s\n", old_name, new_name));
-				return 1; /* it worked! */
-			}
-		}
-	}
-	printk("rename %s to %s failed!\n", old_name, new_name);
-	return 0; /* not there... */
-
-	/*
-	 * This one will change the name of the first matching symbol!
-	 *
-	 * With this function, you can replace the name of a symbol defined
-	 * in the current module with a new name, e.g. when you want to insert
-	 * your own function instead of a previously defined function
-	 * with the same name.
-	 *
-	 * "Normal" usage:
-	 *
-	 * bogus_function(int params)
-	 * {
-	 *	do something "smart";
-	 *	return real_function(params);
-	 * }
-	 *
-	 * ...
-	 *
-	 * init_module()
-	 * {
-	 *	if (rename_module_symbol("_bogus_function", "_real_function"))
-	 *		printk("yep!\n");
-	 *	else
-	 *		printk("no way!\n");
-	 * ...
-	 * }
-	 *
-	 * When loading this module, real_function will be resolved
-	 * to the real function address.
-	 * All later loaded modules that refer to "real_function()" will
-	 * then really call "bogus_function()" instead!!!
-	 *
-	 * This feature will give you ample opportunities to get to know
-	 * the taste of your foot when you stuff it into your mouth!!!
-	 */
-}
-
 /*
  * Allocate space for a module.
  */
diff -u --recursive --new-file v1.3.75/linux/kernel/sched.c linux/kernel/sched.c
--- v1.3.75/linux/kernel/sched.c	Sun Mar 17 09:04:08 1996
+++ linux/kernel/sched.c	Tue Mar 19 08:28:55 1996
@@ -27,7 +27,6 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 
-#include <asm/smp.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/segment.h>
@@ -581,6 +580,50 @@
 #endif
 }
 
+static inline void run_timer_list(void)
+{
+	struct timer_list * timer;
+
+	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();
+	}
+}
+
+static inline void run_old_timers(void)
+{
+	struct timer_struct *tp;
+	unsigned long mask;
+
+	for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) {
+		if (mask > timer_active)
+			break;
+		if (!(mask & timer_active))
+			continue;
+		if (tp->expires > jiffies)
+			continue;
+		timer_active &= ~mask;
+		tp->fn();
+		sti();
+	}
+}
+
+void tqueue_bh(void)
+{
+	run_task_queue(&tq_timer);
+}
+
+void immediate_bh(void)
+{
+	run_task_queue(&tq_immediate);
+}
+
 unsigned long timer_active = 0;
 struct timer_struct timer_table[32];
 
@@ -611,18 +654,19 @@
 	return nr;
 }
 
-static inline void calc_load(void)
+static inline void calc_load(unsigned long ticks)
 {
 	unsigned long active_tasks; /* fixed-point */
 	static int count = LOAD_FREQ;
 
-	if (count-- > 0)
-		return;
-	count = LOAD_FREQ;
-	active_tasks = count_active_tasks();
-	CALC_LOAD(avenrun[0], EXP_1, active_tasks);
-	CALC_LOAD(avenrun[1], EXP_5, active_tasks);
-	CALC_LOAD(avenrun[2], EXP_15, active_tasks);
+	count -= ticks;
+	if (count < 0) {
+		count += LOAD_FREQ;
+		active_tasks = count_active_tasks();
+		CALC_LOAD(avenrun[0], EXP_1, active_tasks);
+		CALC_LOAD(avenrun[1], EXP_5, active_tasks);
+		CALC_LOAD(avenrun[2], EXP_15, active_tasks);
+	}
 }
 
 /*
@@ -749,71 +793,20 @@
 #endif
 }
 
-/*
- * disregard lost ticks for now.. We don't care enough.
- */
-static void timer_bh(void)
+static void update_wall_time_one_tick(void)
 {
-	unsigned long mask;
-	struct timer_struct *tp;
-	struct timer_list * timer;
-
-	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();
-	}
-	sti();
-	
-	for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) {
-		if (mask > timer_active)
-			break;
-		if (!(mask & timer_active))
-			continue;
-		if (tp->expires > jiffies)
-			continue;
-		timer_active &= ~mask;
-		tp->fn();
-		sti();
-	}
-}
-
-void tqueue_bh(void)
-{
-	run_task_queue(&tq_timer);
-}
-
-void immediate_bh(void)
-{
-	run_task_queue(&tq_immediate);
-}
-
-void do_timer(struct pt_regs * regs)
-{
-	unsigned long mask;
-	struct timer_struct *tp;
-	long ltemp, psecs;
-#ifdef  __SMP__
-	int cpu,i;
-#endif
-
-	/* Advance the phase, once it gets to one microsecond, then
+	/*
+	 * Advance the phase, once it gets to one microsecond, then
 	 * advance the tick more.
 	 */
 	time_phase += time_adj;
 	if (time_phase <= -FINEUSEC) {
-		ltemp = -time_phase >> SHIFT_SCALE;
+		long ltemp = -time_phase >> SHIFT_SCALE;
 		time_phase += ltemp << SHIFT_SCALE;
 		xtime.tv_usec += tick + time_adjust_step - ltemp;
 	}
 	else if (time_phase >= FINEUSEC) {
-		ltemp = time_phase >> SHIFT_SCALE;
+		long ltemp = time_phase >> SHIFT_SCALE;
 		time_phase -= ltemp << SHIFT_SCALE;
 		xtime.tv_usec += tick + time_adjust_step + ltemp;
 	} else
@@ -841,161 +834,203 @@
 	}
 	else
 	    time_adjust_step = 0;
+}
+
+/*
+ * Using a loop looks inefficient, but "ticks" is
+ * usually just one (we shouldn't be losing ticks,
+ * we're doing this this way mainly for interrupt
+ * latency reasons, not because we think we'll
+ * have lots of lost timer ticks
+ */
+static void update_wall_time(unsigned long ticks)
+{
+	do {
+		ticks--;
+		update_wall_time_one_tick();
+	} while (ticks);
 
 	if (xtime.tv_usec >= 1000000) {
 	    xtime.tv_usec -= 1000000;
 	    xtime.tv_sec++;
 	    second_overflow();
 	}
+}
 
-	jiffies++;
-	calc_load();
-#ifndef  __SMP__
-	if (user_mode(regs)) {
-		current->utime++;
-		if (current->pid) {
-			if (current->priority < DEF_PRIORITY)
-				kstat.cpu_nice++;
-			else
-				kstat.cpu_user++;
-		}
-		/* Update ITIMER_VIRT for current task if not in a system call */
-		if (current->it_virt_value && !(--current->it_virt_value)) {
-			current->it_virt_value = current->it_virt_incr;
-			send_sig(SIGVTALRM,current,1);
-		}
-	} else {
-		current->stime++;
-		if(current->pid)
-			kstat.cpu_system++;
-		if (prof_buffer && current->pid) {
-			extern int _stext;
-			unsigned long ip = instruction_pointer(regs);
-			ip -= (unsigned long) &_stext;
-			ip >>= prof_shift;
-			if (ip < prof_len)
-				prof_buffer[ip]++;
-		}
+static inline void do_process_times(struct task_struct *p,
+	unsigned long user, unsigned long system)
+{
+	long psecs;
+
+	p->utime += user;
+	if (p->priority < DEF_PRIORITY)
+		kstat.cpu_nice += user;
+	else
+		kstat.cpu_user += user;
+	kstat.cpu_system += system;
+	p->stime += system;
+
+	psecs = (p->stime + p->utime) / HZ;
+	if (psecs > p->rlim[RLIMIT_CPU].rlim_cur) {
+		/* Send SIGXCPU every second.. */
+		if (psecs * HZ == p->stime + p->utime)
+			send_sig(SIGXCPU, p, 1);
+		/* and SIGKILL when we go over max.. */
+		if (psecs > p->rlim[RLIMIT_CPU].rlim_max)
+			send_sig(SIGKILL, p, 1);
 	}
-	/*
-	 * check the cpu time limit on the process.
-	 */
-	if ((current->rlim[RLIMIT_CPU].rlim_max != RLIM_INFINITY) &&
-	    (((current->stime + current->utime) / HZ) >= current->rlim[RLIMIT_CPU].rlim_max))
-		send_sig(SIGKILL, current, 1);
-	if ((current->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) &&
-	    (((current->stime + current->utime) % HZ) == 0)) {
-		psecs = (current->stime + current->utime) / HZ;
-		/* send when equal */
-		if (psecs == current->rlim[RLIMIT_CPU].rlim_cur)
-			send_sig(SIGXCPU, current, 1);
-		/* and every five seconds thereafter. */
-		else if ((psecs > current->rlim[RLIMIT_CPU].rlim_cur) &&
-			((psecs - current->rlim[RLIMIT_CPU].rlim_cur) % 5) == 0)
-			send_sig(SIGXCPU, current, 1);
+}
+
+static inline void do_it_virt(struct task_struct * p, unsigned long ticks)
+{
+	unsigned long it_virt = p->it_virt_value;
+
+	if (it_virt) {
+		if (it_virt < ticks) {
+			it_virt = ticks + p->it_virt_incr;
+			send_sig(SIGVTALRM, p, 1);
+		}
+		p->it_virt_value = it_virt - ticks;
 	}
+}
 
-	if (current->pid && 0 > --current->counter) {
-		current->counter = 0;
-		need_resched = 1;
+static inline void do_it_prof(struct task_struct * p, unsigned long ticks)
+{
+	unsigned long it_prof = p->it_prof_value;
+
+	if (it_prof) {
+		if (it_prof < ticks) {
+			it_prof = ticks + p->it_prof_incr;
+			send_sig(SIGPROF, p, 1);
+		}
+		p->it_prof_value = it_prof - ticks;
 	}
-	/* Update ITIMER_PROF for the current task */
-	if (current->it_prof_value && !(--current->it_prof_value)) {
-		current->it_prof_value = current->it_prof_incr;
-		send_sig(SIGPROF,current,1);
+}
+
+static __inline__ void update_one_process(struct task_struct *p,
+	unsigned long ticks, unsigned long user, unsigned long system)
+{
+	do_process_times(p, user, system);
+	do_it_virt(p, user);
+	do_it_prof(p, ticks);
+}	
+
+static void update_process_times(unsigned long ticks, unsigned long system)
+{
+#ifndef  __SMP__
+	struct task_struct * p = current;
+	if (p->pid) {
+		p->counter -= ticks;
+		if (p->counter < 0) {
+			p->counter = 0;
+			need_resched = 1;
+		}
+
+		update_one_process(p, ticks, ticks-system, system);
 	}
 #else
+	int cpu,i;
 	cpu = smp_processor_id();
 	for (i=0;i<=smp_top_cpu;i++)
 	{
+		struct task_struct *p;
+		
 		if(cpu_number_map[i]==-1)
 			continue;
 #ifdef __SMP_PROF__
 		if (test_bit(i,&smp_idle_map)) 
 			smp_idle_count[i]++;
 #endif
-		if (((cpu==i) && user_mode(regs)) ||
-			((cpu!=i) && 0==smp_proc_in_lock[i])) 
-		{
-			current_set[i]->utime++;
-			if (current_set[i]->pid) 
-			{
-				if (current_set[i]->priority < DEF_PRIORITY)
-					kstat.cpu_nice++;
-				else
-					kstat.cpu_user++;
-			}
-			/* Update ITIMER_VIRT for current task if not in a system call */
-			if (current_set[i]->it_virt_value && !(--current_set[i]->it_virt_value)) {
-				current_set[i]->it_virt_value = current_set[i]->it_virt_incr;
-				send_sig(SIGVTALRM,current_set[i],1);
-			}
-		} else {
-			current_set[i]->stime++;
-			if(current_set[i]->pid)
-				kstat.cpu_system++;
-			if (prof_buffer && current_set[i]->pid) {
-				extern int _stext;
-				unsigned long ip = instruction_pointer(regs);
-				ip -= (unsigned long) &_stext;
-				ip >>= prof_shift;
-				if (ip < prof_len)
-					prof_buffer[ip]++;
-			}
-		}
+		p = current_set[i];
 		/*
-		 * check the cpu time limit on the process.
+		 * Do we have a real process?
 		 */
-		if ((current_set[i]->rlim[RLIMIT_CPU].rlim_max != RLIM_INFINITY) &&
-			  (((current_set[i]->stime + current_set[i]->utime) / HZ) >=
-			  current_set[i]->rlim[RLIMIT_CPU].rlim_max))
-			send_sig(SIGKILL, current_set[i], 1);
-		if ((current_set[i]->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) &&
-			  (((current_set[i]->stime + current_set[i]->utime) % HZ) == 0)) {
-			psecs = (current_set[i]->stime + current_set[i]->utime) / HZ;
-			/* send when equal */
-			if (psecs == current_set[i]->rlim[RLIMIT_CPU].rlim_cur)
-				send_sig(SIGXCPU, current_set[i], 1);
-			/* and every five seconds thereafter. */
-			else if ((psecs > current_set[i]->rlim[RLIMIT_CPU].rlim_cur) &&
-				  ((psecs - current_set[i]->rlim[RLIMIT_CPU].rlim_cur) % 5) == 0)
-				send_sig(SIGXCPU, current_set[i], 1);
-		}
-		if (current_set[i]->pid && 0 > --current_set[i]->counter) {
-			current_set[i]->counter = 0;
-			if (i==cpu)
-				need_resched = 1;
-			else
-				smp_message_pass(i, MSG_RESCHEDULE, 0L, 0);
-		} else
-			if ((0==current_set[i]->pid) && (0x7fffffff & smp_process_available)){
-				/* runnable process found; wakeup idle process */
-				if (cpu==i)
-					need_resched = 1;
-				else
-					smp_message_pass(i, MSG_RESCHEDULE, 0L, 0);
+		if (p->pid) {
+			/* assume user-mode process */
+			unsigned long utime = ticks;
+			unsigned long stime = 0;
+			if (cpu == i) {
+				utime = ticks-system;
+				stime = system;
+			} else if (smp_proc_in_lock[i]) {
+				utime = 0;
+				stime = ticks;
 			}
+			update_one_process(p, ticks, utime, stime);
 
-		/* Update ITIMER_PROF for the current task */
-		if (current_set[i]->it_prof_value && !(--current_set[i]->it_prof_value)) {
-			current_set[i]->it_prof_value = current_set[i]->it_prof_incr;
-			send_sig(SIGPROF,current_set[i],1);
+			p->counter -= ticks;
+			if (p->counter >= 0)
+				continue;
+			p->counter = 0;
+		} else {
+			/*
+			 * Idle processor found, do we have anything
+			 * we could run?
+			 */
+			if (!(0x7fffffff & smp_process_available))
+				continue;
 		}
+		/* Ok, we should reschedule, do the magic */
+		if (i==cpu)
+			need_resched = 1;
+		else
+			smp_message_pass(i, MSG_RESCHEDULE, 0L, 0);
 	}
+#endif
+}
+
+static unsigned long lost_ticks = 0;
+static unsigned long lost_ticks_system = 0;
+
+static void timer_bh(void)
+{
+	unsigned long ticks, system;
+
+	run_old_timers();
 
+	cli();
+	run_timer_list();
+	ticks = lost_ticks;
+	lost_ticks = 0;
+	system = lost_ticks_system;
+	lost_ticks_system = 0;
+	sti();
+
+	if (ticks) {
+		calc_load(ticks);
+		update_wall_time(ticks);
+		update_process_times(ticks, system);
+	}
+}
+
+/*
+ * Run the bottom half stuff only about 100 times a second,
+ * we'd just use up unnecessary CPU time for timer handling
+ * otherwise
+ */
+#if HZ > 100
+#define should_run_timers(x) ((x) >= HZ/100)
+#else
+#define should_run_timers(x) (1)
 #endif
 
-	for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) {
-		if (mask > timer_active)
-			break;
-		if (!(mask & timer_active))
-			continue;
-		if (tp->expires > jiffies)
-			continue;
+void do_timer(struct pt_regs * regs)
+{
+	(*(unsigned long *)&jiffies)++;
+	lost_ticks++;
+	if (should_run_timers(lost_ticks))
 		mark_bh(TIMER_BH);
+	if (!user_mode(regs)) {
+		lost_ticks_system++;
+		if (prof_buffer && current->pid) {
+			extern int _stext;
+			unsigned long ip = instruction_pointer(regs);
+			ip -= (unsigned long) &_stext;
+			ip >>= prof_shift;
+			if (ip < prof_len)
+				prof_buffer[ip]++;
+		}
 	}
-	if (timer_head.next->expires <= jiffies)
-		mark_bh(TIMER_BH);
 	if (tq_timer != &tq_last)
 		mark_bh(TQUEUE_BH);
 }
diff -u --recursive --new-file v1.3.75/linux/mm/kmalloc.c linux/mm/kmalloc.c
--- v1.3.75/linux/mm/kmalloc.c	Fri Mar 15 16:03:21 1996
+++ linux/mm/kmalloc.c	Mon Mar 18 07:58:04 1996
@@ -177,7 +177,7 @@
 {
 	unsigned long flags;
 	unsigned long type;
-	int order, i, sz;
+	int order, i, sz, dma;
 	struct block_header *p;
 	struct page_descriptor *page, **pg;
 
@@ -187,9 +187,11 @@
 		return (NULL);
 	}
 
+	dma = 0;
 	type = MF_USED;
 	pg = &sizes[order].firstfree;
 	if (priority & GFP_DMA) {
+		dma = 1;
 		type = MF_DMA;
 		pg = &sizes[order].dmafree;
 	}
@@ -227,7 +229,7 @@
 	sz = BLOCKSIZE(order);
 
 	page = (struct page_descriptor *) __get_free_pages(priority,
-			sizes[order].gfporder, priority & GFP_DMA);
+			sizes[order].gfporder, dma);
 
 	if (!page) {
 		static unsigned long last = 0;
diff -u --recursive --new-file v1.3.75/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- v1.3.75/linux/net/ipv4/ip_fw.c	Tue Feb 20 14:37:30 1996
+++ linux/net/ipv4/ip_fw.c	Tue Mar 19 12:51:42 1996
@@ -444,14 +444,16 @@
 			if(opt != 1) {
 				if(f->fw_flg&IP_FW_F_ACCEPT) {
 					if(f->fw_flg&IP_FW_F_MASQ)
-						printk("Masquerade ");
+						printk("masq ");
 					else
-						printk("Accept ");
+						printk("acc  ");
 				} else if(f->fw_flg&IP_FW_F_ICMPRPL)
-					printk("Reject ");
+					printk("rej  ");
 				else
-					printk("Deny ");
+					printk("deny ");
 			}
+			if (rif)
+				printk("%s ", rif->name);
 			switch(ip->protocol)
 			{
 				case IPPROTO_TCP:
@@ -459,6 +461,7 @@
 					break;
 				case IPPROTO_UDP:
 					printk("UDP ");
+					break;
 				case IPPROTO_ICMP:
 					printk("ICMP:%d ", icmp_type);
 					break;
diff -u --recursive --new-file v1.3.75/linux/scripts/Menuconfig linux/scripts/Menuconfig
--- v1.3.75/linux/scripts/Menuconfig	Fri Mar 15 16:03:22 1996
+++ linux/scripts/Menuconfig	Tue Mar 19 09:07:02 1996
@@ -78,10 +78,10 @@
 	if extract_help $1 >help.out
 	then
 		$DIALOG	--backtitle "$backtitle" --title "$2"\
-			--textbox help.out 20 75
+			--textbox help.out $LINES $COLS
 	else
 		$DIALOG	--backtitle "$backtitle" \
-			--textbox help.out 20 75
+			--textbox help.out $LINES $COLS
 	fi
 	rm help.out
 }
@@ -91,7 +91,7 @@
 #
 function show_readme() {
 	$DIALOG --backtitle "$backtitle" \
-		--textbox scripts/README.Menuconfig 21 75
+		--textbox scripts/README.Menuconfig $LINES $COLS
 }
 
 #
@@ -102,7 +102,8 @@
 	echo -ne "$DIALOG --title '$1'\
 			--backtitle '$backtitle' \
 			--menu '$menu_instructions' \
-			21 75 11 '$default' " >MCmenu
+			$LINES $COLS $((LINES-10)) \
+			'$default' " >MCmenu
 	>MCradiolists
 }
 
@@ -840,6 +841,19 @@
 cleanup2 () {
 	rm -f .tmpconfig .tmpconfig.h
 }
+
+x=`stty -a`
+case $x in
+*\ rows\ *\;*)
+	LINES=${x##*rows}    LINES=${LINES%%;*} LINES=$((${LINES:-25}-4))
+	COLS=${x##*columns}  COLS=${COLS%%;*}   COLS=$((${COLS:-80}-5))
+	;;
+*)
+	LINES=21
+	COLS=75
+	;;
+esac
+	
 
 menu_instructions="\
 Arrow keys navigate the menu.  \
diff -u --recursive --new-file v1.3.75/linux/scripts/README.Menuconfig linux/scripts/README.Menuconfig
--- v1.3.75/linux/scripts/README.Menuconfig	Sun Mar 10 09:49:57 1996
+++ linux/scripts/README.Menuconfig	Tue Mar 19 09:07:02 1996
@@ -1,22 +1,8 @@
-This is the Linux kernel Menuconfig README file.
-
 Menuconfig gives the Linux kernel configuration a long needed face
 lift.  Featuring text based color menus and dialogs, it does not
 require X Windows.  With this utility you can easily select a kernel
 option to modify without sifting through 100 other options.
 
-The windowing support utility (lxdialog) is a VERY modified version of
-the dialog utility by Savio Lam <lam836@cs.cuhk.hk>.  Although lxdialog
-is significantly different from dialog, I have left Savio's copyrights
-intact.  Please DO NOT contact Savio with questions about lxdialog.
-He will not be able to assist.
-
-Please feel free to send any questions, comments or suggestions to
-William Roadcap <roadcapw@cfw.com>.
-
-READ ON! There are hints and notices below...
-
-
 Some Menuconfig keyboard hints:
 
 Menus
@@ -27,6 +13,9 @@
              Pressing a hotkey more than once will sequence
              through all items which use that hotkey.
 
+   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll
+   unseen options into view.
+
 o  Use the cursor keys to highlight <Select> and press <ENTER>.  
    Shortcut: Press the <SPACE BAR> or <S> if there is no item using
              <S> as it's hotkey.
@@ -90,8 +79,8 @@
 information which may help you determine the cause.
 
 
-Other information:
-
+Other information
+-----------------
 The windowing utility, lxdialog, will only be rebuilt if your kernel
 source tree is fresh, or changes are patched into it via a kernel
 patch or you do 'make mrproper'.  If changes to lxdialog are patched
@@ -105,6 +94,11 @@
 display correctly in a RXVT window because rxvt display's only one
 intensity of color, bright.
 
+Menuconfig will display larger menus on screens or xterms which are
+set to display more than the standard 25 row by 80 column geometry.
+In order for this to work, the "stty -a" command must be able to 
+display the screen's current row and column geometry.
+
 
 NOTICE:  lxdialog requires the ncurses libraries to compile.  If you
          don't already have ncurses you really should get it.
@@ -137,5 +131,18 @@
 "single_menu_mode=TRUE".
 
 This mode is not recommended unless you have a fairly fast machine.
+*********************************************************************
+
+
+Propaganda
+----------
+The windowing support utility (lxdialog) is a VERY modified version of
+the dialog utility by Savio Lam <lam836@cs.cuhk.hk>.  Although lxdialog
+is significantly different from dialog, I have left Savio's copyrights
+intact.  Please DO NOT contact Savio with questions about lxdialog.
+He will not be able to assist.
+
+Please feel free to send any questions, comments or suggestions to
+William Roadcap <roadcapw@cfw.com>.
 
-<END OF README>
+<END OF FILE>
diff -u --recursive --new-file v1.3.75/linux/scripts/header.tk linux/scripts/header.tk
--- v1.3.75/linux/scripts/header.tk	Sun Mar 17 09:04:09 1996
+++ linux/scripts/header.tk	Sun Mar 17 09:58:21 1996
@@ -297,8 +297,8 @@
 #nothing done for comments now.
 }
 
-proc do_make { w line option dir target target } {
-#nothing to do for now.
+proc do_make { command } {
+	exec sh -c $command
 }
 
 proc dohelp {w var }  {
diff -u --recursive --new-file v1.3.75/linux/scripts/lxdialog/menubox.c linux/scripts/lxdialog/menubox.c
--- v1.3.75/linux/scripts/lxdialog/menubox.c	Sun Mar 10 09:49:57 1996
+++ linux/scripts/lxdialog/menubox.c	Tue Mar 19 09:05:24 1996
@@ -53,7 +53,7 @@
  * Print the scroll indicators.
  */
 static void
-print_arrows (WINDOW * win, int choice, int item_no, int scroll,
+print_arrows (WINDOW * win, int item_no, int scroll,
 		int y, int x, int height)
 {
     int cur_y, cur_x;
@@ -78,7 +78,7 @@
    y = y + height + 1;
    wmove(win, y, x);
 
-   if ((height < item_no) && (scroll + choice < item_no - 1)) {
+   if ((height < item_no) && (scroll + height < item_no)) {
 	wattrset (win, darrow_attr);
 	waddch (win, ACS_DARROW);
 	waddstr (win, "(+)");
@@ -191,7 +191,7 @@
 
     wnoutrefresh (menu);
 
-    print_arrows(dialog, choice, item_no, scroll,
+    print_arrows(dialog, item_no, scroll,
 		 box_y, box_x+item_x+1, menu_height);
 
     print_buttons (dialog, height, width, 0);
@@ -211,75 +211,84 @@
                 		break;
 		}
 
-	if (i < max_choice || key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+') {
-	    if (key == KEY_UP || key == '-') {
-		if (choice == 0) {
-		    if (scroll) {
+	if (i < max_choice || 
+            key == KEY_UP || key == KEY_DOWN ||
+            key == '-' || key == '+' ||
+            key == KEY_PPAGE || key == KEY_NPAGE) {
 
-			/* Scroll menu down */
-			if (menu_height > 1) {
-			    /* De-highlight current first item */
-			    print_item (menu, items[scroll*2+1], 0, FALSE,
-                                        (items[scroll*2][0] != ':'));
-			    scrollok (menu, TRUE);
-			    wscrl (menu, -1);
-			    scrollok (menu, FALSE);
-			}
-			scroll--;
-			print_item (menu, items[scroll * 2 + 1], 0, TRUE,
-                                   (items[scroll*2][0] != ':'));
-			wnoutrefresh (menu);
+            print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
+                       (items[(scroll+choice)*2][0] != ':'));
 
-    			print_arrows(dialog, choice, item_no, scroll,
-		 			box_y, box_x+item_x+1, menu_height);
+	    if (key == KEY_UP || key == '-') {
+                if (choice < 6 && scroll) {
+	            /* Scroll menu down */
+                    scrollok (menu, TRUE);
+                    wscrl (menu, -1);
+                    scrollok (menu, FALSE);
 
-		    }
-		    continue;	/* wait for another key press */
-		} else
-		    i = choice - 1;
-	    } else if (key == KEY_DOWN || key == '+')
-		if (choice == max_choice - 1) {
-		    if (scroll + choice < item_no - 1) {
-			/* Scroll menu up */
-			if (menu_height > 1) {
-			    /* De-highlight current last item */
-			    print_item (menu, items[(scroll + max_choice - 1)
-					   * 2 + 1], max_choice - 1, FALSE,
-                                           (items[(scroll+max_choice-1)*2][0] != ':'));
-			    scrollok (menu, TRUE);
-			    scroll (menu);
-			    scrollok (menu, FALSE);
-			}
-			scroll++;
-			print_item (menu, items[(scroll+max_choice-1)*2+1],
-				    max_choice-1, TRUE,
-                                    (items[(scroll+max_choice-1)*2][0] != ':'));
-
-			wnoutrefresh (menu);
-
-    			print_arrows(dialog, choice, item_no, scroll,
-		 			box_y, box_x+item_x+1, menu_height);
-
-			wrefresh (dialog);
-		    }
-		    continue;	/* wait for another key press */
+                    scroll--;
+
+                    print_item (menu, items[scroll * 2 + 1], 0, FALSE,
+                               (items[scroll*2][0] != ':'));
 		} else
-		    i = choice + 1;
+		    choice = MAX(choice - 1, 0);
+
+	    } else if (key == KEY_DOWN || key == '+')  {
 
-	    if (i != choice) {
-		/* De-highlight current item */
 		print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
                                 (items[(scroll+choice)*2][0] != ':'));
 
-		/* Highlight new item */
-		choice = i;
-		print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
-                                (items[(scroll+choice)*2][0] != ':'));
-		wnoutrefresh (menu);
-		wrefresh (dialog);
-	    }
+                if ((choice > 4) && (scroll + max_choice < item_no)) {
+		    /* Scroll menu up */
+		    scrollok (menu, TRUE);
+                    scroll (menu);
+                    scrollok (menu, FALSE);
+
+                    scroll++;
+
+                    print_item (menu, items[(scroll+max_choice-1)*2+1],
+                               max_choice-1, FALSE,
+                               (items[(scroll+max_choice-1)*2][0] != ':'));
+                } else
+                    choice = MIN(choice+1, max_choice-1);
+
+	    } else if (key == KEY_PPAGE) {
+	        scrollok (menu, TRUE);
+                for (i=0; (i < max_choice) && (scroll > 0); i++) {
+                    wscrl (menu, -1);
+                    scroll--;
+                    print_item (menu, items[scroll * 2 + 1], 0, FALSE,
+                               (items[scroll*2][0] != ':'));
+                }
+                scrollok (menu, FALSE);
+                choice = 0;
+
+            } else if (key == KEY_NPAGE) {
+	        scrollok (menu, TRUE);
+                for (i=0; (i < max_choice) && (scroll+max_choice < item_no); i++) {
+		    scroll(menu);
+                    scroll++;
+                    print_item (menu, items[(scroll+max_choice-1)*2+1],
+                                max_choice-1, FALSE,
+                                (items[(scroll+max_choice-1)*2][0] != ':'));
+                }
+                scrollok (menu, FALSE);
+                choice = 0;
+
+            } else
+                choice = i;
+
+            print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
+                       (items[(scroll+choice)*2][0] != ':'));
+
+            print_arrows(dialog, item_no, scroll,
+                         box_y, box_x+item_x+1, menu_height);
+
+            wnoutrefresh (menu);
+            wrefresh (dialog);
+
 	    continue;		/* wait for another key press */
-	}
+        }
 
 	switch (key) {
 	case KEY_LEFT:
diff -u --recursive --new-file v1.3.75/linux/scripts/tkcond.c linux/scripts/tkcond.c
--- v1.3.75/linux/scripts/tkcond.c	Sun Mar 17 09:04:09 1996
+++ linux/scripts/tkcond.c	Sun Mar 17 09:58:21 1996
@@ -359,6 +359,7 @@
 	case tok_int:
 	case tok_hex:
 	case tok_choice:
+	case tok_make:
 	  /*
 	   * We need to duplicate the chain of conditions and attach them to
 	   * this token.
diff -u --recursive --new-file v1.3.75/linux/scripts/tkgen.c linux/scripts/tkgen.c
--- v1.3.75/linux/scripts/tkgen.c	Sun Mar 17 09:04:09 1996
+++ linux/scripts/tkgen.c	Sun Mar 17 09:58:21 1996
@@ -24,6 +24,9 @@
  *                - Fixed a bug I introduced into Choice dependencies.  Thanks
  *                  to Robert Krawitz for pointing this out.
  *
+ * 1996 03 16
+ * Avery Pennarun - basic "do_make" support added to let sound config work.
+ *
  * TO DO:
  *   - clean up - there are useless ifdef's everywhere.
  *   - do more sensible things with the 'config -resizable" business.
@@ -41,6 +44,10 @@
  *   - choice buttons should default to the first menu option, rather than a
  *           blank.  Also look up the right variable when the help button
  *           is pressed.
+ *   - remove the remaining bits of the now-unnecessary "next/prev" submenu
+ *           code.
+ *   - clean up +/- 16 confusion for enabling/disabling variables; causes
+ *           problems with dependencies.
  *   
  */
 #include <stdio.h>
@@ -430,6 +437,9 @@
       printf("} then { write_hex $cfg $autocfg %s $%s $notmod }\n",
              item->optionname, item->optionname);
       break;
+    case tok_make:
+      printf("} then { do_make {%s} }\n",item->value);
+      break;
     case tok_choose:
     case tok_choice:
       fprintf(stderr,"Fixme\n");
@@ -610,7 +620,6 @@
       case tok_int:
       case tok_hex:
       case tok_choose:
-      case tok_sound:
 	tot++;
 	break;
       case tok_choice:
@@ -667,7 +676,6 @@
 	case tok_int:
 	case tok_hex:
 	case tok_choose:
-	case tok_sound:
 	  /*
 	   * If we have overfilled the menu, then go to the next one.
 	   */
@@ -820,19 +828,6 @@
 		 cfg->label,
 		 cfg->optionname);
 	  break;
-#ifdef INCOMPAT_SOUND_CONFIG
-	case tok_sound:
-	  if( cfg->menu_number != menu_num )
-	    {
-	      end_proc(menu_num, menu_min, menu_max);
-	      start_proc(menulabel, cfg->menu_number, FALSE);
-	      menu_num = cfg->menu_number;
-	    }
-	  printf("\tdo_sound $w.config.f %d %d\n",
-		 cfg->menu_number,
-		 cfg->menu_line);
-	  break;
-#endif
 	default:
 	  break;
 	}
@@ -963,7 +958,8 @@
 	  if(cfg->flags & GLOBAL_WRITTEN) break;
 	  cfg->flags |= GLOBAL_WRITTEN;
 	  printf("\tglobal %s\n", cfg->optionname);
-
+	  /* fall through */
+	case tok_make:
 	case tok_comment:
 	  if (cfg->cond != NULL ) 
 	    generate_if_for_outfile(cfg, cfg->cond);
@@ -1016,6 +1012,10 @@
 		  printf("\twrite_hex $cfg $autocfg %s $%s $notmod\n",
 			 cfg->optionname,
 			 cfg->optionname);
+	        }
+	      else if (cfg->tok == tok_make )
+	        {
+	          printf("\tdo_make {%s}\n",cfg->value);
 	        }
 	      else
 		{
diff -u --recursive --new-file v1.3.75/linux/scripts/tkparse.c linux/scripts/tkparse.c
--- v1.3.75/linux/scripts/tkparse.c	Wed Mar 13 10:09:29 1996
+++ linux/scripts/tkparse.c	Sun Mar 17 09:58:21 1996
@@ -326,10 +326,9 @@
       tok = tok_menuoption;
       pnt += 15;
     }
-  else if      (strncmp(pnt, "$MAKE -C drivers/sound", 22) == 0) 
+  else if (strncmp(pnt, "$MAKE ", 6) == 0) 
     {
-      pnt += 22;
-      tok = tok_sound;
+      tok = tok_make;
     }
   else if (strncmp(pnt, "comment", 7) == 0) 
     {
@@ -508,9 +507,11 @@
 	  pnt = get_qstring(pnt, &kcfg->label);
 	}
       break;
+    case tok_make:
+      kcfg->value=strdup(pnt);
+      break;
     case tok_else:
     case tok_fi:
-    case tok_sound:
     case tok_endmenu:
       break;
     case tok_if:
diff -u --recursive --new-file v1.3.75/linux/scripts/tkparse.h linux/scripts/tkparse.h
--- v1.3.75/linux/scripts/tkparse.h	Wed Mar 13 10:09:29 1996
+++ linux/scripts/tkparse.h	Sun Mar 17 09:58:21 1996
@@ -12,13 +12,12 @@
   tok_fi, 
   tok_int,
   tok_hex,
-  tok_sound,
+  tok_make,
   tok_define,
   tok_choose,
   tok_choice,
   tok_endmenu,
   tok_unknown
-
 };
 
 enum operator {
