diff -u --recursive --new-file v1.1.21/linux/Makefile linux/Makefile
--- v1.1.21/linux/Makefile	Wed Jun 22 14:57:07 1994
+++ linux/Makefile	Wed Jun 22 14:16:27 1994
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 21
+SUBLEVEL = 22
 
 all:	Version zImage
 
diff -u --recursive --new-file v1.1.21/linux/config.in linux/config.in
--- v1.1.21/linux/config.in	Wed Jun 22 14:57:07 1994
+++ linux/config.in	Thu Jun 23 22:43:37 1994
@@ -70,10 +70,10 @@
 bool 'Network device support?' CONFIG_NETDEVICES y
 if [ "$CONFIG_NETDEVICES" = "n" ]; then
 
-comment 'Skipping ethercard configuration options...'
+comment 'Skipping network driver configuration options...'
 
 else
-bool 'Dummy net driver support' CONFIG_DUMMY y
+bool 'Dummy net driver support' CONFIG_DUMMY n
 bool 'SLIP (serial line) support' CONFIG_SLIP n
 if [ "$CONFIG_SLIP" = "y" ]; then
   bool ' CSLIP compressed headers' SL_COMPRESSED y
@@ -81,29 +81,49 @@
 fi
 bool 'PPP (point-to-point) support' CONFIG_PPP n
 bool 'Load balancing support (experimental)' CONFIG_SLAVE_BALANCING n
+bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n
+bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n
+if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
+	bool 'WD80*3 support' CONFIG_WD80x3 n
+	bool 'SMC Ultra support' CONFIG_ULTRA n
+fi
+bool '3COM cards' CONFIG_NET_VENDOR_3COM y
+if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
+	bool '3c501 support' CONFIG_EL1 n
+	bool '3c503 support' CONFIG_EL2 n
+	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
+		bool '3c505 support' CONFIG_ELPLUS n
+		bool '3c507 support' CONFIG_EL16 n
+	fi
+	bool '3c509/3c579 support' CONFIG_EL3 y
+fi
+bool 'Other ISA cards' CONFIG_NET_ISA n
+if [ "$CONFIG_NET_ISA" = "y" ]; then
+	bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE y
+	bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 n
+	bool 'DEPCA support' CONFIG_DEPCA n
+	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
+		bool 'EtherExpress support' CONFIG_EEXPRESS n
+	fi
+	bool 'HP PCLAN support' CONFIG_HPLAN n
+	bool 'NE2000/NE1000 support' CONFIG_NE2000 n
+fi
 bool 'PLIP (parallel port) support' CONFIG_PLIP n
-bool 'NE2000/NE1000 support' CONFIG_NE2000 n
-bool 'WD80*3 support' CONFIG_WD80x3 n
-bool 'SMC Ultra support' CONFIG_ULTRA n
-bool '3c501 support' CONFIG_EL1 n
-bool '3c503 support' CONFIG_EL2 n
-#bool '3c505 support' CONFIG_ELPLUS n
-#bool '3c507 support' CONFIG_EL16 n
-bool '3c509/3c579 support' CONFIG_EL3 y
-bool 'HP PCLAN support' CONFIG_HPLAN n
-bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE n
-bool 'AT1700 support' CONFIG_AT1700 n
-#bool 'Zenith Z-Note support' CONFIG_ZNET n
-#bool 'EtherExpress support' CONFIG_EEXPRESS n
-#bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
-bool 'DEPCA support' CONFIG_DEPCA n
+bool 'EISA and on board controllers' CONFIG_NET_EISA n
+	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
+		bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
+		bool 'AT1700 support' CONFIG_AT1700 n
+	fi
+	bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
 #bool 'NI52EE support' CONFIG_NI52 n
 #bool 'NI65EE support' CONFIG_NI65 n
-#bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
-#bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 n
-bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
-bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n
-bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
+bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n
+if [ "$CONFIG_NET_POCKET" = "y" ]; then
+	bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
+	bool 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n
+	bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
+	bool 'Zenith Z-Note support' CONFIG_ZNET n
+fi
 fi
 fi
 
diff -u --recursive --new-file v1.1.21/linux/drivers/block/hd.c linux/drivers/block/hd.c
--- v1.1.21/linux/drivers/block/hd.c	Wed Jun 22 14:57:07 1994
+++ linux/drivers/block/hd.c	Thu Jun 23 23:09:19 1994
@@ -655,8 +655,10 @@
 			hd_info[drive].ctl = *(8+BIOS);
 			hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
 			hd_info[drive].sect = *(14+BIOS);
+#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
 			if (hd_info[drive].cyl && NR_HD == drive)
 				NR_HD++;
+#endif
 			BIOS += 16;
 		}
 
diff -u --recursive --new-file v1.1.21/linux/drivers/char/console.c linux/drivers/char/console.c
--- v1.1.21/linux/drivers/char/console.c	Tue May 24 00:34:47 1994
+++ linux/drivers/char/console.c	Wed Jun 22 14:18:28 1994
@@ -133,6 +133,8 @@
 	/* mode flags */
 	unsigned long	vc_charset	: 1;	/* Character set G0 / G1 */
 	unsigned long	vc_s_charset	: 1;	/* Saved character set */
+	unsigned long	vc_disp_ctrl	: 1;	/* Display chars < 32? */
+	unsigned long	vc_toggle_meta	: 1;	/* Toggle high bit? */
 	unsigned long	vc_decscnm	: 1;	/* Screen Mode */
 	unsigned long	vc_decom	: 1;	/* Origin Mode */
 	unsigned long	vc_decawm	: 1;	/* Autowrap Mode */
@@ -185,6 +187,8 @@
 #define video_mem_start	(vc_cons[currcons].vc_video_mem_start)
 #define video_mem_end	(vc_cons[currcons].vc_video_mem_end)
 #define video_erase_char (vc_cons[currcons].vc_video_erase_char)	
+#define disp_ctrl	(vc_cons[currcons].vc_disp_ctrl)
+#define toggle_meta	(vc_cons[currcons].vc_toggle_meta)
 #define decscnm		(vc_cons[currcons].vc_decscnm)
 #define decom		(vc_cons[currcons].vc_decom)
 #define decawm		(vc_cons[currcons].vc_decawm)
@@ -682,6 +686,33 @@
 			case 7:
 				reverse = 1;
 				break;
+			case 10: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select primary font, don't display
+				  * control chars if defined, don't set
+				  * bit 8 on output.
+				  */
+				translate = (charset == 0
+						? G0_charset
+						: G1_charset);
+				disp_ctrl = 0;
+				toggle_meta = 0;
+				break;
+			case 11: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select first alternate font, let's
+				  * chars < 32 be displayed as ROM chars.
+				  */
+				translate = NULL_TRANS;
+				disp_ctrl = 1;
+				toggle_meta = 0;
+				break;
+			case 12: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select second alternate font, toggle
+				  * high bit before displaying as ROM char.
+				  */
+				translate = NULL_TRANS;
+				disp_ctrl = 1;
+				toggle_meta = 1;
+				break;
 			case 21:
 			case 22:
 				intensity = 1;
@@ -695,8 +726,21 @@
 			case 27:
 				reverse = 0;
 				break;
-			case 39:
+			case 38: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Enables underscore, white foreground
+				  * with white underscore (Linux - use
+				  * default foreground).
+				  */
+				color = (def_color & 0x0f) | background;
+				underline = 1;
+				break;
+			case 39: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Disable underline option.
+				  * Reset colour to default? It did this
+				  * before...
+				  */
 				color = (def_color & 0x0f) | background;
+				underline = 0;
 				break;
 			case 49:
 				color = (def_color & 0xf0) | foreground;
@@ -957,6 +1001,9 @@
 	charset		= 0;
 	need_wrap	= 0;
 
+	disp_ctrl	= 0;
+	toggle_meta	= 0;
+
 	decscnm		= 0;
 	decom		= 0;
 	decawm		= 1;
