diff -c -d -P -r kernel-source-2.2.17/Documentation/Configure.help kernel-source-2.2.17-XSurfIDE/Documentation/Configure.help
*** kernel-source-2.2.17/Documentation/Configure.help	Mon Jun 11 21:49:59 2001
--- kernel-source-2.2.17-XSurfIDE/Documentation/Configure.help	Sat Jun  9 19:59:04 2001
***************
*** 697,702 ****
--- 697,711 ----
    (hard disks, CD-ROM drives, etc.) that are connected to the builtin
    IDE interface.
  
+ Amiga X-Surf Ethernet Card IDE Port Support
+ CONFIG_BLK_DEV_XSURFIDE
+   This is a driver for the IDE ports of the X-Surf Ethernet card.
+   These ports provide a low speed IDE connector on any Amiga with
+   an X-Surf card.
+   Say Y if you have such an Amiga with an X-Surf and want to use IDE devices
+   (hard disks, CD-ROM drives, etc.) that are connected to the 
+   IDE interface.
+ 
  Falcon IDE interface support
  CONFIG_BLK_DEV_FALCON_IDE
    This is the IDE driver for the builtin IDE interface on the Atari
***************
*** 11349,11354 ****
--- 11358,11376 ----
    This driver is also available as a module ( = code which can be
    inserted in and removed from the running kernel whenever you
    want). The module is called ariadne2.o. If you want to compile it as
+   a module, say M here and read Documentation/modules.txt.
+ 
+ X-Surf support
+ CONFIG_XSURF
+   If you have an Individual Computers X-Surf Ethernet adapter, say Y.
+   Otherwise, say N.
+ 
+   This only supports the Ethernet interface, not the IDE or 
+   expansion ports.
+ 
+   This driver is also available as a module ( = code which can be
+   inserted in and removed from the running kernel whenever you
+   want). The module is called xsurf.o. If you want to compile it as
    a module, say M here and read Documentation/modules.txt.
  
  A2065 support
diff -c -d -P -r kernel-source-2.2.17/arch/m68k/config.in kernel-source-2.2.17-XSurfIDE/arch/m68k/config.in
*** kernel-source-2.2.17/arch/m68k/config.in	Mon Jun 11 21:49:59 2001
--- kernel-source-2.2.17-XSurfIDE/arch/m68k/config.in	Sat Jun  9 19:37:59 2001
***************
*** 250,255 ****
--- 250,256 ----
    tristate 'Ariadne II support' CONFIG_ARIADNE2
    tristate 'A2065 support' CONFIG_A2065
    tristate 'Hydra support' CONFIG_HYDRA
+   tristate 'X-Surf support' CONFIG_XSURF
  fi
  if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then
    tristate 'PCMCIA NE2000 support' CONFIG_APNE
Only in kernel-source-2.2.17/arch/m68k/kernel: m68k_defs.h
diff -c -d -P -r kernel-source-2.2.17/drivers/block/Config.in kernel-source-2.2.17-XSurfIDE/drivers/block/Config.in
*** kernel-source-2.2.17/drivers/block/Config.in	Mon Jun 11 21:49:59 2001
--- kernel-source-2.2.17-XSurfIDE/drivers/block/Config.in	Sun Jun 10 22:32:22 2001
***************
*** 33,38 ****
--- 33,41 ----
        if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
  	bool '   Amiga IDE Doubler support' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE
        fi
