ALPHA-pl15e
diff --git a/Makefile b/Makefile
index a65d090..85f0f4c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 0.99
 PATCHLEVEL = 15
-ALPHA = d
+ALPHA = e
 
 all:	Version zImage
 
diff --git a/drivers/FPU-emu/control_w.h b/drivers/FPU-emu/control_w.h
index 6830321..ef5fced 100644
--- a/drivers/FPU-emu/control_w.h
+++ b/drivers/FPU-emu/control_w.h
@@ -35,9 +35,10 @@
 
 /* p 15-5: Precision control bits affect only the following:
    ADD, SUB(R), MUL, DIV(R), and SQRT */
-#define PR_24_BITS      _Const_(0x000)
-#define PR_53_BITS      _Const_(0x200)
-#define PR_64_BITS      _Const_(0x300)
+#define PR_24_BITS        _Const_(0x000)
+#define PR_53_BITS        _Const_(0x200)
+#define PR_64_BITS        _Const_(0x300)
+#define PR_RESERVED_BITS  _Const_(0x100)
 /* FULL_PRECISION simulates all exceptions masked */
 #define FULL_PRECISION  (PR_64_BITS | RC_RND | 0x3f)
 
diff --git a/drivers/FPU-emu/errors.c b/drivers/FPU-emu/errors.c
index 0454c51..d1098ea 100644
--- a/drivers/FPU-emu/errors.c
+++ b/drivers/FPU-emu/errors.c
@@ -261,6 +261,7 @@
 	      0x233  in reg_round.S
 	      0x234  in reg_round.S
 	      0x235  in reg_round.S
+	      0x236  in reg_round.S
  */
 
 void exception(int n)
diff --git a/drivers/FPU-emu/fpu_emu.h b/drivers/FPU-emu/fpu_emu.h
index 49e02ed..3db50e6 100644
--- a/drivers/FPU-emu/fpu_emu.h
+++ b/drivers/FPU-emu/fpu_emu.h
@@ -81,6 +81,12 @@
 #define PREFIX_REPE 0xf3
 #define PREFIX_REPNE 0xf2
 #define PREFIX_LOCK 0xf0
+#define PREFIX_CS_ 1
+#define PREFIX_DS_ 2
+#define PREFIX_ES_ 3
+#define PREFIX_FS_ 4
+#define PREFIX_GS_ 5
+#define PREFIX_SS_ 6
 
 /* These are to defeat the default action, giving the instruction
    no net effect: */
diff --git a/drivers/FPU-emu/fpu_entry.c b/drivers/FPU-emu/fpu_entry.c
index 944a9da..001beaf 100644
--- a/drivers/FPU-emu/fpu_entry.c
+++ b/drivers/FPU-emu/fpu_entry.c
@@ -560,7 +560,7 @@
   unsigned char byte;
   unsigned char *ip = *fpu_eip;
 
-  *override = (overrides) { 0, 0, PREFIX_DS };       /* defaults */
+  *override = (overrides) { 0, 0, PREFIX_DS_ };       /* defaults */
 
   RE_ENTRANT_CHECK_OFF;
   FPU_code_verify_area(1);
@@ -580,23 +580,23 @@
 	  goto do_next_byte;
 
 	case PREFIX_CS:
-	  override->segment = PREFIX_CS;
+	  override->segment = PREFIX_CS_;
 	  goto do_next_byte;
 	case PREFIX_ES:
-	  override->segment = PREFIX_ES;
+	  override->segment = PREFIX_ES_;
 	  goto do_next_byte;
 	case PREFIX_SS:
-	  override->segment = PREFIX_SS;
+	  override->segment = PREFIX_SS_;
 	  goto do_next_byte;
 	case PREFIX_FS:
-	  override->segment = PREFIX_FS;
+	  override->segment = PREFIX_FS_;
 	  goto do_next_byte;
 	case PREFIX_GS:
-	  override->segment = PREFIX_GS;
+	  override->segment = PREFIX_GS_;
 	  goto do_next_byte;
 
 	case PREFIX_DS:   /* Redundant unless preceded by another override. */
-	  override->segment = PREFIX_DS;
+	  override->segment = PREFIX_DS_;
 
 /* lock is not a valid prefix for FPU instructions,
    let the cpu handle it to generate a SIGILL. */