@@ -1026,7 +1073,11 @@
 	while (!tty->stopped &&	count) {
 		c = from_user ? get_fs_byte(buf) : *buf;
 		buf++; n++; count--;
-		if (vc_state == ESnormal && translate[c]) {
+		if (vc_state == ESnormal
+		&& (c >= 32 || (disp_ctrl && (c&0x7f) != 27))
+		&& (toggle_meta ? translate[c|0x80] : translate[c])) {
+			if (toggle_meta)
+				c |= 0x80;
 			if (need_wrap) {
 				cr(currcons);
 				lf(currcons);
diff -u --recursive --new-file v1.1.21/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v1.1.21/linux/drivers/net/3c505.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/3c505.c	Thu Jun 23 12:07:41 1994
@@ -0,0 +1,941 @@
+/*
+ * Linux ethernet device driver for the 3Com Etherlink Plus (3C505)
+ * 	By Craig Southeren
+ *
+ * 3c505.c	This module implements an interface to the 3Com
+ *		Etherlink Plus (3c505) ethernet card. Linux device 
+ *		driver interface reverse engineered from the Linux 3C509
+ *		device drivers. Vital 3C505 information gleaned from
+ *		the Crynwr packet driver
+ *
+ * Version:	@(#)3c505.c	0.1	23/09/93
+ *
+ * Authors:	Linux 3c505 device driver by:
+ *			Craig Southeren, <geoffw@extro.ucc.su.oz.au>
+ *              Linux 3C509 driver by:
+ *             		Donald Becker, <becker@super.org>
+ *		Crynwr packet driver by
+ *			Krishnan Gopalan and Gregg Stefancik,
+ * 			   Clemson Univesity Engineering Computer Operations.
+ *			Portions of the code have been adapted from the 3c505
+ *			   driver for NCSA Telnet by Bruce Orchard and later
+ *			   modified by Warren Van Houten and krus@diku.dk.
+ *              3C505 technical information provided by
+ *                      Terry Murphy, of 3Com Network Adapter Division
+ *		Special thanks to Juha Laiho, <jlaiho@ichaos.nullnet.fi>
+ *                     
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/in.h>
+#include <asm/io.h>
+#ifndef port_read
+#include "iow.h"
+#endif
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include "3c505.h"
+
+#ifdef ELP_DEBUG
+static int elp_debug = ELP_DEBUG;
+#else
+static int elp_debug = 0;
+#endif
+
+/*
+ *  0 = no messages
+ *  1 = messages when high level commands performed
+ *  2 = messages when low level commands performed
+ *  3 = messages when interrupts received
+ */
+
+#define	ELP_VERSION	"0.1.0"
+
+extern struct device *irq2dev_map[16];
+
+/*****************************************************************
+ *
+ * useful macros
+ *
+ *****************************************************************/
+
+#define	INB(port)	inb((unsigned short)port) 
+#define	OUTB(val,port)	outb((unsigned char)val,(unsigned short)port);
+
+#ifndef	TRUE
+#define	TRUE	1
+#endif
+
+#ifndef	FALSE
+#define	FALSE	0
+#endif
+
+
+/*****************************************************************
+ *
+ * PCB structure
+ *
+ *****************************************************************/
+
+typedef struct {
+  unsigned char   command;		/* PCB command code */
+  unsigned char   length;		/* PCB data length */
+  unsigned char   data[MAX_PCB_DATA];	/* PCB data */
+} pcb_struct;
+
+
+/*****************************************************************
+ *
+ *  structure to hold context information for adapter
+ *
+ *****************************************************************/
+
+typedef struct {
+  int        io_addr;	     /* base I/O address */
+  short      got_configure;  /* set to TRUE when configure response received */
+  pcb_struct tx_pcb;         /* PCB for foreground sending */
+  pcb_struct rx_pcb;         /* PCB for foreground receiving */
+  pcb_struct itx_pcb;        /* PCB for background sending */
+  pcb_struct irx_pcb;        /* PCB for background receiving */
+  struct enet_statistics stats;
+} elp_device;
+
+/*****************************************************************
+ *
+ *  useful functions for accessing the adapter
+ *
+ *****************************************************************/
+
+/*
+ * use this routine when accessing the ASF bits as they are
+ * changed asynchronously by the adapter
+ */
+
+/* get adapter PCB status */
+#define	GET_ASF()  	(get_status(adapter)&ASF_PCB_MASK)
+#define	GET_STATUS()  	(get_status(adapter))
+
+static int get_status (elp_device * adapter)
+
+{
+  register int stat1;
+  do {
+    stat1 = INB(adapter->io_addr+PORT_STATUS);
+  } while (stat1 != INB(adapter->io_addr+PORT_STATUS));
+  return stat1;
+}
+
+#define	SET_HSF(hsf)	(set_hsf(adapter,hsf))
+
+static void set_hsf (elp_device * adapter, int hsf)
+
+{
+  cli();
+  OUTB((INB(adapter->io_addr+PORT_CONTROL)&(~HSF_PCB_MASK))|hsf, adapter->io_addr+PORT_CONTROL); 
+  sti(); 
+}
+
+#define	WAIT_HCRE(toval)	(wait_hcre(adapter,toval))
+
+static int wait_hcre(elp_device * adapter, int toval)
+
+{
+  int timeout = jiffies + toval;
+  while(((INB(adapter->io_addr+PORT_STATUS)&STATUS_HCRE)==0) &&
+         (jiffies <= timeout))
+    ;
+  if (jiffies > timeout) {
+    printk("elp0: timeout waiting for HCRE\n");
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/*****************************************************************
+ *
+ * send_pcb
+ *   Send a PCB to the adapter. 
+ *
+ *	output byte to command reg  --<--+
+ *	wait until HCRE is non zero      |
+ *	loop until all bytes sent   -->--+
+ *	set HSF1 and HSF2 to 1
+ *	output pcb length
+ *	wait until ASF give ACK or NAK
+ *	set HSF1 and HSF2 to 0
+ *
+ *****************************************************************/
+
+static int send_pcb(elp_device * adapter, pcb_struct * pcb)
+
+{
+  int i;
+  int cont;
+  int retry = 0;
+  int timeout;
+
+  while (1) {
+
+    cont = 1;
+
+    /*
+     * load each byte into the command register and
+     * wait for the HCRE bit to indicate the adapter
+     * had read the byte
+     */
+    SET_HSF(0); 
+    OUTB(pcb->command, (adapter->io_addr)+PORT_COMMAND);
+    cont = WAIT_HCRE(5);
+   /* SET_HSF(0);  */
+
+    if (cont) {
+      OUTB(pcb->length, (adapter->io_addr)+PORT_COMMAND);
+      cont = WAIT_HCRE(2);
+    }
+
+    for (i = 0; cont && (i < pcb->length); i++) {
+      OUTB(pcb->data[i], (adapter->io_addr)+PORT_COMMAND);
+      cont = WAIT_HCRE(2);
+    }
+
+    /* set the host status bits to indicate end of PCB */
+    /* send the total packet length as well */
+    /* wait for the adapter to indicate that it has read the PCB */
+    if (cont) {
+      SET_HSF(HSF_PCB_END);
+      OUTB(2+pcb->length, adapter->io_addr+PORT_COMMAND);
+      timeout = jiffies + 6;
+      while (jiffies < timeout) {
+        i = GET_ASF();
+        if ((i == ASF_PCB_ACK) ||
+            (i == ASF_PCB_NAK))
+          break;
+      }
+      if (i == ASF_PCB_ACK) {
+        SET_HSF(0); 
+        return TRUE;
+      } else if (i = ASF_PCB_NAK) {
+        SET_HSF(0);
+        printk("elp0: PCB send was NAKed\n");
+        {
+          int to = jiffies + 5;
+          while (jiffies < to)
+            ;
+        }
+      }
+    }
+
+    if (elp_debug >= 6)
+      printk("elp0: NAK/timeout on send PCB\n");
+    if ((retry++ & 7) == 0) 
+      printk("elp0: retry #%i on send PCB\n", retry);
+  }
+}
+
+/*****************************************************************
+ *
+ * receive_pcb
+ *   Read a PCB to the adapter
+ *
+ *	wait for ACRF to be non-zero         ---<---+
+ *      input a byte                                |
+ *      if ASF1 and ASF2 were not both one          |
+ *           before byte was read, loop      --->---+
+ *      set HSF1 and HSF2 for ack
+ *
+ *****************************************************************/
+
+static int receive_pcb(elp_device * adapter, pcb_struct * pcb)
+
+{
+  int i;
+  int total_length;
+  int stat;
+
+  /* get the command code */
+  while (((stat = GET_STATUS())&STATUS_ACRF) == 0)
+    ;
+  SET_HSF(0); 
+  pcb->command = INB(adapter->io_addr+PORT_COMMAND);
+  if ((stat & ASF_PCB_MASK) != ASF_PCB_END) {
+
+    /* read the data length */
+    while (((stat = GET_STATUS())&STATUS_ACRF) == 0)
+      ;
+    pcb->length = INB(adapter->io_addr+PORT_COMMAND);
+    if ((stat & ASF_PCB_MASK) != ASF_PCB_END) {
+
+      /* read the data */
+      i = 0;
+      do {
+        while (((stat = GET_STATUS())&STATUS_ACRF) == 0)
+          ;
+        pcb->data[i++] = INB(adapter->io_addr+PORT_COMMAND);
+      } while ((stat & ASF_PCB_MASK) != ASF_PCB_END);
+
+      /* woops, the last "data" byte was really the length! */
+      total_length = pcb->data[--i];
+
+      /* safety check total length vs data length */
+      if (total_length != (pcb->length + 2)) {
+        if (elp_debug >= 6)
+          printk("elp0: mangled PCB received\n");
+        SET_HSF(HSF_PCB_NAK);
+        return FALSE;
+      }
+      SET_HSF(HSF_PCB_ACK);
+      return TRUE;
+    }
+  }
+
+  SET_HSF(HSF_PCB_NAK); 
+  return FALSE;
+}
+
+static void adapter_hard_reset(elp_device * adapter)
+
+{
+  int timeout;
+
+  /*
+   * take FLSH and ATTN high
+   */
+  OUTB(CONTROL_ATTN|CONTROL_FLSH, adapter->io_addr+PORT_CONTROL); 
+
+  /*
+   * wait for a little bit
+   */
+  for (timeout = jiffies + 20; jiffies <= timeout; )
+    ;
+  
+  /*
+   * now take them low
+   */
+  OUTB(0, adapter->io_addr+PORT_CONTROL); 
+
+  /*
+   * wait for a little bit
+   */
+  for (timeout = jiffies + 20; jiffies <= timeout; )
+    ;
+  
+  /*
+   * now hang around until the board gets it's act together
+   */
+  for (timeout = jiffies + (100 * 15); jiffies <= timeout; ) 
+    if (GET_ASF() != ASF_PCB_END)
+      break;
+}
+
+static void adapter_reset(elp_device * adapter)
+
+{
+  int timeout;
+
+  cli();
+  OUTB(CONTROL_ATTN|INB(adapter->io_addr+PORT_CONTROL), adapter->io_addr+PORT_CONTROL);
+  sti();
+
+  /*
+   * wait for a little bit
+   */
+  for (timeout = jiffies + 20; jiffies <= timeout; )
+    ;
+  
+  cli();
+  OUTB(INB(adapter->io_addr+PORT_CONTROL)&~(CONTROL_ATTN), adapter->io_addr+PORT_CONTROL);
+  sti();
+}
+
+/******************************************************
+ *
+ *  queue a receive command on the adapter so we will get an
+ *  interrupt when a packet is received.
+ *
+ ******************************************************/
+
+static int start_receive(elp_device * adapter, pcb_struct * tx_pcb)
+
+{
+  if (elp_debug > 3)
+    printk("elp0: restarting receiver\n");
+  tx_pcb->command = CMD_RECEIVE_PACKET;
+  tx_pcb->length  = 8;
+  tx_pcb->data[4] = 1600 & 0xff;
+  tx_pcb->data[5] = 1600 >> 8;
+  tx_pcb->data[6] = 0;		/* set timeout to zero */
+  tx_pcb->data[7] = 0;
+  return send_pcb(adapter, tx_pcb); 
+}
+
+/******************************************************
+ *
+ * extract a packet from the adapter
+ * this routine is only called from within the interrupt
+ * service routine, so no cli/sti calls are needed
+ * note that the length is always assumed to be even
+ *
+ ******************************************************/
+
+static void receive_packet(struct device * dev,
+                              elp_device * adapter,
+                                       int len)
+
+{
+  register int i;
+  unsigned short * ptr;
+  short d;
+
+  /*
+   * allocate a buffer to put the packet into.
+   */
+  struct sk_buff *skb;
+  skb = alloc_skb(len+3, GFP_ATOMIC);
+
+  /*
+   * make sure the data register is going the right way
+   */
+  OUTB(INB(adapter->io_addr+PORT_CONTROL)|CONTROL_DIR, adapter->io_addr+PORT_CONTROL); 
+
+  /*
+   * if buffer could not be allocated, swallow it
+   */
+  if (skb == NULL) {
+    for (i = 0; i < (len/2); i++) {
+      while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_HRDY) == 0)
+        ;
+      d = inw(adapter->io_addr+PORT_DATA);
+    }
+    adapter->stats.rx_dropped++;
+
+  } else {
+
+    /*
+     * now read the data from the adapter
+     */
+    ptr = (unsigned short *)(skb->data);
+    for (i = 0; i < (len/2); i++) { 
+      while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_HRDY) == 0) {
+        ;
+      }
+      *ptr = inw(adapter->io_addr+PORT_DATA); 
+      ptr++; 
+    }
+
+    /*
+     * the magic routine "dev_rint" passes the packet up the
+     * protocol chain. If it returns 0, we can assume the packet was
+     * swallowed up. If not, then we are responsible for freeing memory
+     */
+    if (dev_rint((unsigned char *)skb, len, IN_SKBUFF, dev) != 0) {
+      printk("%s: receive buffers full.\n", dev->name);
+      kfree_skb(skb, FREE_READ);
+    }
+  }
+
+  OUTB(INB(adapter->io_addr+PORT_CONTROL)&(~CONTROL_DIR), adapter->io_addr+PORT_CONTROL); 
+}
+
+
+/******************************************************
+ *
+ * interrupt handler
+ *
+ ******************************************************/
+
+static void elp_interrupt(int reg_ptr)
+
+{
+  int len;
+  int dlen;
+  int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
+  struct device *dev;
+  elp_device * adapter;
+
+  if (irq < 0 || irq > 15) {
+    printk ("elp0: illegal IRQ number found in interrupt routine (%i)\n", irq);
+    return;
+  }
+
+  if (irq != 0xc) {
+    printk ("elp0: warning - interrupt routine has incorrect IRQ of %i\n", irq);
+    return;
+  }
+
+  dev = irq2dev_map[irq];
+  adapter = (elp_device *) dev->priv;
+
+  if (dev == NULL) {
+    printk ("elp_interrupt(): irq %d for unknown device.\n", irq);
+    return;
+  }
+
+  if (dev->interrupt)
+    if (elp_debug >= 3)
+      printk("%s: Re-entering the interrupt handler.\n", dev->name);
+  dev->interrupt = 1;
+
+  /*
+   * allow interrupts (we need timers!)
+   */
+  sti();
+
+  /*
+   * receive a PCB from the adapter
+   */
+  while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_ACRF) != 0) {
+    
+    if (receive_pcb(adapter, &adapter->irx_pcb)) {
+
+      switch (adapter->irx_pcb.command) {
+
+        /*
+         * 82586 configured correctly
+         */
+        case CMD_CONFIGURE_82586_RESPONSE:
+          adapter->got_configure = 1;
+          if (elp_debug >= 3)
+            printk("%s: interrupt - configure response received\n", dev->name);
+          break;
+
+        /*
+         * received a packet
+         */
+        case CMD_RECEIVE_PACKET_COMPLETE:
+          len  = adapter->irx_pcb.data[6] + (adapter->irx_pcb.data[7] << 8);
+          dlen  = adapter->irx_pcb.data[4] + (adapter->irx_pcb.data[5] << 8);
+          if (adapter->irx_pcb.data[8] != 0) {
+            printk("%s: interrupt - packet not received correctly\n", dev->name);
+          } else {
+            if (elp_debug >= 3)
+              printk("%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
+            receive_packet(dev, adapter, dlen);
+            if (elp_debug >= 3)
+              printk("%s: packet received\n", dev->name);
+            adapter->stats.rx_packets++;
+          }
+          if (dev->start && !start_receive(adapter, &adapter->itx_pcb)) 
+            if (elp_debug >= 2)
+              printk("%s: interrupt - failed to send receive start PCB\n", dev->name);
+          if (elp_debug >= 3)
+            printk("%s: receive procedure complete\n", dev->name);
+
+          break;
+
+        /*
+         * sent a packet
+         */
+        case CMD_TRANSMIT_PACKET_COMPLETE:
+          if (elp_debug >= 3) 
+            printk("%s: interrupt - packet sent\n", dev->name);
+          if (adapter->irx_pcb.data[4] != 0)
+            if (elp_debug >= 2)
+              printk("%s: interrupt - error sending packet %4.4x\n", dev->name, 
+                adapter->irx_pcb.data[4] + (adapter->irx_pcb.data[5] << 8));
+          dev->tbusy = 0;
+          mark_bh(INET_BH);
+          adapter->stats.tx_packets++;
+          break;
+
+        /*
+         * some unknown PCB
+         */
+        default:
+          printk("%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
+          break;
+      }
+    } else 
+      printk("%s: failed to read PCB on interrupt\n", dev->name);
+  }
+
+  /*
+   * indicate no longer in interrupt routine
+   */
+  dev->interrupt = 0;
+}
+
+
+/******************************************************
+ *
+ * open the board
+ *
+ ******************************************************/
+
+static int elp_open (struct device *dev)
+
+{
+  elp_device * adapter = (elp_device *) dev->priv;
+
+  if (elp_debug >= 1)
+    printk("%s: request to open device\n", dev->name);
+
+  /*
+   * make sure we actually found the device
+   */
+  if (adapter == NULL) {
+    printk("%s: Opening a non-existent physical device\n", dev->name);
+    return -EAGAIN;
+  }
+
+  /*
+   * interrupt routine not entered
+   */
+  dev->interrupt = 0;
+
+  /*
+   *  transmitter not busy 
+   */
+  dev->tbusy = 0;
+
+  /*
+   * install our interrupt service routine
+   */
+  if (request_irq(dev->irq, &elp_interrupt))  
+    return -EAGAIN;
+
+  /*
+   * make sure we can find the device header given the interrupt number
+   */
+  irq2dev_map[dev->irq] = dev;
+
+  /*
+   * enable interrupts on the board
+   */
+  OUTB(CONTROL_CMDE, adapter->io_addr+PORT_CONTROL);
+
+  /*
+   * device is now offically open!
+   */
+  dev->start = 1;
+
+  /*
+   * configure adapter to receive broadcast messages and wait for response
+   */
+  if (elp_debug >= 2)
+    printk("%s: sending 82586 configure command\n", dev->name);
+  adapter->tx_pcb.command = CMD_CONFIGURE_82586;
+  adapter->tx_pcb.data[0] = 1;
+  adapter->tx_pcb.data[1] = 0;
+  adapter->tx_pcb.length  = 2;
+  adapter->got_configure  = 0;
+  if (!send_pcb(adapter, &adapter->tx_pcb))
+    printk("%s: couldn't send 82586 configure command\n", dev->name);
+  else
+    while (adapter->got_configure == 0)
+      ;
+
+  /*
+   * queue a receive command to start things rolling
+   */
+  if (!start_receive(adapter, &adapter->tx_pcb))
+    printk("%s: start receive command failed \n", dev->name);
+  if (elp_debug >= 2)
+    printk("%s: start receive command sent\n", dev->name);
+
+  return 0;			/* Always succeed */
+}
+
+/******************************************************
+ *
+ * close the board
+ *
+ ******************************************************/
+
+static int elp_close (struct device *dev)
+
+{
+  elp_device * adapter = (elp_device *) dev->priv;
+
+  if (elp_debug >= 1)
+    printk("%s: request to close device\n", dev->name);
+
+  /*
+   * disable interrupts on the board
+   */
+  OUTB(0x00, adapter->io_addr+PORT_CONTROL);
+
+  /*
+   *  flag transmitter as busy (i.e. not available)
+   */
+  dev->tbusy = 1;
+
+  /*
+   *  indicate device is closed
+   */
+  dev->start = 0;
+
+  /*
+   * release the IRQ
+   */
+  free_irq(dev->irq);
+
+  /*
+   * and we no longer have to map irq to dev either
+   */
+  irq2dev_map[dev->irq] = 0;
+
+  return 0;
+}
+
+
+/******************************************************
+ *
+ * send a packet to the adapter
+ *
+ ******************************************************/
+
+static int send_packet (elp_device * adapter, unsigned char * ptr, int len)
+
+{
+  int i;
+
+  /*
+   * make sure the length is even and no shorter than 60 bytes
+   */
+  unsigned int nlen = (((len < 60) ? 60 : len) + 1) & (~1);
+
+  /*
+   * send the adapter a transmit packet command. Ignore segment and offset
+   * and make sure the length is even
+   */
+  adapter->tx_pcb.command = CMD_TRANSMIT_PACKET;
+  adapter->tx_pcb.length  = 6;
+  adapter->tx_pcb.data[4] = nlen & 0xff;
+  adapter->tx_pcb.data[5] = nlen >> 8;
+  if (!send_pcb(adapter, &adapter->tx_pcb)) 
+    return FALSE;
+
+  /*
+   * make sure the data register is going the right way
+   */
+  cli(); 
+  OUTB(INB(adapter->io_addr+PORT_CONTROL)&(~CONTROL_DIR), adapter->io_addr+PORT_CONTROL); 
+  sti(); 
+
+  /*
+   * write data to the adapter
+   */
+  for (i = 0; i < (nlen/2);i++) {
+    while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_HRDY) == 0)
+      ;
+    outw(*(short *)ptr, adapter->io_addr+PORT_DATA);
+    ptr +=2;
+  }
+  
+  return TRUE;
+}
+
+/******************************************************
+ *
+ * start the transmitter
+ *    return 0 if sent OK, else return 1
+ *
+ ******************************************************/
+
+static int elp_start_xmit(struct sk_buff *skb, struct device *dev)
+
+{
+  elp_device * adapter = (elp_device *) dev->priv;
+
+  /*
+   * not sure what this does, but the 3c609 driver does it, so...
+   */
+  if (skb == NULL) {
+    dev_tint(dev);
+    return 0;
+  }
+
+  /*
+   * if we ended up with a munged length, don't send it
+   */
+  if (skb->len <= 0)
+    return 0;
+
+  if (elp_debug >= 1)
+    printk("%s: request to send packet of length %i\n", dev->name, skb->len);
+
+  /*
+   * if the transmitter is still busy, we have a transmit timeout...
+   */
+  if (dev->tbusy) {
+    int tickssofar = jiffies - dev->trans_start;
+    if (tickssofar < 500)
+      return 1;
+    printk("%s: transmit timed out, resetting adapter\n", dev->name);
+    if ((INB(adapter->io_addr+PORT_STATUS)&STATUS_ACRF) != 0) 
+      printk("%s: hmmm...seemed to have missed an interrupt!\n", dev->name);
+    adapter_reset(adapter);
+    dev->trans_start = jiffies;
+    dev->tbusy = 0;
+  }
+
+  /*
+   * send the packet at (void *)(skb+1) for skb->len
+   */
+  if (!send_packet(adapter, (unsigned char *)(skb->data), skb->len)) {
+    printk("%s: send packet PCB failed\n", dev->name);
+    return 1;
+  }
+
+  if (elp_debug >= 2)
+    printk("%s: packet of length %i sent\n", dev->name, skb->len);
+
+
+  /*
+   * start the transmit timeout
+   */
+  dev->trans_start = jiffies;
+
+  /*
+   * the transmitter is now busy
+   */
+  dev->tbusy = 1;
+
+  /*
+   * if we have been asked to free the buffer, do so
+   */
+  dev_kfree_skb(skb, FREE_WRITE);
+
+  return 0;
+}
+
+/******************************************************
+ *
+ * return statistics on the board
+ *
+ ******************************************************/
+
+static struct enet_statistics * elp_get_stats(struct device *dev)
+
+{
+  if (elp_debug >= 1)
+    printk("%s: request for stats\n", dev->name);
+
+  elp_device * adapter = (elp_device *) dev->priv;
+  return &adapter->stats;
+}
+
+/******************************************************
+ *
+ * initialise Etherlink Pus board
+ *
+ ******************************************************/
+
+static void elp_init(struct device *dev)
+
+{
+  int i;
+  elp_device * adapter;
+
+  /*
+   * NULL out buffer pointers
+   */
+  for (i = 0; i < DEV_NUMBUFFS; i++)
+    dev->buffs[i] = NULL;
+
+  /*
+   * set ptrs to various functions
+   */
+  dev->open             = elp_open;		/* local */
+  dev->stop             = elp_close;		/* local */
+  dev->get_stats	= elp_get_stats;	/* local */
+  dev->hard_start_xmit  = elp_start_xmit;       /* local */
+
+  dev->hard_header	= eth_header;		/* eth.c */
+  dev->add_arp	        = eth_add_arp;		/* eth.c */
+  dev->rebuild_header	= eth_rebuild_header;	/* eth.c */
+  dev->type_trans	= eth_type_trans;	/* eth.c */
+
+  dev->queue_xmit	= dev_queue_xmit;	/* dev.c */
+
+  /*
+   * setup ptr to adapter specific information
+   */
+  adapter = (elp_device *)(dev->priv = kmalloc(sizeof(elp_device), GFP_KERNEL));
+  adapter->io_addr = dev->base_addr;
+  memset(&(adapter->stats), 0, sizeof(struct enet_statistics));
+
+
+  /*
+   * Ethernet information
+   */
+  dev->type		= ARPHRD_ETHER;
+  dev->hard_header_len  = ETH_HLEN;
+  dev->mtu		= 1500;         /* eth_mtu */
+  dev->addr_len	        = ETH_ALEN;
+  for (i = 0; i < dev->addr_len; i++) 
+    dev->broadcast[i] = 0xff;
+
+  /*
+   * New-style flags. 
+   */
+  dev->flags		= IFF_BROADCAST;
+  dev->family		= AF_INET;
+  dev->pa_addr	        = 0;
+  dev->pa_brdaddr	= 0;
+  dev->pa_mask	        = 0;
+  dev->pa_alen        	= sizeof(unsigned long);
+
+  /*
+   * memory information
+   */
+  dev->mem_start = dev->mem_end = dev->rmem_end = dev->mem_start = 0;
+}
+
+
+/******************************************************
+ *
+ * probe for an Etherlink Plus board at the specified address
+ * by attempting to get the ethernet address. 
+ *
+ ******************************************************/
+
+int elp_probe(struct device *dev)
+
+{
+  elp_device adapter;
+  int            i;
+
+  /*
+   *  setup adapter structure
+   */
+  adapter.io_addr = dev->base_addr;
+
+  printk ("%s: probing for 3c505...", dev->name);
+
+  /*
+   * get the adapter's undivided attention (if it's there!)
+   */
+  adapter_hard_reset(&adapter); 
+
+  /*
+   * use ethernet address command to probe for board in polled mode
+   */
+  adapter.tx_pcb.command = CMD_STATION_ADDRESS;
+  adapter.tx_pcb.length  = 0;
+  if (!send_pcb   (&adapter, &adapter.tx_pcb) ||
+      !receive_pcb(&adapter, &adapter.rx_pcb) ||
+      (adapter.rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
+      (adapter.rx_pcb.length != 6)) {
+    printk("not found\n");
+    return -ENODEV;
+  }
+
+  for (i = 0; i < 6; i++) 
+    dev->dev_addr[i] = adapter.rx_pcb.data[i];
+
+  printk("found at port 0x%x, address = %s\n", dev->base_addr, eth_print(dev->dev_addr));
+  
+  elp_init(dev);
+  return 0;
+}
+
diff -u --recursive --new-file v1.1.21/linux/drivers/net/3c505.h linux/drivers/net/3c505.h
--- v1.1.21/linux/drivers/net/3c505.h	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/3c505.h	Wed Jun 22 17:30:14 1994
@@ -0,0 +1,124 @@
+/*****************************************************************
+ *
+ *  defines for 3Com Etherlink Plus adapter
+ *
+ *****************************************************************/
+
+/*
+ * I/O register offsets
+ */
+#define	PORT_COMMAND	0x00	/* read/write */
+#define	PORT_STATUS	0x02	/* read only */
+#define	PORT_AUXDMA	0x02	/* write only */
+#define	PORT_DATA	0x04	/* read/write */
+#define	PORT_CONTROL	0x06	/* read/write */
+
+/*
+ * host control registers bits
+ */
+#define	CONTROL_ATTN	0x80	/* attention */
+#define	CONTROL_FLSH	0x40	/* flush data register */
+#define CONTROL_DMAE	0x20	/* DMA enable */
+#define CONTROL_DIR	0x10	/* direction */
+#define	CONTROL_TCEN	0x08	/* terminal count interrupt enable */
+#define	CONTROL_CMDE	0x04	/* command register interrupt enable */
+#define	CONTROL_HSF2	0x02	/* host status flag 2 */
+#define	CONTROL_HSF1	0x01	/* host status flag 1 */
+
+/*
+ * combinations of HSF flags used for PCB transmission
+ */
+#define	HSF_PCB_ACK	(CONTROL_HSF1)
+#define	HSF_PCB_NAK	(CONTROL_HSF2)
+#define	HSF_PCB_END	(CONTROL_HSF2|CONTROL_HSF1)
+#define	HSF_PCB_MASK	(CONTROL_HSF2|CONTROL_HSF1)
+
+/*
+ * host status register bits
+ */
+#define	STATUS_HRDY	0x80	/* data register ready */
+#define	STATUS_HCRE	0x40	/* command register empty */
+#define	STATUS_ACRF	0x20	/* adapter command register full */
+#define	STATUS_DIR 	0x10	/* direction */
+#define	STATUS_DONE	0x08	/* DMA done */
+#define	STATUS_ASF3	0x04	/* adapter status flag 3 */
+#define	STATUS_ASF2	0x02	/* adapter status flag 2 */
+#define	STATUS_ASF1	0x01	/* adapter status flag 1 */
+
+/*
+ * combinations of ASF flags used for PCB reception
+ */
+#define	ASF_PCB_ACK	(STATUS_ASF1)
+#define	ASF_PCB_NAK	(STATUS_ASF2)
+#define	ASF_PCB_END	(STATUS_ASF2|STATUS_ASF1)
+#define	ASF_PCB_MASK	(STATUS_ASF2|STATUS_ASF1)
+
+/*
+ * host aux DMA register bits
+ */
+#define	AUXDMA_BRST	0x01	/* DMA burst */
+
+/*
+ * maximum amount of data data allowed in a PCB
+ */
+#define	MAX_PCB_DATA	62
+
+/*****************************************************************
+ *
+ *  timeout value
+ *	this is a rough value used for loops to stop them from 
+ *	locking up the whole machine in the case of failure or
+ *	error conditions
+ *
+ *****************************************************************/
+
+#define	TIMEOUT	10000
+
+/*****************************************************************
+ *
+ * PCB commands
+ *
+ *****************************************************************/
+
+enum {
+  /*
+   * host PCB commands
+   */
+  CMD_CONFIGURE_ADAPTER_MEMORY	= 0x01,
+  CMD_CONFIGURE_82586		= 0x02,
+  CMD_STATION_ADDRESS		= 0x03,
+  CMD_DMA_DOWNLOAD		= 0x04,
+  CMD_DMA_UPLOAD		= 0x05,
+  CMD_PIO_DOWNLOAD		= 0x06,
+  CMD_PIO_UPLOAD		= 0x07,
+  CMD_RECEIVE_PACKET		= 0x08,
+  CMD_TRANSMIT_PACKET		= 0x09,
+  CMD_NETWORK_STATISTICS	= 0x0a,
+  CMD_LOAD_MULTICAST_LIST	= 0x0b,
+  CMD_CLEAR_PROGRAM		= 0x0c,
+  CMD_DOWNLOAD_PROGRAM		= 0x0d,
+  CMD_EXECUTE_PROGRAM		= 0x0e,
+  CMD_SELF_TEST			= 0x0f,
+  CMD_SET_STATION_ADDRESS	= 0x10,
+  CMD_ADAPTER_INFO		= 0x11,
+
+  /*
+   * adapter PCB commands
+   */
+  CMD_CONFIGURE_ADAPTER_RESPONSE	= 0x31,
+  CMD_CONFIGURE_82586_RESPONSE		= 0x32,
+  CMD_ADDRESS_RESPONSE			= 0x33,
+  CMD_DOWNLOAD_DATA_REQUEST		= 0x34,
+  CMD_UPLOAD_DATA_REQUEST		= 0x35,
+  CMD_RECEIVE_PACKET_COMPLETE		= 0x38,
+  CMD_TRANSMIT_PACKET_COMPLETE		= 0x39,
+  CMD_NETWORK_STATISTICS_RESPONSE	= 0x3a,
+  CMD_LOAD_MULTICAST_RESPONSE		= 0x3b,
+  CMD_CLEAR_PROGRAM_RESPONSE		= 0x3c,
+  CMD_DOWNLOAD_PROGRAM_RESPONSE		= 0x3d,
+  CMD_EXECUTE_RESPONSE			= 0x3e,
+  CMD_SELF_TEST_RESPONSE		= 0x3f,
+  CMD_SET_ADDRESS_RESPONSE		= 0x40,
+  CMD_ADAPTER_INFO_RESPONSE		= 0x41
+};
+
diff -u --recursive --new-file v1.1.21/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v1.1.21/linux/drivers/net/3c509.c	Tue Jun 21 14:16:20 1994
+++ linux/drivers/net/3c509.c	Thu Jun 23 23:06:39 1994
@@ -94,7 +94,9 @@
 
 	/* First check for a board on the EISA bus. */
 	if (EISA_bus) {
-		for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
+		static int eisa_addr;
+		for (ioaddr=0x1000 ; ioaddr < 0x9000; ioaddr += 0x1000) {
+			eisa_addr = ioaddr;
 			/* Check the standard EISA ID register for an encoded '3Com'. */
 			if (inw(ioaddr + 0xC80) != 0x6d50)
 				continue;
diff -u --recursive --new-file v1.1.21/linux/drivers/net/ac32000.c linux/drivers/net/ac32000.c
--- v1.1.21/linux/drivers/net/ac32000.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/ac32000.c	Wed Jun 22 17:36:53 1994
@@ -0,0 +1,275 @@
+/* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */
+/*
+	Written 1993, 1994 by Donald Becker.
+	Copyright 1993 United States Government as represented by the Director,
+	National Security Agency.  This software may only be used and distributed
+	according to the terms of the GNU Public License as modified by SRC,
+	incorporated herein by reference.
+
+	The author may be reached as becker@cesdis.gsfc.nasa.gov, or
+	C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
+
+	This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN
+	Adapter.  The programming information is from the users manual, as related
+	by glee@ardnassak.math.clemson.edu.
+  */
+
+static char *version =
+	"ac3200.c:v0.03 2/6/94 Donald Becker (becker@super.org)\n";
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <linux/netdevice.h>
+#include "8390.h"
+
+/* Offsets from the base address. */
+#define AC_NIC_BASE		0x00
+#define AC_SA_PROM		0x16			/* The station address PROM. */
+#define  AC_ADDR0		 0x00			/* Prefix station address values. */
+#define  AC_ADDR1		 0x40			/* !!!!These are just guesses!!!! */
+#define  AC_ADDR2		 0x90
+#define AC_ID_PORT		0xC80
+#define AC_EISA_ID		 0x0110d305
+#define AC_RESET_PORT	0xC84
+#define  AC_RESET		 0x00
+#define  AC_ENABLE		 0x01
+#define AC_CONFIG		0xC90	/* The configuration port. */
+
+/* Decoding of the configuration register. */
+static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3};
+static int addrmap[8] =
+{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000,  0xD0000, 0 };
+static char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
+
+#define config2irq(configval)	config2irqmap[((configval) >> 3) & 7]
+#define config2mem(configval)	addrmap[(configval) & 7]
+#define config2name(configval)	port_name[((configval) >> 6) & 3]
+
+/* First and last 8390 pages. */
+#define AC_START_PG		0x00	/* First page of 8390 TX buffer */
+#define AC_STOP_PG		0x80	/* Last page +1 of the 8390 RX ring */
+
+int ac3200_probe(struct device *dev);
+static int ac_probe1(int ioaddr, struct device *dev);
+
+static int ac_open(struct device *dev);
+static void ac_reset_8390(struct device *dev);
+static int ac_block_input(struct device *dev, int count,
+						  char *buf, int ring_offset);
+static void ac_block_output(struct device *dev, const int count,
+							const unsigned char *buf, const int start_page);
+static int ac_close_card(struct device *dev);
+
+
+/*	Probe for the AC3200.
+
+	The AC3200 can be identified by either the EISA configuration registers,
+	or the unique value in the station address PROM.
+	*/
+
+int ac3200_probe(struct device *dev)
+{
+	unsigned short ioaddr = dev->base_addr;
+
+	if (ioaddr > 0x1ff)		/* Check a single specified location. */
+		return ac_probe1(ioaddr, dev);
+	else if (ioaddr > 0)		/* Don't probe at all. */
+		return ENXIO;
+
+	/* If you have a pre-pl15 machine you should delete this line. */
+	if ( ! EISA_bus)
+		return ENXIO;
+
+	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
+		if (ac_probe1(ioaddr, dev) == 0)
+			return 0;
+
+	return ENODEV;
+}
+
+static int ac_probe1(int ioaddr, struct device *dev)
+{
+	int i;
+
+#ifndef final_version
+	printk("AC3200 ethercard probe at %#3x:", ioaddr);
+
+	for(i = 0; i < 6; i++)
+		printk(" %02x", inb(ioaddr + AC_SA_PROM + i));
+#endif
+
+	/* !!!!The values of AC_ADDRn (see above) should be corrected when we
+	   find out the correct station address prefix!!!! */
+	if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
+		|| inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
+		|| inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
+#ifndef final_version
+		printk(" not found (invalid prefix).\n");
+#endif
+		return ENODEV;
+	}
+
+	/* The correct probe method is to check the EISA ID. */
+	for (i = 0; i < 4; i++)
+		if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
+			printk("EISA ID mismatch, %8x vs %8x.\n",
+				   inl(ioaddr + AC_EISA_ID), AC_EISA_ID); 
+			return ENODEV;
+		}
+
+	for(i = 0; i < ETHER_ADDR_LEN; i++)
+		dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
+
+#ifndef final_version
+	printk("\nAC3200 ethercard configuration register is %#02x,"
+		   " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
+		   inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
+		   inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
+#endif
+
+	/* Assign and snarf the interrupt now. */
+	if (dev->irq == 0)
+		dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
+	else if (dev->irq == 2)
+		dev->irq = 9;
+
+	if (irqaction (dev->irq, &ei_sigaction)) {
+		printk (" unable to get IRQ %d.\n", dev->irq);
+		return 0;
+	}
+
+	dev->base_addr = ioaddr;
+
+#ifdef notyet
+	if (dev->mem_start)	{		/* Override the value from the board. */
+		for (i = 0; i < 7; i++)
+			if (addrmap[i] == dev->mem_start)
+				break;
+		if (i >= 7)
+			i = 0;
+		outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
+	}
+#endif
+
+	dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
+	dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
+	dev->rmem_start = dev->mem_start + TX_PAGES*256;
+	dev->mem_end = dev->rmem_end = dev->mem_start
+		+ (AC_STOP_PG - AC_START_PG)*256;
+
+	ethdev_init(dev);
+
+	ei_status.name = "AC3200";
+	ei_status.tx_start_page = AC_START_PG;
+	ei_status.rx_start_page = AC_START_PG + TX_PAGES;
+	ei_status.stop_page = AC_STOP_PG;
+	ei_status.word16 = 1;
+
+	printk("\n%s: AC3200 at %#x, IRQ %d, %s port, shared memory at %#x-%#x.\n",
+		   dev->name, ioaddr, dev->irq, port_name[dev->if_port],
+		   dev->mem_start, dev->mem_end-1);
+
+	if (ei_debug > 0)
+		printk(version);
+
+	ei_status.reset_8390 = &ac_reset_8390;
+	ei_status.block_input = &ac_block_input;
+	ei_status.block_output = &ac_block_output;
+
+	dev->open = &ac_open;
+	dev->stop = &ac_close_card;
+	NS8390_init(dev, 0);
+	return 0;
+}
+
+static int ac_open(struct device *dev)
+{
+#ifdef notyet
+	/* Someday we may enable the IRQ and shared memory here. */
+	int ioaddr = dev->base_addr;
+
+	if (irqaction(dev->irq, &ei_sigaction))
+		return -EAGAIN;
+#endif
+
+	return ei_open(dev);
+}
+
+static void ac_reset_8390(struct device *dev)
+{
+	ushort ioaddr = dev->base_addr;
+
+	outb(AC_RESET, ioaddr + AC_RESET_PORT);
+	if (ei_debug > 1) printk("resetting AC3200, t=%d...", jiffies);
+
+	ei_status.txing = 0;
+	outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
+	if (ei_debug > 1) printk("reset done\n");
+
+	return;
+}
+
+/*  Block input and output are easy on shared memory ethercards, the only
+	complication is when the ring buffer wraps. */
+
+static int ac_block_input(struct device *dev, int count, char *buf,
+						  int ring_offset)
+{
+	long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
+
+	if (xfer_start + count > dev->rmem_end) {
+		/* We must wrap the input move. */
+		int semi_count = dev->rmem_end - xfer_start;
+		memcpy(buf, (char*)xfer_start, semi_count);
+		count -= semi_count;
+		memcpy(buf + semi_count, (char *)dev->rmem_start, count);
+		return dev->rmem_start + count;
+	}
+	memcpy(buf, (char*)xfer_start, count);
+
+	return ring_offset + count;
+}
+
+static void ac_block_output(struct device *dev, int count,
+							const unsigned char *buf, int start_page)
+{
+	long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
+
+	memcpy((unsigned char *)shmem, buf, count);
+}
+
+static int ac_close_card(struct device *dev)
+{
+	dev->start = 0;
+	dev->tbusy = 1;
+
+	if (ei_debug > 1)
+		printk("%s: Shutting down ethercard.\n", dev->name);
+
+#ifdef notyet
+	/* We should someday disable shared memory and interrupts. */
+	outb(0x00, ioaddr + 6);	/* Disable interrupts. */
+	free_irq(dev->irq);
+	irq2dev_map[dev->irq] = 0;
+#endif
+
+	NS8390_init(dev, 0);
+
+	return 0;
+}
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c"
+ *  version-control: t
+ *  kept-new-versions: 5
+ *  tab-width: 4
+ * End:
+ */
diff -u --recursive --new-file v1.1.21/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v1.1.21/linux/drivers/net/depca.c	Tue Jun 21 14:16:21 1994
+++ linux/drivers/net/depca.c	Wed Jun 22 21:39:50 1994
@@ -21,15 +21,17 @@
 	DE201 Turbo
 	DE202 Turbo (TP BNC)
 	DE210
+	DE422       (EISA)
 
     The  driver has been tested on DE100, DE200 and DE202 cards  in  a
-    relatively busy network.
+    relatively busy network. The DE422 has been tested a little.
 
-    This driver  will  not work  for the DE203,  DE204  and DE205 series  of
-    cards, since they have a new custom ASIC in place of the AMD LANCE chip.
+    This  driver will NOT work   for the DE203,  DE204  and DE205 series  of
+    cards,  since they have  a  new custom ASIC in   place of the AMD  LANCE
+    chip. 
 
     The author may be reached as davies@wanton.lkg.dec.com or
-    Digital Equipment Corporation, 146 Main Street, Maynard MA 01754.
+    Digital Equipment Corporation, 550 King Street, Littleton MA 01460.
 
     =========================================================================
     The driver was based on the 'lance.c' driver from Donald Becker which is
@@ -59,14 +61,15 @@
     the   filter bit   positions  correctly.  Hash   filtering  is  not  yet
     implemented in the current driver set.
 
-    The original DEPCA  card requires that  the ethernet ROM address counter
+    The original DEPCA  card requires that the  ethernet ROM address counter
     be enabled to count and has an 8 bit NICSR.  The ROM counter enabling is
-    only done when  a 0x08 is read as  the first address octet  (to minimise
-    the chances of  writing over some other hardware's  I/O  register).  The
-    size of the NICSR is tested by a word read: if  both bytes are the same,
-    the register  is 8 bits wide.   Also,  there is a   maximum of only 48kB
-    network  RAM for   this card.  My   thanks  to Torbjorn Lindh   for help
-    debugging all this  (and holding  my  feet to the   fire until I got  it
+    only  done when a  0x08 is read as the  first address octet (to minimise
+    the chances  of writing over some  other hardware's  I/O register).  The
+    NICSR accesses   have been changed  to  byte accesses  for all the cards
+    supported by this driver, since there is only one  useful bit in the MSB
+    (remote boot timeout) and it  is not used.  Also, there  is a maximum of
+    only 48kB network  RAM for this  card.  My thanks  to Torbjorn Lindh for
+    help debugging all this (and holding my feet to  the fire until I got it
     right).
 
     The DE200  series  boards have  on-board 64kB  RAM for  use  as a shared
@@ -74,22 +77,26 @@
     mode which has not  been implemented in  this driver (only the 32kB  and
     64kB modes are supported [16kB/48kB for the original DEPCA]).
 
-    At the  most only 2 DEPCA  cards can be supported  because there is only
-    provision for two I/O base addresses on the cards (0x300 and 0x200). The
-    base  address is  'autoprobed' by  looking  for  the self  test PROM and
-    detecting the  card name.  The shared memory  base address is decoded by
-    'autoprobing' the Ethernet PROM address information. The second DEPCA is
-    detected and information placed  in the base_addr  variable of the  next
-    device  structure   (which is created    if  necessary),  thus  enabling
-    ethif_probe initialization for the device.
+    At the most only 2 DEPCA cards can  be supported on  the ISA bus because
+    there is only provision  for two I/O base addresses  on each card (0x300
+    and 0x200). The I/O address is detected by searching for a byte sequence
+    in the Ethernet station address PROM at the expected I/O address for the
+    Ethernet  PROM.   The shared memory  base   address  is 'autoprobed'  by
+    looking  for the self  test PROM  and detecting the  card name.   When a
+    second  DEPCA is  detected,  information  is   placed in the   base_addr
+    variable of the  next device structure (which  is created if necessary),
+    thus  enabling ethif_probe  initialization  for the device.  More than 2
+    EISA cards can  be  supported, but  care will  be  needed assigning  the
+    shared memory to ensure that each slot has the  correct IRQ, I/O address
+    and shared memory address assigned.
 
     ************************************************************************
 
-    NOTE: If you are using two  DEPCAs, it is important  that you assign the
-    base memory addresses  correctly.  The driver  autoprobes I/O 0x300 then
-    0x200.  The base memory  address for the  first device must be less than
-    that of the second so that the auto probe will  correctly assign the I/O
-    and  memory addresses on  the same card.  I can't  think of  a way to do
+    NOTE: If you are using two  ISA DEPCAs, it is  important that you assign
+    the base memory addresses correctly.   The  driver autoprobes I/O  0x300
+    then 0x200.  The  base memory address for  the first device must be less
+    than that of the second so that the auto probe will correctly assign the
+    I/O and memory addresses on the same card.  I can't think of a way to do
     this unambiguously at the moment, since there is nothing on the cards to
     tie I/O and memory information together.
 
@@ -126,12 +133,14 @@
                           Add jabber packet fix from murf@perftech.com
 			  and becker@super.org
       0.34   7-mar-94     Fix DEPCA max network memory RAM & NICSR access.
-      0.35   8-mar-94     Added DE201 recognition.
+      0.35   8-mar-94     Added DE201 recognition. Tidied up.
+      0.351 30-apr-94     Added EISA support. Added DE422 recognition.
+      0.36  16-may-94     DE422 fix released.
 
     =========================================================================
 */
 
-static char *version = "depca.c:v0.35 3/8/94 davies@wanton.lkg.dec.com\n";
+static char *version = "depca.c:v0.36 5/16/94 davies@wanton.lkg.dec.com\n";
 
 #include <stdarg.h>
 #include <linux/config.h>
@@ -148,7 +157,6 @@
 #include <asm/dma.h>
 
 #include <linux/netdevice.h>
-#include "iow.h"                    /* left in for pl13/14 compatibility... */
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include "depca.h"
@@ -159,11 +167,6 @@
 int depca_debug = 1;
 #endif
 
-#ifndef DEPCA_IRQ
-/*#define DEPCA_IRQ	{5,9,10,11,15,0}*/
-#define DEPCA_IRQ	5
-#endif
-
 #ifndef PROBE_LENGTH
 #define PROBE_LENGTH    32
 #endif
@@ -173,7 +176,10 @@
 #endif
 
 #ifndef DEPCA_SIGNATURE
-#define DEPCA_SIGNATURE {"DEPCA","DE100","DE200","DE201","DE202","DE210",""}
+#define DEPCA_SIGNATURE {"DEPCA","DE100",\
+                         "DE200","DE201","DE202","DE210",\
+                         "DE422",\
+                         ""}
 #define DEPCA_NAME_LENGTH 8
 #endif
 
@@ -195,6 +201,14 @@
 #define MAX_NUM_DEPCAS 2
 #endif
 
+#ifndef DEPCA_EISA_IO_PORTS 
+#define DEPCA_EISA_IO_PORTS 0x0c00       /* I/O port base address, slot 0 */
+#endif
+
+#ifndef MAX_EISA_SLOTS
+#define MAX_EISA_SLOTS 8
+#endif
+
 /*
 ** Set the number of Tx and Rx buffers. 
 */
@@ -230,8 +244,8 @@
     short misc;                 /* Errors and TDR info */
 };
 
-struct depca_ring_info {
-};
+#define LA_MASK 0x0000ffff      /* LANCE address mask for mapping network RAM
+				   to LANCE memory address space */
 
 /*
 ** The Lance initialization block, described in databook, in common memory.
@@ -249,6 +263,7 @@
     struct depca_rx_head *rx_ring; /* Pointer to start of RX descriptor ring */
     struct depca_tx_head *tx_ring; /* Pointer to start of TX descriptor ring */
     struct depca_init	init_block;/* Initialization block */
+    long bus_offset;            /* (E)ISA bus address offset vs LANCE */
     long dma_buffs;		/* Start address of Rx and Tx buffers. */
     int	cur_rx, cur_tx;		/* The next free ring entry */
     int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
@@ -287,8 +302,10 @@
 #ifdef HAVE_MULTICAST
 static void SetMulticastFilter(int num_addrs, char *addrs, char *multicast_table);
 #endif
+static struct device *isa_probe(struct device *dev);
+static struct device *eisa_probe(struct device *dev);
+static struct device *alloc_device(struct device *dev, int ioaddr);
 
-static int depca_na;
 static int num_depcas = 0, num_eth = 0;;
 
 /*
@@ -298,96 +315,26 @@
     outw(CSR0, DEPCA_ADDR);\
     outw(STOP, DEPCA_DATA)
 
-#define GET_NICSR(a,b) \
-    if (depca_na) { \
-      (a) = inw((b)); \
-    } else { \
-      (a) = inb((b)); \
-    }
-
-#define PUT_NICSR(a,b) \
-    if (depca_na) { \
-      outw((a), (b)); \
-    } else { \
-      outb((a), (b)); \
-    }
 
-
 
 
 int depca_probe(struct device *dev)
 {
-    int *port, ports[] = DEPCA_IO_PORTS;
     int base_addr = dev->base_addr;
-    int status;
-    struct device *eth0 = (struct device *) NULL;
+    int status = -ENODEV;
+    struct device *eth0;
 
     if (base_addr > 0x1ff) {	      /* Check a single specified location. */
-      status = -ENODEV;
       if (DevicePresent(base_addr) == 0) { /* Is DEPCA really here? */
 	status = depca_probe1(dev, base_addr);
       }
     } else if (base_addr > 0) {	      /* Don't probe at all. */
-		status = -ENXIO;
+      status = -ENXIO;
     } else {                          /* First probe for the DEPCA test */
                                       /* pattern in ROM */
-
-      for (status = -ENODEV, port = &ports[0]; 
-	                    *port && (num_depcas < MAX_NUM_DEPCAS); port++) {
-	int ioaddr = *port;
-
-#ifdef HAVE_PORTRESERVE
-	if (check_region(ioaddr, DEPCA_TOTAL_SIZE))
-	    continue;
-#endif
-	if (DevicePresent(ioaddr) == 0) {
-	  if (num_depcas > 0) {        /* only gets here in autoprobe */
-
-	    /*
-	    ** Check the device structures for an end of list or unused device
-	    */
-	    while (dev->next != (struct device *)NULL) {
-	      if (dev->next->base_addr == 0xffe0) break;
-	      dev = dev->next;         /* walk through eth device list */
-	      num_eth++;               /* increment eth device number */
-	    }
-
-	    /*
-	    ** If no more device structures, malloc one up. If memory could
-	    ** not be allocated, print an error message.
-	    ** 
-	    */
-	    if (dev->next == (struct device *)NULL) {
-	      dev->next = (struct device *)kmalloc(sizeof(struct device) + 8,
-                                                                  GFP_KERNEL);
-	    } else {
-	      printk("eth%d: Device not initialised, insufficient memory\n",
-		                                                      num_eth);
-	    }
-
-	    /*
-	    ** If the memory was allocated, point to the new memory area
-	    ** and initialize it (name, I/O address, next device (NULL) and
-	    ** initialisation probe routine).
-	    */
-	    if ((dev->next != (struct device *)NULL) &&
-		(num_eth > 0) && (num_eth < 9999)) {
-	      dev = dev->next;         /* point to the new device */
-	      dev->name = (char *)(dev + sizeof(struct device));
-	      sprintf(dev->name,"eth%d", num_eth); /* New device name */
-	      dev->base_addr = ioaddr; /* assign the io address */
-	      dev->next = (struct device *)NULL; /* mark the end of list */
-	      dev->init = &depca_probe;/* initialisation routine */
-	    }
-	  } else {
-	    eth0 = dev;                /* remember the first device */
-	    status = depca_probe1(dev, ioaddr);
-	  }
-	  num_depcas++;
-	  num_eth++;
-	}
-      }
-      if (eth0) dev = eth0;             /* restore the first device */
+      eth0=isa_probe(dev);
+      eth0=eisa_probe(eth0);
+      if (dev->priv) status=0;
     }
 
     if (status) dev->base_addr = base_addr;
@@ -406,14 +353,13 @@
 
 
     /*
-    ** Stop the DEPCA. Enable the DBR ROM and the ethernet ROM address counter
-    ** (for the really old DEPCAs). Disable interrupts and remote boot.
+    ** Stop the DEPCA. Enable the DBR ROM. Disable interrupts and remote boot.
     */
     STOP_DEPCA;
 
-    GET_NICSR(nicsr, DEPCA_NICSR);
-    nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | AAC | IM);
-    PUT_NICSR(nicsr, DEPCA_NICSR);
+    nicsr = inb(DEPCA_NICSR);
+    nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
+    outb(nicsr, DEPCA_NICSR);
 
     if (inw(DEPCA_DATA) == STOP) {
 
@@ -436,11 +382,16 @@
 	}
       }
 