+       if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+         bool '   Amiga X-Surf IDE interface support' CONFIG_BLK_DEV_XSURFIDE
+       fi
      fi
      if [ "$CONFIG_ZORRO" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
        bool '   Buddha/Catweasel IDE interface support' CONFIG_BLK_DEV_BUDDHA
diff -c -d -P -r kernel-source-2.2.17/drivers/block/Makefile kernel-source-2.2.17-XSurfIDE/drivers/block/Makefile
*** kernel-source-2.2.17/drivers/block/Makefile	Mon Jun 11 21:49:59 2001
--- kernel-source-2.2.17-XSurfIDE/drivers/block/Makefile	Sat Jun  9 19:55:37 2001
***************
*** 244,249 ****
--- 244,253 ----
  IDE_OBJS += gayle.o
  endif
  
+ ifeq ($(CONFIG_BLK_DEV_XSURFIDE),y)
+ IDE_OBJS += xsurf-ide.o
+ endif
+ 
  ifeq ($(CONFIG_BLK_DEV_Q40IDE),y)
  IDE_OBJS += q40ide.o
  endif
diff -c -d -P -r kernel-source-2.2.17/drivers/block/ide.c kernel-source-2.2.17-XSurfIDE/drivers/block/ide.c
*** kernel-source-2.2.17/drivers/block/ide.c	Mon Jun 11 21:49:59 2001
--- kernel-source-2.2.17-XSurfIDE/drivers/block/ide.c	Sat Jun  9 22:07:12 2001
***************
*** 209,214 ****
--- 209,215 ----
      extern int macide_probe_hwif(int index, ide_hwif_t *hwif);
      extern int buddha_probe_hwif(int index, ide_hwif_t *hwif);
      extern int q40ide_probe_hwif(int index, ide_hwif_t *hwif);
+     extern int xsurfide_probe_hwif(int index, ide_hwif_t *hwif);
  
      return 0
  #ifdef CONFIG_BLK_DEV_PCIDE
***************
*** 228,233 ****
--- 229,237 ----
  #endif
  #ifdef CONFIG_Q40
          || q40ide_probe_hwif(index, hwif)
+ #endif
+ #ifdef CONFIG_BLK_DEV_XSURFIDE
+       || xsurfide_probe_hwif(index, hwif)
  #endif
      ;
  }