@@ -635,7 +635,7 @@
 }
 
 
-void __math_abort(struct info * info, unsigned int signal)
+void math_abort(struct info * info, unsigned int signal)
 {
 	FPU_EIP = FPU_ORIG_EIP;
 	current->tss.trap_no = 16;
diff --git a/drivers/FPU-emu/fpu_proto.h b/drivers/FPU-emu/fpu_proto.h
index a55f2d9..5003cca 100644
--- a/drivers/FPU-emu/fpu_proto.h
+++ b/drivers/FPU-emu/fpu_proto.h
@@ -52,7 +52,7 @@
 
 /* fpu_entry.c */
 asmlinkage void math_emulate(long arg);
-extern void __math_abort(struct info *info, unsigned int signal);
+extern void math_abort(struct info *info, unsigned int signal);
 
 /* fpu_etc.c */
 extern void fp_etc(void);
diff --git a/drivers/FPU-emu/fpu_system.h b/drivers/FPU-emu/fpu_system.h
index a8e7af3..1d25911 100644
--- a/drivers/FPU-emu/fpu_system.h
+++ b/drivers/FPU-emu/fpu_system.h
@@ -25,10 +25,6 @@
 #define FPU_CS			(*(unsigned short *) &(FPU_info->___cs))
 #define FPU_SS			(*(unsigned short *) &(FPU_info->___ss))
 #define FPU_DS			(*(unsigned short *) &(FPU_info->___ds))
-#define FPU_VM86_ES             ((&FPU_SS)[2])
-#define FPU_VM86_DS             ((&FPU_SS)[4])
-#define FPU_VM86_FS             ((&FPU_SS)[6])
-#define FPU_VM86_GS             ((&FPU_SS)[8])
 #define FPU_EAX			(FPU_info->___eax)
 #define FPU_EFLAGS		(FPU_info->___eflags)
 #define FPU_EIP			(FPU_info->___eip)
diff --git a/drivers/FPU-emu/get_address.c b/drivers/FPU-emu/get_address.c
index 224cb60..3fb115c 100644
--- a/drivers/FPU-emu/get_address.c
+++ b/drivers/FPU-emu/get_address.c
@@ -39,6 +39,18 @@
 
 #define REG_(x) (*(long *)(reg_offset[(x)]+(char *) FPU_info))
 
+static int reg_offset_vm86[] = {
+	offsetof(struct info,___cs),
+	offsetof(struct info,___vm86_ds),
+	offsetof(struct info,___vm86_es),
+	offsetof(struct info,___vm86_fs),
+	offsetof(struct info,___vm86_gs),
+	offsetof(struct info,___ss)
+      };
+
+#define VM86_REG_(x) (*(unsigned short *) \
+		      (reg_offset_vm86[((unsigned)x)]+(char *) FPU_info))
+
 
 /* Decode the SIB byte. This function assumes mod != 0 */
 static void *sib(int mod, unsigned long *fpu_eip)
@@ -94,32 +106,18 @@
   return (void *) offset;
 }
 
-static unsigned long vm86_segment(char segment)
+
+static unsigned long vm86_segment(unsigned char segment)
 { 
-  switch ( segment )
+  segment--;
+#ifdef PARANOID
+  if ( segment > PREFIX_SS_ )
     {
-    case PREFIX_CS:
-      return FPU_CS << 4;
-      break;
-    case PREFIX_SS:
-      return FPU_SS << 4;
-      break;
-    case PREFIX_ES:
-      return FPU_VM86_ES << 4;
-      break;
-    case PREFIX_DS:
-      return FPU_VM86_DS << 4;
-      break;
-    case PREFIX_FS:
-      return FPU_VM86_FS << 4;
-      break;
-    case PREFIX_GS:
-      return FPU_VM86_GS << 4;
-      break;
-    default:
       EXCEPTION(EX_INTERNAL|0x130);
-      return 0; /* Keep gcc quiet. */
+      math_abort(FPU_info,SIGSEGV);
     }
+#endif PARANOID
+  return (unsigned long)VM86_REG_(segment) << 4;
 }
 
 
@@ -156,7 +154,7 @@
      in 32 bit protected mode. */
 #define FPU_WRITE_BIT 0x10
   if ( !addr_modes.vm86 && (FPU_modrm & FPU_WRITE_BIT)
-      && (addr_modes.override.segment == PREFIX_CS) )
+      && (addr_modes.override.segment == PREFIX_CS_) )
     {
       math_abort(FPU_info,SIGSEGV);
     }