-      if (*name != (char)NULL) {          /* found a DEPCA device */
+      if (*name != (char)NULL) {             /* found a DEPCA device */
 	mem_start = mem_base[i];
 	dev->base_addr = ioaddr;
 
-	printk("%s: DEPCA at %#3x is a %s, ", dev->name, ioaddr, name);
+	if ((ioaddr&0x0fff)==DEPCA_EISA_IO_PORTS) {/* EISA slot address */
+	  printk("%s: %s at %#3x (EISA slot %d)", 
+		                 dev->name, name, ioaddr, ((ioaddr>>12)&0x0f));
+	} else {                             /* ISA port address */
+	  printk("%s: %s at %#3x", dev->name, name, ioaddr);
+	}
 
       /* There is a 32 byte station address PROM at DEPCA_PROM address.
 	 The first six bytes are the station address. They can be read
@@ -457,7 +408,7 @@
 	  j = 0;
 	}
 
-	printk("ethernet address ");
+	printk(", h/w address ");
 	for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet address */
 	  printk("%2.2x:", dev->dev_addr[i] = inb(DEPCA_PROM + j));
 	}
@@ -481,27 +432,32 @@
 	}
 
 	/* 
-	 ** Determine the base address for the DEPCA RAM from the NI-CSR
-	 ** and make up a DEPCA-specific-data structure. 
+	** Determine the base address for the DEPCA RAM from the NI-CSR
+	** and make up a DEPCA-specific-data structure. 
         */
 
 	if (nicsr & BUF) {
 	  offset = 0x8000;              /* 32kbyte RAM offset*/
 	  nicsr &= ~BS;                 /* DEPCA RAM in top 32k */
-	  printk(",\n      with %dkB RAM", netRAM-(offset >> 10));
+	  printk(",\n      has %dkB RAM", netRAM - 32);
+	} else 	if ((nicsr & _128KB) && (netRAM!=48)) {
+	  offset = 0x0000;
+	  printk(",\n      has 128kB RAM");
 	} else {
 	  offset = 0x0000;              /* 64k/48k bytes RAM */
-	  printk(",\n      with %dkB RAM", netRAM);
+	  printk(",\n      has %dkB RAM", netRAM);
 	}
 