diff -c -d -P -r kernel-source-2.2.17/drivers/block/xsurf-ide.c kernel-source-2.2.17-XSurfIDE/drivers/block/xsurf-ide.c
*** kernel-source-2.2.17/drivers/block/xsurf-ide.c	Wed Dec 31 19:00:00 1969
--- kernel-source-2.2.17-XSurfIDE/drivers/block/xsurf-ide.c	Mon Jun 11 22:48:45 2001
***************
*** 0 ****
--- 1,170 ----
+ /*
+  *  linux/drivers/block/xsurfide.c -- Amiga Xsurf IDE port driver 
+  *
+  *  This has NOT been extensivly tested!
+  *  I was able to ID the drive, partition it, create a filesystem and 
+  *  copy some files to it.
+  * 
+  *  I have only tested the 3.5" interface.  I do not have a spare 2.5" 
+  *  drive, especially one that uses less than 300mA (X-Surf power limit)
+  *
+  *  Written with the help of the Inside_XSurf.txt file from www.jschonfeld.com
+  *  and a very minimal understanding of IDE/Zorro/etc.
+  *
+  *  Based on buddha.c:
+  *	Copyright (C) 1997 by Geert Uytterhoeven
+  *
+  *  This driver was written by based on the specifications in README.buddha.
+  *
+  *  This file is subject to the terms and conditions of the GNU General Public
+  *  License.  See the file COPYING in the main directory of this archive for
+  *  more details.
+  *
+  *  TODO:
+  *    - test it :-)
+  */
+ 
+ #include <linux/types.h>
+ #include <linux/mm.h>
+ #include <linux/interrupt.h>
+ #include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/zorro.h>
+ 
+ #include "ide.h"
+ 
+ #include <asm/amigahw.h>
+ #include <asm/amigaints.h>
+ 
+ 
+ /* zorro_find() part numbers for the two parts of the board */
+ #define XSURF_ETH_PART 0
+ #define XSURF_IDE_PART 1
+ 
+     /*
+      *  The Xsurfide has 2 IDE interfaces
+      */
+ 
+ #define XSURFIDE_NUM_HWIFS	2
+ 
+ 
+     /*
+      *  Bases of the IDE interfaces (relative to the board address)
+      */
+ 
+ #define XSURFIDE_BASE1	0xd000  /* 3.5" port */
+ #define XSURFIDE_BASE2	0xb000  /* 2.5" port */
+ 
+ static const u_int xsurfide_bases[XSURFIDE_NUM_HWIFS] = {
+     XSURFIDE_BASE1, XSURFIDE_BASE2
+ };
+ 
+ 
+     /*
+      *  Offsets from one of the above bases
+      */
+ 
+ #define XSURFIDE_DATA	0x00
+ #define XSURFIDE_ERROR	0x06		/* see err-bits */
+ #define XSURFIDE_NSECTOR	0x0a		/* nr of sectors to read/write */
+ #define XSURFIDE_SECTOR	0x0e		/* starting sector */
+ #define XSURFIDE_LCYL	0x12		/* starting cylinder */
+ #define XSURFIDE_HCYL	0x16		/* high byte of starting cyl */
+ #define XSURFIDE_SELECT	0x1a		/* 101dhhhh , d=drive, hhhh=head */
+ #define XSURFIDE_STATUS	0x1e		/* see status-bits */
+ #define XSURFIDE_CONTROL	-1 /* X-Surf does not have /CS1 */
+ 
+ static const u_int xsurfide_offsets[IDE_NR_PORTS] = {
+     XSURFIDE_DATA, XSURFIDE_ERROR, XSURFIDE_NSECTOR, XSURFIDE_SECTOR, XSURFIDE_LCYL,
+     XSURFIDE_HCYL, XSURFIDE_SELECT, XSURFIDE_STATUS, XSURFIDE_CONTROL
+ };
+ 
+ 
+     /*
+      *  Other registers
+      */
+ 
+ #define XSURFIDE_IRQ1	0x007e		/* MSB = 1, Harddisk is source of */
+ #define XSURFIDE_IRQ2	0x007e		/* interrupt */
+ 
+ static const int xsurfide_irqports[XSURFIDE_NUM_HWIFS] = {
+     XSURFIDE_IRQ1, XSURFIDE_IRQ2, 
+ };
+ 
+     /*
+      *  Board information
+      */
+ 
+ static u_long xsurfide_board = 0;
+ static int xsurfide_num_hwifs = -1;
+ 
+ 
+     /*
+      *  Check and acknowledge the interrupt status
+      */
+ 
+ static int xsurfide_ack_intr(ide_hwif_t *hwif)
+ {
+     unsigned char ch;
+ 
+     ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+     if (!(ch & 0x80))
+ 	return 0;
+     return 1;
+ }
+ 
+ 
+     /*
+      *  Any X-Surf boards present?
+      */
+ 
+ static int find_xsurfide(void)
+ {
+     u_int key;
+     const struct ConfigDev *cd;
+ 
+     xsurfide_num_hwifs = 0;
+     if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_XSURF, XSURF_IDE_PART, 0))) {
+       xsurfide_num_hwifs = XSURFIDE_NUM_HWIFS;
+       if (key) {
+ 	cd = zorro_get_board(key);
+ 	xsurfide_board = (u_long)cd->cd_BoardAddr;
+ 	if (xsurfide_board) {
+ 	  xsurfide_board = ZTWO_VADDR(xsurfide_board);
+ 	  zorro_config_board(key, XSURF_IDE_PART);
+ 	}
+       }
+     }
+     return xsurfide_num_hwifs;
+ }
+ 
+ 
+ /*
+  *  Probe for a Xsurfide IDE interface
+  *  We support only _one_ of them, no multiple boards!
+  */
+ 
+ int xsurfide_probe_hwif(int index, ide_hwif_t *hwif)
+ {
+   static int xsurfide_index[XSURFIDE_NUM_HWIFS] = { 0, };
+   int i;
+   
+   if (xsurfide_num_hwifs < 0 && !find_xsurfide())
+     return 0;
+   
+   for (i = 0; i < xsurfide_num_hwifs; i++) {
+     if (!xsurfide_index[i]) {
+       printk("ide%d: X-Surf IDE interface\n", index);
+       xsurfide_index[i] = index+1;
+     }
+     if (xsurfide_index[i] == index+1) {
+       ide_setup_ports(hwif, (ide_ioreg_t)(xsurfide_board+xsurfide_bases[i]),
+ 		      xsurfide_offsets,
+ 		      (ide_ioreg_t)(xsurfide_board+xsurfide_irqports[i]),
+ 		      xsurfide_ack_intr);
+       hwif->irq = IRQ_AMIGA_PORTS;
+       return 1;
+     }
+   }
+   return 0;
+ }
diff -c -d -P -r kernel-source-2.2.17/drivers/net/Config.in kernel-source-2.2.17-XSurfIDE/drivers/net/Config.in
*** kernel-source-2.2.17/drivers/net/Config.in	Mon Jun 11 21:49:57 2001
--- kernel-source-2.2.17-XSurfIDE/drivers/net/Config.in	Sat Jun  9 19:37:59 2001
***************
*** 58,63 ****
--- 58,64 ----
      tristate 'Ariadne II support' CONFIG_ARIADNE2
      tristate 'A2065 support' CONFIG_A2065
      tristate 'Hydra support' CONFIG_HYDRA