@@ -235,7 +233,7 @@
      in 32 bit protected mode. */
 #define FPU_WRITE_BIT 0x10
   if ( !addr_modes.vm86 && (FPU_modrm & FPU_WRITE_BIT)
-      && (addr_modes.override.segment == PREFIX_CS) )
+      && (addr_modes.override.segment == PREFIX_CS_) )
     {
       math_abort(FPU_info,SIGSEGV);
     }
diff --git a/drivers/FPU-emu/reg_ld_str.c b/drivers/FPU-emu/reg_ld_str.c
index a768b4c..030aceb 100644
--- a/drivers/FPU-emu/reg_ld_str.c
+++ b/drivers/FPU-emu/reg_ld_str.c
@@ -1205,6 +1205,10 @@
       s += 0x1c;
     }
 
+#ifdef PECULIAR_486
+  control_word &= ~0xe080;
+#endif PECULIAR_486
+
   top = (partial_status >> SW_Top_Shift) & 7;
 
   if ( partial_status & ~control_word & CW_Exceptions )
@@ -1318,7 +1322,11 @@
     {
       RE_ENTRANT_CHECK_OFF;
       FPU_verify_area(VERIFY_WRITE,d,14);
+#ifdef PECULIAR_486
+      put_fs_long(control_word & ~0xe080, (unsigned short *) d);
+#else
       put_fs_word(control_word, (unsigned short *) d);
+#endif PECULIAR_486
       put_fs_word(status_word(), (unsigned short *) (d+2));
       put_fs_word(tag_word(), (unsigned short *) (d+4));
       put_fs_word(ip_offset, (unsigned short *) (d+6));
diff --git a/drivers/FPU-emu/reg_round.S b/drivers/FPU-emu/reg_round.S
index 4209b22..88a6bbd 100644
--- a/drivers/FPU-emu/reg_round.S
+++ b/drivers/FPU-emu/reg_round.S
@@ -156,9 +156,19 @@
 	cmpl	PR_24_BITS,%ecx
 	je	LRound_To_24
 
+#ifdef PECULIAR_486
+/* With the precision control bits set to 01 "(reserved)", a real 80486
+   behaves as if the precision control bits were set to 11 "64 bits" */
+	cmpl	PR_RESERVED_BITS,%ecx
+	je	LRound_To_64
+#ifdef PARANOID
+	jmp	L_bugged_denorm_486
+#endif PARANOID
+#else
 #ifdef PARANOID
 	jmp	L_bugged_denorm	/* There is no bug, just a bad control word */
 #endif PARANOID
+#endif PECULIAR_486
 
 
 /* Round etc to 24 bit precision */
@@ -643,12 +653,19 @@
 
 
 #ifdef PARANOID
-/* If we ever get here then we have problems! */
+#ifdef PECULIAR_486
+L_bugged_denorm_486:
+	pushl	EX_INTERNAL|0x236
+	call	EXCEPTION
+	popl	%ebx
+	jmp	L_exception_exit
+#else
 L_bugged_denorm:
 	pushl	EX_INTERNAL|0x230
 	call	EXCEPTION
 	popl	%ebx
 	jmp	L_exception_exit
+#endif PECULIAR_486
 
 L_bugged_round24:
 	pushl	EX_INTERNAL|0x231
diff --git a/drivers/char/serial.c b/drivers/char/serial.c
index 2b6aa0c..88aa55b 100644
--- a/drivers/char/serial.c
+++ b/drivers/char/serial.c
@@ -258,7 +258,13 @@
 	struct async_struct *info;
 	
 	info = rs_table + DEV_TO_SL(tty->line);
-	
+
+	if (info->flags & ASYNC_CLOSING) {
+		tty->stopped = 0;
+		tty->hw_stopped = 0;
+		return;
+	}
+
 	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
 #ifdef ISR_HACK
 	serial_out(info, UART_IER, info->IER);
@@ -431,7 +437,7 @@
 			rs_sched_event(info, RS_EVENT_HANGUP);
 		}
 	}