-	mem_start += offset;
-	printk(" starting at 0x%.5lx", mem_start);
+	mem_start += offset;            /* (E)ISA start address */
+	printk(" at 0x%.5lx", mem_start);
 
 	/*
-	 ** Enable the shadow RAM.
+	** Enable the shadow RAM.
 	*/
-	nicsr |= SHE;
-	PUT_NICSR(nicsr, DEPCA_NICSR);
+	if (strstr(name,"DEPCA")==(char *)NULL) {
+	  nicsr |= SHE;
+	  outb(nicsr, DEPCA_NICSR);
+	}
  
 	/*
 	** Calculate the ring size based on the available RAM
@@ -551,12 +507,15 @@
 	lp->tx_ring = (struct depca_tx_head *)mem_start;
 
 	mem_start += (sizeof(struct depca_tx_head) * j);
-	lp->dma_buffs = mem_start & 0x00ffffff;
+	lp->bus_offset = mem_start & 0x00ff0000;
+	mem_start &= LA_MASK;           /* LANCE re-mapped start address */
+
+	lp->dma_buffs = mem_start;
 
 	mem_start += (PKT_BUF_SZ * j);
 	/* (mem_start now points to the start of the Tx buffers) */
 
-	/* Initialise the data structures */
+	/* Initialise the data structures wrt CPU */
 	memset(lp->rx_ring, 0, sizeof(struct depca_rx_head)*j);
 	memset(lp->tx_ring, 0, sizeof(struct depca_tx_head)*j);
 
@@ -593,15 +552,10 @@
 	LoadCSRs(dev);
 
 	/*
-	** Store the NICSR width for this DEPCA
-	*/
-	lp->depca_na = depca_na;
-
-	/*
 	** Enable DEPCA board interrupts for autoprobing
 	*/
 	nicsr = ((nicsr & ~IM)|IEN);
-	PUT_NICSR(nicsr, DEPCA_NICSR);
+	outb(nicsr, DEPCA_NICSR);
 
 	/* The DMA channel may be passed in on this parameter. */
 	dev->dma = 0;
@@ -616,13 +570,13 @@
 	  
 	  dev->irq = autoirq_report(1);
 	  if (dev->irq) {
-	    printk(" and probed IRQ%d.\n", dev->irq);
+	    printk(" and uses IRQ%d.\n", dev->irq);
 	  } else {
-	    printk(". Failed to detect IRQ line.\n");
+	    printk(" and failed to detect IRQ line.\n");
 	    status = -EAGAIN;
 	  }
 	} else {
-	  printk(". Assigned IRQ%d.\n", dev->irq);
+	  printk(" and assigned IRQ%d.\n", dev->irq);
 	}
       } else {
 	status = -ENXIO;
@@ -644,7 +598,7 @@
 	dev->mem_start = 0;
 	
 	/* Fill in the generic field of the device structure. */
-	ether_setup(dev);
+ 	ether_setup(dev);
       }
     } else {
       status = -ENXIO;
@@ -670,9 +624,8 @@
     /*
     ** Stop the DEPCA & get the board status information.  
     */
-    depca_na=lp->depca_na;
     STOP_DEPCA;
-    GET_NICSR(nicsr, DEPCA_NICSR);
+    nicsr = inb(DEPCA_NICSR);
 
     /* 
     ** Re-initialize the DEPCA... 
@@ -723,7 +676,7 @@
     ** Enable DEPCA board interrupts
     */
     nicsr = ((nicsr & ~IM & ~LED)|SHE|IEN);
-    PUT_NICSR(nicsr, DEPCA_NICSR);
+    outb(nicsr, DEPCA_NICSR);
     outw(CSR0,DEPCA_ADDR);
 
     dev->tbusy = 0;                         
@@ -734,8 +687,7 @@
 
     if (depca_debug > 1){
       printk("CSR0: 0x%4.4x\n",inw(DEPCA_DATA));
-      GET_NICSR(nicsr, DEPCA_NICSR);
-      printk("nicsr: 0x%4.4x\n",nicsr);
+      printk("nicsr: 0x%02x\n",inb(DEPCA_NICSR));
     }
 
     return 0;			          /* Always succeed */
@@ -767,8 +719,8 @@
     for (i = 0; i < 4; i++) {
       lp->init_block.filter[i] = 0x0000;
     }
-    lp->init_block.rx_ring = (unsigned long)lp->rx_ring | lp->rlen;
-    lp->init_block.tx_ring = (unsigned long)lp->tx_ring | lp->rlen;
+    lp->init_block.rx_ring = ((unsigned long)lp->rx_ring & LA_MASK) | lp->rlen;
+    lp->init_block.tx_ring = ((unsigned long)lp->tx_ring & LA_MASK) | lp->rlen;
 
     lp->init_block.mode = 0x0000;            /* Enable the Tx and Rx */ 
 }
@@ -789,10 +741,10 @@
       if (tickssofar < 10) {
 	status = -1;
       } else {
-	STOP_DEPCA;
-	printk("%s: transmit timed out, status %4.4x, resetting.\n",
+	printk("%s: transmit timed out, status %04x, resetting.\n",
 	       dev->name, inw(DEPCA_DATA));
 	
+	STOP_DEPCA;
 	depca_init_ring(dev);
 	LoadCSRs(dev);
 	InitRestartDepca(dev);
@@ -835,7 +787,8 @@
       char *p = (char *) skb->data;
 
       entry &= lp->rmask;  		    /* Ring around buffer number. */
-      buf = (unsigned char *)(lp->tx_ring[entry].base & 0x00ffffff);
+      buf = (unsigned char *)((lp->tx_ring[entry].base+lp->bus_offset) & 
+			                                           0x00ffffff);
 
       /* Wait for a full ring to free up */
       while (lp->tx_ring[entry].base < 0);
@@ -870,7 +823,8 @@
 	/* Get new buffer pointer */
 	entry = lp->cur_tx++;
 	entry &= lp->rmask;  		    /* Ring around buffer number. */
-	buf = (unsigned char *)(lp->tx_ring[entry].base & 0x00ffffff);
+	buf = (unsigned char *)((lp->tx_ring[entry].base+lp->bus_offset) &
+				                                   0x00ffffff);
 
 	/* Wait for a full ring to free up */
 	while (lp->tx_ring[entry].base < 0);
@@ -898,7 +852,8 @@
 
       if (depca_debug > 4) {
 	unsigned char *pkt =
-	  (unsigned char *)(lp->tx_ring[entry].base & 0x00ffffff);
+	  (unsigned char *)((lp->tx_ring[entry].base+lp->bus_offset) &
+			                                           0x00ffffff);
 
 	printk("%s: tx ring[%d], %#lx, sk_buf %#lx len %d.\n",
 	       dev->name, entry, (unsigned long) &lp->tx_ring[entry],
@@ -933,54 +888,52 @@
 
     if (dev == NULL) {
 	printk ("depca_interrupt(): irq %d for unknown device.\n", irq);
-	return;
     } else {
       lp = (struct depca_private *)dev->priv;
       ioaddr = dev->base_addr;
-      depca_na = lp->depca_na;
-    }
 
-    if (dev->interrupt)
+      if (dev->interrupt)
 	printk("%s: Re-entering the interrupt handler.\n", dev->name);
 
-    dev->interrupt = MASK_INTERRUPTS;
+      dev->interrupt = MASK_INTERRUPTS;
 
-    /* mask the DEPCA board interrupts and turn on the LED */
-    GET_NICSR(nicsr, DEPCA_NICSR);
-    nicsr |= (IM|LED);
-    PUT_NICSR(nicsr, DEPCA_NICSR);
+      /* mask the DEPCA board interrupts and turn on the LED */
+      nicsr = inb(DEPCA_NICSR);
+      nicsr |= (IM|LED);
+      outb(nicsr, DEPCA_NICSR);
 
-    outw(CSR0, DEPCA_ADDR);
-    csr0 = inw(DEPCA_DATA);
+      outw(CSR0, DEPCA_ADDR);
+      csr0 = inw(DEPCA_DATA);
 
-    /* Acknowledge all of the current interrupt sources ASAP. */
-    outw(csr0 & ~(INEA|TDMD|STOP|STRT|INIT), DEPCA_DATA);
+      /* Acknowledge all of the current interrupt sources ASAP. */
+      outw(csr0 & ~(INEA|TDMD|STOP|STRT|INIT), DEPCA_DATA);
 
-    if (depca_debug > 5)
+      if (depca_debug > 5)
 	printk("%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
 	       dev->name, csr0, inw(DEPCA_DATA));
 
-    if (csr0 & RINT)		/* Rx interrupt (packet arrived) */
+      if (csr0 & RINT)		/* Rx interrupt (packet arrived) */
 	depca_rx(dev);
 
-    if (csr0 & TINT) 	        /* Tx interrupt (packet sent) */
+      if (csr0 & TINT) 	        /* Tx interrupt (packet sent) */
         depca_tx(dev);
 
-    /* Clear the interrupts we've handled. */
-    outw(CSR0, DEPCA_ADDR);
-    outw(BABL|CERR|MISS|MERR|RINT|TINT|IDON|INEA, DEPCA_DATA);
+      /* Clear the interrupts we've handled. */
+      outw(CSR0, DEPCA_ADDR);
+      outw(BABL|CERR|MISS|MERR|RINT|TINT|IDON|INEA, DEPCA_DATA);
 
-    if (depca_debug > 4) {
-      printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
-	     dev->name, inw(DEPCA_ADDR),
-	     inw(DEPCA_DATA));
-    }
+      if (depca_debug > 4) {
+	printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
+	       dev->name, inw(DEPCA_ADDR),
+	       inw(DEPCA_DATA));
+      }
 
-    /* Unmask the DEPCA board interrupts and turn off the LED */
-    nicsr = (nicsr & ~IM & ~LED);
-    PUT_NICSR(nicsr, DEPCA_NICSR);
+      /* Unmask the DEPCA board interrupts and turn off the LED */
+      nicsr = (nicsr & ~IM & ~LED);
+      outb(nicsr, DEPCA_NICSR);
+      dev->interrupt = UNMASK_INTERRUPTS;
+    }
 
-    dev->interrupt = UNMASK_INTERRUPTS;
     return;
 }
 
@@ -1036,7 +989,8 @@
 	    skb->len = pkt_len;
 	    skb->dev = dev;
 	    memcpy(skb->data,
-		   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
+		  (unsigned char *)((lp->rx_ring[entry].base+lp->bus_offset) &
+				                                   0x00ffffff),
 		   pkt_len);
 	    /* 
 	    ** Notify the upper protocol layers that there is another 
@@ -1146,9 +1100,11 @@
   int ioaddr = dev->base_addr;
 
   outw(CSR1, DEPCA_ADDR);                /* initialisation block address LSW */
-  outw((unsigned short)(unsigned long)&lp->init_block, DEPCA_DATA);
+  outw((unsigned short)((unsigned long)(&lp->init_block) & LA_MASK), 
+                                                                   DEPCA_DATA);
   outw(CSR2, DEPCA_ADDR);                /* initialisation block address MSW */
-  outw((unsigned short)((unsigned long)&lp->init_block >> 16), DEPCA_DATA);
+  outw((unsigned short)(((unsigned long)(&lp->init_block) & LA_MASK) >> 16), 
+                                                                   DEPCA_DATA);
   outw(CSR3, DEPCA_ADDR);                /* ALE control */
   outw(ACON, DEPCA_DATA);
   outw(CSR0, DEPCA_ADDR);                /* point back to CSR0 */
@@ -1274,6 +1230,118 @@
 #endif  /* HAVE_MULTICAST */
 
 /*
+** ISA bus I/O device probe
+*/
+static struct device *isa_probe(dev)
+struct device *dev;
+{
+  int *port, ports[] = DEPCA_IO_PORTS;
+  int status;
+
+  for (status = -ENODEV, port = &ports[0]; 
+                             *port && (num_depcas < MAX_NUM_DEPCAS); port++) {
+    int ioaddr = *port;
+
+#ifdef HAVE_PORTRESERVE
+    if (check_region(ioaddr, DEPCA_TOTAL_SIZE))
+	    continue;
+#endif
+
+    if (DevicePresent(ioaddr) == 0) {
+      if (num_depcas > 0) {        /* only gets here in autoprobe */
+	dev = alloc_device(dev, ioaddr);
+      } else {
+	if ((status = depca_probe1(dev, ioaddr)) == 0) {
+	  num_depcas++;
+	}
+      }
+      num_eth++;
+    }
+  }
+  return dev;
+}
+
+/*
+** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
+** the motherboard.
+*/
+static struct device *eisa_probe(dev)
+struct device *dev;
+{
+  int i, ioaddr = DEPCA_EISA_IO_PORTS;
+  int status;
+
+  ioaddr+=0x1000;                         /* get the first slot address */
+  for (status = -ENODEV, i=1; i<MAX_EISA_SLOTS; i++, ioaddr+=0x1000) {
+
+#ifdef HAVE_PORTRESERVE
+    if (check_region(ioaddr, DEPCA_TOTAL_SIZE))
+	    continue;
+#endif
+    if (DevicePresent(ioaddr) == 0) {
+      if (num_depcas > 0) {        /* only gets here in autoprobe */
+	dev = alloc_device(dev, ioaddr);
+      } else {
+	if ((status = depca_probe1(dev, ioaddr)) == 0) {
+	  num_depcas++;
+	}
+      }
+      num_eth++;
+    }
+  }
+  return dev;
+}
+
+/*
+** Allocate the device by pointing to the next available space in the
+** device structure. Should one not be available, it is created.
+*/
+static struct device *alloc_device(dev, ioaddr)
+struct device *dev;
+int ioaddr;
+{
+  /*
+  ** Check the device structures for an end of list or unused device
+  */
+  while (dev->next != (struct device *)NULL) {
+    if (dev->next->base_addr == 0xffe0) break;
+    dev = dev->next;         /* walk through eth device list */
+    num_eth++;               /* increment eth device number */
+  }
+
+  /*
+  ** If no more device structures, malloc one up. If memory could
+  ** not be allocated, print an error message.
+  */
+  if (dev->next == (struct device *)NULL) {
+    dev->next = (struct device *)kmalloc(sizeof(struct device) + 8,
+					 GFP_KERNEL);
+    if (dev->next == (struct device *)NULL) {
+      printk("eth%d: Device not initialised, insufficient memory\n",
+	     num_eth);
+    }
+  }
+  
+  /*
+  ** If the memory was allocated, point to the new memory area
+  ** and initialize it (name, I/O address, next device (NULL) and
+  ** initialisation probe routine).
+  */
+  if ((dev->next != (struct device *)NULL) &&
+      (num_eth > 0) && (num_eth < 9999)) {
+    dev = dev->next;                    /* point to the new device */
+    dev->name = (char *)(dev + sizeof(struct device));
+    sprintf(dev->name,"eth%d", num_eth);/* New device name */
+    dev->base_addr = ioaddr;            /* assign the io address */
+    dev->next = (struct device *)NULL;  /* mark the end of list */
+    dev->init = &depca_probe;           /* initialisation routine */
+    num_depcas++;
+  }
+
+  return dev;
+}
+
+/*
 ** Look for a particular board name in the on-board Remote Diagnostics
 ** and Boot (RDB) ROM. This will also give us a clue to the network RAM
 ** base address.
@@ -1315,9 +1383,7 @@
 ** messing around with some other hardware, but it assumes that this DEPCA
 ** card initialized itself correctly. It also assumes that all past and
 ** future DEPCA/EtherWORKS cards will have ethernet addresses beginning with
-** a 0x08. The choice of byte or word addressing is made here based on whether
-** word read of the NICSR returns two identical lower and upper bytes: if so
-** the register is 8 bits wide.
+** a 0x08.
 */
 
 static int DevicePresent(short ioaddr)