+     tristate 'X-Surf support' CONFIG_XSURF
    fi
    if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
      tristate 'MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC
diff -c -d -P -r kernel-source-2.2.17/drivers/net/Makefile kernel-source-2.2.17-XSurfIDE/drivers/net/Makefile
*** kernel-source-2.2.17/drivers/net/Makefile	Mon Jun 11 21:49:59 2001
--- kernel-source-2.2.17-XSurfIDE/drivers/net/Makefile	Sat Jun  9 19:37:59 2001
***************
*** 1069,1074 ****
--- 1069,1085 ----
    endif
  endif
  
+ ifeq ($(CONFIG_XSURF),y)
+ L_OBJS += xsurf.o
+ CONFIG_8390_BUILTIN = y
+ else
+   ifeq ($(CONFIG_XSURF),m)
+   M_OBJS += xsurf.o
+   CONFIG_8390_MODULE = y
+   endif
+ endif
+ 
+ 
  # If anything built-in uses the 8390, then build it into the kernel also.
  # If not, but a module uses it, build as a module.
  ifdef CONFIG_8390_BUILTIN
diff -c -d -P -r kernel-source-2.2.17/drivers/net/xsurf.c kernel-source-2.2.17-XSurfIDE/drivers/net/xsurf.c
*** kernel-source-2.2.17/drivers/net/xsurf.c	Wed Dec 31 19:00:00 1969
--- kernel-source-2.2.17-XSurfIDE/drivers/net/xsurf.c	Sun Jun 10 22:27:01 2001
***************
*** 0 ****
--- 1,444 ----
+ /* xsurf.c - Driver for the X-Surf card
+  * June 2, 2001
+  * 
+  * This is just the patch from www.jschonfeld.com applied to the 
+  * AriadneII driver.  I also went and changed all the variable names and the strings.
+  *
+  * This is only the Ethernet driver.  It does not support the IDE or expansion 
+  * ports on the card.
+  *
+  * As usual there is no warrenty.  Use at your own risk.  It worked for me...
+  * 
+  * Original comments below
+  */
+ 
+ /*
+  *  Amiga Linux/m68k Ariadne II Ethernet Driver
+  *
+  *  (C) Copyright 1998 by some Elitist 680x0 Users(TM)
+  *
+  *  ---------------------------------------------------------------------------
+  *
+  *  This program is based on all the other NE2000 drivers for Linux
+  *
+  *  ---------------------------------------------------------------------------
+  *
+  *  This file is subject to the terms and conditions of the GNU General Public
+  *  License.  See the file COPYING in the main directory of the Linux
+  *  distribution for more details.
+  *
+  *  ---------------------------------------------------------------------------
+  *
+  *  The Ariadne II is a Zorro-II board made by Village Tronic. It contains a
+  *  Realtek RTL8019AS Ethernet Controller.
+  */
+ 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/zorro.h>
+ 
+ #include <asm/system.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/amigaints.h>
+ #include <asm/amigahw.h>
+ 
+ #include "8390.h"
+ 
+ /* zorro_find() part numbers for the two parts of the board */
+ #define XSURF_ETH_PART 0
+ #define XSURF_IDE_PART 1
+ 
+ #define XSURF_BASE		0x8600
+ #define ARIADNE2_BOOTROM	0xc000
+ 
+ 
+ #define NE_BASE		(dev->base_addr)
+ #define NE_CMD		(0x00*2)
+ #define NE_DATAPORT	(0x10*2)	/* NatSemi-defined port window offset. */
+ #define NE_RESET	(0x1f*2)	/* Issue a read to reset, a write to clear. */
+ #define NE_IO_EXTENT	(0x20*2)
+ 
+ #define NE_EN0_ISR	(0x07*2)
+ #define NE_EN0_DCFG	(0x0e*2)
+ 
+ #define NE_EN0_RSARLO	(0x08*2)
+ #define NE_EN0_RSARHI	(0x09*2)
+ #define NE_EN0_RCNTLO	(0x0a*2)
+ #define NE_EN0_RXCR	(0x0c*2)
+ #define NE_EN0_TXCR	(0x0d*2)
+ #define NE_EN0_RCNTHI	(0x0b*2)
+ #define NE_EN0_IMR	(0x0f*2)
+ 
+ #define NESM_START_PG	0x40	/* First page of TX buffer */
+ #define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
+ 
+ 
+ #define WORDSWAP(a)	((((a)>>8)&0xff) | ((a)<<8))
+ 
+ int xsurf_probe(struct device *dev);
+ static int xsurf_init(struct device *dev, unsigned int key,
+ 			 unsigned long board);
+ 
+ static int xsurf_open(struct device *dev);
+ static int xsurf_close(struct device *dev);
+ 
+ static void xsurf_reset_8390(struct device *dev);
+ static void xsurf_get_8390_hdr(struct device *dev,
+ 				  struct e8390_pkt_hdr *hdr, int ring_page);
+ static void xsurf_block_input(struct device *dev, int count,
+ 				 struct sk_buff *skb, int ring_offset);
+ static void xsurf_block_output(struct device *dev, const int count,
+ 				  const unsigned char *buf,
+ 				  const int start_page);
+ 
+ 
+ __initfunc(int xsurf_probe(struct device *dev))
+ {
+     unsigned int key;
+     const struct ConfigDev *cd;
+     u_long board;
+     int err;
+ 
+     if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_XSURF, XSURF_ETH_PART, 0))) {
+ 	cd = zorro_get_board(key);
+ 	if ((board = (u_long)cd->cd_BoardAddr)) {
+ 	    if ((err = xsurf_init(dev, key, ZTWO_VADDR(board))))
+ 		return err;
+ 	    zorro_config_board(key, XSURF_ETH_PART);
+ 	    return 0;
+ 	}
+     }
+     return -ENODEV;
+ }
+ 
+ __initfunc(static int xsurf_init(struct device *dev, unsigned int key,
+ 				    unsigned long board))
+ {
+     int i;
+     unsigned char SA_prom[32];
+     const char *name = NULL;
+     int start_page, stop_page;
+     static u32 xsurf_offsets[16] = {
+ 	0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
+ 	0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+     };
+     int ioaddr = board+XSURF_BASE;
+ 
+     if (load_8390_module("xsurf.c"))
+ 	return -ENOSYS;
+ 
+     /* We should have a "dev" from Space.c or the static module table. */
+     if (dev == NULL) {
+ 	printk(KERN_ERR "xsurf.c: Passed a NULL device.\n");
+ 	dev = init_etherdev(0, 0);
+     }
+ 
+     /* Reset card. Who knows what dain-bramaged state it was left in. */
+     {
+ 	unsigned long reset_start_time = jiffies;
+ 
+ 	writeb(readb(ioaddr + NE_RESET), ioaddr + NE_RESET);
+ 
+ 	while ((readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
+ 	    if (jiffies - reset_start_time > 2*HZ/100) {
+ 		printk(" not found (no reset ack).\n");
+ 		return -ENODEV;
+ 	    }
+ 
+ 	writeb(0xff, ioaddr + NE_EN0_ISR);		/* Ack all intr. */
+     }
+ 
+     /* Read the 16 bytes of station address PROM.
+        We must first initialize registers, similar to NS8390_init(eifdev, 0).
+        We can't reliably read the SAPROM address without this.
+        (I learned the hard way!). */
+     {
+ 	struct {
+ 	    u32 value;
+ 	    u32 offset;
+ 	} program_seq[] = {
+ 	    {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/
+ 	    {0x48,	NE_EN0_DCFG},	/* Set byte-wide (0x48) access. */
+ 	    {0x00,	NE_EN0_RCNTLO},	/* Clear the count regs. */
+ 	    {0x00,	NE_EN0_RCNTHI},
+ 	    {0x00,	NE_EN0_IMR},	/* Mask completion irq. */
+ 	    {0xFF,	NE_EN0_ISR},
+ 	    {E8390_RXOFF, NE_EN0_RXCR},	/* 0x20  Set to monitor */
+ 	    {E8390_TXOFF, NE_EN0_TXCR},	/* 0x02  and loopback mode. */
+ 	    {32,	NE_EN0_RCNTLO},
+ 	    {0x00,	NE_EN0_RCNTHI},
+ 	    {0x00,	NE_EN0_RSARLO},	/* DMA starting at 0x0000. */
+ 	    {0x00,	NE_EN0_RSARHI},
+ 	    {E8390_RREAD+E8390_START, NE_CMD},
+ 	};
+ 	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) {
+ 	    writeb(program_seq[i].value, ioaddr + program_seq[i].offset);
+ 	}
+     }
+     for (i = 0; i < 16; i++) {
+ 	SA_prom[i] = readb(ioaddr + NE_DATAPORT);
+ 	(void)readb(ioaddr + NE_DATAPORT);
+     }
+ 
+     /* We must set the 8390 for word mode. */
+     writeb(0x49, ioaddr + NE_EN0_DCFG);
+     start_page = NESM_START_PG;
+     stop_page = NESM_STOP_PG;
+ 
+     name = "NE2000";
+ 
+     dev->base_addr = ioaddr;
+ 
+     /* Install the Interrupt handler */
+     if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, 0, "Xsurf Ethernet",
+ 		    dev))
+ 	return -EAGAIN;
+ 
+     /* Allocate dev->priv and fill in 8390 specific dev fields. */
+     if (ethdev_init(dev)) {
+ 	printk("Unable to get memory for dev->priv.\n");
+ 	return -ENOMEM;
+     }
+     ((struct ei_device *)dev->priv)->priv = key;
+ 
+     for(i = 0; i < ETHER_ADDR_LEN; i++) {
+ #ifdef DEBUG
+ 	printk(" %2.2x", SA_prom[i]);
+ #endif
+ 	dev->dev_addr[i] = SA_prom[i];
+     }
+ 
+     printk("%s: Xsurf at 0x%08lx, Ethernet Address "
+ 	   "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board,
+ 	   dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ 	   dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+ 
+     ei_status.name = name;
+     ei_status.tx_start_page = start_page;
+     ei_status.stop_page = stop_page;
+     ei_status.word16 = 1;
+ 
+     ei_status.rx_start_page = start_page + TX_PAGES;
+ 
+     ei_status.reset_8390 = &xsurf_reset_8390;
+     ei_status.block_input = &xsurf_block_input;
+     ei_status.block_output = &xsurf_block_output;
+     ei_status.get_8390_hdr = &xsurf_get_8390_hdr;
+     ei_status.reg_offset = xsurf_offsets;
+     dev->open = &xsurf_open;
+     dev->stop = &xsurf_close;
+     NS8390_init(dev, 0);
+     return 0;
+ }
+ 
+ static int xsurf_open(struct device *dev)
+ {
+     ei_open(dev);
+     MOD_INC_USE_COUNT;
+     return 0;
+ }
+ 
+ static int xsurf_close(struct device *dev)
+ {
+     if (ei_debug > 1)
+ 	printk("%s: Shutting down ethercard.\n", dev->name);
+     ei_close(dev);
+     MOD_DEC_USE_COUNT;
+     return 0;
+ }
+ 
+ /* Hard reset the card.  This used to pause for the same period that a
+    8390 reset command required, but that shouldn't be necessary. */
+ static void xsurf_reset_8390(struct device *dev)
+ {
+     unsigned long reset_start_time = jiffies;
+ 
+     if (ei_debug > 1)
+ 	printk("resetting the 8390 t=%ld...", jiffies);
+ 
+     writeb(readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+ 
+     ei_status.txing = 0;
+     ei_status.dmaing = 0;
+ 
+     /* This check _should_not_ be necessary, omit eventually. */
+     while ((readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
+ 	if (jiffies - reset_start_time > 2*HZ/100) {
+ 	    printk("%s: ne_reset_8390() did not complete.\n", dev->name);
+ 	    break;
+ 	}
+     writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr. */
+ }
+ 
+ /* Grab the 8390 specific header. Similar to the block_input routine, but
+    we don't need to be concerned with ring wrap as the header will be at
+    the start of a page, so we optimize accordingly. */
+ 
+ static void xsurf_get_8390_hdr(struct device *dev,
+ 				  struct e8390_pkt_hdr *hdr, int ring_page)
+ {
+     int nic_base = dev->base_addr;
+     int cnt;
+     short *ptrs;
+ 
+     /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+     if (ei_status.dmaing) {
+ 	printk("%s: DMAing conflict in ne_get_8390_hdr "
+ 	   "[DMAstat:%d][irqlock:%d][intr:%ld].\n", dev->name, ei_status.dmaing,
+ 	   ei_status.irqlock, dev->interrupt);
+ 	return;
+     }
+ 
+     ei_status.dmaing |= 0x01;
+     writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+     writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+     writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
+     writeb(0, nic_base + NE_EN0_RCNTHI);
+     writeb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
+     writeb(ring_page, nic_base + NE_EN0_RSARHI);
+     writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+ 
+     ptrs = (short*)hdr;
+     for (cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
+ 	*ptrs++ = readw(NE_BASE + NE_DATAPORT);
+ 
+     writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+ 
+     hdr->count = WORDSWAP(hdr->count);
+ 
+     ei_status.dmaing &= ~0x01;
+ }
+ 
+ /* Block input and output, similar to the Crynwr packet driver.  If you
+    are porting to a new ethercard, look at the packet driver source for hints.
+    The NEx000 doesn't share the on-board packet memory -- you have to put
+    the packet out through the "remote DMA" dataport using writeb. */
+ 
+ static void xsurf_block_input(struct device *dev, int count,
+ 				 struct sk_buff *skb, int ring_offset)
+ {
+     int nic_base = dev->base_addr;
+     char *buf = skb->data;
+     short *ptrs;
+     int cnt;
+ 
+     /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+     if (ei_status.dmaing) {
+ 	printk("%s: DMAing conflict in ne_block_input "
+ 	   "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+ 	   dev->name, ei_status.dmaing, ei_status.irqlock,
+ 	   dev->interrupt);
+ 	return;
+     }
+     ei_status.dmaing |= 0x01;
+     writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+     writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+     writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+     writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
+     writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
+     writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
+     writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+     ptrs = (short*)buf;
+     for (cnt = 0; cnt < (count>>1); cnt++)
+ 	*ptrs++ = readw(NE_BASE + NE_DATAPORT);
+     if (count & 0x01)
+ 	buf[count-1] = readb(NE_BASE + NE_DATAPORT);
+ 
+     writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+     ei_status.dmaing &= ~0x01;
+ }
+ 
+ static void xsurf_block_output(struct device *dev, int count,
+ 				  const unsigned char *buf,
+ 				  const int start_page)
+ {
+     int nic_base = NE_BASE;
+     unsigned long dma_start;
+     short *ptrs;
+     int cnt;
+ 
+     /* Round the count up for word writes.  Do we need to do this?
+        What effect will an odd byte count have on the 8390?
+        I should check someday. */
+     if (count & 0x01)
+ 	count++;
+ 
+     /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+     if (ei_status.dmaing) {
+ 	printk("%s: DMAing conflict in ne_block_output."
+ 	   "[DMAstat:%d][irqlock:%d][intr:%ld]\n", dev->name, ei_status.dmaing,
+ 	   ei_status.irqlock, dev->interrupt);
+ 	return;
+     }
+     ei_status.dmaing |= 0x01;
+     /* We should already be in page 0, but to be safe... */
+     writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+ 
+     writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+ 
+    /* Now the normal output. */
+     writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+     writeb(count >> 8,   nic_base + NE_EN0_RCNTHI);
+     writeb(0x00, nic_base + NE_EN0_RSARLO);
+     writeb(start_page, nic_base + NE_EN0_RSARHI);
+ 
+     writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+     ptrs = (short*)buf;
+     for (cnt = 0; cnt < count>>1; cnt++)
+ 	writew(*ptrs++, NE_BASE+NE_DATAPORT);
+ 
+     dma_start = jiffies;
+ 
+     while ((readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
+ 	if (jiffies - dma_start > 2*HZ/100) {		/* 20ms */
+ 		printk("%s: timeout waiting for Tx RDC.\n", dev->name);
+ 		xsurf_reset_8390(dev);
+ 		NS8390_init(dev,1);
+ 		break;
+ 	}
+ 
+     writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
+     ei_status.dmaing &= ~0x01;
+     return;
+ }
+ 
+ #ifdef MODULE
+ static char devicename[9] = { 0, };
+ 
+ static struct device xsurf_dev =
+ {
+     devicename,
+     0, 0, 0, 0,
+     0, 0,
+     0, 0, 0, NULL, xsurf_probe,
+ };
+ 
+ int init_module(void)
+ {
+     int err;
+     if ((err = register_netdev(&xsurf_dev))) {
+ 	if (err == -EIO)
+ 	    printk("No Xsurf ethernet card found.\n");
+ 	return err;
+     }
+     lock_8390_module();
+     return 0;
+ }
+ 
+ void cleanup_module(void)
+ {
+     unsigned int key = ((struct ei_device *)xsurf_dev.priv)->priv;
+     free_irq(IRQ_AMIGA_PORTS, &xsurf_dev);
+     unregister_netdev(&xsurf_dev);
+     zorro_unconfig_board(key, XSURF_ETH_PART);
+     unlock_8390_module();
+ }
+ 
+ #endif	/* MODULE */
diff -c -d -P -r kernel-source-2.2.17/include/linux/zorro.h kernel-source-2.2.17-XSurfIDE/include/linux/zorro.h
*** kernel-source-2.2.17/include/linux/zorro.h	Thu Feb 25 13:02:12 1999
--- kernel-source-2.2.17-XSurfIDE/include/linux/zorro.h	Sat Jun  9 19:37:59 2001
***************
*** 470,475 ****
--- 470,476 ----
  #define ZORRO_MANUF_INDIVIDUAL_COMPUTERS			0x1212
  #define  ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA			ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x00, 0)
  #define  ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL		ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x2A, 0)
+ #define ZORRO_PROD_INDIVIDUAL_COMPUTERS_XSURF			ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x17, 0)
  
  #define ZORRO_MANUF_KUPKE_3					0x1248
  #define  ZORRO_PROD_KUPKE_GOLEM_HD_3000				ZORRO_ID(KUPKE_3, 0x01, 0)