-	if (C_CRTSCTS(info->tty)) {
+	if (C_CRTSCTS(info->tty) && !(info->flags & ASYNC_CLOSING)) {
 		if (info->tty->hw_stopped) {
 			if (status & UART_MSR_CTS) {
 #ifdef SERIAL_DEBUG_INTR
@@ -1029,9 +1035,11 @@
 	if (!tty || tty->stopped || tty->hw_stopped)
 		return;
 	info = rs_table + DEV_TO_SL(tty->line);
-	if (!info || !info->tty || !(info->flags & ASYNC_INITIALIZED))
-		return;
 	cli();
+	if (!info || !info->tty || !(info->flags & ASYNC_INITIALIZED)) {
+		sti();
+		return;
+	}
 	restart_port(info);
 	info->IER = (UART_IER_MSI | UART_IER_RLSI |
 		     UART_IER_THRI | UART_IER_RDI);
diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c
index 45e6958..3476788 100644
--- a/drivers/char/tpqic02.c
+++ b/drivers/char/tpqic02.c
@@ -1816,7 +1816,7 @@
 	int stat;
 
 	if (TP_DIAGS(current_tape_dev))
-		printk(TPQIC_NAME ": request READ, minor=%x, buf=%lx, count=%x, pos=%x, flags=%x\n",
+		printk(TPQIC_NAME ": request READ, minor=%x, buf=%p, count=%x, pos=%x, flags=%x\n",
 			MINOR(dev), buf, count, filp->f_pos, flags);
 
 	if (count % TAPE_BLKSIZE) {	/* Only allow mod 512 bytes at a time. */
@@ -1833,7 +1833,7 @@
 	/* Make sure buffer is safe to write into. */
 	error = verify_area(VERIFY_WRITE, buf, count);
 	if (error) {
-		printk(TPQIC_NAME ": read: verify_area(WRITE, %lx, %x) failed\n", buf, count);
+		printk(TPQIC_NAME ": read: verify_area(WRITE, %p, %x) failed\n", buf, count);
 		return error;
 	}
 
@@ -1985,7 +1985,7 @@
 	unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
 
 	if (TP_DIAGS(current_tape_dev))
-		printk(TPQIC_NAME ": request WRITE, minor=%x, buf=%lx, count=%x, pos=%x, flags=%x\n",
+		printk(TPQIC_NAME ": request WRITE, minor=%x, buf=%p, count=%x, pos=%x, flags=%x\n",
 			MINOR(dev), buf, count, filp->f_pos, flags);
 
 	if (count % TAPE_BLKSIZE) {	/* only allow mod 512 bytes at a time */
@@ -2010,7 +2010,7 @@
 	/* Make sure buffer is safe to read from. */
 	error = verify_area(VERIFY_READ, buf, count);
 	if (error) {
-		printk(TPQIC_NAME ": write: verify_area(READ, %lx, %x) failed\n", buf, count);
+		printk(TPQIC_NAME ": write: verify_area(READ, %p, %x) failed\n", buf, count);
 		return error;
 	}
 
@@ -2107,7 +2107,7 @@
 		}
 	}
 	tpqputs("write request for <0 bytes");
-	printk(TPQIC_NAME ": status_bytes_wr %x, buf %x, total_bytes_done %x, count %x\n", status_bytes_wr, buf, total_bytes_done, count);
+	printk(TPQIC_NAME ": status_bytes_wr %x, buf %p, total_bytes_done %x, count %x\n", status_bytes_wr, buf, total_bytes_done, count);
 	return -EINVAL;
 } /* tape_qic02_write */
 
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 514fa8c..dc6cf50 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -19,6 +19,7 @@
  *		Alan Cox	:	Honours the old SL_COMPRESSED flag
  *		Alan Cox	:	KISS AX.25 and AXUI IP support
  *		Michael Riepe	:	Automatic CSLIP recognition added
+ *		Charles Hedrick :	CSLIP header length problem fix.
  */
  
 #include <asm/segment.h>
@@ -522,6 +523,8 @@
 {
   struct tty_struct *tty;
   struct slip *sl;
+  
+  int size;
 
   /* Find the correct SLIP channel to use. */
   sl = &sl_ctrl[dev->base_addr];
@@ -555,8 +558,19 @@
   	}
 #endif  	
 	sl_lock(sl);
-/*	sl_hex_dump(skb->data,skb->len);*/
-	sl_encaps(sl, skb->data, skb->len);
+	
+	size=skb->len;
+	if(size<sizeof(struct iphdr))
+	{
+		printk("Runt IP frame fed to slip!\n");
+	}
+	else
+	{
+		size=((struct iphdr *)(skb->data))->tot_len;
+		size=ntohs(size);
+	/*	sl_hex_dump(skb->data,skb->len);*/
+		sl_encaps(sl, skb->data, size);
+	}
 	if (skb->free) kfree_skb(skb, FREE_WRITE);
   }
   return(0);
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 4790437..d3f1ac1 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -675,7 +675,7 @@
   WAIT(INTRFLAGS(base),INTRMASK,HACC,0);
   aha1542_intr_reset(base);
   
-  if (mbenable_result[0] & 0x08) {
+  if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
      mbenable_cmd[0]=CMD_MBENABLE;
      mbenable_cmd[1]=0;
      mbenable_cmd[2]=mbenable_result[1];
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 157c5bd..9629bb8 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -18,7 +18,7 @@
 #ifdef CONSTANTS
 #undef CONSTANTS
 #endif
-#define CONSTANTS (CONST_CMD | CONST_STATUS | CONST_SENSE | CONST_XSENSE)
+#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE)
 #endif
 
 #if (CONSTANTS & CONST_COMMAND)
diff --git a/fs/buffer.c b/fs/buffer.c
index 31c203d..17fc97c 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -484,17 +484,15 @@
 #endif
 	}
 
-	if (!bh && nr_free_pages > 5) {
-		if (grow_buffers(GFP_BUFFER, size))
-			goto repeat;
-	}
-	
-/* and repeat until we find something good */
 	if (!bh) {
+		if (nr_free_pages > 5)
+			if (grow_buffers(GFP_BUFFER, size))
+				goto repeat;
 		if (!grow_buffers(GFP_ATOMIC, size))
 			sleep_on(&buffer_wait);
 		goto repeat;
 	}
+
 	wait_on_buffer(bh);
 	if (bh->b_count || bh->b_size != size)
 		goto repeat;
@@ -920,7 +918,7 @@
 	do {
 		if (!tmp)
 			return 0;
-		if (tmp->b_count || tmp->b_dirt || tmp->b_lock)
+		if (tmp->b_count || tmp->b_dirt || tmp->b_lock || tmp->b_wait)
 			return 0;
 		tmp = tmp->b_this_page;
 	} while (tmp != bh);
diff --git a/fs/exec.c b/fs/exec.c
index 4f744f1..efa15a7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -134,7 +134,11 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 	memcpy(corefile,"core.",5);
+#if 0
 	memcpy(corefile+5,current->comm,sizeof(current->comm));
+#else
+	corefile[4] = '\0';
+#endif
 	if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
 		inode = NULL;
 		goto end_coredump;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 1a4f2c2..a513b9c 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -42,9 +42,9 @@
 
 	if (count < 0)
 		return -EINVAL;
-	if (p >= high_memory)
+	if (p >= high_memory + PAGE_SIZE)
 		return 0;
-	if (count > high_memory - p)
+	if (count > high_memory + PAGE_SIZE - p)
 		count = high_memory - p;
 	read = 0;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index be397d6..4244ea3 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -320,12 +320,13 @@
 extern void putname(char * name);
 
 extern int register_blkdev(unsigned int, const char *, struct file_operations *);
+extern int unregister_blkdev(unsigned int major, const char * name);
 extern int blkdev_open(struct inode * inode, struct file * filp);
 extern struct file_operations def_blk_fops;
 extern struct inode_operations blkdev_inode_operations;
 
 extern int register_chrdev(unsigned int, const char *, struct file_operations *);
-extern int unregister_chrdev( unsigned int major, const char * name);
+extern int unregister_chrdev(unsigned int major, const char * name);
 extern int chrdev_open(struct inode * inode, struct file * filp);
 extern struct file_operations def_chr_fops;
 extern struct inode_operations chrdev_inode_operations;
diff --git a/include/linux/math_emu.h b/include/linux/math_emu.h
index ec8d6ba..0d9606d 100644
--- a/include/linux/math_emu.h
+++ b/include/linux/math_emu.h
@@ -9,6 +9,11 @@
 	unsigned sigh;
 };
 
+
+/* This structure matches the layout of the data saved to the stack
+   following a device-not-present interrupt, part of it saved
+   automatically by the 80386/80486.
+   */
 struct info {
 	long ___orig_eip;
 	long ___ret_from_system_call;
@@ -29,30 +34,10 @@
 	long ___eflags;
 	long ___esp;
 	long ___ss;
+	long ___vm86_es; /* This and the following only in vm86 mode */
+	long ___vm86_ds;
+	long ___vm86_fs;
+	long ___vm86_gs;
 };
 
-#if 0
-#define EAX (info->___eax)
-#define EBX (info->___ebx)
-#define ECX (info->___ecx)
-#define EDX (info->___edx)
-#define ESI (info->___esi)
-#define EDI (info->___edi)
-#define EBP (info->___ebp)
-#define ESP (info->___esp)
-#define EIP (info->___eip)
-#define ORIG_EIP (info->___orig_eip)
-#define EFLAGS (info->___eflags)
-#define DS (*(unsigned short *) &(info->___ds))
-#define ES (*(unsigned short *) &(info->___es))
-#define FS (*(unsigned short *) &(info->___fs))
-#define CS (*(unsigned short *) &(info->___cs))
-#define SS (*(unsigned short *) &(info->___ss))
-#endif
-
-void __math_abort(struct info *, unsigned int);
-
-#define math_abort(x,y) \
-(((volatile void (*)(struct info *,unsigned int)) __math_abort)((x),(y)))
-
 #endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index d1ae039..8411af1 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -11,7 +11,7 @@
 
 int __verify_write(unsigned long addr, unsigned long count);
 
-extern inline int verify_area(int type, void * addr, unsigned long size)
+extern inline int verify_area(int type, const void * addr, unsigned long size)
 {
 	if (TASK_SIZE <= (unsigned long) addr)
 		return -EFAULT;
diff --git a/kernel/ksyms.S b/kernel/ksyms.S
index d219643..a91314f 100644
--- a/kernel/ksyms.S
+++ b/kernel/ksyms.S
@@ -9,6 +9,8 @@
 
 _register_chrdev
 _unregister_chrdev
+_register_blkdev
+_unregister_blkdev
 _wake_up_interruptible
 
 _wp_works_ok
diff --git a/kernel/signal.c b/kernel/signal.c
index dde9e11..5352421 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -235,11 +235,13 @@
 	COPY_SEG(gs);
 	COPY_SEG_STRICT(ss);
 	COPY_SEG_STRICT(cs);
-	COPY(eip); COPY(eflags);
+	COPY(eip);
 	COPY(ecx); COPY(edx);
 	COPY(ebx);
 	COPY(esp); COPY(ebp);
 	COPY(edi); COPY(esi);
+	regs->eflags &= ~0xCD5;
+	regs->eflags |= context.eflags & 0xCD5;
 	regs->orig_eax = -1;		/* disable syscall checks */
 	return context.eax;
 badframe:
diff --git a/net/inet/tcp.c b/net/inet/tcp.c
index 0133e18..221111d 100644
--- a/net/inet/tcp.c
+++ b/net/inet/tcp.c
@@ -59,6 +59,7 @@
  *		Alan Cox	:	Added a couple of small NET2E timer fixes
  *		Charles Hedrick :	TCP fixes
  *		Toomas Tamm	:	TCP window fixes
+ *		Alan Cox	:	Small URG fix to rlogin ^C ack fight
  *
  *
  * To Fix:
@@ -1314,6 +1315,8 @@
 	do {
 		int amt;
 
+		if (before(sk->copied_seq+1, skb->h.th->seq))
+			break;
 		if (skb->h.th->urg && !skb->urg_used) {
 			if (skb->h.th->urg_ptr == 0) {
 				skb->h.th->urg_ptr = ntohs(skb->len);
@@ -1329,6 +1332,7 @@
 				skb->urg_used = 1;
 				sk->urg--;
 			}
+			cleanup_rbuf(sk);
 			release_sock(sk);
 			copied += amt;
 			return(copied);
@@ -1337,6 +1341,7 @@
 	} while(skb != sk->rqueue);
   }
 /*sk->urg = 0;*/
+  cleanup_rbuf(sk);
   release_sock(sk);
   return(0);
 }