@@ -1325,7 +1391,6 @@
   static short fp=1,sigLength=0;
   static char devSig[] = PROBE_SEQUENCE;
   char data;
-  unsigned char LSB,MSB;
   int i, j, nicsr, status = 0;
   static char asc2hex(char value);
 
@@ -1337,26 +1402,12 @@
   data = inb(DEPCA_PROM);                /* read data */
 
 /*
-** Determine whether a byte or word access should be made on the NICSR.
-** Since the I/O 'functions' are actually in-line code, the choice not to use
-** pointers to functions vs. just set a conditional, is made for us. This code
-** assumes that the NICSR has an asymmetric bit pattern already in it.
-*/
-  nicsr = inw(DEPCA_NICSR);
-  LSB = nicsr & 0xff;
-  MSB = (((unsigned) nicsr) >> 8) & 0xff;
-  if (MSB == LSB) {
-    depca_na = 0;        /* byte accesses */
-  } else {
-    depca_na = 1;        /* word accesses */
-  }
-
-/*
 ** Enable counter
 */
   if (data == 0x08) {
+    nicsr = inb(DEPCA_NICSR);
     nicsr |= AAC;
-    PUT_NICSR(nicsr, DEPCA_NICSR);
+    outb(nicsr, DEPCA_NICSR);
   }
   
 /* 
@@ -1382,7 +1433,7 @@
 /* 
 ** Search the Ethernet address ROM for the signature. Since the ROM address
 ** counter can start at an arbitrary point, the search must include the entire
-** probe sequence length plus the length of the (signature - 1).
+** probe sequence length plus the (length_of_the_signature - 1).
 ** Stop the search IMMEDIATELY after the signature is found so that the
 ** PROM address counter is correctly positioned at the start of the
 ** ethernet address for later read out.
diff -u --recursive --new-file v1.1.21/linux/drivers/net/depca.h linux/drivers/net/depca.h
--- v1.1.21/linux/drivers/net/depca.h	Tue Apr 19 10:52:45 1994
+++ linux/drivers/net/depca.h	Wed Jun 22 21:39:50 1994
@@ -14,7 +14,9 @@
 #define DEPCA_RBI   ioaddr+0x02   /* RAM buffer index (2k buffer mode) */
 #define DEPCA_DATA  ioaddr+0x04   /* LANCE registers' data port */
 #define DEPCA_ADDR  ioaddr+0x06   /* LANCE registers' address port */
+#define DEPCA_HBASE ioaddr+0x08   /* EISA high memory base address reg. */
 #define DEPCA_PROM  ioaddr+0x0c   /* Ethernet address ROM data port */
+#define DEPCA_CNFG  ioaddr+0x0c   /* EISA Configuration port */
 #define DEPCA_RBSA  ioaddr+0x0e   /* RAM buffer starting address (2k buff.) */
 
 /*
@@ -35,6 +37,7 @@
 #define BUF      	0x0020	/* BUFfer size (1->32k, 0->64k) */
 #define RBE      	0x0010	/* Remote Boot Enable (1->net boot) */
 #define AAC      	0x0008  /* Address ROM Address Counter (1->enable) */
+#define _128KB      	0x0008  /* 128kB Network RAM (1->enable) */
 #define IM       	0x0004	/* Interrupt Mask (1->mask) */
 #define IEN      	0x0002	/* Interrupt tristate ENable (1->enable) */
 #define LED      	0x0001	/* LED control */
@@ -119,6 +122,20 @@
 #define TMD3_LCAR    0x0800	/* Loss of CARrier */
 #define TMD3_RTRY    0x0400	/* ReTRY error */
 
+/* 
+** EISA configuration Register (CNFG) bit definitions 
+*/
+ 
+#define TIMEOUT       	0x0100	/* 0:2.5 mins, 1: 30 secs */
+#define REMOTE      	0x0080  /* Remote Boot Enable -> 1 */
+#define IRQ11       	0x0040  /* Enable -> 1 */
+#define IRQ10    	0x0020	/* Enable -> 1 */
+#define IRQ9    	0x0010	/* Enable -> 1 */
+#define IRQ5      	0x0008  /* Enable -> 1 */
+#define BUFF     	0x0004	/* 0: 64kB or 128kB, 1: 32kB */
+#define PADR16   	0x0002	/* RAM on 64kB boundary */
+#define PADR17    	0x0001	/* RAM on 128kB boundary */
+
 /*
 ** Miscellaneous
 */
@@ -126,3 +143,6 @@
 #define MASK_INTERRUPTS   1
 #define UNMASK_INTERRUPTS 0
 
+#define EISA_EN         0x0001   /* Enable EISA bus buffers */
+#define DEPCA_EISA_ID   ioaddr+0x80   /* ID long word for EISA card */
+#define DEPCA_EISA_CTRL ioaddr+0x84   /* Control word for EISA card */
diff -u --recursive --new-file v1.1.21/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v1.1.21/linux/drivers/net/e2100.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/e2100.c	Wed Jun 22 17:38:02 1994
@@ -0,0 +1,341 @@
+/* e2100.c: A Cabletron E2100 series ethernet driver for linux. */
+/*
+    Written 1993 by Donald Becker.
+    Copyright 1993 United States Government as represented by the
+    Director, National Security Agency.  This software may be used and
+    distributed according to the terms of the GNU Public License,
+    incorporated herein by reference.
+
+    This is a driver for the Cabletron E2100 series ethercards.
+
+    The Author may be reached as becker@cesdis.gsfc.nasa.gov, or
+    C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
+
+	The E2100 series ethercard is a fairly generic shared memory 8390
+	implementation.  The only unusual aspect is the way the shared memory
+	registers are set: first you do an inb() in what is normally the
+	station address region, and the low four bits of next outb() is used
+	as the write value for that register.  Either someone wasn't too used
+	to dem bit en bites, or they were trying to obfusicate the programming
+	interface.
+
+	There is an additional complication when setting the window on the packet
+	buffer.  You must first do a read into the packet buffer region with the
+	low 8 address bits the address setting the page for the start of the packet
+	buffer window, and then do the above operation.  See mem_on() for details.
+
+	One bug on the chip is that even a hard reset won't disable the memory
+	window, usually resulting in a hung machine if mem_off() isn't called.
+	If this happens, you must power down the machine for about 30 seconds.
+*/
+
+static char *version =
+    "e2100.c:v0.01 11/21/93 Donald Becker (becker@super.org)\n";
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#ifndef PRE_PL13
+#include <linux/ioport.h>       /* Delete if your kernel doesn't have it. */
+#endif
+
+#include <linux/netdevice.h>
+#include "8390.h"
+
+/* Compatibility definitions for earlier kernel versions. */
+#ifndef HAVE_PORTRESERVE
+#define check_region(ioaddr, size)              0
+#define snarf_region(ioaddr, size);             do ; while (0)
+#endif
+#ifndef HAVE_AUTOIRQ
+/* From auto_irq.c, in ioport.h for later versions. */
+extern void autoirq_setup(int waittime);
+extern int autoirq_report(int waittime);
+/* The map from IRQ number (as passed to the interrupt handler) to
+   'struct device'. */
+extern struct device *irq2dev_map[16];
+#endif
+
+/* Offsets from the base_addr.
+   Read from the ASIC register, and the low 3(?) bits of the next outb() address
+   is used to set the cooresponding register. */
+#define E21_NIC_OFFSET  0       /* Offset to the 8390 NIC. */
+#define E21_ASIC		0x10
+#define E21_MEM_ENABLE	0x10
+#define  E21_MEM_ON		0x05	/* Enable memory in 16 bit mode. */
+#define  E21_MEM_ON_8	0x07	/* Enable memory in  8 bit mode. */
+#define E21_MEM_BASE	0x11	
+#define E21_IRQ_LOW		0x12	/* The low three bits of the IRQ number. */
+#define E21_IRQ_HIGH	0x14	/* The high IRQ bit, and ...  */
+#define  E21_ALT_IFPORT 0x02	/* Set to use the other (BNC,AUI) port. */
+#define  E21_BIG_MEM	0x04	/* Use a bigger (64K) buffer (we don't) */
+#define E21_SAPROM      0x10    /* Offset to station address data. */
+#define ETHERCARD_TOTAL_SIZE    0x20
+
+extern inline void mem_on(short port, volatile char *mem_base,
+						  unsigned char start_page )
+{
+	/* This is a little weird: set the shared memory window by doing a
+	   read.  The low address bits specify the starting page. */
+	mem_base[start_page];
+	inb(port + E21_MEM_ENABLE);
+	outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
+}
+
+extern inline void mem_off(short port)
+{
+	inb(port + E21_MEM_ENABLE);
+	outb(0x00, port + E21_MEM_ENABLE);
+}
+
+/* In other drivers I put the TX pages first, but the E2100 window circuitry
+   is designed to have a 4K Tx region last. The windowing circuitry wraps the
+   window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring
+   appear contiguously in the window. */
+#define E21_RX_START_PG    0x00    /* First page of RX buffer */
+#define E21_RX_STOP_PG     0x30    /* Last page +1 of RX ring */
+#define E21_BIG_RX_STOP_PG 0xF0    /* Last page +1 of RX ring */
+#define E21_TX_START_PG  E21_RX_STOP_PG    /* First page of TX buffer */
+
+int e2100_probe(struct device *dev);
+int e21_probe1(struct device *dev, int ioaddr);
+
+static int e21_open(struct device *dev);
+static void e21_reset_8390(struct device *dev);
+static int e21_block_input(struct device *dev, int count,
+                          char *buf, int ring_offset);
+static void e21_block_output(struct device *dev, int count,
+                            const unsigned char *buf, const start_page);
+static int e21_close(struct device *dev);
+
+
+/*  Probe for the E2100 series ethercards.  These cards have an 8390 at the
+	base address and the station address at both offset 0x10 and 0x18.  I read
+	the station address from offset 0x18 to avoid the dataport of NE2000
+	ethercards, and look for Ctron's unique ID (first three octets of the
+	station address).
+ */
+
+int e2100_probe(struct device *dev)
+{
+    int *port, ports[] = {0x300, 0x280, 0x380, 0x220, 0};
+    short base_addr = dev->base_addr;
+
+    if (base_addr > 0x1ff)              /* Check a single specified location. */
+        return e21_probe1(dev, base_addr);
+    else if (base_addr > 0)             /* Don't probe at all. */
+        return ENXIO;
+
+    for (port = &ports[0]; *port; port++) {
+        ushort ioaddr = *port;
+
+        if (check_region(ioaddr, ETHERCARD_TOTAL_SIZE))
+            continue;
+        if (inb(ioaddr + E21_SAPROM + 0) == 0x00
+			&& inb(ioaddr + E21_SAPROM + 1) == 0x00
+			&& inb(ioaddr + E21_SAPROM + 2) == 0x1d
+            && e21_probe1(dev, ioaddr) == 0)
+            return 0;
+    }
+    return -ENODEV;
+}
+
+int e21_probe1(struct device *dev, int ioaddr)
+{
+	int i, status;
+	unsigned char *station_addr = dev->dev_addr;
+
+	/* We've already checked the station address prefix, now verify by making
+	   certain that there is a 8390 at the expected location. */
+	outb(E8390_NODMA + E8390_STOP, ioaddr);
+	SLOW_DOWN_IO;
+	status = inb(ioaddr);
+	if (status != 0x21 && status != 0x23)
+		return -ENODEV;
+
+#ifdef testing_only
+	printk("%s: E21xx at %#3x (PAXI backwards): ", dev->name, ioaddr);
+	for (i = 0; i < 16; i++)
+		printk(" %02X", inb(ioaddr + 0x1f - i));
+	printk("\n");
+#endif
+
+	/* Read the station address PROM.  */
+	for (i = 0; i < 6; i++)
+		station_addr[i] = inb(ioaddr + E21_SAPROM + i);
+
+	/* Grab the region so we can find another board if needed . */
+	snarf_region(ioaddr, ETHERCARD_TOTAL_SIZE);
+
+	printk("%s: E21xx at %#3x, ", dev->name, ioaddr);
+	for (i = 0; i < 6; i++)
+		printk(" %02X", station_addr[i]);
+
+	if (dev->irq < 2) {
+		int irqlist[] = {15,11,10,12,5,9,3,4}, i;
+		for (i = 0; i < 8; i++)
+			if (request_irq (irqlist[i], NULL) != -EBUSY) {
+				dev->irq = irqlist[i];
+				break;
+			}
+	} else if (dev->irq == 2)     /* Fixup bogosity: IRQ2 is really IRQ9 */
+		dev->irq = 9;
+
+	/* Snarf the interrupt now. */
+	if (irqaction (dev->irq, &ei_sigaction)) {
+		printk (" unable to get IRQ %d.\n", dev->irq);
+		return -EBUSY;
+	}
+
+	/* The 8390 is at the base address. */
+	dev->base_addr = ioaddr;
+
+	ethdev_init(dev);
+
+	ei_status.name = "E2100";
+	ei_status.word16 = 1;
+	ei_status.tx_start_page = E21_TX_START_PG;
+	ei_status.rx_start_page = E21_RX_START_PG;
+	ei_status.stop_page = E21_RX_STOP_PG;
+
+	/* Check the media port used.  The port can be passed in on the
+	   low mem_end bits. */
+	if (dev->mem_end & 15)
+		dev->if_port = dev->mem_end & 7;
+	else {
+		dev->if_port = 0;
+		inb_p(ioaddr + E21_IRQ_HIGH); 	/* Select if_port detect. */
+		for(i = 0; i < 6; i++)
+			if (station_addr[i] != inb(ioaddr + E21_SAPROM))
+				dev->if_port = 1;
+	}
+
+	/* Never map in the E21 shared memory unless you are actively using it.
+	   Also, the shared memory has effective only one setting -- spread all
+	   over the 128K region! */
+	if (dev->mem_start == 0)
+		dev->mem_start = 0xd0000;
+	
+#ifdef notdef
+	/* These values are unused.  The E2100 has a 2K window into the packet
+	   buffer.  The window can be set to start on any page boundary. */
+	dev->rmem_start = dev->mem_start + TX_PAGES*256;
+	dev->mem_end = dev->rmem_end = dev->mem_start + 2*1024;
+#endif
+
+	printk(" IRQ %d, %s interface,  memory at %#x-%#x.\n", dev->irq,
+		   dev->if_port ? "secondary" : "primary", dev->mem_start,
+		   dev->mem_start + 2*1024 - 1);
+
+	if (ei_debug > 0)
+		printk(version);
+
+	ei_status.reset_8390 = &e21_reset_8390;
+	ei_status.block_input = &e21_block_input;
+	ei_status.block_output = &e21_block_output;
+	dev->open = &e21_open;
+	dev->stop = &e21_close;
+	NS8390_init(dev, 0);
+
+	return 0;
+}
+
+static int
+e21_open(struct device *dev)
+{
+    short ioaddr = dev->base_addr;
+
+	/* Set the interrupt line and memory base on the hardware. */
+	inb_p(ioaddr + E21_IRQ_LOW);
+	outb_p(0, ioaddr + E21_ASIC + (dev->irq & 7));
+	inb_p(ioaddr + E21_IRQ_HIGH); 			/* High IRQ bit, and if_port. */
+	outb_p(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
+		   + (dev->if_port ? E21_ALT_IFPORT : 0));
+	inb_p(ioaddr + E21_MEM_BASE);
+	outb_p(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
+
+	return ei_open(dev);
+}
+
+static void
+e21_reset_8390(struct device *dev)
+{
+    short ioaddr = dev->base_addr;
+
+    outb(0x01, ioaddr);
+    if (ei_debug > 1) printk("resetting the E2180x3 t=%d...", jiffies);
+    ei_status.txing = 0;
+
+    /* Set up the ASIC registers, just in case something changed them. */
+
+    if (ei_debug > 1) printk("reset done\n");
+    return;
+}
+
+/* Block input and output are easy on shared memory ethercards.  The E21xx makes
+   block_input() especially easy by wrapping the top ring buffer to the bottom
+   automatically. */
+static int
+e21_block_input(struct device *dev, int count, char *buf, int ring_offset)
+{
+    short ioaddr = dev->base_addr;
+	char *shared_mem = (char *)dev->mem_start;
+	int start_page = (ring_offset>>8);
+
+	mem_on(ioaddr, shared_mem, start_page);
+
+    /* We'll always get a 4 byte header read first. */
+    if (count == 4)
+        ((int*)buf)[0] = ((int*)shared_mem)[0];
+    else
+        memcpy(buf, shared_mem + (ring_offset & 0xff), count);
+
+    /* Turn off memory access: we would need to reprogram the window anyway. */
+	mem_off(ioaddr);
+
+    return 0;
+}
+
+static void
+e21_block_output(struct device *dev, int count, const unsigned char *buf,
+                int start_page)
+{
+    short ioaddr = dev->base_addr;
+	volatile char *shared_mem = (char *)dev->mem_start;
+
+	/* Set the shared memory window start by doing a read, with the low address
+	   bits specifing the starting page. */
+	*(shared_mem + start_page);
+	mem_on(ioaddr, shared_mem, start_page);
+
+	memcpy((char*)shared_mem, buf, count);
+	mem_off(ioaddr);
+}
+
+static int
+e21_close(struct device *dev)
+{
+    short ioaddr = dev->base_addr;
+
+    if (ei_debug > 1)
+        printk("%s: Shutting down ethercard.\n", dev->name);
+    NS8390_init(dev, 0);
+
+	mem_off(ioaddr);
+
+    return 0;
+}
+
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c e2100.c"
+ *  version-control: t
+ *  tab-width: 4
+ *  kept-new-versions: 5
+ * End:
+ */
diff -u --recursive --new-file v1.1.21/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- v1.1.21/linux/drivers/net/loopback.c	Tue Jun 21 14:16:21 1994
+++ linux/drivers/net/loopback.c	Thu Jun 23 22:09:33 1994
@@ -128,7 +128,7 @@
 #endif
 
   /* New-style flags. */
-  dev->flags		= IFF_LOOPBACK;
+  dev->flags		= IFF_LOOPBACK|IFF_BROADCAST;
   dev->family		= AF_INET;
 #ifdef CONFIG_INET    
   dev->pa_addr		= in_aton("127.0.0.1");
diff -u --recursive --new-file v1.1.21/linux/drivers/net/znote.c linux/drivers/net/znote.c
--- v1.1.21/linux/drivers/net/znote.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/net/znote.c	Thu Jun 23 22:51:47 1994
@@ -0,0 +1,947 @@
+/* znet.c: An Zenith Z-Note ethernet driver for linux. */
+
+static char *version = "znet.c:v0.04 5/10/94 becker@cesdis.gsfc.nasa.gov\n";
+
+/*
+	Written by Donald Becker.
+
+	The author may be reached as becker@cesdis.gsfc.nasa.gov.
+	This driver is based on the Linux skeleton driver.  The copyright of the
+	skeleton driver is held by the United States Government, as represented
+	by DIRNSA, and it is released under the GPL.
+
+	Thanks to Mike Hollick for alpha testing and suggestions.
+
+  References:
+	   The Crynwr packet driver.
+
+	  "82593 CSMA/CD Core LAN Controller" Intel datasheet, 1992
+	  Intel Microcommunications Databook, Vol. 1, 1990.
+    As usual with Intel, the documentation is incomplete and inaccurate.
+	I had to read the Crynwr packet driver to figure out how to actually
+	use the i82593, and guess at what register bits matched the loosely
+	related i82586.
+
+					Theory of Operation
+
+	The i82593 used in the Zenith Z-Note series operates using two(!) slave
+	DMA	channels, one interrupt, and one 8-bit I/O port.
+
+	While there	several ways to configure '593 DMA system, I chose the one
+	that seemed commesurate with the highest system performance in the face
+	of moderate interrupt latency: Both DMA channels are configued as
+	recirculating ring buffers, with one channel (#0) dedicated to Rx and
+	the other channel (#1) to Tx and configuration.  (Note that this is
+	different than the Crynwr driver, where the Tx DMA channel is initialized
+	before each operation.  That approach simplifies operation and Tx error
+	recovery, but requires additional I/O in normal operation and precludes
+	transmit buffer	chaining.)
+
+	Both rings are set to 8192 bytes using {TX,RX}_RING_SIZE.  This provides
+	a reasonable ring size for Rx, while simplifying DMA buffer allocation --
+	DMA buffers must not cross a 128K boundary.  (In truth the size selection
+	was influenced by my lack of '593 documentation.  I thus was constrained
+	to use the Crynwr '593 initialization table, which sets the Rx ring size
+	to 8K.)
+
+	Despite my usual low opinion about Intel-designed parts, I must admit
+	that the bulk data handling of the i82593 is a good design for
+	an integrated system, like a laptop, where using two slave DMA channels
+	doesn't pose a problem.  I still take issue with using only a single I/O
+	port.  In the same controlled environment there are essentially no
+	limitations on I/O space, and using multiple locations would eliminate
+	the	need for multiple operations when looking at status registers,
+	setting the Rx ring boundary, or switching to promiscuous mode.
+
+	I also question Zenith's selection of the '593: one of the advertised
+	advantages of earlier Intel parts was that if you figured out the magic
+	initialization incantation you could use the same part on many different
+	network types.  Zenith's use of the "FriendlyNet" (sic) connector rather
+	than an	on-board transceiver leads me to believe that they were planning
+	to take advantage of this.  But, uhmmm, the '593 omits all but ethernet
+	functionality from the serial subsystem.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+
+#ifndef HAVE_AUTOIRQ
+/* From auto_irq.c, in ioport.h for later versions. */
+extern void autoirq_setup(int waittime);
+extern int autoirq_report(int waittime);
+/* The map from IRQ number (as passed to the interrupt handler) to
+   'struct device'. */
+extern struct device *irq2dev_map[16];
+#endif
+
+#ifndef HAVE_ALLOC_SKB
+#define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
+#define kfree_skbmem(addr, size) kfree_s(addr,size);
+#endif
+
+#ifndef ZNET_DEBUG
+#define ZNET_DEBUG 3
+#endif
+static unsigned int znet_debug = ZNET_DEBUG;
+
+/* The DMA modes we need aren't in <dma.h>. */
+#define DMA_RX_MODE		0x14	/* Auto init, I/O to mem, ++, demand. */
+#define DMA_TX_MODE		0x18	/* Auto init, Mem to I/O, ++, demand. */
+#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
+#define DMA_BUF_SIZE 8192
+#define RX_BUF_SIZE 8192
+#define TX_BUF_SIZE 8192
+
+/* Commands to the i82593 channel 0. */
+#define CMD0_CHNL_0			0x00
+#define CMD0_CHNL_1			0x10		/* Switch to channel 1. */
+#define CMD0_NOP (CMD0_CHNL_0)
+#define CMD0_PORT_1	CMD0_CHNL_1
+#define CMD1_PORT_0	1
+#define CMD0_IA_SETUP		1
+#define CMD0_CONFIGURE		2
+#define CMD0_MULTICAST_LIST 3
+#define CMD0_TRANSMIT		4
+#define CMD0_DUMP			6
+#define CMD0_DIAGNOSE		7
+#define CMD0_Rx_ENABLE		8
+#define CMD0_Rx_DISABLE		10
+#define CMD0_Rx_STOP		11
+#define CMD0_RETRANSMIT		12
+#define CMD0_ABORT			13
+#define CMD0_RESET			14
+
+#define CMD0_ACK 0x80
+
+#define CMD0_STAT0 (0 << 5)
+#define CMD0_STAT1 (1 << 5)
+#define CMD0_STAT2 (2 << 5)
+#define CMD0_STAT3 (3 << 5)
+
+#define net_local znet_private
+struct znet_private {
+	int rx_dma, tx_dma;
+	struct enet_statistics stats;
+	/* The starting, current, and end pointers for the packet buffers. */
+	ushort *rx_start, *rx_cur, *rx_end;
+	ushort *tx_start, *tx_cur, *tx_end;
+	ushort tx_buf_len;			/* Tx buffer lenght, in words. */
+};
+
+/* Only one can be built-in;-> */
+static struct znet_private zn;
+static ushort dma_buffer1[DMA_BUF_SIZE/2];
+static ushort dma_buffer2[DMA_BUF_SIZE/2];
+static ushort dma_buffer3[DMA_BUF_SIZE/2 + 8];
+
+/* The configuration block.  What an undocumented nightmare.  The first
+   set of values are those suggested (without explaination) for ethernet
+   in the Intel 82586 databook.	 The rest appear to be completely undocumented,
+   except for cryptic notes in the Crynwr packet driver.  This driver uses
+   the Crynwr values verbatim. */
+
+static unsigned char i593_init[] = {
+  0xAA,					/* 0: 16-byte input & 80-byte output FIFO. */
+						/*	  threshhold, 96-byte FIFO, 82593 mode. */
+  0x88,					/* 1: Continuous w/interrupts, 128-clock DMA.*/
+  0x2E,					/* 2: 8-byte preamble, NO address insertion, */
+						/*	  6-byte Ethernet address, loopback off.*/
+  0x00,					/* 3: Default priorities & backoff methods. */
+  0x60,					/* 4: 96-bit interframe spacing. */
+  0x00,					/* 5: 512-bit slot time (low-order). */
+  0xF2,					/* 6: Slot time (high-order), 15 COLL retries. */
+  0x00,					/* 7: Promisc-off, broadcast-on, default CRC. */
+  0x00,					/* 8: Default carrier-sense, collision-detect. */
+  0x40,					/* 9: 64-byte minimum frame length. */
+  0x5F,					/* A: Type/length checks OFF, no CRC input,
+						   "jabber" termination, etc. */
+  0x00,					/* B: Full-duplex disabled. */
+  0x3F,					/* C: Default multicast addresses & backoff. */
+  0x07,					/* D: Default IFS retriggering. */
+  0x31,					/* E: Internal retransmit, drop "runt" packets,
+						   synchr. DRQ deassertion, 6 status bytes. */
+  0x22,					/* F: Receive ring-buffer size (8K), 
+						   receive-stop register enable. */
+};
+
+struct netidblk {
+	char magic[8];		/* The magic number (string) "NETIDBLK" */
+	unsigned char netid[8]; /* The physical station address */
+	char nettype, globalopt;
+	char vendor[8];		/* The machine vendor and product name. */
+	char product[8];
+	char irq1, irq2;		/* Interrupts, only one is currently used.	*/
+	char dma1, dma2;
+	short dma_mem_misc[8];		/* DMA buffer locations (unused in Linux). */
+	short iobase1, iosize1;
+	short iobase2, iosize2;		/* Second iobase unused. */
+	char driver_options;			/* Misc. bits */
+	char pad;
+};
+
+int znet_probe(struct device *dev);
+static int	znet_open(struct device *dev);
+static int	znet_send_packet(struct sk_buff *skb, struct device *dev);
+static void	znet_interrupt(int reg_ptr);
+static void	znet_rx(struct device *dev);
+static int	znet_close(struct device *dev);
+static struct enet_statistics *net_get_stats(struct device *dev);
+static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
+static void hardware_init(struct device *dev);
+static int do_command(short ioaddr, int command, int length, ushort *buffer);
+static int	wait_for_done(short ioaddr);
+static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset);
+
+#ifdef notdef
+static struct sigaction znet_sigaction = { &znet_interrupt, 0, 0, NULL, };
+#endif
+
+
+/* The Z-Note probe is pretty easy.  The NETIDBLK exists in the safe-to-probe
+   BIOS area.  We just scan for the signature, and pull the vital parameters
+   out of the structure. */
+
+int znet_probe(struct device *dev)
+{
+	int i;
+	struct netidblk *netinfo;
+	char *p;
+
+	/* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
+	for(p = (char *)0xf0000; p < (char *)0x100000; p++)
+		if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0)
+			break;
+
+	if (p >= (char *)0x100000) {
+		if (znet_debug > 1)
+			printk("No Z-Note ethernet adaptor found.\n");
+		return ENODEV;
+	}
+	netinfo = (struct netidblk *)p;
+	dev->base_addr = netinfo->iobase1;
+	dev->irq = netinfo->irq1;
+
+	printk("%s: ZNET at %#3x,", dev->name, dev->base_addr);
+
+	/* The station address is in the "netidblk" at 0x0f0000. */
+	for (i = 0; i < 6; i++)
+		printk(" %2.2x", dev->dev_addr[i] = netinfo->netid[i]);
+
+	printk(", using IRQ %d DMA %d and %d.\n", dev->irq, netinfo->dma1,
+		netinfo->dma2);
+
+	if (znet_debug > 1) {
+		printk("%s: vendor '%16.16s' IRQ1 %d IRQ2 %d DMA1 %d DMA2 %d.\n",
+			   dev->name, netinfo->vendor,
+			   netinfo->irq1, netinfo->irq2,
+			   netinfo->dma1, netinfo->dma2);
+		printk("%s: iobase1 %#x size %d iobase2 %#x size %d net type %2.2x.\n",
+			   dev->name, netinfo->iobase1, netinfo->iosize1,
+			   netinfo->iobase2, netinfo->iosize2, netinfo->nettype);
+	}
+
+	if (znet_debug > 0)
+		printk(version);
+
+	dev->priv = (void *) &zn;
+	zn.rx_dma = netinfo->dma1;
+	zn.tx_dma = netinfo->dma2;
+
+	/* These should never fail.  You can't add devices to a sealed box! */
+	if (request_irq(dev->irq, &znet_interrupt)
+		|| request_dma(zn.rx_dma)
+		|| request_dma(zn.tx_dma)) {
+		printk("Not opened -- resource busy?!?\n");
+		return EBUSY;
+	}
+	irq2dev_map[dev->irq] = dev;
+
+	/* Allocate buffer memory.	We can cross a 128K boundary, so we
+	   must be careful about the allocation.  It's easiest to waste 8K. */
+	if (dma_page_eq(dma_buffer1, &dma_buffer1[RX_BUF_SIZE/2-1]))
+	  zn.rx_start = dma_buffer1;
+	else 
+	  zn.rx_start = dma_buffer2;
+
+	if (dma_page_eq(dma_buffer3, &dma_buffer3[RX_BUF_SIZE/2-1]))
+	  zn.tx_start = dma_buffer3;
+	else
+	  zn.tx_start = dma_buffer2;
+	zn.rx_end = zn.rx_start + RX_BUF_SIZE/2;
+	zn.tx_buf_len = TX_BUF_SIZE/2;
+	zn.tx_end = zn.tx_start + zn.tx_buf_len;
+
+	/* The ZNET-specific entries in the device structure. */
+	dev->open = &znet_open;
+	dev->hard_start_xmit = &znet_send_packet;
+	dev->stop = &znet_close;
+	dev->get_stats	= net_get_stats;
+#ifdef HAVE_MULTICAST
+	dev->set_multicast_list = &set_multicast_list;
+#endif
+
+	/* Fill in the generic field of the device structure. */
+	for (i = 0; i < DEV_NUMBUFFS; i++)
+		dev->buffs[i] = NULL;
+
+	dev->hard_header	= eth_header;
+	dev->add_arp		= eth_add_arp;
+	dev->queue_xmit		= dev_queue_xmit;
+	dev->rebuild_header	= eth_rebuild_header;
+	dev->type_trans		= eth_type_trans;
+
+	dev->type			= ARPHRD_ETHER;
+	dev->hard_header_len = ETH_HLEN;
+	dev->mtu			= 1500; /* eth_mtu */
+	dev->addr_len		= ETH_ALEN;
+	for (i = 0; i < ETH_ALEN; i++) {
+		dev->broadcast[i]=0xff;
+	}
+
+	/* New-style flags. */
+	dev->flags			= IFF_BROADCAST;
+	dev->family			= AF_INET;
+	dev->pa_addr		= 0;
+	dev->pa_brdaddr		= 0;
+	dev->pa_mask		= 0;
+	dev->pa_alen		= sizeof(unsigned long);
+
+	return 0;
+}
+
+
+static int znet_open(struct device *dev)
+{
+	int ioaddr = dev->base_addr;
+
+	if (znet_debug > 2)
+		printk("%s: znet_open() called.\n", dev->name);
+
+	/* Turn on the 82501 SIA, using zenith-specific magic. */
+	outb(0x10, 0xe6);					/* Select LAN control register */
+	outb(inb(0xe7) | 0x84, 0xe7);		/* Turn on LAN power (bit 2). */
+	/* According to the Crynwr driver we should wait 50 msec. for the
+	   LAN clock to stabilize.  My experiments indicates that the '593 can
+	   be initialized immediately.  The delay is probably needed for the
+	   DC-to-DC converter to come up to full voltage, and for the oscillator
+	   to be spot-on at 20Mhz before transmitting.
+	   Until this proves to be a problem we rely on the higher layers for the
+	   delay and save allocating a timer entry. */
+
+	/* This follows the packet driver's lead, and checks for success. */
+	if (inb(ioaddr) != 0x10 && inb(ioaddr) != 0x00)
+		printk("%s: Problem turning on the transceiver power.\n", dev->name);
+
+	dev->tbusy = 0;
+	dev->interrupt = 0;
+	hardware_init(dev);
+	dev->start = 1;
+
+	return 0;
+}
+
+static int znet_send_packet(struct sk_buff *skb, struct device *dev)
+{
+	int ioaddr = dev->base_addr;
+
+	if (znet_debug > 4)
+		printk("%s: ZNet_send_packet(%d).\n", dev->name, dev->tbusy);
+
+	/* Transmitter timeout, could be a serious problems. */
+	if (dev->tbusy) {
+		ushort event, tx_status, rx_offset, state;
+		int tickssofar = jiffies - dev->trans_start;
+		if (tickssofar < 10)
+			return 1;
+		outb(CMD0_STAT0, ioaddr); event = inb(ioaddr);
+		outb(CMD0_STAT1, ioaddr); tx_status = inw(ioaddr);
+		outb(CMD0_STAT2, ioaddr); rx_offset = inw(ioaddr);
+		outb(CMD0_STAT3, ioaddr); state = inb(ioaddr);
+		printk("%s: transmit timed out, status %02x %04x %04x %02x,"
+			   " resetting.\n", dev->name, event, tx_status, rx_offset, state);
+		if (tx_status == 0x0400)
+		  printk("%s: Tx carrier error, check transceiver cable.\n",
+				 dev->name);
+		outb(CMD0_RESET, ioaddr);
+		hardware_init(dev);
+	}
+
+	if (skb == NULL) {
+		dev_tint(dev);
+		return 0;
+	}
+
+	/* Fill in the ethernet header. */
+	if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
+		skb->dev = dev;
+		arp_queue (skb);
+		return 0;
+	}
+
+	/* Check that the part hasn't reset itself, probably from suspend. */
+	outb(CMD0_STAT0, ioaddr);
+	if (inw(ioaddr) == 0x0010
+		&& inw(ioaddr) == 0x0000
+		&& inw(ioaddr) == 0x0010)
+	  hardware_init(dev);
+
+	/* Block a timer-based transmit from overlapping.  This could better be
+	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+	if (set_bit(0, (void*)&dev->tbusy) != 0)
+		printk("%s: Transmitter access conflict.\n", dev->name);
+	else {
+		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+		unsigned char *buf = (void *)(skb+1);
+		ushort *tx_link = zn.tx_cur - 1;
+		ushort rnd_len = (length + 1)>>1;
+
+		{
+			short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
+			unsigned addr = inb(dma_port);
+			addr |= inb(dma_port) << 8;
+			addr <<= 1;
+			if (((int)zn.tx_cur & 0x1ffff) != addr)
+			  printk("Address mismatch at Tx: %#x vs %#x.\n",
+					 (int)zn.tx_cur & 0xffff, addr);
+			zn.tx_cur = (ushort *)(((int)zn.tx_cur & 0xfe0000) | addr);
+		}
+
+		if (zn.tx_cur >= zn.tx_end)
+		  zn.tx_cur = zn.tx_start;
+		*zn.tx_cur++ = length;
+		if (zn.tx_cur + rnd_len + 1 > zn.tx_end) {
+			int semi_cnt = (zn.tx_end - zn.tx_cur)<<1; /* Cvrt to byte cnt. */
+			memcpy(zn.tx_cur, buf, semi_cnt);
+			rnd_len -= semi_cnt>>1;
+			memcpy(zn.tx_start, buf + semi_cnt, length - semi_cnt);
+			zn.tx_cur = zn.tx_start + rnd_len;
+		} else {
+			memcpy(zn.tx_cur, buf, skb->len);
+			zn.tx_cur += rnd_len;
+		}
+		*zn.tx_cur++ = 0;
+		cli(); {
+			*tx_link = CMD0_TRANSMIT + CMD0_CHNL_1;
+			/* Is this always safe to do? */
+			outb(CMD0_TRANSMIT + CMD0_CHNL_1,ioaddr);
+		} sti();
+
+		dev->trans_start = jiffies;
+		if (znet_debug > 4)
+		  printk("%s: Transmitter queued, length %d.\n", dev->name, length);
+	}
+	dev_kfree_skb(skb, FREE_WRITE); 
+	return 0;
+}
+
+/* The ZNET interrupt handler. */
+static void	znet_interrupt(int reg_ptr)
+{
+	int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
+	struct device *dev = irq2dev_map[irq];
+	int ioaddr;
+	int boguscnt = 20;
+
+	if (dev == NULL) {
+		printk ("znet_interrupt(): IRQ %d for unknown device.\n", irq);
+		return;
+	}
+
+	dev->interrupt = 1;
+	ioaddr = dev->base_addr;
+
+	outb(CMD0_STAT0, ioaddr);
+	do {
+		ushort status = inb(ioaddr);
+		if (znet_debug > 5) {
+			ushort result, rx_ptr, running;
+			outb(CMD0_STAT1, ioaddr);
+			result = inw(ioaddr);
+			outb(CMD0_STAT2, ioaddr);
+			rx_ptr = inw(ioaddr);
+			outb(CMD0_STAT3, ioaddr);
+			running = inb(ioaddr);
+			printk("%s: interrupt, status %02x, %04x %04x %02x serial %d.\n",
+				 dev->name, status, result, rx_ptr, running, boguscnt);
+		}
+		if ((status & 0x80) == 0)
+			break;
+
+		if ((status & 0x0F) == 4) {	/* Transmit done. */
+			struct net_local *lp = (struct net_local *)dev->priv;
+			int tx_status;
+			outb(CMD0_STAT1, ioaddr);
+			tx_status = inw(ioaddr);
+			/* It's undocumented, but tx_status seems to match the i82586. */
+			if (tx_status & 0x2000) {
+				lp->stats.tx_packets++;
+				lp->stats.collisions += tx_status & 0xf;
+			} else {
+				if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
+				if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
+				if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
+				if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
+				/* ...and the catch-all. */
+				if (tx_status | 0x0760 != 0x0760)
+				  lp->stats.tx_errors++;
+			}
+			dev->tbusy = 0;
+			mark_bh(INET_BH);	/* Inform upper layers. */
+		}
+
+		if ((status & 0x40)
+			|| (status & 0x0f) == 11) {
+			znet_rx(dev);
+		}
+		/* Clear the interrupts we've handled. */
+		outb(CMD0_ACK,ioaddr);
+	} while (boguscnt--);
+
+	dev->interrupt = 0;
+	return;
+}
+
+static void znet_rx(struct device *dev)
+{
+	struct net_local *lp = (struct net_local *)dev->priv;
+	int ioaddr = dev->base_addr;
+	int boguscount = 1;
+	short next_frame_end_offset = 0; 		/* Offset of next frame start. */
+	short *cur_frame_end;
+	short cur_frame_end_offset;
+
+	outb(CMD0_STAT2, ioaddr);
+	cur_frame_end_offset = inw(ioaddr);
+
+	if (cur_frame_end_offset == zn.rx_cur - zn.rx_start) {
+		printk("%s: Interrupted, but nothing to receive, offset %03x.\n",
+			   dev->name, cur_frame_end_offset);
+		return;
+	}
+
+	/* Use same method as the Crynwr driver: construct a forward list in
+	   the same area of the backwards links we now have.  This allows us to
+	   pass packets to the upper layers in the order they were received --
+	   important for fast-path sequential operations. */
+	 while (zn.rx_start + cur_frame_end_offset != zn.rx_cur
+			&& ++boguscount < 5) {
+		unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
+		int count, status;
+
+		if (cur_frame_end_offset < 4) {
+			/* Oh no, we have a special case: the frame trailer wraps around
+			   the end of the ring buffer.  We've saved space at the end of
+			   the ring buffer for just this problem. */
+			memcpy(zn.rx_end, zn.rx_start, 8);
+			cur_frame_end_offset += (RX_BUF_SIZE/2);
+		}
+		cur_frame_end = zn.rx_start + cur_frame_end_offset - 4;
+
+		lo_status = *cur_frame_end++;
+		hi_status = *cur_frame_end++;
+		status = ((hi_status & 0xff) << 8) + (lo_status & 0xff);
+		lo_cnt = *cur_frame_end++;
+		hi_cnt = *cur_frame_end++;
+		count = ((hi_cnt & 0xff) << 8) + (lo_cnt & 0xff);
+
+		if (znet_debug > 5)
+		  printk("Constructing trailer at location %03x, %04x %04x %04x %04x"
+				 " count %#x status %04x.\n",
+				 cur_frame_end_offset<<1, lo_status, hi_status, lo_cnt, hi_cnt,
+				 count, status);
+		cur_frame_end[-4] = status;
+		cur_frame_end[-3] = next_frame_end_offset;
+		cur_frame_end[-2] = count;
+		next_frame_end_offset = cur_frame_end_offset;
+		cur_frame_end_offset -= ((count + 1)>>1) + 3;
+		if (cur_frame_end_offset < 0)
+		  cur_frame_end_offset += RX_BUF_SIZE/2;
+	};
+
+	/* Now step  forward through the list. */
+	do {
+		ushort *this_rfp_ptr = zn.rx_start + next_frame_end_offset;
+		int status = this_rfp_ptr[-4];
+		int pkt_len = this_rfp_ptr[-2];
+	  
+		if (znet_debug > 5)
+		  printk("Looking at trailer ending at %04x status %04x length %03x"
+				 " next %04x.\n", next_frame_end_offset<<1, status, pkt_len,
+				 this_rfp_ptr[-3]<<1);
+		/* Once again we must assume that the i82586 docs apply. */
+		if ( ! (status & 0x2000)) {				/* There was an error. */
+			lp->stats.rx_errors++;
+			if (status & 0x0800) lp->stats.rx_crc_errors++;
+			if (status & 0x0400) lp->stats.rx_frame_errors++;
+			if (status & 0x0200) lp->stats.rx_over_errors++; /* Wrong. */
+			if (status & 0x0100) lp->stats.rx_fifo_errors++;
+			if (status & 0x0080) lp->stats.rx_length_errors++;
+		} else if (pkt_len > 1536) {
+			lp->stats.rx_length_errors++;
+		} else {
+			/* Malloc up new buffer. */
+			int sksize = sizeof(struct sk_buff) + pkt_len;
+			struct sk_buff *skb;
+
+			skb = alloc_skb(sksize, GFP_ATOMIC);
+			if (skb == NULL) {
+				if (znet_debug)
+				  printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+				lp->stats.rx_dropped++;
+				break;
+			}
+			skb->mem_len = sksize;
+			skb->mem_addr = skb;
+			skb->len = pkt_len;
+			skb->dev = dev;
+
+			if (&zn.rx_cur[(pkt_len+1)>>1] > zn.rx_end) {
+				int semi_cnt = (zn.rx_end - zn.rx_cur)<<1;
+				memcpy((unsigned char *) (skb + 1), zn.rx_cur, semi_cnt);
+				memcpy((unsigned char *) (skb + 1) + semi_cnt, zn.rx_start,
+					   pkt_len - semi_cnt);
+			} else {
+				memcpy((unsigned char *) (skb + 1), zn.rx_cur, pkt_len);
+				if (znet_debug > 6) {
+					unsigned int *packet = (unsigned int *) (skb + 1);
+					printk("Packet data is %08x %08x %08x %08x.\n", packet[0],
+						   packet[1], packet[2], packet[3]);
+				}
+		  }
+
+#ifdef HAVE_NETIF_RX
+			netif_rx(skb);
+#else
+			skb->lock = 0;
+			if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
+				kfree_s(skb, sksize);
+				lp->stats.rx_dropped++;
+				break;
+			}
+#endif
+			lp->stats.rx_packets++;
+		}
+		zn.rx_cur = this_rfp_ptr;
+		if (zn.rx_cur >= zn.rx_end)
+			zn.rx_cur -= RX_BUF_SIZE/2;
+		update_stop_hit(ioaddr, (zn.rx_cur - zn.rx_start)<<1);
+		next_frame_end_offset = this_rfp_ptr[-3];
+		if (next_frame_end_offset == 0)		/* Read all the frames? */
+			break;			/* Done for now */
+		this_rfp_ptr = zn.rx_start + next_frame_end_offset;
+	} while (--boguscount);
+
+	/* If any worth-while packets have been received, dev_rint()
+	   has done a mark_bh(INET_BH) for us and will work on them
+	   when we get to the bottom-half routine. */
+	return;
+}
+
+/* The inverse routine to znet_open(). */
+static int znet_close(struct device *dev)
+{
+	int ioaddr = dev->base_addr;
+
+	dev->tbusy = 1;
+	dev->start = 0;
+
+	outb(CMD0_RESET, ioaddr);			/* CMD0_RESET */
+
+	disable_dma(zn.rx_dma);
+	disable_dma(zn.tx_dma);
+
+	free_irq(dev->irq);
+
+	if (znet_debug > 1)
+		printk("%s: Shutting down ethercard.\n", dev->name);
+	/* Turn off transceiver power. */
+	outb(0x10, 0xe6);					/* Select LAN control register */
+	outb(inb(0xe7) & ~0x84, 0xe7);		/* Turn on LAN power (bit 2). */
+
+	return 0;
+}
+
+/* Get the current statistics.	This may be called with the card open or
+   closed. */
+static struct enet_statistics *net_get_stats(struct device *dev)
+{
+		struct net_local *lp = (struct net_local *)dev->priv;
+
+		return &lp->stats;
+}
+
+#ifdef HAVE_MULTICAST
+/* Set or clear the multicast filter for this adaptor.
+   num_addrs == -1	Promiscuous mode, receive all packets
+   num_addrs == 0	Normal mode, clear multicast list
+   num_addrs > 0	Multicast mode, receive normal and MC packets, and do
+			best-effort filtering.
+   As a side effect this routine must also initialize the device parameters.
+   This is taken advantage of in open().
+
+   N.B. that we change i593_init[] in place.  This (properly) makes the
+   mode change persistent, but must be changed if this code is moved to
+   a multiple adaptor environment.
+ */
+static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
+{
+	short ioaddr = dev->base_addr;
+
+	if (num_addrs < 0) {
+		/* Enable promiscuous mode */
+		i593_init[7] &= ~3;		i593_init[7] |= 1;
+		i593_init[13] &= ~8;	i593_init[13] |= 8;
+	} else if (num_addrs > 0) {
+		/* Enable accept-all-multicast mode */
+		i593_init[7] &= ~3;		i593_init[7] |= 0;
+		i593_init[13] &= ~8;	i593_init[13] |= 8;
+	} else {					/* Enable normal mode. */
+		i593_init[7] &= ~3;		i593_init[7] |= 0;
+		i593_init[13] &= ~8;	i593_init[13] |= 0;
+	}
+	*zn.tx_cur++ = sizeof(i593_init);
+	memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
+	zn.tx_cur += sizeof(i593_init)/2;
+	outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
+#ifdef not_tested
+	if (num_addrs > 0) {
+		int addrs_len = 6*num_addrs;
+		*zn.tx_cur++ = addrs_len;
+		memcpy(zn.tx_cur, addrs, addrs_len);
+		outb(CMD0_MULTICAST_LIST+CMD0_CHNL_1, ioaddr);
+		zn.tx_cur += addrs_len>>1;
+	}
+#endif
+}
+#endif
+
+void show_dma(void)
+{
+	short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
+	unsigned addr = inb(dma_port);
+	addr |= inb(dma_port) << 8;
+	printk("Addr: %04x cnt:%3x...", addr<<1,
+		   get_dma_residue(zn.tx_dma));
+}
+
+/* Initialize the hardware.  We have to do this when the board is open()ed
+   or when we come out of suspend mode. */
+static void hardware_init(struct device *dev)
+{
+	short ioaddr = dev->base_addr;
+
+	zn.rx_cur = zn.rx_start;
+	zn.tx_cur = zn.tx_start;
+
+	/* Reset the chip, and start it up. */
+	outb(CMD0_RESET, ioaddr);
+
+	cli(); {							/* Protect against a DMA flip-flop */
+		disable_dma(zn.rx_dma); 		/* reset by an interrupting task. */
+		clear_dma_ff(zn.rx_dma);
+		set_dma_mode(zn.rx_dma, DMA_RX_MODE);
+		set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
+		set_dma_count(zn.rx_dma, RX_BUF_SIZE);
+		enable_dma(zn.rx_dma);
+		/* Now set up the Tx channel. */
+		disable_dma(zn.tx_dma);
+		clear_dma_ff(zn.tx_dma);
+		set_dma_mode(zn.tx_dma, DMA_TX_MODE);
+		set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
+		set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
+		enable_dma(zn.tx_dma);
+	} sti();
+
+	if (znet_debug > 1)
+	  printk("%s: Initializing the i82593, tx buf %p... ", dev->name,
+			 zn.tx_start);
+	/* Do an empty configure command, just like the Crynwr driver.  This
+	   resets to chip to its default values. */
+	*zn.tx_cur++ = 0;
+	*zn.tx_cur++ = 0;
+	printk("stat:%02x ", inb(ioaddr)); show_dma();
+	outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
+	*zn.tx_cur++ = sizeof(i593_init);
+	memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
+	zn.tx_cur += sizeof(i593_init)/2;
+	printk("stat:%02x ", inb(ioaddr)); show_dma();
+	outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
+	*zn.tx_cur++ = 6;
+	memcpy(zn.tx_cur, dev->dev_addr, 6);
+	zn.tx_cur += 3;
+	printk("stat:%02x ", inb(ioaddr)); show_dma();
+	outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
+	printk("stat:%02x ", inb(ioaddr)); show_dma();
+
+	update_stop_hit(ioaddr, 8192);
+	if (znet_debug > 1)  printk("enabling Rx.\n");
+	outb(CMD0_Rx_ENABLE+CMD0_CHNL_0, ioaddr);
+	dev->tbusy = 0;
+}
+
+#ifdef notdef
+foo()
+{
+	/*do_command(ioaddr, CMD0_CONFIGURE+CMD0_CHNL_1, sizeof(i593_init) + 2,
+			   zn.tx_buffer);*/
+	/*do_command(ioaddr, CMD0_CONFIGURE+CMD0_CHNL_1, 32, zn.tx_buffer);*/
+	/*outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);*/
+
+	if (znet_debug > 1)  printk("Set Address... ");
+	*zn.tx_cur++ = 6;
+	memcpy(zn.tx_cur, dev->dev_addr, 6);
+	zn.tx_cur += 3;
+	outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
+	{
+		unsigned stop_time = jiffies + 3; 
+		while (jiffies < stop_time);
+	}
+	if (znet_debug > 2) {
+		short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
+		unsigned addr = inb(dma_port);
+		addr |= inb(dma_port) << 8;
+		printk("Terminal addr is %04x, cnt. %03x...", addr<<1,
+			   get_dma_residue(zn.tx_dma));
+	}
+	*zn.tx_cur++ = 6;
+	memcpy(zn.tx_cur, dev->dev_addr, 6);
+	zn.tx_cur += 3;
+	outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
+	{
+		unsigned stop_time = jiffies + 2; 
+		while (jiffies < stop_time);
+	}
+	if (znet_debug > 2) {
+		short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
+		unsigned addr = inb(dma_port);
+		addr |= inb(dma_port) << 8;
+		printk("Terminal addr is %04x, cnt. %03x...", addr<<1,
+			   get_dma_residue(zn.tx_dma));
+	}
+	wait_for_done(ioaddr);
+
+	if (znet_debug > 1)  printk("Set Mode... ");
+	set_multicast_list(dev, 0, 0);
+	{
+		unsigned stop_time = jiffies + 3; 
+		while (jiffies < stop_time);
+	}
+	if (znet_debug > 2) {
+		short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
+		unsigned addr = inb(dma_port);
+		addr |= inb(dma_port) << 8;
+		printk("Terminal addr is %04x, cnt. %03x...", addr<<1,
+			   get_dma_residue(zn.tx_dma));
+	}
+	if (znet_debug > 2) {
+		int i;
+		outb(CMD0_DUMP+CMD0_CHNL_0, ioaddr);
+		printk("Dumping state:");
+		for (i = 0; i < 16; i++)
+			printk(" %04x", *zn.rx_cur++);
+		printk("\n             :");
+		for (;i < 32; i++)
+			printk(" %04x", *zn.rx_cur++);
+		printk("\n");
+		wait_for_done(ioaddr);
+	}
+}
+
+static int do_command(short ioaddr, int command, int length, ushort *buffer)
+{
+	/* This isn't needed, but is here for safety. */
+	outb(CMD0_NOP+CMD0_STAT3,ioaddr);
+	if (inb(ioaddr) & 3)
+	  printk("znet: do_command() while the i82593 is busy.\n");
+
+	cli();
+	disable_dma(zn.tx_dma);
+	clear_dma_ff(zn.tx_dma);
+	set_dma_mode(zn.tx_dma,DMA_MODE_WRITE);
+	set_dma_addr(zn.tx_dma,(unsigned int) zn.tx_start);
+	set_dma_count(zn.tx_dma,length);
+	sti();
+	enable_dma(zn.tx_dma);
+	outb(command, ioaddr);
+	return 0;
+}
+
+/* wait_for_done - this is a blatent rip-off of the wait_for_done routine
+ ** from the Crynwr packet driver.	It does not work correctly - doesn't
+ ** acknowledge the interrupts it gets or something.  It does determine
+ ** when the command is done, or if there are none executing, though...
+ **		-Mike
+ */
+static int wait_for_done(short ioaddr)
+{
+  unsigned int stat;
+  unsigned stop_time = jiffies + 10;
+  int ticks = 0;
+
+  /* check to see if we are busy */
+  outb(CMD0_NOP+CMD0_STAT3,ioaddr);
+  stat = inb(ioaddr);
+
+  /* check if busy */
+  if ((stat&3)==0) {
+	if (znet_debug > 5)
+	  printk("wait_for_done(): Not busy, status %02x.\n", stat);
+	return 0;
+  }
+
+  while (jiffies < stop_time) {
+	  /* now check */
+	  outb(CMD0_NOP+CMD0_STAT3,ioaddr);
+	  stat = inb(ioaddr);
+	  if ((stat&3)==0) {
+		  if (znet_debug > 5)
+			printk("Command completed after %d ticks status %02x.\n",
+				   ticks, stat);
+		  outb((CMD0_NOP|CMD0_ACK),ioaddr);
+		  return 0;
+	  }
+	  ticks++;
+  }
+  outb(CMD0_ABORT, ioaddr);
+  if (znet_debug)
+	printk("wait_for_done: command not ACK'd, status %02x after abort %02x.\n",
+		   stat, inb(ioaddr));
+
+  /* should re-initialize here... */
+  return 1;
+}
+#endif /* notdef */
+
+static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
+{
+	outb(CMD0_PORT_1, ioaddr);
+	if (znet_debug > 5)
+	  printk("Updating stop hit with value %02x.\n",
+			 (rx_stop_offset >> 6) | 0x80);
+	outb((rx_stop_offset >> 6) | 0x80, ioaddr);
+	outb(CMD1_PORT_0, ioaddr);
+}
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c znet.c"
+ *  version-control: t
+ *  kept-new-versions: 5
+ *  c-indent-level: 4
+ *  tab-width: 4
+ * End:
+ */
diff -u --recursive --new-file v1.1.21/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.1.21/linux/drivers/scsi/scsi.c	Fri Jun 17 15:20:06 1994
+++ linux/drivers/scsi/scsi.c	Thu Jun 23 22:29:28 1994
@@ -142,6 +142,7 @@
    {"MAXTOR","XT-4380S","B3C"},   /* Locks-up when LUN>0 polled. */
    {"MAXTOR","MXT-1240S","I1.2"}, /* Locks up when LUN > 0 polled */
    {"MAXTOR","XT-4170S","B5A"},   /* Locks-up sometimes when LUN>0 polled. */
+   {"MAXTOR","XT-8760S","B6B"},   /* Locks-up when LUN > 0 is polled */
    {"MAXTOR","XT-8760S","B7B"},   /* guess what? */
    {"NEC","CD-ROM DRIVE:841","1.0"},  /* Locks-up when LUN>0 polled. */
    {"RODIME","RO3000S","2.33"},  /* Locks up if polled for lun != 0 */
diff -u --recursive --new-file v1.1.21/linux/include/linux/if_arp.h linux/include/linux/if_arp.h
--- v1.1.21/linux/include/linux/if_arp.h	Tue May 24 00:34:56 1994
+++ linux/include/linux/if_arp.h	Thu Jun 23 22:09:41 1994
@@ -37,6 +37,7 @@
 #define ARPHRD_CSLIP6	259
 #define ARPHRD_RSRVD	260		/* Notional KISS type 		*/
 #define ARPHRD_ADAPT	264
+#define ARPHRD_PPP	512
 
 /* ARP protocol opcodes. */
 #define	ARPOP_REQUEST	1		/* ARP request			*/
diff -u --recursive --new-file v1.1.21/linux/include/linux/route.h linux/include/linux/route.h
--- v1.1.21/linux/include/linux/route.h	Tue May 24 00:34:56 1994
+++ linux/include/linux/route.h	Thu Jun 23 22:09:41 1994
@@ -22,6 +22,7 @@
 
 
 /* This structure gets passed by the SIOCADDRTOLD and SIOCDELRTOLD calls. */
+
 struct old_rtentry {
 	unsigned long	rt_genmask;
 	struct sockaddr	rt_dst;
@@ -44,7 +45,8 @@
 	struct ifnet	*rt_ifp;
 	short		rt_metric;	/* +1 for binary compatibility!	*/
 	char		*rt_dev;	/* forcing the device at add	*/
-	unsigned long	rt_mtu;		/* per route MTU/Window */
+	unsigned long	rt_mss;		/* per route MTU/Window */
+	unsigned long	rt_window;	/* Window clamping */
 };
 
 
@@ -54,5 +56,14 @@
 #define RTF_REINSTATE	0x0008		/* re-instate route after tmout	  */
 #define	RTF_DYNAMIC	0x0010		/* created dyn. (by redirect)	  */
 #define	RTF_MODIFIED	0x0020		/* modified dyn. (by redirect)	  */
-#define RTF_MTU		0x0040		/* specific MSS for this route	  */
+#define RTF_MSS		0x0040		/* specific MSS for this route	  */
+#define RTF_WINDOW	0x0080		/* per route window clamping	  */
+
+/*
+ *	REMOVE THESE BY 1.2.0 !!!!!!!!!!!!!!!!!
+ */
+ 
+#define	RTF_MTU		RTF_MSS
+#define rt_mtu		rt_mss		
+
 #endif	/* _LINUX_ROUTE_H */
diff -u --recursive --new-file v1.1.21/linux/mm/memory.c linux/mm/memory.c
--- v1.1.21/linux/mm/memory.c	Wed Jun 22 14:57:10 1994
+++ linux/mm/memory.c	Wed Jun 22 14:18:49 1994
@@ -45,6 +45,8 @@
 #include <linux/types.h>
 #include <linux/ptrace.h>
 #include <linux/mman.h>
+#include <linux/segment.h>
+#include <asm/segment.h>
 
 /*
  * Define this if things work differently on a i386 and a i486:
@@ -677,6 +679,13 @@
 int verify_area(int type, const void * addr, unsigned long size)
 {
 	struct vm_area_struct * vma;
+
+	/* If the current user space is mapped to kernel space (for the
+	 * case where we use a fake user buffer with get_fs/set_fs()) we
+	 * don't expect to find the address in the user vm map.
+	 */
+	if (get_fs() == get_ds())
+		return 0;
 
 	for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
 		if (!vma)
diff -u --recursive --new-file v1.1.21/linux/modules/NET_MODULES linux/modules/NET_MODULES
--- v1.1.21/linux/modules/NET_MODULES	Tue May 31 12:48:19 1994
+++ linux/modules/NET_MODULES	Thu Jun 23 23:01:49 1994
@@ -1 +1 @@
-3c509.o de600.o 3c501.o plip.o
+3c509.o de600.o de620.o 3c501.o plip.o
diff -u --recursive --new-file v1.1.21/linux/net/inet/af_inet.c linux/net/inet/af_inet.c
--- v1.1.21/linux/net/inet/af_inet.c	Wed Jun 22 14:57:11 1994
+++ linux/net/inet/af_inet.c	Thu Jun 23 22:28:16 1994
@@ -839,7 +839,7 @@
 	int err;
 	sock->conn = NULL;
 
-	if (sock->state == SS_CONNECTING && sk->state == TCP_ESTABLISHED)
+	if (sock->state == SS_CONNECTING && tcp_connected(sk->state))
 	{
 		sock->state = SS_CONNECTED;
 		/* Connection completing after a connect/EINPROGRESS/select/connect */
diff -u --recursive --new-file v1.1.21/linux/net/inet/icmp.c linux/net/inet/icmp.c
--- v1.1.21/linux/net/inet/icmp.c	Tue May 24 00:35:01 1994
+++ linux/net/inet/icmp.c	Thu Jun 23 22:09:40 1994
@@ -308,7 +308,7 @@
 			 */
 #ifdef not_a_good_idea
 			ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
-				ip, 0, icmph->un.gateway, dev,0);
+				ip, 0, icmph->un.gateway, dev,0, 0);
 			break;
 #endif
 		case ICMP_REDIR_HOST:
@@ -324,7 +324,7 @@
 				break;
 			printk("redirect from %08lx\n", source);
 			ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_HOST | RTF_GATEWAY),
-				ip, 0, icmph->un.gateway, dev,0);
+				ip, 0, icmph->un.gateway, dev,0, 0);
 			break;
 		case ICMP_REDIR_NETTOS:
 		case ICMP_REDIR_HOSTTOS:
diff -u --recursive --new-file v1.1.21/linux/net/inet/ip.c linux/net/inet/ip.c
--- v1.1.21/linux/net/inet/ip.c	Wed Jun 22 14:57:11 1994
+++ linux/net/inet/ip.c	Thu Jun 23 22:09:40 1994
@@ -1523,8 +1523,8 @@
 #ifdef CONFIG_IP_FORWARD
 		ip_forward(skb, dev, is_frag);
 #else
-		printk("Machine %lx tried to use us as a forwarder to %lx but we have forwarding disabled!\n",
-			iph->saddr,iph->daddr);
+/*		printk("Machine %lx tried to use us as a forwarder to %lx but we have forwarding disabled!\n",
+			iph->saddr,iph->daddr);*/
 		ip_statistics.IpInAddrErrors++;
 #endif			
 		/*
diff -u --recursive --new-file v1.1.21/linux/net/inet/ipx.c linux/net/inet/ipx.c
--- v1.1.21/linux/net/inet/ipx.c	Tue Jun 21 14:16:28 1994
+++ linux/net/inet/ipx.c	Thu Jun 23 22:09:40 1994
@@ -26,6 +26,7 @@
  *			identification, support for local net 0 and
  *			multiple datalinks <Greg Page>
  *	Revision 0.26:  Device drop kills IPX routes via it. (needed for modules)
+ *	Revision 0.27:  Autobind <Mark Evans>
  *
  *			
  *
@@ -640,18 +641,11 @@
 static unsigned short first_free_socketnum(void)
 {
 	static unsigned short	socketNum = 0x4000;
-	unsigned short	startNum, foundNum = 0;
 
-	startNum = socketNum;
-	do {
-		if (ipx_find_socket(htons(socketNum)) == NULL) {
-			foundNum = socketNum;
-		}
-		socketNum++;
+	while (ipx_find_socket(htons(socketNum)) != NULL)
 		if (socketNum > 0x7ffc) socketNum = 0x4000;
-	}	while (!foundNum && (socketNum != startNum));
 
-	return	htons(foundNum);
+	return	htons(socketNum++);
 }
 	
 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
@@ -736,9 +730,17 @@
 		return(-EINVAL);
 	addr=(struct sockaddr_ipx *)uaddr;
 	
-	if(sk->ipx_source_addr.net==0)	/* Must bind first - no autobinding in this */
-		return -EINVAL;
-		
+	if(sk->ipx_source_addr.net==0)
+	/* put the autobinding in */
+	{
+		struct sockaddr_ipx uaddr;
+		int ret;
+	
+		uaddr.sipx_port = 0;
+		uaddr.sipx_network = 0L; 
+		ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
+		if (ret != 0) return (ret);
+	}
 	
 	sk->ipx_dest_addr.net=addr->sipx_network;
 	sk->ipx_dest_addr.sock=addr->sipx_port;
@@ -970,6 +972,18 @@
 		
 	if(usipx)
 	{
+		if(sk->ipx_source_addr.net==0)
+		/* put the autobinding in */
+		{
+			struct sockaddr_ipx uaddr;
+			int ret;
+
+			uaddr.sipx_port = 0;
+			uaddr.sipx_network = 0L; 
+			ret = ipx_bind (sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx));
+			if (ret != 0) return (ret);
+		}
+
 		if(addr_len <sizeof(*usipx))
 			return(-EINVAL);
 		if(usipx->sipx_family != AF_IPX)
diff -u --recursive --new-file v1.1.21/linux/net/inet/route.c linux/net/inet/route.c
--- v1.1.21/linux/net/inet/route.c	Tue May 24 00:35:03 1994
+++ linux/net/inet/route.c	Thu Jun 23 22:09:40 1994
@@ -21,6 +21,8 @@
  *		Alan Cox	:	Added BSD route gw semantics
  *		Alan Cox	:	Super /proc >4K 
  *		Alan Cox	:	MTU in route table
+ *		Alan Cox	: 	MSS actually. Also added the window
+ *					clamper.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -195,7 +197,7 @@
  */
  
 void ip_rt_add(short flags, unsigned long dst, unsigned long mask,
-	unsigned long gw, struct device *dev, unsigned short mtu)
+	unsigned long gw, struct device *dev, unsigned short mtu, unsigned long window)
 {
 	struct rtable *r, *rt;
 	struct rtable **rp;
@@ -267,12 +269,16 @@
 	rt->rt_dev = dev;
 	rt->rt_gateway = gw;
 	rt->rt_mask = mask;
-	rt->rt_mtu = dev->mtu;
+	rt->rt_mss = dev->mtu - HEADER_SIZE;
+	rt->rt_window = 0;	/* Default is no clamping */
 
 	/* Are the MSS/Window valid ? */
 
-	if(rt->rt_flags & RTF_MTU)
-		rt->rt_mtu = mtu;
+	if(rt->rt_flags & RTF_MSS)
+		rt->rt_mss = mtu;
+		
+	if(rt->rt_flags & RTF_WINDOW)
+		rt->rt_window = window;
 
 	/*
 	 *	What we have to do is loop though this until we have
@@ -449,7 +455,7 @@
 	 *	Add the route
 	 */
 	 
-	ip_rt_add(flags, daddr, mask, gw, dev, r->rt_mtu);
+	ip_rt_add(flags, daddr, mask, gw, dev, r->rt_mss, r->rt_window);
 	return 0;
 }
 
@@ -481,7 +487,7 @@
 	int size;
 
 	len += sprintf(buffer,
-		 "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\tMTU\n");
+		 "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\n");
 	pos=len;
   
 	/*
@@ -490,10 +496,10 @@
 	 
 	for (r = rt_base; r != NULL; r = r->rt_next) 
 	{
-        	size = sprintf(buffer+len, "%s\t%08lX\t%08lX\t%02X\t%d\t%lu\t%d\t%08lX\t%d\n",
+        	size = sprintf(buffer+len, "%s\t%08lX\t%08lX\t%02X\t%d\t%lu\t%d\t%08lX\t%d\t%lu\n",
 			r->rt_dev->name, r->rt_dst, r->rt_gateway,
 			r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric,
-			r->rt_mask, (int)r->rt_mtu);
+			r->rt_mask, (int)r->rt_mss, r->rt_window);
 		len+=size;
 		pos+=size;
 		if(pos<offset)
diff -u --recursive --new-file v1.1.21/linux/net/inet/route.h linux/net/inet/route.h
--- v1.1.21/linux/net/inet/route.h	Tue May 24 00:35:03 1994
+++ linux/net/inet/route.h	Thu Jun 23 22:09:40 1994
@@ -36,14 +36,15 @@
 	unsigned char		rt_metric;
 	short			rt_refcnt;
 	unsigned long		rt_use;
-	unsigned short		rt_mss, rt_mtu;
+	unsigned short		rt_mss;
+	unsigned long		rt_window;
 	struct device		*rt_dev;
 };
 
 
 extern void		ip_rt_flush(struct device *dev);
 extern void		ip_rt_add(short flags, unsigned long addr, unsigned long mask,
-			       unsigned long gw, struct device *dev, unsigned short);
+			       unsigned long gw, struct device *dev, unsigned short mss, unsigned long window);
 extern struct rtable	*ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr);
 extern struct rtable 	*ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr);
 extern int		rt_get_info(char * buffer, char **start, off_t offset, int length);
diff -u --recursive --new-file v1.1.21/linux/net/inet/sock.h linux/net/inet/sock.h
--- v1.1.21/linux/net/inet/sock.h	Tue Jun 21 14:16:29 1994
+++ linux/net/inet/sock.h	Thu Jun 23 22:09:40 1994
@@ -109,6 +109,7 @@
   volatile unsigned short	mss;       /* current eff. mss - can change */
   volatile unsigned short	user_mss;  /* mss requested by user in ioctl */
   volatile unsigned short	max_window;
+  unsigned long 		window_clamp;
   unsigned short		num;
   volatile unsigned short	cong_window;
   volatile unsigned short	cong_count;
diff -u --recursive --new-file v1.1.21/linux/net/inet/tcp.c linux/net/inet/tcp.c
--- v1.1.21/linux/net/inet/tcp.c	Wed Jun 22 14:57:11 1994
+++ linux/net/inet/tcp.c	Thu Jun 23 22:09:41 1994
@@ -76,6 +76,9 @@
  *		Alan Cox	:	Move to kernel side addressing changes.
  *		Alan Cox	:	Beginning work on TCP fastpathing (not yet usable)
  *		Arnt Gulbrandsen:	Turbocharged tcp_check() routine.
+ *		Alan Cox	:	TCP fast path debugging
+ *		Alan Cox	:	Window clamping
+ *		Michael Riepe	:	Bug in tcp_check()
  *
  *
  * To Fix:
@@ -152,7 +155,7 @@
 #include <asm/segment.h>
 #include <linux/mm.h>
 
-#define TCP_FASTPATH
+#undef TCP_FASTPATH
 
 #define SEQ_TICK 3
 unsigned long seq_offset;
@@ -183,8 +186,6 @@
    in order to get the data we are waiting for into the memory limit.
    Secondly we bin common duplicate forms at receive time
    
-   TODO: add sk->window_clamp to limit windows over the DE600 and AX.25
-
    Better heuristics welcome
 */
    
@@ -192,6 +193,8 @@
 {
 	int new_window = sk->prot->rspace(sk);
 	
+	if(sk->window_clamp)
+		new_window=min(sk->window_clamp,new_window);
 /*
  * two things are going on here.  First, we don't ever offer a
  * window less than min(sk->mss, MAX_WINDOW/2).  This is the
@@ -565,8 +568,7 @@
 	    adcl $0, %%ebx
 	    movl %%edx, %%ecx
 2:	    andl $28, %%ecx
-	    cmpl $4, %%ecx
-	    jb 4f
+	    je 4f
 	    shrl $2, %%ecx
 	    clc
 3:	    lodsl
@@ -578,11 +580,13 @@
 	    je 5f
 	    lodsw
 	    addl %%eax, %%ebx
+	    adcl $0, %%ebx
 	    movw $0, %%ax
 5:	    test $1, %%edx
 	    je 6f
 	    lodsb
 	    addl %%eax, %%ebx
+	    adcl $0, %%ebx
 6:	    movl %%ebx, %%eax
 	    shrl $16, %%eax
 	    addw %%ax, %%bx
@@ -2024,10 +2028,16 @@
 	 */
 
 	rt=ip_rt_route(saddr, NULL,NULL);
+	
+	if(rt!=NULL && (rt->rt_flags&RTF_WINDOW))
+		sk->window_clamp=rt->rt_window;
+	else
+		sk->window_clamp=0;
+		
 	if (sk->user_mss)
 		newsk->mtu = sk->user_mss;
-	else if(rt!=NULL && (rt->rt_flags&RTF_MTU))
-		newsk->mtu = rt->rt_mtu - HEADER_SIZE;
+	else if(rt!=NULL && (rt->rt_flags&RTF_MSS))
+		newsk->mtu = rt->rt_mss - HEADER_SIZE;
 	else 
 	{
 #ifdef CONFIG_INET_SNARL	/* Sub Nets ARe Local */
@@ -2270,6 +2280,7 @@
 				         sizeof(struct tcphdr),sk->ip_tos,sk->ip_ttl);
 			if (tmp < 0) 
 			{
+				sk->write_seq++;	/* Very important 8) */
 				kfree_skb(buff,FREE_WRITE);
 
 				/*
@@ -2481,12 +2492,18 @@
 	if (sk->retransmits && sk->timeout == TIME_KEEPOPEN)
 	  	sk->retransmits = 0;
 
+#if 0
 /*
  *	Not quite clear why the +1 and -1 here, and why not +1 in next line 
  */
  
 	if (after(ack, sk->sent_seq+1) || before(ack, sk->rcv_ack_seq-1)) 
+#else	
+	if (after(ack, sk->sent_seq) || before(ack, sk->rcv_ack_seq)) 
+#endif	
 	{
+		if(sk->debug)
+			printk("Ack ignored %lu %lu\n",ack,sk->sent_seq);
 		if (after(ack, sk->sent_seq) ||
 		   (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT)) 
 		{
@@ -2841,6 +2858,7 @@
 
 	if (sk->state == TCP_FIN_WAIT1) 
 	{
+
 		if (!sk->dead) 
 			sk->state_change(sk);
 		if (sk->rcv_ack_seq == sk->write_seq) 
@@ -2866,6 +2884,7 @@
 
 	if (sk->state == TCP_CLOSING) 
 	{
+
 		if (!sk->dead) 
 			sk->state_change(sk);
 		if (sk->rcv_ack_seq == sk->write_seq) 
@@ -2974,10 +2993,12 @@
 				sk->state_change(sk);
 			return(0);
 		}
+#if 0		
 		/* Discard the frame here - we've already proved its a duplicate */
 		
 		kfree_skb(skb, FREE_READ);
 		return(0);				
+#endif		
 	}
 	/*
 	 * 	Now we have to walk the chain, and figure out where this one
@@ -3523,11 +3544,16 @@
 	t1->urg_ptr = 0;
 	t1->doff = 6;
 	/* use 512 or whatever user asked for */
+	
+	if(rt!=NULL && (rt->rt_flags&RTF_WINDOW))
+		sk->window_clamp=rt->rt_window;
+	else
+		sk->window_clamp=0;
 
 	if (sk->user_mss)
 		sk->mtu = sk->user_mss;
-	else if(rt!=NULL && rt->rt_flags&RTF_MTU)
-		sk->mtu = rt->rt_mtu;
+	else if(rt!=NULL && (rt->rt_flags&RTF_MTU))
+		sk->mtu = rt->rt_mss;
 	else 
 	{
 #ifdef CONFIG_INET_SNARL
@@ -3779,7 +3805,7 @@
  */
  
 	/* Im trusting gcc to optimise this sensibly... might need judicious application of a software mallet */
-	if(!(sk->shutdown & RCV_SHUTDOWN) && sk->state==TCP_ESTABLISHED && !th->urg && !th->syn && !th->fin && !th->rst && !th->urg)
+	if(!(sk->shutdown & RCV_SHUTDOWN) && sk->state==TCP_ESTABLISHED && !th->urg && !th->syn && !th->fin && !th->rst)
 	{	
 		/* Packets in order. Fits window */
 		if(th->seq == sk->acked_seq+1 && sk->window && tcp_clean_end(sk))
@@ -3804,7 +3830,7 @@
 					sk->window-=skb->len;			/* We know its effect on the window */
 				else
 					sk->window=0;
-				sk->acked_seq = th->ack_seq;		/* Easy */
+				sk->acked_seq = th->seq+skb->len;	/* Easy */
 				skb->acked=1;				/* Guaranteed true */
 				if(!sk->delay_acks || sk->ack_backlog >= sk->max_ack_backlog || 
 					sk->bytes_rcv > sk->max_unacked)
@@ -3939,17 +3965,18 @@
 				return(0);
 			}
 
-			if (th->fin && tcp_fin(skb, sk, th, saddr, dev)) {
-				kfree_skb(skb, FREE_READ);
-				release_sock(sk);
-				return(0);
-			}
 	
 			if (tcp_data(skb, sk, saddr, len)) {
 				kfree_skb(skb, FREE_READ);
 				release_sock(sk);
 				return(0);
 			}	
+
+			if (th->fin && tcp_fin(skb, sk, th, saddr, dev)) {
+				kfree_skb(skb, FREE_READ);
+				release_sock(sk);
+				return(0);
+			}
 	
 			release_sock(sk);
 			return(0);
