Index: c/src/libchip/ChangeLog
===================================================================
--- c/src/libchip/ChangeLog	(revision cd66632f0bfb4075dc7130af8b698a4ff0112814)
+++ c/src/libchip/ChangeLog	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
@@ -1,2 +1,9 @@
+2002-07-16	Eric Norum <eric.norum@usask.ca>
+
+	* New driver for the Intel EtherExpressPro (82559ER) chip.
+	* network/if_fxp.c, network/if_fxpreg.h, network/if_fxpvar.h,
+	network/pci.h: New file.
+	* network/Makefile.am: Modified to reflect above.
+
 2001-05-14	Till Straumann <strauman@slac.stanford.edu>
 
Index: c/src/libchip/network/Makefile.am
===================================================================
--- c/src/libchip/network/Makefile.am	(revision cd66632f0bfb4075dc7130af8b698a4ff0112814)
+++ c/src/libchip/network/Makefile.am	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
@@ -10,8 +10,8 @@
 
 # add cs8900.c to work with it and make it compile
-C_FILES = dec21140.c i82586.c sonic.c
+C_FILES = dec21140.c i82586.c sonic.c if_fxp.c
 C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
 
-include_libchip_HEADERS = cs8900.h i82586var.h sonic.h
+include_libchip_HEADERS = cs8900.h i82586var.h if_fxpvar.h sonic.h
 
 OBJS = $(C_O_FILES)
@@ -53,5 +53,5 @@
 
 EXTRA_DIST = README README.cs8900 README.dec21140 README.i82586 README.sonic \
-    cs8900.c dec21140.c i82586.c sonic.c
+    cs8900.c dec21140.c i82586.c if_fxp.c sonic.c
 
 include $(top_srcdir)/../../../automake/local.am
Index: c/src/libchip/network/if_fxp.c
===================================================================
--- c/src/libchip/network/if_fxp.c	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
+++ c/src/libchip/network/if_fxp.c	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
@@ -0,0 +1,2294 @@
+/*-
+ * Copyright (c) 1995, David Greenman
+ * Copyright (c) 2001 Jonathan Lemon <jlemon@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/dev/fxp/if_fxp.c,v 1.118 2001/09/05 23:33:58 brooks Exp $
+ */
+
+/*
+ * Intel EtherExpress Pro/100B PCI Fast Ethernet driver
+ */
+
+/*
+ * RTEMS Revision Preliminary History
+ *
+ * July XXX, 2002     W. Eric Norum <eric.norum@usask.ca>
+ *     Placed in RTEMS CVS repository.  All further modifications will be
+ *     noted in the CVS log and not in this comment.
+ *
+ * July 11, 2002     W. Eric Norum <eric.norum@usask.ca>
+ *     Minor modifications to get driver working with NIC on VersaLogic
+ *     Bobcat PC-104 single-board computer.  The Bobcat has no video
+ *     driver so printf/printk calls are directed to COM2:.  This
+ *     arrangement seems to require delays after the printk calls or
+ *     else things lock up.  Perhaps the RTEMS pc386 console code
+ *     should be modified to insert these delays itself.
+ *
+ * June 27, 2002     W. Eric Norum <eric.norum@usask.ca>
+ *     Obtained from Thomas Doerfler <Thomas.Doerfler@imd-systems.de>.
+ *     A big thank-you to Thomas for making this available.
+ *
+ * October 01, 2001  Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
+ *     Original RTEMS modifications.
+ */
+
+#if defined(__i386__)
+
+/*#define DEBUG_OUT 0*/
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+#include <bsp.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <bsp.h>
+#include <pcibios.h>
+#include <irq.h>
+#include "pci.h"
+
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#include <net/bpf.h>
+
+#include <vm/vm.h>		/* for vtophys */
+
+#include <net/if_types.h>
+
+#include "if_fxpreg.h"
+#include "if_fxpvar.h"
+
+/*
+ * some adaptation replacements for RTEMS
+ */
+static rtems_interval fxp_ticksPerSecond;
+#define device_printf(device,format,args...) printk(format,## args)
+#define DELAY(n) rtems_task_wake_after(((n)*fxp_ticksPerSecond/1000000)+1)
+#ifdef DEBUG_OUT
+#define DBGLVL_PRINTK(LVL,format, args...)                   \
+if (DEBUG_OUT >= (LVL)) {                                    \
+  printk(format, ## args);                                   \
+}
+#else
+#define DBGLVL_PRINTK(LVL,format, args...)
+#endif
+
+/*
+ * RTEMS event used by interrupt handler to signal driver tasks.
+ * This must not be any of the events used by the network task synchronization.
+ */
+#define INTERRUPT_EVENT	RTEMS_EVENT_1
+
+/*
+ * remapping between PCI device and CPU memmory address view...
+ */
+#if defined(__i386)
+#define vtophys(p) (u_int32_t)(p)
+#else
+#define vtophys(p) vtophys(p)
+#endif
+
+#define NFXPDRIVER 1
+static struct fxp_softc fxp_softc[NFXPDRIVER];
+static int fxp_is_verbose = TRUE;
+/*
+ * NOTE!  On the Alpha, we have an alignment constraint.  The
+ * card DMAs the packet immediately following the RFA.  However,
+ * the first thing in the packet is a 14-byte Ethernet header.
+ * This means that the packet is misaligned.  To compensate,
+ * we actually offset the RFA 2 bytes into the cluster.  This
+ * alignes the packet after the Ethernet header at a 32-bit
+ * boundary.  HOWEVER!  This means that the RFA is misaligned!
+ */
+#define	RFA_ALIGNMENT_FUDGE	2
+
+/*
+ * Set initial transmit threshold at 64 (512 bytes). This is
+ * increased by 64 (512 bytes) at a time, to maximum of 192
+ * (1536 bytes), if an underrun occurs.
+ */
+static int tx_threshold = 64;
+
+/*
+ * The configuration byte map has several undefined fields which
+ * must be one or must be zero.  Set up a template for these bits
+ * only, (assuming a 82557 chip) leaving the actual configuration
+ * to fxp_init.
+ *
+ * See struct fxp_cb_config for the bit definitions.
+ */
+static u_char fxp_cb_config_template[] = {
+	0x0, 0x0,		/* cb_status */
+	0x0, 0x0,		/* cb_command */
+	0x0, 0x0, 0x0, 0x0,	/* link_addr */
+	0x0,	/*  0 */
+	0x0,	/*  1 */
+	0x0,	/*  2 */
+	0x0,	/*  3 */
+	0x0,	/*  4 */
+	0x0,	/*  5 */
+	0x32,	/*  6 */
+	0x0,	/*  7 */
+	0x0,	/*  8 */
+	0x0,	/*  9 */
+	0x6,	/* 10 */
+	0x0,	/* 11 */
+	0x0,	/* 12 */
+	0x0,	/* 13 */
+	0xf2,	/* 14 */
+	0x48,	/* 15 */
+	0x0,	/* 16 */
+	0x40,	/* 17 */
+	0xf0,	/* 18 */
+	0x0,	/* 19 */
+	0x3f,	/* 20 */
+	0x5	/* 21 */
+};
+
+struct fxp_ident {
+	u_int16_t	devid;
+	char 		*name;
+};
+
+/*
+ * Claim various Intel PCI device identifiers for this driver.  The
+ * sub-vendor and sub-device field are extensively used to identify
+ * particular variants, but we don't currently differentiate between
+ * them.
+ */
+#ifdef NOTUSED
+static struct fxp_ident fxp_ident_table[] = {
+    { 0x1229,		"Intel Pro 10/100B/100+ Ethernet" },
+    { 0x2449,		"Intel Pro/100 Ethernet" },
+    { 0x1209,		"Intel Embedded 10/100 Ethernet" },
+    { 0x1029,		"Intel Pro/100 Ethernet" },
+    { 0x1030,		"Intel Pro/100 Ethernet" },
+    { 0x1031,		"Intel Pro/100 Ethernet" },
+    { 0x1032,		"Intel Pro/100 Ethernet" },
+    { 0x1033,		"Intel Pro/100 Ethernet" },
+    { 0x1034,		"Intel Pro/100 Ethernet" },
+    { 0x1035,		"Intel Pro/100 Ethernet" },
+    { 0x1036,		"Intel Pro/100 Ethernet" },
+    { 0x1037,		"Intel Pro/100 Ethernet" },
+    { 0x1038,		"Intel Pro/100 Ethernet" },
+    { 0,		NULL },
+};
+#endif
+
+#if 0
+static int		fxp_probe(device_t dev);
+static int		fxp_attach(device_t dev);
+static int		fxp_detach(device_t dev);
+static int		fxp_shutdown(device_t dev);
+#endif
+int	fxp_output (struct ifnet *,
+	   struct mbuf *, struct sockaddr *, struct rtentry *);
+
+
+static rtems_isr        fxp_intr(rtems_vector_number v);
+static void 		fxp_init(void *xsc);
+static void 		fxp_tick(void *xsc);
+static void 		fxp_start(struct ifnet *ifp);
+static void		fxp_stop(struct fxp_softc *sc);
+static void 		fxp_release(struct fxp_softc *sc);
+static int		fxp_ioctl(struct ifnet *ifp, int command,
+			    caddr_t data);
+static void 		fxp_watchdog(struct ifnet *ifp);
+static int		fxp_add_rfabuf(struct fxp_softc *sc, struct mbuf *oldm);
+static void		fxp_mc_setup(struct fxp_softc *sc);
+static u_int16_t	fxp_eeprom_getword(struct fxp_softc *sc, int offset,
+			    int autosize);
+static void 		fxp_eeprom_putword(struct fxp_softc *sc, int offset,
+			    u_int16_t data);
+static void		fxp_autosize_eeprom(struct fxp_softc *sc);
+static void		fxp_read_eeprom(struct fxp_softc *sc, u_short *data,
+			    int offset, int words);
+static void		fxp_write_eeprom(struct fxp_softc *sc, u_short *data,
+			    int offset, int words);
+#ifdef NOTUSED
+static int		fxp_ifmedia_upd(struct ifnet *ifp);
+static void		fxp_ifmedia_sts(struct ifnet *ifp,
+			    struct ifmediareq *ifmr);
+static int		fxp_serial_ifmedia_upd(struct ifnet *ifp);
+static void		fxp_serial_ifmedia_sts(struct ifnet *ifp,
+			    struct ifmediareq *ifmr);
+static volatile int	fxp_miibus_readreg(device_t dev, int phy, int reg);
+static void		fxp_miibus_writereg(device_t dev, int phy, int reg,
+			    int value);
+#endif
+static __inline void	fxp_lwcopy(volatile u_int32_t *src,
+			    volatile u_int32_t *dst);
+static __inline void 	fxp_scb_wait(struct fxp_softc *sc);
+static __inline void	fxp_scb_cmd(struct fxp_softc *sc, int cmd);
+static __inline void	fxp_dma_wait(volatile u_int16_t *status,
+			    struct fxp_softc *sc);
+
+/*
+ * Inline function to copy a 16-bit aligned 32-bit quantity.
+ */
+static __inline void
+fxp_lwcopy(volatile u_int32_t *src, volatile u_int32_t *dst)
+{
+#ifdef __i386__
+	*dst = *src;
+#else
+	volatile u_int16_t *a = (volatile u_int16_t *)src;
+	volatile u_int16_t *b = (volatile u_int16_t *)dst;
+
+	b[0] = a[0];
+	b[1] = a[1];
+#endif
+}
+
+/*
+ * inline access functions to pci space registers
+ */
+static __inline u_int8_t fxp_csr_read_1(struct fxp_softc *sc,int  reg) {
+  u_int8_t val;
+  if (sc->pci_regs_are_io) {
+    inport_byte(sc->pci_regs_base + reg,val);
+  }
+  else {
+    val = *(u_int8_t *)(sc->pci_regs_base+reg);
+  }
+  return val;
+}
+static __inline u_int32_t fxp_csr_read_2(struct fxp_softc *sc,int  reg) {
+  u_int16_t val;
+  if (sc->pci_regs_are_io) {
+    inport_word(sc->pci_regs_base + reg,val);
+  }
+  else {
+    val = *(u_int16_t *)(sc->pci_regs_base+reg);
+  }
+  return val;
+}
+static __inline u_int32_t fxp_csr_read_4(struct fxp_softc *sc,int  reg) {
+  u_int32_t val;
+  if (sc->pci_regs_are_io) {
+    inport_long(sc->pci_regs_base + reg,val);
+  }
+  else {
+    val = *(u_int32_t *)(sc->pci_regs_base+reg);
+  }
+  return val;
+}
+
+/*
+ * Wait for the previous command to be accepted (but not necessarily
+ * completed).
+ */
+static __inline void
+fxp_scb_wait(struct fxp_softc *sc)
+{
+	int i = 10000;
+
+	while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i)
+		DELAY(2);
+	if (i == 0)
+		device_printf(sc->dev, "SCB timeout: 0x%x 0x%x 0x%x 0x%x\n",
+		    CSR_READ_1(sc, FXP_CSR_SCB_COMMAND),
+		    CSR_READ_1(sc, FXP_CSR_SCB_STATACK),
+		    CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS),
+		    CSR_READ_2(sc, FXP_CSR_FLOWCONTROL));
+}
+
+static __inline void
+fxp_scb_cmd(struct fxp_softc *sc, int cmd)
+{
+
+	if (cmd == FXP_SCB_COMMAND_CU_RESUME && sc->cu_resume_bug) {
+		CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_CB_COMMAND_NOP);
+		fxp_scb_wait(sc);
+	}
+	CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd);
+}
+
+static __inline void
+fxp_dma_wait(volatile u_int16_t *status, struct fxp_softc *sc)
+{
+	int i = 10000;
+
+	while (!(*status & FXP_CB_STATUS_C) && --i)
+		DELAY(2);
+	if (i == 0)
+		device_printf(sc->dev, "DMA timeout\n");
+}
+
+static __inline unsigned int pci_get_vendor(struct fxp_softc *sc) {
+  u_int16_t vendor;
+  pcib_conf_read16(sc->pci_signature,0,&vendor);
+  return vendor;
+}
+
+static __inline unsigned int pci_get_device(struct fxp_softc *sc) {
+  u_int16_t device;
+  pcib_conf_read16(sc->pci_signature,2,&device);
+  return device;
+}
+
+static __inline unsigned int pci_get_subvendor(struct fxp_softc *sc) {
+  u_int16_t subvendor;
+  pcib_conf_read16(sc->pci_signature,0x2c,&subvendor);
+  return subvendor;
+}
+
+static __inline unsigned int pci_get_subdevice(struct fxp_softc *sc) {
+  u_int16_t subdevice;
+  pcib_conf_read16(sc->pci_signature,0x2e,&subdevice);
+  return subdevice;
+}
+
+static __inline unsigned int pci_get_revid(struct fxp_softc *sc) {
+  u_int8_t revid;
+  pcib_conf_read8(sc->pci_signature,0x08,&revid);
+  return revid;
+}
+
+static void nopOn(const rtems_irq_connect_data* notUsed)
+{
+  /*
+   * code should be moved from fxp_Enet_initialize_hardware
+   * to this location
+   */
+}
+
+static int fxpIsOn(const rtems_irq_connect_data* irq)
+{
+  return BSP_irq_enabled_at_i8259s (irq->name);
+}
+
+int
+rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
+{
+	int error = 0;
+	struct fxp_softc *sc;
+	struct ifnet *ifp;
+	u_int16_t val16;
+	u_int32_t val32;
+	u_int16_t data;
+	int i;
+	int s;
+	int unitNumber;
+	char *unitName;
+	u_int16_t dev_id;
+	u_int8_t interrupt;
+	int mtu;
+
+    /*
+     * Set up some timing values
+     */
+    rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &fxp_ticksPerSecond);
+	DBGLVL_PRINTK(1,"fxp_attach called\n");
+
+	/*
+ 	 * Parse driver name
+	 */
+	if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
+		return 0;
+	
+	/*
+	 * Is driver free?
+	 */
+	if ((unitNumber <= 0) || (unitNumber > NFXPDRIVER)) {
+		device_printf(dev,"Bad FXP unit number.\n");
+		return 0;
+	}
+	sc = &fxp_softc[unitNumber - 1];
+	ifp = &sc->arpcom.ac_if;
+	if (ifp->if_softc != NULL) {
+		device_printf(dev,"FXP Driver already in use.\n");
+		return 0;
+	}
+
+	bzero(sc, sizeof(*sc));
+#ifdef NOTUSED
+	sc->dev = dev;
+	callout_handle_init(&sc->stat_ch);
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_DEF | MTX_RECURSE);
+#endif
+	s = splimp(); 
+
+	/*
+	 * init PCI Bios interface...
+	 */
+	i = pcib_init();
+	DBGLVL_PRINTK(2,"fxp_attach: pcib_init returned %d\n",i);
+	if (i != PCIB_ERR_SUCCESS) {
+	  device_printf(dev, "could not initialize pci bios interface\n");
+	  return 0;
+	}
+	
+	/*
+	 * find device on pci bus
+	 */	
+	i = pcib_find_by_devid(0x8086,0x1209,unitNumber-1,
+			       &(sc->pci_signature));
+	DBGLVL_PRINTK(2,"fxp_attach: find_devid returned %d "
+		      "and pci signature 0x%x\n",
+		      i,sc->pci_signature);
+
+	/*
+	 * FIXME: add search for more device types...
+	 */
+	if (i != PCIB_ERR_SUCCESS) {
+	  device_printf(dev, "could not find 82559ER device\n");
+	  return 0;
+	}
+	  
+
+	/*
+	 * Enable bus mastering. Enable memory space too, in case
+	 * BIOS/Prom forgot about it.
+	 */
+	pcib_conf_read16(sc->pci_signature, PCI_COMMAND,&val16);
+	val16 |= (PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER);
+	pcib_conf_write16(sc->pci_signature, PCI_COMMAND, val16);
+	DBGLVL_PRINTK(3,"fxp_attach: PCI_COMMAND_write = 0x%x\n",val16);
+	pcib_conf_read16(sc->pci_signature, PCI_COMMAND,&val16);
+	DBGLVL_PRINTK(4,"fxp_attach: PCI_COMMAND_read  = 0x%x\n",val16);
+
+	/*
+	 * Figure out which we should try first - memory mapping or i/o mapping?
+	 * We default to memory mapping. Then we accept an override from the
+	 * command line. Then we check to see which one is enabled.
+	 */
+#ifdef NOTUSED
+	m1 = PCI_COMMAND_MEMORY;
+	m2 = PCI_COMMAND_IO;
+	prefer_iomap = 0;
+	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
+	    "prefer_iomap", &prefer_iomap) == 0 && prefer_iomap != 0) {
+		m1 = PCI_COMMAND_IO;
+		m2 = PCI_COMMAND_MEMORY;
+	}
+
+	if (val & m1) {
+		sc->rtp = ((m1 == PCI_COMMAND_MEMORY)
+			   ? SYS_RES_MEMORY : SYS_RES_IOPORT);
+		sc->rgd = ((m1 == PCI_COMMAND_MEMORY)
+			   ? FXP_PCI_MMBA   : FXP_PCI_IOBA);
+		sc->mem = bus_alloc_resource(dev, sc->rtp, &sc->rgd,
+	                                     0, ~0, 1, RF_ACTIVE);
+	}
+	if (sc->mem == NULL && (val & m2)) {
+		sc->rtp = ((m2 == PCI_COMMAND_MEMORY)
+			   ? SYS_RES_MEMORY : SYS_RES_IOPORT);
+		sc->rgd = ((m2 == PCI_COMMAND_MEMORY)
+			   ? FXP_PCI_MMBA : FXP_PCI_IOBA);
+		sc->mem = bus_alloc_resource(dev, sc->rtp, &sc->rgd,
+                                            0, ~0, 1, RF_ACTIVE);
+	}
+
+	if (!sc->mem) {
+		device_printf(dev, "could not map device registers\n");
+		error = ENXIO;
+		goto fail;
+        }
+	if (fxp_is_verbose) {
+		device_printf(dev, "using %s space register mapping\n",
+		   sc->rtp == SYS_RES_MEMORY? "memory" : "I/O");
+	}
+
+	sc->sc_st = rman_get_bustag(sc->mem);
+	sc->sc_sh = rman_get_bushandle(sc->mem);
+
+	/*
+	 * Allocate our interrupt.
+	 */
+	rid = 0;
+	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+				 RF_SHAREABLE | RF_ACTIVE);
+	if (sc->irq == NULL) {
+		device_printf(dev, "could not map interrupt\n");
+		error = ENXIO;
+		goto fail;
+	}
+
+	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
+			       fxp_intr, sc, &sc->ih);
+	if (error) {
+		device_printf(dev, "could not setup irq\n");
+		goto fail;
+	}
+#endif
+
+	/*
+	 * get mapping and base address of registers
+	 */
+	pcib_conf_read16(sc->pci_signature, PCI_COMMAND,&val16);
+	DBGLVL_PRINTK(4,"fxp_attach: PCI_COMMAND_read  = 0x%x\n",val16);
+	if((val16 & PCI_COMMAND_IO) != 0) {
+	  sc->pci_regs_are_io = TRUE;
+	  pcib_conf_read32(sc->pci_signature,
+			   PCI_BASE_ADDRESS_1,
+			   &val32);	  
+	  sc->pci_regs_base = val32 & PCI_BASE_ADDRESS_IO_MASK;
+	}
+	else {
+	  sc->pci_regs_are_io = FALSE;
+	  pcib_conf_read32(sc->pci_signature,
+			   PCI_BASE_ADDRESS_0,
+			   &val32);
+	  sc->pci_regs_base = val32 & PCI_BASE_ADDRESS_MEM_MASK;
+	}
+	DBGLVL_PRINTK(3,"fxp_attach: CSR registers are mapped in %s space"
+		      " at address 0x%x\n",
+		      sc->pci_regs_are_io ? "I/O" : "MEM",
+		      sc->pci_regs_base);
+
+	/*
+	 * get interrupt level to be used
+	 */
+	pcib_conf_read8(sc->pci_signature, 60, &interrupt);
+	DBGLVL_PRINTK(3,"fxp_attach: interrupt = 0x%x\n",interrupt);
+	sc->irqInfo.name = (rtems_irq_symbolic_name)interrupt;
+	/*
+	 * Set up interrupts
+	 */
+	sc->irqInfo.hdl = (rtems_irq_hdl)fxp_intr;
+	sc->irqInfo.on  = nopOn;
+	sc->irqInfo.off = nopOn;
+	sc->irqInfo.isOn = fxpIsOn;  
+	s = BSP_install_rtems_irq_handler (&sc->irqInfo);
+	if (!s)
+	  rtems_panic ("Can't attach fxp interrupt handler for irq %d\n",
+		       sc->irqInfo.name);
+	/*
+	 * Reset to a stable state.
+	CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
+	 */
+	CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET);
+	DELAY(10);
+
+	sc->cbl_base = malloc(sizeof(struct fxp_cb_tx) * FXP_NTXCB,
+	    M_DEVBUF, M_NOWAIT);
+	DBGLVL_PRINTK(3,"fxp_attach: sc->cbl_base = 0x%x\n",sc->cbl_base);
+	if (sc->cbl_base == NULL)
+		goto failmem;
+	else 
+	        bzero(sc->cbl_base,sizeof(struct fxp_cb_tx) * FXP_NTXCB);
+
+	sc->fxp_stats = malloc(sizeof(struct fxp_stats), M_DEVBUF,
+	    M_NOWAIT);
+	DBGLVL_PRINTK(3,"fxp_attach: sc->fxp_stats = 0x%x\n",sc->fxp_stats);
+	if (sc->fxp_stats == NULL)
+		goto failmem;
+	else
+	        bzero(sc->fxp_stats,sizeof(struct fxp_stats));
+
+	sc->mcsp = malloc(sizeof(struct fxp_cb_mcs), M_DEVBUF, M_NOWAIT);
+	DBGLVL_PRINTK(3,"fxp_attach: sc->mcsp = 0x%x\n",sc->mcsp);
+	if (sc->mcsp == NULL)
+		goto failmem;
+
+	/*
+	 * Pre-allocate our receive buffers.
+	 */
+	for (i = 0; i < FXP_NRFABUFS; i++) {
+		if (fxp_add_rfabuf(sc, NULL) != 0) {
+			goto failmem;
+		}
+	}
+
+	/*
+	 * Find out how large of an SEEPROM we have.
+	 */
+	DBGLVL_PRINTK(3,"fxp_attach: calling fxp_autosize_eeprom\n");
+	fxp_autosize_eeprom(sc);
+
+	/*
+	 * Determine whether we must use the 503 serial interface.
+	 */
+	fxp_read_eeprom(sc, &data, 6, 1);
+	if ((data & FXP_PHY_DEVICE_MASK) != 0 &&
+	    (data & FXP_PHY_SERIAL_ONLY))
+		sc->flags |= FXP_FLAG_SERIAL_MEDIA;
+
+	/*
+	 * Find out the basic controller type; we currently only
+	 * differentiate between a 82557 and greater.
+	 */
+	fxp_read_eeprom(sc, &data, 5, 1);
+	if ((data >> 8) == 1)
+		sc->chip = FXP_CHIP_82557;
+	DBGLVL_PRINTK(3,"fxp_attach: sc->chip = %d\n",sc->chip);
+
+	/*
+	 * Enable workarounds for certain chip revision deficiencies.
+	 *
+	 * Systems based on the ICH2/ICH2-M chip from Intel have a defect
+	 * where the chip can cause a PCI protocol violation if it receives
+	 * a CU_RESUME command when it is entering the IDLE state.  The 
+	 * workaround is to disable Dynamic Standby Mode, so the chip never
+	 * deasserts CLKRUN#, and always remains in an active state.
+	 *
+	 * See Intel 82801BA/82801BAM Specification Update, Errata #30.
+	 */
+#ifdef NOTUSED
+	i = pci_get_device(dev);
+#else
+	pcib_conf_read16(sc->pci_signature,2,&dev_id);
+	DBGLVL_PRINTK(3,"fxp_attach: device id = 0x%x\n",dev_id);
+#endif
+	if (dev_id == 0x2449 || (dev_id > 0x1030 && dev_id < 0x1039)) {
+        device_printf(dev, "*** See Intel 82801BA/82801BAM Specification Update, Errata #30. ***\n");
+		fxp_read_eeprom(sc, &data, 10, 1);
+		if (data & 0x02) {			/* STB enable */
+			u_int16_t cksum;
+			int i;
+
+			device_printf(dev,
+		    "*** DISABLING DYNAMIC STANDBY MODE IN EEPROM ***\n");
+			data &= ~0x02;
+			fxp_write_eeprom(sc, &data, 10, 1);
+			device_printf(dev, "New EEPROM ID: 0x%x\n", data);
+			cksum = 0;
+			for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) {
+				fxp_read_eeprom(sc, &data, i, 1);
+				cksum += data;
+			}
+			i = (1 << sc->eeprom_size) - 1;
+			cksum = 0xBABA - cksum;
+			fxp_read_eeprom(sc, &data, i, 1);
+			fxp_write_eeprom(sc, &cksum, i, 1);
+			device_printf(dev,
+			    "EEPROM checksum @ 0x%x: 0x%x -> 0x%x\n",
+			    i, data, cksum);
+			/*
+			 * We need to do a full PCI reset here.  A software 
+			 * reset to the port doesn't cut it, but let's try
+			 * anyway.
+			 */
+			CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET);
+			DELAY(50);
+			device_printf(dev,
+	    "*** PLEASE REBOOT THE SYSTEM NOW FOR CORRECT OPERATION ***\n");
+#if 1
+			/*
+			 * If the user elects to continue, try the software
+			 * workaround, as it is better than nothing.
+			 */
+			sc->flags |= FXP_FLAG_CU_RESUME_BUG;
+#endif
+		}
+	}
+
+	/*
+	 * If we are not a 82557 chip, we can enable extended features.
+	 */
+	if (sc->chip != FXP_CHIP_82557) {
+	  u_int8_t tmp_val;
+		/*
+		 * If MWI is enabled in the PCI configuration, and there
+		 * is a valid cacheline size (8 or 16 dwords), then tell
+		 * the board to turn on MWI.
+		 */
+	        pcib_conf_read8(sc->pci_signature,
+				PCI_CACHE_LINE_SIZE,&tmp_val);
+		DBGLVL_PRINTK(3,"fxp_attach: CACHE_LINE_SIZE = %d\n",tmp_val);
+		if (val16 & PCI_COMMAND_MEMORY &&
+		    tmp_val != 0)
+			sc->flags |= FXP_FLAG_MWI_ENABLE;
+
+		/* turn on the extended TxCB feature */
+		sc->flags |= FXP_FLAG_EXT_TXCB;
+
+		/* enable reception of long frames for VLAN */
+		sc->flags |= FXP_FLAG_LONG_PKT_EN;
+		DBGLVL_PRINTK(3,"fxp_attach: sc->flags = 0x%x\n",
+			      sc->flags);
+	}
+
+	/*
+	 * Read MAC address.
+	 */
+	fxp_read_eeprom(sc, (u_int16_t *)sc->arpcom.ac_enaddr, 0, 3);
+	if (fxp_is_verbose) {
+	    device_printf(dev, "Ethernet address %x:%x:%x:%x:%x:%x %s \n",
+	        ((u_int8_t *)sc->arpcom.ac_enaddr)[0],
+	        ((u_int8_t *)sc->arpcom.ac_enaddr)[1],
+    	    ((u_int8_t *)sc->arpcom.ac_enaddr)[2],
+    	    ((u_int8_t *)sc->arpcom.ac_enaddr)[3],
+    	    ((u_int8_t *)sc->arpcom.ac_enaddr)[4],
+    	    ((u_int8_t *)sc->arpcom.ac_enaddr)[5],
+    	    sc->flags & FXP_FLAG_SERIAL_MEDIA ? ", 10Mbps" : "");
+		device_printf(dev, "PCI IDs: 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+		    pci_get_vendor(sc), pci_get_device(sc),
+		    pci_get_subvendor(sc), pci_get_subdevice(sc),
+		    pci_get_revid(sc));
+		device_printf(dev, "Chip Type: %d\n", sc->chip);
+	}
+
+#ifdef NOTUSED /* do not set up interface at all... */
+	/*
+	 * If this is only a 10Mbps device, then there is no MII, and
+	 * the PHY will use a serial interface instead.
+	 *
+	 * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter
+	 * doesn't have a programming interface of any sort.  The
+	 * media is sensed automatically based on how the link partner
+	 * is configured.  This is, in essence, manual configuration.
+	 */
+	if (sc->flags & FXP_FLAG_SERIAL_MEDIA) {
+		ifmedia_init(&sc->sc_media, 0, fxp_serial_ifmedia_upd,
+		    fxp_serial_ifmedia_sts);
+		ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
+		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
+	} else {
+		if (mii_phy_probe(dev, &sc->miibus, fxp_ifmedia_upd,
+		    fxp_ifmedia_sts)) {
+	                device_printf(dev, "MII without any PHY!\n");
+			error = ENXIO;
+			goto fail;
+		}
+	}
+#endif
+	if (config->mtu)
+		mtu = config->mtu;
+	else
+		mtu = ETHERMTU;
+
+	ifp->if_softc = sc;
+	ifp->if_unit = unitNumber;
+	ifp->if_name = unitName;
+	ifp->if_mtu  = mtu;
+	ifp->if_baudrate = 100000000;
+	ifp->if_init = fxp_init;
+	ifp->if_ioctl = fxp_ioctl;
+	ifp->if_start = fxp_start;
+	ifp->if_output = ether_output;
+	ifp->if_watchdog = fxp_watchdog;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX /*| IFF_MULTICAST*/;
+	if (ifp->if_snd.ifq_maxlen == 0)
+		ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+	/*
+	 * Attach the interface.
+	 */
+	DBGLVL_PRINTK(3,"fxp_attach: calling if_attach\n");
+	if_attach (ifp);
+	DBGLVL_PRINTK(3,"fxp_attach: calling ether_if_attach\n");
+	ether_ifattach(ifp);
+	DBGLVL_PRINTK(3,"fxp_attach: return from ether_if_attach\n");
+
+#ifdef NOTUSED
+	/*
+	 * Tell the upper layer(s) we support long frames.
+	 */
+	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+#endif
+	/*
+	 * Let the system queue as many packets as we have available
+	 * TX descriptors.
+	 */
+	ifp->if_snd.ifq_maxlen = FXP_NTXCB - 1;
+
+	splx(s);
+	return (0);
+
+failmem:
+	device_printf(dev, "Failed to malloc memory\n");
+	error = ENOMEM;
+#ifdef NOTUSED
+fail:
+#endif
+	splx(s);
+	fxp_release(sc);
+	return (error);
+}
+
+/*
+ * release all resources
+ */
+static void
+fxp_release(struct fxp_softc *sc)
+{
+
+#ifdef NOTUSED
+	bus_generic_detach(sc->dev);
+	if (sc->miibus)
+		device_delete_child(sc->dev, sc->miibus);
+#endif
+	if (sc->cbl_base)
+		free(sc->cbl_base, M_DEVBUF);
+	if (sc->fxp_stats)
+		free(sc->fxp_stats, M_DEVBUF);
+	if (sc->mcsp)
+		free(sc->mcsp, M_DEVBUF);
+	if (sc->rfa_headm)
+		m_freem(sc->rfa_headm);
+
+#ifdef NOTUSED
+	if (sc->ih)
+		bus_teardown_intr(sc->dev, sc->irq, sc->ih);
+	if (sc->irq)
+		bus_release_resource(sc->dev, SYS_RES_IRQ, 0, sc->irq);
+	if (sc->mem)
+		bus_release_resource(sc->dev, sc->rtp, sc->rgd, sc->mem);
+	mtx_destroy(&sc->sc_mtx);
+#endif
+}
+
+#if NOTUSED
+/*
+ * Detach interface.
+ */
+static int
+fxp_detach(device_t dev)
+{
+	struct fxp_softc *sc = device_get_softc(dev);
+	int s;
+
+	/* disable interrupts */
+	CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
+
+	s = splimp();
+
+	/*
+	 * Stop DMA and drop transmit queue.
+	 */
+	fxp_stop(sc);
+
+	/*
+	 * Close down routes etc.
+	 */
+	ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED);
+
+	/*
+	 * Free all media structures.
+	 */
+	ifmedia_removeall(&sc->sc_media);
+
+	splx(s);
+
+	/* Release our allocated resources. */
+	fxp_release(sc);
+
+	return (0);
+}
+
+/*
+ * Device shutdown routine. Called at system shutdown after sync. The
+ * main purpose of this routine is to shut off receiver DMA so that
+ * kernel memory doesn't get clobbered during warmboot.
+ */
+static int
+fxp_shutdown(device_t dev)
+{
+	/*
+	 * Make sure that DMA is disabled prior to reboot. Not doing
+	 * do could allow DMA to corrupt kernel memory during the
+	 * reboot before the driver initializes.
+	 */
+	fxp_stop((struct fxp_softc *) device_get_softc(dev));
+	return (0);
+}
+#endif
+
+/*
+ * Show interface statistics
+ */
+static void
+fxp_stats(struct fxp_softc *sc)
+{
+	struct ifnet *ifp = &sc->sc_if;
+
+	printf ("   Output packets:%-8lu", ifp->if_opackets);
+	printf ("    Collisions:%-8lu", ifp->if_collisions);
+	printf (" Output errors:%-8lu\n", ifp->if_oerrors);
+	printf ("    Input packets:%-8lu", ifp->if_ipackets);
+	printf ("  Input errors:%-8lu\n", ifp->if_ierrors);
+}
+
+static void 
+fxp_eeprom_shiftin(struct fxp_softc *sc, int data, int length)
+{
+	u_int16_t reg;
+	int x;
+
+	/*
+	 * Shift in data.
+	 */
+	for (x = 1 << (length - 1); x; x >>= 1) {
+		if (data & x)
+			reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
+		else
+			reg = FXP_EEPROM_EECS;
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
+		DELAY(1);
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
+		DELAY(1);
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
+		DELAY(1);
+	}
+}
+
+/*
+ * Read from the serial EEPROM. Basically, you manually shift in
+ * the read opcode (one bit at a time) and then shift in the address,
+ * and then you shift out the data (all of this one bit at a time).
+ * The word size is 16 bits, so you have to provide the address for
+ * every 16 bits of data.
+ */
+static u_int16_t
+fxp_eeprom_getword(struct fxp_softc *sc, int offset, int autosize)
+{
+	u_int16_t reg, data;
+	int x;
+
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
+	/*
+	 * Shift in read opcode.
+	 */
+	fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_READ, 3);
+	/*
+	 * Shift in address.
+	 */
+	data = 0;
+	for (x = 1 << (sc->eeprom_size - 1); x; x >>= 1) {
+		if (offset & x)
+			reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
+		else
+			reg = FXP_EEPROM_EECS;
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
+		DELAY(1);
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
+		DELAY(1);
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
+		DELAY(1);
+		reg = CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO;
+		data++;
+		if (autosize && reg == 0) {
+			sc->eeprom_size = data;
+			break;
+		}
+	}
+	/*
+	 * Shift out data.
+	 */
+	data = 0;
+	reg = FXP_EEPROM_EECS;
+	for (x = 1 << 15; x; x >>= 1) {
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
+		DELAY(1);
+		if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO)
+			data |= x;
+		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
+		DELAY(1);
+	}
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
+	DELAY(1);
+
+	return (data);
+}
+
+static void
+fxp_eeprom_putword(struct fxp_softc *sc, int offset, u_int16_t data)
+{
+	int i;
+
+	/*
+	 * Erase/write enable.
+	 */
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
+	fxp_eeprom_shiftin(sc, 0x4, 3);
+	fxp_eeprom_shiftin(sc, 0x03 << (sc->eeprom_size - 2), sc->eeprom_size);
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
+	DELAY(1);
+	/*
+	 * Shift in write opcode, address, data.
+	 */
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
+	fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3);
+	fxp_eeprom_shiftin(sc, offset, sc->eeprom_size);
+	fxp_eeprom_shiftin(sc, data, 16);
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
+	DELAY(1);
+	/*
+	 * Wait for EEPROM to finish up.
+	 */
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
+	DELAY(1);
+	for (i = 0; i < 1000; i++) {
+		if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO)
+			break;
+		DELAY(50);
+	}
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
+	DELAY(1);
+	/*
+	 * Erase/write disable.
+	 */
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
+	fxp_eeprom_shiftin(sc, 0x4, 3);
+	fxp_eeprom_shiftin(sc, 0, sc->eeprom_size);
+	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
+	DELAY(1);
+}
+
+/*
+ * From NetBSD:
+ *
+ * Figure out EEPROM size.
+ *
+ * 559's can have either 64-word or 256-word EEPROMs, the 558
+ * datasheet only talks about 64-word EEPROMs, and the 557 datasheet
+ * talks about the existance of 16 to 256 word EEPROMs.
+ *
+ * The only known sizes are 64 and 256, where the 256 version is used
+ * by CardBus cards to store CIS information.
+ *
+ * The address is shifted in msb-to-lsb, and after the last
+ * address-bit the EEPROM is supposed to output a `dummy zero' bit,
+ * after which follows the actual data. We try to detect this zero, by
+ * probing the data-out bit in the EEPROM control register just after
+ * having shifted in a bit. If the bit is zero, we assume we've
+ * shifted enough address bits. The data-out should be tri-state,
+ * before this, which should translate to a logical one.
+ */
+static void
+fxp_autosize_eeprom(struct fxp_softc *sc)
+{
+
+	/* guess maximum size of 256 words */
+	sc->eeprom_size = 8;
+
+	/* autosize */
+	(void) fxp_eeprom_getword(sc, 0, 1);
+}
+
+static void
+fxp_read_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
+{
+	int i;
+
+	for (i = 0; i < words; i++) {
+		data[i] = fxp_eeprom_getword(sc, offset + i, 0);
+		DBGLVL_PRINTK(4,"fxp_eeprom_read(off=0x%x)=0x%x\n",
+			      offset+i,data[i]);
+	}
+}
+
+static void
+fxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
+{
+	int i;
+
+	for (i = 0; i < words; i++)
+		fxp_eeprom_putword(sc, offset + i, data[i]);
+		DBGLVL_PRINTK(4,"fxp_eeprom_write(off=0x%x,0x%x)\n",
+			      offset+i,data[i]);
+}
+
+/*
+ * Start packet transmission on the interface.
+ */
+static void
+fxp_start(struct ifnet *ifp)
+{
+	struct fxp_softc *sc = ifp->if_softc;
+	struct fxp_cb_tx *txp;
+
+	DBGLVL_PRINTK(3,"fxp_start called\n");
+
+	/*
+	 * See if we need to suspend xmit until the multicast filter
+	 * has been reprogrammed (which can only be done at the head
+	 * of the command chain).
+	 */
+	if (sc->need_mcsetup) {
+		return;
+	}
+
+	txp = NULL;
+
+	/*
+	 * We're finished if there is nothing more to add to the list or if
+	 * we're all filled up with buffers to transmit.
+	 * NOTE: One TxCB is reserved to guarantee that fxp_mc_setup() can add
+	 *       a NOP command when needed.
+	 */
+	while (ifp->if_snd.ifq_head != NULL && sc->tx_queued < FXP_NTXCB - 1) {
+		struct mbuf *m, *mb_head;
+		int segment;
+
+		/*
+		 * Grab a packet to transmit.
+		 */
+		IF_DEQUEUE(&ifp->if_snd, mb_head);
+
+		/*
+		 * Get pointer to next available tx desc.
+		 */
+		txp = sc->cbl_last->next;
+
+		/*
+		 * Go through each of the mbufs in the chain and initialize
+		 * the transmit buffer descriptors with the physical address
+		 * and size of the mbuf.
+		 */
+tbdinit:
+		for (m = mb_head, segment = 0; m != NULL; m = m->m_next) {
+			if (m->m_len != 0) {
+				if (segment == FXP_NTXSEG)
+					break;
+				txp->tbd[segment].tb_addr =
+				    vtophys(mtod(m, vm_offset_t));
+				txp->tbd[segment].tb_size = m->m_len;
+				segment++;
+			}
+		}
+		if (m != NULL) {
+			struct mbuf *mn;
+
+			/*
+			 * We ran out of segments. We have to recopy this
+			 * mbuf chain first. Bail out if we can't get the
+			 * new buffers.
+			 */
+			MGETHDR(mn, M_DONTWAIT, MT_DATA);
+			if (mn == NULL) {
+				m_freem(mb_head);
+				break;
+			}
+			if (mb_head->m_pkthdr.len > MHLEN) {
+				MCLGET(mn, M_DONTWAIT);
+				if ((mn->m_flags & M_EXT) == 0) {
+					m_freem(mn);
+					m_freem(mb_head);
+					break;
+				}
+			}
+			m_copydata(mb_head, 0, mb_head->m_pkthdr.len,
+			    mtod(mn, caddr_t));
+			mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len;
+			m_freem(mb_head);
+			mb_head = mn;
+			goto tbdinit;
+		}
+
+		txp->tbd_number = segment;
+		txp->mb_head = mb_head;
+		txp->cb_status = 0;
+		if (sc->tx_queued != FXP_CXINT_THRESH - 1) {
+			txp->cb_command =
+			    FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF |
+			    FXP_CB_COMMAND_S;
+		} else {
+			txp->cb_command =
+			    FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF |
+			    FXP_CB_COMMAND_S | FXP_CB_COMMAND_I;
+			/*
+			 * Set a 5 second timer just in case we don't hear
+			 * from the card again.
+			 */
+			ifp->if_timer = 5;
+		}
+		txp->tx_threshold = tx_threshold;
+	
+		/*
+		 * Advance the end of list forward.
+		 */
+
+#ifdef __alpha__
+		/*
+		 * On platforms which can't access memory in 16-bit
+		 * granularities, we must prevent the card from DMA'ing
+		 * up the status while we update the command field.
+		 * This could cause us to overwrite the completion status.
+		 */
+		atomic_clear_short(&sc->cbl_last->cb_command,
+		    FXP_CB_COMMAND_S);
+#else
+		sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;
+#endif /*__alpha__*/
+		sc->cbl_last = txp;
+
+		/*
+		 * Advance the beginning of the list forward if there are
+		 * no other packets queued (when nothing is queued, cbl_first
+		 * sits on the last TxCB that was sent out).
+		 */
+		if (sc->tx_queued == 0)
+			sc->cbl_first = txp;
+
+		sc->tx_queued++;
+
+#ifdef NOTUSED
+		/*
+		 * Pass packet to bpf if there is a listener.
+		 */
+		if (ifp->if_bpf)
+			bpf_mtap(ifp, mb_head);
+#endif
+	}
+
+	/*
+	 * We're finished. If we added to the list, issue a RESUME to get DMA
+	 * going again if suspended.
+	 */
+	if (txp != NULL) {
+		fxp_scb_wait(sc);
+		fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
+	}
+}
+
+/*
+ * Process interface interrupts.
+ */
+static rtems_isr fxp_intr(rtems_vector_number v)
+{
+  /*
+   * FIXME: currently only works with one interface... 
+   */
+  struct fxp_softc *sc = &(fxp_softc[0]);
+
+  /*
+   * disable interrupts
+   */
+  CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
+  /*
+   * send event to deamon
+   */
+  rtems_event_send (sc->daemonTid, INTERRUPT_EVENT);
+}
+
+static void fxp_daemon(void *xsc)
+{
+	struct fxp_softc *sc = xsc;
+	struct ifnet *ifp = &sc->sc_if;
+	u_int8_t statack;
+	rtems_event_set events;
+	rtems_interrupt_level level;
+
+#ifdef NOTUSED
+	if (sc->suspended) {
+		return;
+	}
+#endif
+	for (;;) {
+
+	DBGLVL_PRINTK(4,"fxp_daemon waiting for event\n");
+	  /*
+	   * wait for event to receive from interrupt function
+	   */
+	  rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+				      RTEMS_WAIT|RTEMS_EVENT_ANY,
+				      RTEMS_NO_TIMEOUT,
+				      &events);
+	  while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
+	    DBGLVL_PRINTK(4,"fxp_daemon: processing event, statack = 0x%x\n",
+			  statack);
+#ifdef NOTUSED
+		/*
+		 * It should not be possible to have all bits set; the
+		 * FXP_SCB_INTR_SWI bit always returns 0 on a read.  If 
+		 * all bits are set, this may indicate that the card has
+		 * been physically ejected, so ignore it.
+		 */  
+		if (statack == 0xff) 
+			return;
+#endif
+
+		/*
+		 * First ACK all the interrupts in this pass.
+		 */
+		CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack);
+
+		/*
+		 * Free any finished transmit mbuf chains.
+		 *
+		 * Handle the CNA event likt a CXTNO event. It used to
+		 * be that this event (control unit not ready) was not
+		 * encountered, but it is now with the SMPng modifications.
+		 * The exact sequence of events that occur when the interface
+		 * is brought up are different now, and if this event
+		 * goes unhandled, the configuration/rxfilter setup sequence
+		 * can stall for several seconds. The result is that no
+		 * packets go out onto the wire for about 5 to 10 seconds
+		 * after the interface is ifconfig'ed for the first time.
+		 */
+		if (statack & (FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA)) {
+			struct fxp_cb_tx *txp;
+
+			for (txp = sc->cbl_first; sc->tx_queued &&
+			    (txp->cb_status & FXP_CB_STATUS_C) != 0;
+			    txp = txp->next) {
+				if (txp->mb_head != NULL) {
+					m_freem(txp->mb_head);
+					txp->mb_head = NULL;
+				}
+				sc->tx_queued--;
+			}
+			sc->cbl_first = txp;
+			ifp->if_timer = 0;
+			if (sc->tx_queued == 0) {
+				if (sc->need_mcsetup)
+					fxp_mc_setup(sc);
+			}
+			/*
+			 * Try to start more packets transmitting.
+			 */
+			if (ifp->if_snd.ifq_head != NULL)
+				fxp_start(ifp);
+		}
+		/*
+		 * Process receiver interrupts. If a no-resource (RNR)
+		 * condition exists, get whatever packets we can and
+		 * re-start the receiver.
+		 */
+		if (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR)) {
+			struct mbuf *m;
+			struct fxp_rfa *rfa;
+rcvloop:
+			m = sc->rfa_headm;
+			rfa = (struct fxp_rfa *)(m->m_ext.ext_buf +
+			    RFA_ALIGNMENT_FUDGE);
+
+			if (rfa->rfa_status & FXP_RFA_STATUS_C) {
+				/*
+				 * Remove first packet from the chain.
+				 */
+				sc->rfa_headm = m->m_next;
+				m->m_next = NULL;
+
+				/*
+				 * Add a new buffer to the receive chain.
+				 * If this fails, the old buffer is recycled
+				 * instead.
+				 */
+				if (fxp_add_rfabuf(sc, m) == 0) {
+					struct ether_header *eh;
+					int total_len;
+
+					total_len = rfa->actual_size &
+					    (MCLBYTES - 1);
+					if (total_len <
+					    sizeof(struct ether_header)) {
+						m_freem(m);
+						goto rcvloop;
+					}
+
+					/*
+					 * Drop the packet if it has CRC
+					 * errors.  This test is only needed
+					 * when doing 802.1q VLAN on the 82557
+					 * chip.
+					 */
+					if (rfa->rfa_status &
+					    FXP_RFA_STATUS_CRC) {
+						m_freem(m);
+						goto rcvloop;
+					}
+
+					m->m_pkthdr.rcvif = ifp;
+					m->m_pkthdr.len = m->m_len = total_len;
+					eh = mtod(m, struct ether_header *);
+					m->m_data +=
+					    sizeof(struct ether_header);
+					m->m_len -=
+					    sizeof(struct ether_header);
+					m->m_pkthdr.len = m->m_len;
+					ether_input(ifp, eh, m);
+				}
+				goto rcvloop;
+			}
+			if (statack & FXP_SCB_STATACK_RNR) {
+				fxp_scb_wait(sc);
+				CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
+				    vtophys(sc->rfa_headm->m_ext.ext_buf) +
+					RFA_ALIGNMENT_FUDGE);
+				fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
+			}
+		}
+	  }
+	  /*
+	   * reenable interrupts
+	   */
+	  rtems_interrupt_disable (level);
+	  CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0);
+	  rtems_interrupt_enable (level);
+	}
+}
+
+/*
+ * Update packet in/out/collision statistics. The i82557 doesn't
+ * allow you to access these counters without doing a fairly
+ * expensive DMA to get _all_ of the statistics it maintains, so
+ * we do this operation here only once per second. The statistics
+ * counters in the kernel are updated from the previous dump-stats
+ * DMA and then a new dump-stats DMA is started. The on-chip
+ * counters are zeroed when the DMA completes. If we can't start
+ * the DMA immediately, we don't wait - we just prepare to read
+ * them again next time.
+ */
+static void
+fxp_tick(void *xsc)
+{
+	struct fxp_softc *sc = xsc;
+	struct ifnet *ifp = &sc->sc_if;
+	struct fxp_stats *sp = sc->fxp_stats;
+	struct fxp_cb_tx *txp;
+	int s;
+
+	DBGLVL_PRINTK(4,"fxp_tick called\n");
+
+	ifp->if_opackets += sp->tx_good;
+	ifp->if_collisions += sp->tx_total_collisions;
+	if (sp->rx_good) {
+		ifp->if_ipackets += sp->rx_good;
+		sc->rx_idle_secs = 0;
+	} else {
+		/*
+		 * Receiver's been idle for another second.
+		 */
+		sc->rx_idle_secs++;
+	}
+	ifp->if_ierrors +=
+	    sp->rx_crc_errors +
+	    sp->rx_alignment_errors +
+	    sp->rx_rnr_errors +
+	    sp->rx_overrun_errors;
+	/*
+	 * If any transmit underruns occured, bump up the transmit
+	 * threshold by another 512 bytes (64 * 8).
+	 */
+	if (sp->tx_underruns) {
+		ifp->if_oerrors += sp->tx_underruns;
+		if (tx_threshold < 192)
+			tx_threshold += 64;
+	}
+	s = splimp();
+	/*
+	 * Release any xmit buffers that have completed DMA. This isn't
+	 * strictly necessary to do here, but it's advantagous for mbufs
+	 * with external storage to be released in a timely manner rather
+	 * than being defered for a potentially long time. This limits
+	 * the delay to a maximum of one second.
+	 */ 
+	for (txp = sc->cbl_first; sc->tx_queued &&
+	    (txp->cb_status & FXP_CB_STATUS_C) != 0;
+	    txp = txp->next) {
+		if (txp->mb_head != NULL) {
+			m_freem(txp->mb_head);
+			txp->mb_head = NULL;
+		}
+		sc->tx_queued--;
+	}
+	sc->cbl_first = txp;
+	/*
+	 * If we haven't received any packets in FXP_MAC_RX_IDLE seconds,
+	 * then assume the receiver has locked up and attempt to clear
+	 * the condition by reprogramming the multicast filter. This is
+	 * a work-around for a bug in the 82557 where the receiver locks
+	 * up if it gets certain types of garbage in the syncronization
+	 * bits prior to the packet header. This bug is supposed to only
+	 * occur in 10Mbps mode, but has been seen to occur in 100Mbps
+	 * mode as well (perhaps due to a 10/100 speed transition).
+	 */
+	if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
+		sc->rx_idle_secs = 0;
+		fxp_mc_setup(sc);
+	}
+	/*
+	 * If there is no pending command, start another stats
+	 * dump. Otherwise punt for now.
+	 */
+	if (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) == 0) {
+		/*
+		 * Start another stats dump.
+		 */
+		fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET);
+	} else {
+		/*
+		 * A previous command is still waiting to be accepted.
+		 * Just zero our copy of the stats and wait for the
+		 * next timer event to update them.
+		 */
+		sp->tx_good = 0;
+		sp->tx_underruns = 0;
+		sp->tx_total_collisions = 0;
+
+		sp->rx_good = 0;
+		sp->rx_crc_errors = 0;
+		sp->rx_alignment_errors = 0;
+		sp->rx_rnr_errors = 0;
+		sp->rx_overrun_errors = 0;
+	}
+#ifdef NOTUSED
+	if (sc->miibus != NULL)
+		mii_tick(device_get_softc(sc->miibus));
+#endif
+	splx(s);
+	/*
+	 * Schedule another timeout one second from now.
+	 */
+	if (sc->stat_ch == fxp_timeout_running) {
+	  timeout(fxp_tick, sc, hz);
+	}
+	else if (sc->stat_ch == fxp_timeout_stop_rq) {
+	  sc->stat_ch = fxp_timeout_stopped;
+	}	  
+}
+
+/*
+ * Stop the interface. Cancels the statistics updater and resets
+ * the interface.
+ */
+static void
+fxp_stop(struct fxp_softc *sc)
+{
+	struct ifnet *ifp = &sc->sc_if;
+	struct fxp_cb_tx *txp;
+	int i;
+
+	DBGLVL_PRINTK(2,"fxp_stop called\n");
+
+	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+	ifp->if_timer = 0;
+
+	/*
+	 * stop stats updater.
+	 */
+	if (sc->stat_ch == fxp_timeout_running) {
+	  DBGLVL_PRINTK(3,"fxp_stop: trying to stop stat update tick\n");
+	  sc->stat_ch = fxp_timeout_stop_rq;
+	  while(sc->stat_ch != fxp_timeout_stopped) {
+	    rtems_bsdnet_semaphore_release();
+	    rtems_task_wake_after(fxp_ticksPerSecond);
+	    rtems_bsdnet_semaphore_obtain();
+	  }
+	  DBGLVL_PRINTK(3,"fxp_stop: stat update tick stopped\n");
+	}
+	/*
+	 * Issue software reset
+	 */
+	DBGLVL_PRINTK(3,"fxp_stop: issue software reset\n");
+	CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
+	DELAY(10);
+
+	/*
+	 * Release any xmit buffers.
+	 */
+	DBGLVL_PRINTK(3,"fxp_stop: releasing xmit buffers\n");
+	txp = sc->cbl_base;
+	if (txp != NULL) {
+		for (i = 0; i < FXP_NTXCB; i++) {
+			if (txp[i].mb_head != NULL) {
+				m_freem(txp[i].mb_head);
+				txp[i].mb_head = NULL;
+			}
+		}
+	}
+	sc->tx_queued = 0;
+
+	/*
+	 * Free all the receive buffers then reallocate/reinitialize
+	 */
+	DBGLVL_PRINTK(3,"fxp_stop: free and reinit all receive buffers\n");
+	if (sc->rfa_headm != NULL)
+		m_freem(sc->rfa_headm);
+	sc->rfa_headm = NULL;
+	sc->rfa_tailm = NULL;
+	for (i = 0; i < FXP_NRFABUFS; i++) {
+		if (fxp_add_rfabuf(sc, NULL) != 0) {
+			/*
+			 * This "can't happen" - we're at splimp()
+			 * and we just freed all the buffers we need
+			 * above.
+			 */
+			panic("fxp_stop: no buffers!");
+		}
+	}
+	DBGLVL_PRINTK(2,"fxp_stop: finished\n");
+}
+
+/*
+ * Watchdog/transmission transmit timeout handler. Called when a
+ * transmission is started on the interface, but no interrupt is
+ * received before the timeout. This usually indicates that the
+ * card has wedged for some reason.
+ */
+static void
+fxp_watchdog(struct ifnet *ifp)
+{
+	struct fxp_softc *sc = ifp->if_softc;
+
+	device_printf(sc->dev, "device timeout\n");
+	ifp->if_oerrors++;
+
+	fxp_init(sc);
+}
+
+static void
+fxp_init(void *xsc)
+{
+	struct fxp_softc *sc = xsc;
+	struct ifnet *ifp = &sc->sc_if;
+	struct fxp_cb_config *cbp;
+	struct fxp_cb_ias *cb_ias;
+	struct fxp_cb_tx *txp;
+	int i, prm, s;
+
+rtems_task_wake_after(100);
+	DBGLVL_PRINTK(2,"fxp_init called\n");
+
+	s = splimp();
+	/*
+	 * Cancel any pending I/O
+	 */
+	fxp_stop(sc);
+
+	prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0;
+
+	DBGLVL_PRINTK(5,"fxp_init: Initializing base of CBL and RFA memory\n");
+	/*
+	 * Initialize base of CBL and RFA memory. Loading with zero
+	 * sets it up for regular linear addressing.
+	 */
+	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);
+
+	fxp_scb_wait(sc);
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);
+
+	/*
+	 * Initialize base of dump-stats buffer.
+	 */
+	DBGLVL_PRINTK(5,"fxp_init: Initializing base of dump-stats buffer\n");
+	fxp_scb_wait(sc);
+	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(sc->fxp_stats));
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);
+
+	/*
+	 * We temporarily use memory that contains the TxCB list to
+	 * construct the config CB. The TxCB list memory is rebuilt
+	 * later.
+	 */
+	cbp = (struct fxp_cb_config *) sc->cbl_base;
+	DBGLVL_PRINTK(5,"fxp_init: cbp = 0x%x\n",cbp);
+
+	/*
+	 * This bcopy is kind of disgusting, but there are a bunch of must be
+	 * zero and must be one bits in this structure and this is the easiest
+	 * way to initialize them all to proper values.
+	 */
+	bcopy(fxp_cb_config_template,
+		(void *)(u_int32_t *)(volatile void *)&cbp->cb_status,
+		sizeof(fxp_cb_config_template));
+
+	cbp->cb_status =	0;
+	cbp->cb_command =	FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL;
+	cbp->link_addr =	-1;	/* (no) next command */
+	cbp->byte_count =	22;	/* (22) bytes to config */
+	cbp->rx_fifo_limit =	8;	/* rx fifo threshold (32 bytes) */
+	cbp->tx_fifo_limit =	0;	/* tx fifo threshold (0 bytes) */
+	cbp->adaptive_ifs =	0;	/* (no) adaptive interframe spacing */
+	cbp->mwi_enable =	sc->flags & FXP_FLAG_MWI_ENABLE ? 1 : 0;
+	cbp->type_enable =	0;	/* actually reserved */
+	cbp->read_align_en =	sc->flags & FXP_FLAG_READ_ALIGN ? 1 : 0;
+	cbp->end_wr_on_cl =	sc->flags & FXP_FLAG_WRITE_ALIGN ? 1 : 0;
+	cbp->rx_dma_bytecount =	0;	/* (no) rx DMA max */
+	cbp->tx_dma_bytecount =	0;	/* (no) tx DMA max */
+	cbp->dma_mbce =		0;	/* (disable) dma max counters */
+	cbp->late_scb =		0;	/* (don't) defer SCB update */
+	cbp->direct_dma_dis =	1;	/* disable direct rcv dma mode */
+	cbp->tno_int_or_tco_en =0;	/* (disable) tx not okay interrupt */
+	cbp->ci_int =		1;	/* interrupt on CU idle */
+	cbp->ext_txcb_dis = 	sc->flags & FXP_FLAG_EXT_TXCB ? 0 : 1;
+	cbp->ext_stats_dis = 	1;	/* disable extended counters */
+	cbp->keep_overrun_rx = 	0;	/* don't pass overrun frames to host */
+	cbp->save_bf =		sc->chip == FXP_CHIP_82557 ? 1 : prm;
+	cbp->disc_short_rx =	!prm;	/* discard short packets */
+	cbp->underrun_retry =	1;	/* retry mode (once) on DMA underrun */
+	cbp->two_frames =	0;	/* do not limit FIFO to 2 frames */
+	cbp->dyn_tbd =		0;	/* (no) dynamic TBD mode */
+	cbp->mediatype =	sc->flags & FXP_FLAG_SERIAL_MEDIA ? 0 : 1;
+	cbp->csma_dis =		0;	/* (don't) disable link */
+	cbp->tcp_udp_cksum =	0;	/* (don't) enable checksum */
+	cbp->vlan_tco =		0;	/* (don't) enable vlan wakeup */
+	cbp->link_wake_en =	0;	/* (don't) assert PME# on link change */
+	cbp->arp_wake_en =	0;	/* (don't) assert PME# on arp */
+	cbp->mc_wake_en =	0;	/* (don't) enable PME# on mcmatch */
+	cbp->nsai =		1;	/* (don't) disable source addr insert */
+	cbp->preamble_length =	2;	/* (7 byte) preamble */
+	cbp->loopback =		0;	/* (don't) loopback */
+	cbp->linear_priority =	0;	/* (normal CSMA/CD operation) */
+	cbp->linear_pri_mode =	0;	/* (wait after xmit only) */
+	cbp->interfrm_spacing =	6;	/* (96 bits of) interframe spacing */
+	cbp->promiscuous =	prm;	/* promiscuous mode */
+	cbp->bcast_disable =	0;	/* (don't) disable broadcasts */
+	cbp->wait_after_win =	0;	/* (don't) enable modified backoff alg*/
+	cbp->ignore_ul =	0;	/* consider U/L bit in IA matching */
+	cbp->crc16_en =		0;	/* (don't) enable crc-16 algorithm */
+	cbp->crscdt =		sc->flags & FXP_FLAG_SERIAL_MEDIA ? 1 : 0;
+
+	cbp->stripping =	!prm;	/* truncate rx packet to byte count */
+	cbp->padding =		1;	/* (do) pad short tx packets */
+	cbp->rcv_crc_xfer =	0;	/* (don't) xfer CRC to host */
+	cbp->long_rx_en =	sc->flags & FXP_FLAG_LONG_PKT_EN ? 1 : 0;
+	cbp->ia_wake_en =	0;	/* (don't) wake up on address match */
+	cbp->magic_pkt_dis =	0;	/* (don't) disable magic packet */
+					/* must set wake_en in PMCSR also */
+	cbp->force_fdx =	0;	/* (don't) force full duplex */
+	cbp->fdx_pin_en =	1;	/* (enable) FDX# pin */
+	cbp->multi_ia =		0;	/* (don't) accept multiple IAs */
+	cbp->mc_all =		sc->flags & FXP_FLAG_ALL_MCAST ? 1 : 0;
+
+	DBGLVL_PRINTK(5,"fxp_init: cbp initialized\n");
+	if (sc->chip == FXP_CHIP_82557) {
+		/*
+		 * The 82557 has no hardware flow control, the values
+		 * below are the defaults for the chip.
+		 */
+		cbp->fc_delay_lsb =	0;
+		cbp->fc_delay_msb =	0x40;
+		cbp->pri_fc_thresh =	3;
+		cbp->tx_fc_dis =	0;
+		cbp->rx_fc_restop =	0;
+		cbp->rx_fc_restart =	0;
+		cbp->fc_filter =	0;
+		cbp->pri_fc_loc =	1;
+	} else {
+		cbp->fc_delay_lsb =	0x1f;
+		cbp->fc_delay_msb =	0x01;
+		cbp->pri_fc_thresh =	3;
+		cbp->tx_fc_dis =	0;	/* enable transmit FC */
+		cbp->rx_fc_restop =	1;	/* enable FC restop frames */
+		cbp->rx_fc_restart =	1;	/* enable FC restart frames */
+		cbp->fc_filter =	!prm;	/* drop FC frames to host */
+		cbp->pri_fc_loc =	1;	/* FC pri location (byte31) */
+	}
+
+	/*
+	 * Start the config command/DMA.
+	 */
+	DBGLVL_PRINTK(5,"fxp_init: starting config command/DMA\n");
+	fxp_scb_wait(sc);
+	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status));
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
+	/* ...and wait for it to complete. */
+	fxp_dma_wait(&cbp->cb_status, sc);
+
+	/*
+	 * Now initialize the station address. Temporarily use the TxCB
+	 * memory area like we did above for the config CB.
+	 */
+	DBGLVL_PRINTK(5,"fxp_init: initialize station address\n");
+	cb_ias = (struct fxp_cb_ias *) sc->cbl_base;
+	cb_ias->cb_status = 0;
+	cb_ias->cb_command = FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL;
+	cb_ias->link_addr = -1;
+	bcopy(sc->arpcom.ac_enaddr,
+	    (void *)(u_int32_t *)(volatile void *)cb_ias->macaddr,
+	    sizeof(sc->arpcom.ac_enaddr));
+
+	/*
+	 * Start the IAS (Individual Address Setup) command/DMA.
+	 */
+	DBGLVL_PRINTK(5,"fxp_init: start IAS command/DMA\n");
+	fxp_scb_wait(sc);
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
+	/* ...and wait for it to complete. */
+	fxp_dma_wait(&cb_ias->cb_status, sc);
+
+	/*
+	 * Initialize transmit control block (TxCB) list.
+	 */
+
+	DBGLVL_PRINTK(5,"fxp_init: initialize TxCB list\n");
+	txp = sc->cbl_base;
+	bzero(txp, sizeof(struct fxp_cb_tx) * FXP_NTXCB);
+	for (i = 0; i < FXP_NTXCB; i++) {
+		txp[i].cb_status = FXP_CB_STATUS_C | FXP_CB_STATUS_OK;
+		txp[i].cb_command = FXP_CB_COMMAND_NOP;
+		txp[i].link_addr =
+		    vtophys(&txp[(i + 1) & FXP_TXCB_MASK].cb_status);
+		if (sc->flags & FXP_FLAG_EXT_TXCB)
+			txp[i].tbd_array_addr = vtophys(&txp[i].tbd[2]);
+		else
+			txp[i].tbd_array_addr = vtophys(&txp[i].tbd[0]);
+		txp[i].next = &txp[(i + 1) & FXP_TXCB_MASK];
+	}
+	/*
+	 * Set the suspend flag on the first TxCB and start the control
+	 * unit. It will execute the NOP and then suspend.
+	 */
+	DBGLVL_PRINTK(5,"fxp_init: setup suspend flag\n");
+	txp->cb_command = FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S;
+	sc->cbl_first = sc->cbl_last = txp;
+	sc->tx_queued = 1;
+
+	fxp_scb_wait(sc);
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
+
+	/*
+	 * Initialize receiver buffer area - RFA.
+	 */
+	DBGLVL_PRINTK(5,"fxp_init: initialize RFA\n");
+	fxp_scb_wait(sc);
+	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
+	    vtophys(sc->rfa_headm->m_ext.ext_buf) + RFA_ALIGNMENT_FUDGE);
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
+
+#ifdef NOTUSED
+	/*
+	 * Set current media.
+	 */
+	if (sc->miibus != NULL)
+		mii_mediachg(device_get_softc(sc->miibus));
+#endif
+
+	ifp->if_flags |= IFF_RUNNING;
+	ifp->if_flags &= ~IFF_OACTIVE;
+
+	if (sc->daemonTid == 0) {
+		/*
+		 * Start driver task
+		 */
+		sc->daemonTid = rtems_bsdnet_newproc ("FXPd", 4096, fxp_daemon, sc);
+
+	}
+	/*
+	 * Enable interrupts.
+	 */
+	CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, 0);
+	splx(s);
+
+	/*
+	 * Start stats updater.
+	 */
+	sc->stat_ch = fxp_timeout_running;
+	DBGLVL_PRINTK(2,"fxp_init: stats updater timeout called with hz=%d\n", hz);
+	timeout(fxp_tick, sc, hz);
+	DBGLVL_PRINTK(2,"fxp_init finished\n");
+}
+
+#ifdef NOTUSED
+static int
+fxp_serial_ifmedia_upd(struct ifnet *ifp)
+{
+
+	return (0);
+}
+
+static void
+fxp_serial_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+
+	ifmr->ifm_active = IFM_ETHER|IFM_MANUAL;
+}
+
+/*
+ * Change media according to request.
+ */
+static int
+fxp_ifmedia_upd(struct ifnet *ifp)
+{
+	struct fxp_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->miibus);
+	mii_mediachg(mii);
+	return (0);
+}
+
+/*
+ * Notify the world which media we're using.
+ */
+static void
+fxp_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct fxp_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->miibus);
+	mii_pollstat(mii);
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+
+	if (ifmr->ifm_status & IFM_10_T && sc->flags & FXP_FLAG_CU_RESUME_BUG)
+		sc->cu_resume_bug = 1;
+	else
+		sc->cu_resume_bug = 0;
+}
+#endif
+
+/*
+ * Add a buffer to the end of the RFA buffer list.
+ * Return 0 if successful, 1 for failure. A failure results in
+ * adding the 'oldm' (if non-NULL) on to the end of the list -
+ * tossing out its old contents and recycling it.
+ * The RFA struct is stuck at the beginning of mbuf cluster and the
+ * data pointer is fixed up to point just past it.
+ */
+static int
+fxp_add_rfabuf(struct fxp_softc *sc, struct mbuf *oldm)
+{
+	u_int32_t v;
+	struct mbuf *m;
+	struct fxp_rfa *rfa, *p_rfa;
+
+	DBGLVL_PRINTK(4,"fxp_add_rfabuf called\n");
+
+	MGETHDR(m, M_DONTWAIT, MT_DATA);
+	if (m != NULL) {
+		MCLGET(m, M_DONTWAIT);
+		if ((m->m_flags & M_EXT) == 0) {
+			m_freem(m);
+			if (oldm == NULL)
+				return 1;
+			m = oldm;
+			m->m_data = m->m_ext.ext_buf;
+		}
+	} else {
+		if (oldm == NULL)
+			return 1;
+		m = oldm;
+		m->m_data = m->m_ext.ext_buf;
+	}
+
+	/*
+	 * Move the data pointer up so that the incoming data packet
+	 * will be 32-bit aligned.
+	 */
+	m->m_data += RFA_ALIGNMENT_FUDGE;
+
+	/*
+	 * Get a pointer to the base of the mbuf cluster and move
+	 * data start past it.
+	 */
+	rfa = mtod(m, struct fxp_rfa *);
+	m->m_data += sizeof(struct fxp_rfa);
+	rfa->size = (u_int16_t)(MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE);
+
+	/*
+	 * Initialize the rest of the RFA.  Note that since the RFA
+	 * is misaligned, we cannot store values directly.  Instead,
+	 * we use an optimized, inline copy.
+	 */
+
+	rfa->rfa_status = 0;
+	rfa->rfa_control = FXP_RFA_CONTROL_EL;
+	rfa->actual_size = 0;
+
+	v = -1;
+	fxp_lwcopy(&v, (volatile u_int32_t *) rfa->link_addr);
+	fxp_lwcopy(&v, (volatile u_int32_t *) rfa->rbd_addr);
+
+	/*
+	 * If there are other buffers already on the list, attach this
+	 * one to the end by fixing up the tail to point to this one.
+	 */
+	if (sc->rfa_headm != NULL) {
+		p_rfa = (struct fxp_rfa *) (sc->rfa_tailm->m_ext.ext_buf +
+		    RFA_ALIGNMENT_FUDGE);
+		sc->rfa_tailm->m_next = m;
+		v = vtophys(rfa);
+		fxp_lwcopy(&v, (volatile u_int32_t *) p_rfa->link_addr);
+		p_rfa->rfa_control = 0;
+	} else {
+		sc->rfa_headm = m;
+	}
+	sc->rfa_tailm = m;
+
+	return (m == oldm);
+}
+
+#ifdef NOTUSED
+static volatile int
+fxp_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct fxp_softc *sc = device_get_softc(dev);
+	int count = 10000;
+	int value;
+
+	CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
+	    (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21));
+
+	while (((value = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) & 0x10000000) == 0
+	    && count--)
+		DELAY(10);
+
+	if (count <= 0)
+		device_printf(dev, "fxp_miibus_readreg: timed out\n");
+
+	return (value & 0xffff);
+}
+
+static void
+fxp_miibus_writereg(device_t dev, int phy, int reg, int value)
+{
+	struct fxp_softc *sc = device_get_softc(dev);
+	int count = 10000;
+
+	CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
+	    (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) |
+	    (value & 0xffff));
+
+	while ((CSR_READ_4(sc, FXP_CSR_MDICONTROL) & 0x10000000) == 0 &&
+	    count--)
+		DELAY(10);
+
+	if (count <= 0)
+		device_printf(dev, "fxp_miibus_writereg: timed out\n");
+}
+#endif
+
+static int
+fxp_ioctl(struct ifnet *ifp, int command, caddr_t data)
+{
+	struct fxp_softc *sc = ifp->if_softc;
+#ifdef NOTUSED
+	struct ifreq *ifr = (struct ifreq *)data;
+	struct mii_data *mii;
+#endif
+	int s, error = 0;
+
+	DBGLVL_PRINTK(2,"fxp_ioctl called\n");
+
+	s = splimp();
+
+	switch (command) {
+	case SIOCSIFADDR:
+	case SIOCGIFADDR:
+	case SIOCSIFMTU:
+		error = ether_ioctl(ifp, command, data);
+		break;
+
+	case SIOCSIFFLAGS:
+		if (ifp->if_flags & IFF_ALLMULTI)
+			sc->flags |= FXP_FLAG_ALL_MCAST;
+		else
+			sc->flags &= ~FXP_FLAG_ALL_MCAST;
+
+		/*
+		 * If interface is marked up and not running, then start it.
+		 * If it is marked down and running, stop it.
+		 * XXX If it's up then re-initialize it. This is so flags
+		 * such as IFF_PROMISC are handled.
+		 */
+		if (ifp->if_flags & IFF_UP) {
+			fxp_init(sc);
+		} else {
+			if (ifp->if_flags & IFF_RUNNING)
+				fxp_stop(sc);
+		}
+		break;
+
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		if (ifp->if_flags & IFF_ALLMULTI)
+			sc->flags |= FXP_FLAG_ALL_MCAST;
+		else
+			sc->flags &= ~FXP_FLAG_ALL_MCAST;
+		/*
+		 * Multicast list has changed; set the hardware filter
+		 * accordingly.
+		 */
+		if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0)
+			fxp_mc_setup(sc);
+		/*
+		 * fxp_mc_setup() can set FXP_FLAG_ALL_MCAST, so check it
+		 * again rather than else {}.
+		 */
+		if (sc->flags & FXP_FLAG_ALL_MCAST)
+			fxp_init(sc);
+		error = 0;
+		break;
+
+#ifdef NOTUSED
+	case SIOCSIFMEDIA:
+	case SIOCGIFMEDIA:
+		if (sc->miibus != NULL) {
+			mii = device_get_softc(sc->miibus);
+                        error = ifmedia_ioctl(ifp, ifr,
+                            &mii->mii_media, command);
+		} else {
+                        error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
+		}
+		break;
+#endif
+
+    case SIO_RTEMS_SHOW_STATS:
+        fxp_stats(sc);
+        break;
+
+	default:
+		error = EINVAL;
+	}
+	splx(s);
+	return (error);
+}
+
+/*
+ * Program the multicast filter.
+ *
+ * We have an artificial restriction that the multicast setup command
+ * must be the first command in the chain, so we take steps to ensure
+ * this. By requiring this, it allows us to keep up the performance of
+ * the pre-initialized command ring (esp. link pointers) by not actually
+ * inserting the mcsetup command in the ring - i.e. its link pointer
+ * points to the TxCB ring, but the mcsetup descriptor itself is not part
+ * of it. We then can do 'CU_START' on the mcsetup descriptor and have it
+ * lead into the regular TxCB ring when it completes.
+ *
+ * This function must be called at splimp.
+ */
+static void
+fxp_mc_setup(struct fxp_softc *sc)
+{
+	struct fxp_cb_mcs *mcsp = sc->mcsp;
+	struct ifnet *ifp = &sc->sc_if;
+#ifdef NOTUSED
+	struct ifmultiaddr *ifma;
+#endif
+	int nmcasts;
+	int count;
+
+	DBGLVL_PRINTK(2,"fxp_mc_setup called\n");
+
+	/*
+	 * If there are queued commands, we must wait until they are all
+	 * completed. If we are already waiting, then add a NOP command
+	 * with interrupt option so that we're notified when all commands
+	 * have been completed - fxp_start() ensures that no additional
+	 * TX commands will be added when need_mcsetup is true.
+	 */
+	if (sc->tx_queued) {
+		struct fxp_cb_tx *txp;
+
+		/*
+		 * need_mcsetup will be true if we are already waiting for the
+		 * NOP command to be completed (see below). In this case, bail.
+		 */
+		if (sc->need_mcsetup)
+			return;
+		sc->need_mcsetup = 1;
+
+		/*
+		 * Add a NOP command with interrupt so that we are notified when all
+		 * TX commands have been processed.
+		 */
+		txp = sc->cbl_last->next;
+		txp->mb_head = NULL;
+		txp->cb_status = 0;
+		txp->cb_command = FXP_CB_COMMAND_NOP |
+		    FXP_CB_COMMAND_S | FXP_CB_COMMAND_I;
+		/*
+		 * Advance the end of list forward.
+		 */
+		sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;
+		sc->cbl_last = txp;
+		sc->tx_queued++;
+		/*
+		 * Issue a resume in case the CU has just suspended.
+		 */
+		fxp_scb_wait(sc);
+		fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
+		/*
+		 * Set a 5 second timer just in case we don't hear from the
+		 * card again.
+		 */
+		ifp->if_timer = 5;
+
+		return;
+	}
+	sc->need_mcsetup = 0;
+
+	/*
+	 * Initialize multicast setup descriptor.
+	 */
+	mcsp->next = sc->cbl_base;
+	mcsp->mb_head = NULL;
+	mcsp->cb_status = 0;
+	mcsp->cb_command = FXP_CB_COMMAND_MCAS |
+	    FXP_CB_COMMAND_S | FXP_CB_COMMAND_I;
+	mcsp->link_addr = vtophys(&sc->cbl_base->cb_status);
+
+	nmcasts = 0;
+#ifdef NOTUSED /* FIXME: Multicast not supported? */
+	if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0) {
+#if __FreeBSD_version < 500000
+		LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+#else
+		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+#endif
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				continue;
+			if (nmcasts >= MAXMCADDR) {
+				sc->flags |= FXP_FLAG_ALL_MCAST;
+				nmcasts = 0;
+				break;
+			}
+			bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
+			    (void *)(uintptr_t)(volatile void *)
+				&sc->mcsp->mc_addr[nmcasts][0], 6);
+			nmcasts++;
+		}
+	}
+#endif
+	mcsp->mc_cnt = nmcasts * 6;
+	sc->cbl_first = sc->cbl_last = (struct fxp_cb_tx *) mcsp;
+	sc->tx_queued = 1;
+
+	/*
+	 * Wait until command unit is not active. This should never
+	 * be the case when nothing is queued, but make sure anyway.
+	 */
+	count = 100;
+	while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) ==
+	    FXP_SCB_CUS_ACTIVE && --count)
+		DELAY(10);
+	if (count == 0) {
+		device_printf(sc->dev, "command queue timeout\n");
+		return;
+	}
+
+	/*
+	 * Start the multicast setup command.
+	 */
+	fxp_scb_wait(sc);
+	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&mcsp->cb_status));
+	fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
+
+	ifp->if_timer = 2;
+	return;
+	}
+
+#endif /* defined(__i386__) */
Index: c/src/libchip/network/if_fxpreg.h
===================================================================
--- c/src/libchip/network/if_fxpreg.h	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
+++ c/src/libchip/network/if_fxpreg.h	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 1995, David Greenman
+ * Copyright (c) 2001 Jonathan Lemon <jlemon@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/dev/fxp/if_fxpreg.h,v 1.23.2.4 2001/08/31 02:17:02 jlemon Exp $
+ */
+
+#define FXP_VENDORID_INTEL	0x8086
+
+#define FXP_PCI_MMBA	0x10
+#define FXP_PCI_IOBA	0x14
+
+/*
+ * Control/status registers.
+ */
+#define	FXP_CSR_SCB_RUSCUS	0	/* scb_rus/scb_cus (1 byte) */
+#define	FXP_CSR_SCB_STATACK	1	/* scb_statack (1 byte) */
+#define	FXP_CSR_SCB_COMMAND	2	/* scb_command (1 byte) */
+#define	FXP_CSR_SCB_INTRCNTL	3	/* scb_intrcntl (1 byte) */
+#define	FXP_CSR_SCB_GENERAL	4	/* scb_general (4 bytes) */
+#define	FXP_CSR_PORT		8	/* port (4 bytes) */
+#define	FXP_CSR_FLASHCONTROL	12	/* flash control (2 bytes) */
+#define	FXP_CSR_EEPROMCONTROL	14	/* eeprom control (2 bytes) */
+#define	FXP_CSR_MDICONTROL	16	/* mdi control (4 bytes) */
+#define	FXP_CSR_FLOWCONTROL	0x19	/* flow control (2 bytes) */
+#define	FXP_CSR_GENCONTROL	0x1C	/* general control (1 byte) */
+
+/*
+ * FOR REFERENCE ONLY, the old definition of FXP_CSR_SCB_RUSCUS:
+ *
+ *	volatile u_int8_t	:2,
+ *				scb_rus:4,
+ *				scb_cus:2;
+ */
+
+#define FXP_PORT_SOFTWARE_RESET		0
+#define FXP_PORT_SELFTEST		1
+#define FXP_PORT_SELECTIVE_RESET	2
+#define FXP_PORT_DUMP			3
+
+#define FXP_SCB_RUS_IDLE		0
+#define FXP_SCB_RUS_SUSPENDED		1
+#define FXP_SCB_RUS_NORESOURCES		2
+#define FXP_SCB_RUS_READY		4
+#define FXP_SCB_RUS_SUSP_NORBDS		9
+#define FXP_SCB_RUS_NORES_NORBDS	10
+#define FXP_SCB_RUS_READY_NORBDS	12
+
+#define FXP_SCB_CUS_IDLE		0
+#define FXP_SCB_CUS_SUSPENDED		1
+#define FXP_SCB_CUS_ACTIVE		2
+
+#define FXP_SCB_INTR_DISABLE		0x01	/* Disable all interrupts */
+#define FXP_SCB_INTR_SWI		0x02	/* Generate SWI */
+#define FXP_SCB_INTMASK_FCP		0x04
+#define FXP_SCB_INTMASK_ER		0x08
+#define FXP_SCB_INTMASK_RNR		0x10
+#define FXP_SCB_INTMASK_CNA		0x20
+#define FXP_SCB_INTMASK_FR		0x40
+#define FXP_SCB_INTMASK_CXTNO		0x80
+
+#define FXP_SCB_STATACK_FCP		0x01	/* Flow Control Pause */
+#define FXP_SCB_STATACK_ER		0x02	/* Early Receive */
+#define FXP_SCB_STATACK_SWI		0x04
+#define FXP_SCB_STATACK_MDI		0x08
+#define FXP_SCB_STATACK_RNR		0x10
+#define FXP_SCB_STATACK_CNA		0x20
+#define FXP_SCB_STATACK_FR		0x40
+#define FXP_SCB_STATACK_CXTNO		0x80
+
+#define FXP_SCB_COMMAND_CU_NOP		0x00
+#define FXP_SCB_COMMAND_CU_START	0x10
+#define FXP_SCB_COMMAND_CU_RESUME	0x20
+#define FXP_SCB_COMMAND_CU_DUMP_ADR	0x40
+#define FXP_SCB_COMMAND_CU_DUMP		0x50
+#define FXP_SCB_COMMAND_CU_BASE		0x60
+#define FXP_SCB_COMMAND_CU_DUMPRESET	0x70
+
+#define FXP_SCB_COMMAND_RU_NOP		0
+#define FXP_SCB_COMMAND_RU_START	1
+#define FXP_SCB_COMMAND_RU_RESUME	2
+#define FXP_SCB_COMMAND_RU_ABORT	4
+#define FXP_SCB_COMMAND_RU_LOADHDS	5
+#define FXP_SCB_COMMAND_RU_BASE		6
+#define FXP_SCB_COMMAND_RU_RBDRESUME	7
+
+/*
+ * Command block definitions
+ */
+struct fxp_cb_nop {
+	void *fill[2];
+	volatile u_int16_t cb_status;
+	volatile u_int16_t cb_command;
+	volatile u_int32_t link_addr;
+};
+struct fxp_cb_ias {
+	void *fill[2];
+	volatile u_int16_t cb_status;
+	volatile u_int16_t cb_command;
+	volatile u_int32_t link_addr;
+	volatile u_int8_t macaddr[6];
+};
+/* I hate bit-fields :-( */
+struct fxp_cb_config {
+	void *fill[2];
+	volatile u_int16_t	cb_status;
+	volatile u_int16_t	cb_command;
+	volatile u_int32_t	link_addr;
+	volatile u_int		byte_count:6,
+				:2;
+	volatile u_int		rx_fifo_limit:4,
+				tx_fifo_limit:3,
+				:1;
+	volatile u_int8_t	adaptive_ifs;
+	volatile u_int		mwi_enable:1,			/* 8,9 */
+				type_enable:1,			/* 8,9 */
+				read_align_en:1,		/* 8,9 */
+				end_wr_on_cl:1,			/* 8,9 */
+				:4;
+	volatile u_int		rx_dma_bytecount:7,
+				:1;
+	volatile u_int		tx_dma_bytecount:7,
+				dma_mbce:1;
+	volatile u_int		late_scb:1,			/* 7 */
+				direct_dma_dis:1,		/* 8,9 */
+				tno_int_or_tco_en:1,		/* 7,9 */
+				ci_int:1,
+				ext_txcb_dis:1,			/* 8,9 */
+				ext_stats_dis:1,		/* 8,9 */
+				keep_overrun_rx:1,
+				save_bf:1;
+	volatile u_int		disc_short_rx:1,
+				underrun_retry:2,
+				:3,
+				two_frames:1,			/* 8,9 */
+				dyn_tbd:1;			/* 8,9 */
+	volatile u_int		mediatype:1,			/* 7 */
+				:6,
+				csma_dis:1;			/* 8,9 */
+	volatile u_int		tcp_udp_cksum:1,		/* 9 */
+				:3,
+				vlan_tco:1,			/* 8,9 */
+				link_wake_en:1,			/* 8,9 */
+				arp_wake_en:1,			/* 8 */
+				mc_wake_en:1;			/* 8 */
+	volatile u_int		:3,
+				nsai:1,
+				preamble_length:2,
+				loopback:2;
+	volatile u_int		linear_priority:3,		/* 7 */
+				:5;
+	volatile u_int		linear_pri_mode:1,		/* 7 */
+				:3,
+				interfrm_spacing:4;
+	volatile u_int		:8;
+	volatile u_int		:8;
+	volatile u_int		promiscuous:1,
+				bcast_disable:1,
+				wait_after_win:1,		/* 8,9 */
+				:1,
+				ignore_ul:1,			/* 8,9 */
+				crc16_en:1,			/* 9 */
+				:1,
+				crscdt:1;
+	volatile u_int		fc_delay_lsb:8;			/* 8,9 */
+	volatile u_int		fc_delay_msb:8;			/* 8,9 */
+	volatile u_int		stripping:1,
+				padding:1,
+				rcv_crc_xfer:1,
+				long_rx_en:1,			/* 8,9 */
+				pri_fc_thresh:3,		/* 8,9 */
+				:1;
+	volatile u_int		ia_wake_en:1,			/* 8 */
+				magic_pkt_dis:1,		/* 8,9,!9ER */
+				tx_fc_dis:1,			/* 8,9 */
+				rx_fc_restop:1,			/* 8,9 */
+				rx_fc_restart:1,		/* 8,9 */
+				fc_filter:1,			/* 8,9 */
+				force_fdx:1,
+				fdx_pin_en:1;
+	volatile u_int		:5,
+				pri_fc_loc:1,			/* 8,9 */
+				multi_ia:1,
+				:1;
+	volatile u_int		:3,
+				mc_all:1,
+				:4;
+};
+
+#define MAXMCADDR 80
+struct fxp_cb_mcs {
+	struct fxp_cb_tx *next;
+	struct mbuf *mb_head;
+	volatile u_int16_t cb_status;
+	volatile u_int16_t cb_command;
+	volatile u_int32_t link_addr;
+	volatile u_int16_t mc_cnt;
+	volatile u_int8_t mc_addr[MAXMCADDR][6];
+};
+
+/*
+ * Number of DMA segments in a TxCB. Note that this is carefully
+ * chosen to make the total struct size an even power of two. It's
+ * critical that no TxCB be split across a page boundry since
+ * no attempt is made to allocate physically contiguous memory.
+ * 
+ */
+#ifdef __alpha__ /* XXX - should be conditional on pointer size */
+#define FXP_NTXSEG      28
+#else
+#define FXP_NTXSEG      29
+#endif
+
+struct fxp_tbd {
+	volatile u_int32_t tb_addr;
+	volatile u_int32_t tb_size;
+};
+struct fxp_cb_tx {
+	struct fxp_cb_tx *next;
+	struct mbuf *mb_head;
+	volatile u_int16_t cb_status;
+	volatile u_int16_t cb_command;
+	volatile u_int32_t link_addr;
+	volatile u_int32_t tbd_array_addr;
+	volatile u_int16_t byte_count;
+	volatile u_int8_t tx_threshold;
+	volatile u_int8_t tbd_number;
+	/*
+	 * The following structure isn't actually part of the TxCB,
+	 * unless the extended TxCB feature is being used.  In this
+	 * case, the first two elements of the structure below are 
+	 * fetched along with the TxCB.
+	 */
+	volatile struct fxp_tbd tbd[FXP_NTXSEG];
+};
+
+/*
+ * Control Block (CB) definitions
+ */
+
+/* status */
+#define FXP_CB_STATUS_OK	0x2000
+#define FXP_CB_STATUS_C		0x8000
+/* commands */
+#define FXP_CB_COMMAND_NOP	0x0
+#define FXP_CB_COMMAND_IAS	0x1
+#define FXP_CB_COMMAND_CONFIG	0x2
+#define FXP_CB_COMMAND_MCAS	0x3
+#define FXP_CB_COMMAND_XMIT	0x4
+#define FXP_CB_COMMAND_RESRV	0x5
+#define FXP_CB_COMMAND_DUMP	0x6
+#define FXP_CB_COMMAND_DIAG	0x7
+/* command flags */
+#define FXP_CB_COMMAND_SF	0x0008	/* simple/flexible mode */
+#define FXP_CB_COMMAND_I	0x2000	/* generate interrupt on completion */
+#define FXP_CB_COMMAND_S	0x4000	/* suspend on completion */
+#define FXP_CB_COMMAND_EL	0x8000	/* end of list */
+
+/*
+ * RFA definitions
+ */
+
+struct fxp_rfa {
+	volatile u_int16_t rfa_status;
+	volatile u_int16_t rfa_control;
+        volatile u_int8_t link_addr[4];
+        volatile u_int8_t rbd_addr[4];
+	volatile u_int16_t actual_size;
+	volatile u_int16_t size;
+};
+#define FXP_RFA_STATUS_RCOL	0x0001	/* receive collision */
+#define FXP_RFA_STATUS_IAMATCH	0x0002	/* 0 = matches station address */
+#define FXP_RFA_STATUS_S4	0x0010	/* receive error from PHY */
+#define FXP_RFA_STATUS_TL	0x0020	/* type/length */
+#define FXP_RFA_STATUS_FTS	0x0080	/* frame too short */
+#define FXP_RFA_STATUS_OVERRUN	0x0100	/* DMA overrun */
+#define FXP_RFA_STATUS_RNR	0x0200	/* no resources */
+#define FXP_RFA_STATUS_ALIGN	0x0400	/* alignment error */
+#define FXP_RFA_STATUS_CRC	0x0800	/* CRC error */
+#define FXP_RFA_STATUS_OK	0x2000	/* packet received okay */
+#define FXP_RFA_STATUS_C	0x8000	/* packet reception complete */
+#define FXP_RFA_CONTROL_SF	0x08	/* simple/flexible memory mode */
+#define FXP_RFA_CONTROL_H	0x10	/* header RFD */
+#define FXP_RFA_CONTROL_S	0x4000	/* suspend after reception */
+#define FXP_RFA_CONTROL_EL	0x8000	/* end of list */
+
+/*
+ * Statistics dump area definitions
+ */
+struct fxp_stats {
+	volatile u_int32_t tx_good;
+	volatile u_int32_t tx_maxcols;
+	volatile u_int32_t tx_latecols;
+	volatile u_int32_t tx_underruns;
+	volatile u_int32_t tx_lostcrs;
+	volatile u_int32_t tx_deffered;
+	volatile u_int32_t tx_single_collisions;
+	volatile u_int32_t tx_multiple_collisions;
+	volatile u_int32_t tx_total_collisions;
+	volatile u_int32_t rx_good;
+	volatile u_int32_t rx_crc_errors;
+	volatile u_int32_t rx_alignment_errors;
+	volatile u_int32_t rx_rnr_errors;
+	volatile u_int32_t rx_overrun_errors;
+	volatile u_int32_t rx_cdt_errors;
+	volatile u_int32_t rx_shortframes;
+	volatile u_int32_t completion_status;
+};
+#define FXP_STATS_DUMP_COMPLETE	0xa005
+#define FXP_STATS_DR_COMPLETE	0xa007
+	
+/*
+ * Serial EEPROM control register bits
+ */
+#define FXP_EEPROM_EESK		0x01 		/* shift clock */
+#define FXP_EEPROM_EECS		0x02 		/* chip select */
+#define FXP_EEPROM_EEDI		0x04 		/* data in */
+#define FXP_EEPROM_EEDO		0x08 		/* data out */
+
+/*
+ * Serial EEPROM opcodes, including start bit
+ */
+#define FXP_EEPROM_OPC_ERASE	0x4
+#define FXP_EEPROM_OPC_WRITE	0x5
+#define FXP_EEPROM_OPC_READ	0x6
+
+/*
+ * Management Data Interface opcodes
+ */
+#define FXP_MDI_WRITE		0x1
+#define FXP_MDI_READ		0x2
+
+/*
+ * PHY device types
+ */
+#define FXP_PHY_DEVICE_MASK	0x3f00
+#define FXP_PHY_SERIAL_ONLY	0x8000
+#define FXP_PHY_NONE		0
+#define FXP_PHY_82553A		1
+#define FXP_PHY_82553C		2
+#define FXP_PHY_82503		3
+#define FXP_PHY_DP83840		4
+#define FXP_PHY_80C240		5
+#define FXP_PHY_80C24		6
+#define FXP_PHY_82555		7
+#define FXP_PHY_DP83840A	10
+#define FXP_PHY_82555B		11
Index: c/src/libchip/network/if_fxpvar.h
===================================================================
--- c/src/libchip/network/if_fxpvar.h	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
+++ c/src/libchip/network/if_fxpvar.h	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
@@ -0,0 +1,201 @@
+/*                  
+ * Copyright (c) 1995, David Greenman
+ * All rights reserved.
+ *              
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:             
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.  
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/dev/fxp/if_fxpvar.h,v 1.17.2.3 2001/06/08 20:36:58 jlemon Exp $
+ */
+
+/*
+ * Misc. defintions for the Intel EtherExpress Pro/100B PCI Fast
+ * Ethernet driver
+ */
+
+/*
+ * Number of transmit control blocks. This determines the number
+ * of transmit buffers that can be chained in the CB list.
+ * This must be a power of two.
+ */
+#define FXP_NTXCB       128
+
+/*
+ * Number of completed TX commands at which point an interrupt
+ * will be generated to garbage collect the attached buffers.
+ * Must be at least one less than FXP_NTXCB, and should be
+ * enough less so that the transmitter doesn't becomes idle
+ * during the buffer rundown (which would reduce performance).
+ */
+#define FXP_CXINT_THRESH 120
+
+/*
+ * TxCB list index mask. This is used to do list wrap-around.
+ */
+#define FXP_TXCB_MASK   (FXP_NTXCB - 1)
+
+/*
+ * Number of receive frame area buffers. These are large so chose
+ * wisely.
+ */
+#if 0
+#define FXP_NRFABUFS    64
+#else
+#define FXP_NRFABUFS    16
+#endif
+/*
+ * Maximum number of seconds that the receiver can be idle before we
+ * assume it's dead and attempt to reset it by reprogramming the
+ * multicast filter. This is part of a work-around for a bug in the
+ * NIC. See fxp_stats_update().
+ */
+#define FXP_MAX_RX_IDLE 15
+
+#if __FreeBSD_version < 500000
+#define	FXP_LOCK(_sc)
+#define	FXP_UNLOCK(_sc)
+#define mtx_init(a, b, c)
+#define mtx_destroy(a)
+struct mtx { int dummy; };
+#else
+#define	FXP_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	FXP_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#endif
+
+#ifdef __alpha__
+#undef vtophys
+#define vtophys(va)	alpha_XXX_dmamap((vm_offset_t)(va))
+#endif /* __alpha__ */
+
+/*
+ * NOTE: Elements are ordered for optimal cacheline behavior, and NOT
+ *	 for functional grouping.
+ */
+struct fxp_softc {
+	struct arpcom arpcom;		/* per-interface network data */
+#ifdef NOTUSED
+	struct resource *mem;		/* resource descriptor for registers */
+	int rtp;			/* register resource type */
+	int rgd;			/* register descriptor in use */
+	struct resource *irq;		/* resource descriptor for interrupt */
+#endif
+	void *ih;			/* interrupt handler cookie */
+	struct mtx sc_mtx;
+#ifdef NOTUSED /* change for RTEMS */
+	bus_space_tag_t sc_st;		/* bus space tag */
+	bus_space_handle_t sc_sh;	/* bus space handle */
+#else
+        int pci_signature;              /* RTEMS i386 PCI signature */
+        boolean pci_regs_are_io;        /* RTEMS dev regs are I/O mapped */
+        u_int32_t pci_regs_base;        /* RTEMS i386 register base */
+        rtems_id daemonTid;             /* Task ID of deamon        */
+        rtems_irq_connect_data	irqInfo;
+
+#endif
+	struct mbuf *rfa_headm;		/* first mbuf in receive frame area */
+	struct mbuf *rfa_tailm;		/* last mbuf in receive frame area */
+	struct fxp_cb_tx *cbl_first;	/* first active TxCB in list */
+	int tx_queued;			/* # of active TxCB's */
+	int need_mcsetup;		/* multicast filter needs programming */
+	struct fxp_cb_tx *cbl_last;	/* last active TxCB in list */
+	struct fxp_stats *fxp_stats;	/* Pointer to interface stats */
+	int rx_idle_secs;		/* # of seconds RX has been idle */
+        enum {fxp_timeout_stopped,fxp_timeout_running,fxp_timeout_stop_rq} 
+          stat_ch;                     /* status of status updater */
+	struct fxp_cb_tx *cbl_base;	/* base of TxCB list */
+	struct fxp_cb_mcs *mcsp;	/* Pointer to mcast setup descriptor */
+#ifdef NOTUSED
+	struct ifmedia sc_media;	/* media information */
+	device_t miibus;
+	device_t dev;
+#endif
+	int eeprom_size;		/* size of serial EEPROM */
+	int suspended;			/* 0 = normal  1 = suspended (APM) */
+	int cu_resume_bug;
+	int chip;
+	int flags;
+	u_int32_t saved_maps[5];	/* pci data */
+	u_int32_t saved_biosaddr;
+	u_int8_t saved_intline;
+	u_int8_t saved_cachelnsz;
+	u_int8_t saved_lattimer;
+};
+
+#define FXP_CHIP_82557		1	/* 82557 chip type */
+
+#define FXP_FLAG_MWI_ENABLE	0x0001	/* MWI enable */
+#define FXP_FLAG_READ_ALIGN	0x0002	/* align read access with cacheline */
+#define FXP_FLAG_WRITE_ALIGN	0x0004	/* end write on cacheline */
+#define FXP_FLAG_EXT_TXCB	0x0008	/* enable use of extended TXCB */
+#define FXP_FLAG_SERIAL_MEDIA	0x0010	/* 10Mbps serial interface */
+#define FXP_FLAG_LONG_PKT_EN	0x0020	/* enable long packet reception */
+#define FXP_FLAG_ALL_MCAST	0x0040	/* accept all multicast frames */
+#define FXP_FLAG_CU_RESUME_BUG	0x0080	/* requires workaround for CU_RESUME */
+
+/* Macros to ease CSR access. */
+#if 0
+#define	CSR_READ_1(sc, reg)						\
+	bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))
+#define	CSR_READ_2(sc, reg)						\
+	bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg))
+#define	CSR_READ_4(sc, reg)						\
+	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
+#define	CSR_WRITE_1(sc, reg, val)					\
+	bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+#define	CSR_WRITE_2(sc, reg, val)					\
+	bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+#define	CSR_WRITE_4(sc, reg, val)					\
+	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+#else
+#define	CSR_READ_1(sc, reg) fxp_csr_read_1(sc,reg)
+#define	CSR_READ_2(sc, reg) fxp_csr_read_2(sc,reg)
+#define	CSR_READ_4(sc, reg) fxp_csr_read_4(sc,reg)
+
+#define	CSR_WRITE_1(sc, reg, val)					\
+  do {                                                                  \
+     if ((sc)->pci_regs_are_io)                                         \
+       outport_byte((sc)->pci_regs_base+(reg),val);                     \
+     else                                                               \
+       *((u_int8_t *)((sc)->pci_regs_base)+(reg)) = val;                \
+  }while (0)
+
+#define	CSR_WRITE_2(sc, reg, val)					\
+  do {                                                                  \
+     if ((sc)->pci_regs_are_io)                                         \
+       outport_word((sc)->pci_regs_base+(reg),val);                     \
+     else                                                               \
+       *((u_int16_t *)((u_int8_t *)((sc)->pci_regs_base)+(reg))) = val; \
+  }while (0)
+
+#define	CSR_WRITE_4(sc, reg, val)					\
+  do {                                                                  \
+     if ((sc)->pci_regs_are_io)                                         \
+       outport_long((sc)->pci_regs_base+(reg),val);                     \
+     else                                                               \
+       *((u_int32_t *)((u_int8_t *)((sc)->pci_regs_base)+(reg))) = val; \
+  }while (0)
+
+#endif 
+
+#define	sc_if			arpcom.ac_if
+
+#define	FXP_UNIT(_sc)		(_sc)->arpcom.ac_if.if_unit
Index: c/src/libchip/network/pci.h
===================================================================
--- c/src/libchip/network/pci.h	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
+++ c/src/libchip/network/pci.h	(revision 2b947a45d7ebba5664c57cc5fc6cf7dc2f35db71)
@@ -0,0 +1,1153 @@
+/*
+ *
+ *	PCI defines and function prototypes
+ *	Copyright 1994, Drew Eckhardt
+ *	Copyright 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ *	For more information, please consult the following manuals (look at
+ *	http://www.pcisig.com/ for how to get them):
+ *
+ *	PCI BIOS Specification
+ *	PCI Local Bus Specification
+ *	PCI to PCI Bridge Specification
+ *	PCI System Design Guide
+ *
+ * $Id$
+ */
+
+#ifndef RTEMS_PCI_H
+#define RTEMS_PCI_H
+
+/*
+ * Under PCI, each device has 256 bytes of configuration address space,
+ * of which the first 64 bytes are standardized as follows:
+ */
+#define PCI_VENDOR_ID		0x00	/* 16 bits */
+#define PCI_DEVICE_ID		0x02	/* 16 bits */
+#define PCI_COMMAND		0x04	/* 16 bits */
+#define  PCI_COMMAND_IO		0x1	/* Enable response in I/O space */
+#define  PCI_COMMAND_MEMORY	0x2	/* Enable response in Memory space */
+#define  PCI_COMMAND_MASTER	0x4	/* Enable bus mastering */
+#define  PCI_COMMAND_SPECIAL	0x8	/* Enable response to special cycles */
+#define  PCI_COMMAND_INVALIDATE	0x10	/* Use memory write and invalidate */
+#define  PCI_COMMAND_VGA_PALETTE 0x20	/* Enable palette snooping */
+#define  PCI_COMMAND_PARITY	0x40	/* Enable parity checking */
+#define  PCI_COMMAND_WAIT 	0x80	/* Enable address/data stepping */
+#define  PCI_COMMAND_SERR	0x100	/* Enable SERR */
+#define  PCI_COMMAND_FAST_BACK	0x200	/* Enable back-to-back writes */
+
+#define PCI_STATUS		0x06	/* 16 bits */
+#define  PCI_STATUS_66MHZ	0x20	/* Support 66 Mhz PCI 2.1 bus */
+#define  PCI_STATUS_UDF		0x40	/* Support User Definable Features */
+
+#define  PCI_STATUS_FAST_BACK	0x80	/* Accept fast-back to back */
+#define  PCI_STATUS_PARITY	0x100	/* Detected parity error */
+#define  PCI_STATUS_DEVSEL_MASK	0x600	/* DEVSEL timing */
+#define  PCI_STATUS_DEVSEL_FAST	0x000	
+#define  PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define  PCI_STATUS_DEVSEL_SLOW 0x400
+#define  PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
+#define  PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
+#define  PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
+#define  PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
+#define  PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
+
+#define PCI_CLASS_REVISION	0x08	/* High 24 bits are class, low 8
+					   revision */
+#define PCI_REVISION_ID         0x08    /* Revision ID */
+#define PCI_CLASS_PROG          0x09    /* Reg. Level Programming Interface */
+#define PCI_CLASS_DEVICE        0x0a    /* Device class */
+
+#define PCI_CACHE_LINE_SIZE	0x0c	/* 8 bits */
+#define PCI_LATENCY_TIMER	0x0d	/* 8 bits */
+#define PCI_HEADER_TYPE		0x0e	/* 8 bits */
+#define  PCI_HEADER_TYPE_NORMAL	0
+#define  PCI_HEADER_TYPE_BRIDGE 1
+#define  PCI_HEADER_TYPE_CARDBUS 2
+
+#define PCI_BIST		0x0f	/* 8 bits */
+#define PCI_BIST_CODE_MASK	0x0f	/* Return result */
+#define PCI_BIST_START		0x40	/* 1 to start BIST, 2 secs or less */
+#define PCI_BIST_CAPABLE	0x80	/* 1 if BIST capable */
+
+/*
+ * Base addresses specify locations in memory or I/O space.
+ * Decoded size can be determined by writing a value of 
+ * 0xffffffff to the register, and reading it back.  Only 
+ * 1 bits are decoded.
+ */
+#define PCI_BASE_ADDRESS_0	0x10	/* 32 bits */
+#define PCI_BASE_ADDRESS_1	0x14	/* 32 bits [htype 0,1 only] */
+#define PCI_BASE_ADDRESS_2	0x18	/* 32 bits [htype 0 only] */
+#define PCI_BASE_ADDRESS_3	0x1c	/* 32 bits */
+#define PCI_BASE_ADDRESS_4	0x20	/* 32 bits */
+#define PCI_BASE_ADDRESS_5	0x24	/* 32 bits */
+#define  PCI_BASE_ADDRESS_SPACE	0x01	/* 0 = memory, 1 = I/O */
+#define  PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define  PCI_BASE_ADDRESS_MEM_TYPE_32	0x00	/* 32 bit address */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_1M	0x02	/* Below 1M */
+#define  PCI_BASE_ADDRESS_MEM_TYPE_64	0x04	/* 64 bit address */
+#define  PCI_BASE_ADDRESS_MEM_PREFETCH	0x08	/* prefetchable? */
+#define  PCI_BASE_ADDRESS_MEM_MASK	(~0x0fUL)
+#define  PCI_BASE_ADDRESS_IO_MASK	(~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS		0x28
+#define PCI_SUBSYSTEM_VENDOR_ID	0x2c
+#define PCI_SUBSYSTEM_ID	0x2e  
+#define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
+#define  PCI_ROM_ADDRESS_ENABLE	0x01
+#define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
+
+/* 0x34-0x3b are reserved */
+#define PCI_INTERRUPT_LINE	0x3c	/* 8 bits */
+#define PCI_INTERRUPT_PIN	0x3d	/* 8 bits */
+#define PCI_MIN_GNT		0x3e	/* 8 bits */
+#define PCI_MAX_LAT		0x3f	/* 8 bits */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS		0x18	/* Primary bus number */
+#define PCI_SECONDARY_BUS	0x19	/* Secondary bus number */
+#define PCI_SUBORDINATE_BUS	0x1a	/* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER	0x1b	/* Latency timer for secondary interface */
+#define PCI_IO_BASE		0x1c	/* I/O range behind the bridge */
+#define PCI_IO_LIMIT		0x1d
+#define  PCI_IO_RANGE_TYPE_MASK	0x0f	/* I/O bridging type */
+#define  PCI_IO_RANGE_TYPE_16	0x00
+#define  PCI_IO_RANGE_TYPE_32	0x01
+#define  PCI_IO_RANGE_MASK	~0x0f
+#define PCI_SEC_STATUS		0x1e	/* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE		0x20	/* Memory range behind */
+#define PCI_MEMORY_LIMIT	0x22
+#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0f
+#define  PCI_MEMORY_RANGE_MASK	~0x0f
+#define PCI_PREF_MEMORY_BASE	0x24	/* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT	0x26
+#define  PCI_PREF_RANGE_TYPE_MASK 0x0f
+#define  PCI_PREF_RANGE_TYPE_32	0x00
+#define  PCI_PREF_RANGE_TYPE_64	0x01
+#define  PCI_PREF_RANGE_MASK	~0x0f
+#define PCI_PREF_BASE_UPPER32	0x28	/* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32	0x2c
+#define PCI_IO_BASE_UPPER16	0x30	/* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16	0x32
+/* 0x34-0x3b is reserved */
+#define PCI_ROM_ADDRESS1	0x38	/* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL	0x3e
+#define  PCI_BRIDGE_CTL_PARITY	0x01	/* Enable parity detection on secondary interface */
+#define  PCI_BRIDGE_CTL_SERR	0x02	/* The same for SERR forwarding */
+#define  PCI_BRIDGE_CTL_NO_ISA	0x04	/* Disable bridging of ISA ports */
+#define  PCI_BRIDGE_CTL_VGA	0x08	/* Forward VGA addresses */
+#define  PCI_BRIDGE_CTL_MASTER_ABORT 0x20  /* Report master aborts */
+#define  PCI_BRIDGE_CTL_BUS_RESET 0x40	/* Secondary bus reset */
+#define  PCI_BRIDGE_CTL_FAST_BACK 0x80	/* Fast Back2Back enabled on secondary interface */
+
+/* Header type 2 (CardBus bridges) */
+/* 0x14-0x15 reserved */
+#define PCI_CB_SEC_STATUS	0x16	/* Secondary status */
+#define PCI_CB_PRIMARY_BUS	0x18	/* PCI bus number */
+#define PCI_CB_CARD_BUS		0x19	/* CardBus bus number */
+#define PCI_CB_SUBORDINATE_BUS	0x1a	/* Subordinate bus number */
+#define PCI_CB_LATENCY_TIMER	0x1b	/* CardBus latency timer */
+#define PCI_CB_MEMORY_BASE_0	0x1c
+#define PCI_CB_MEMORY_LIMIT_0	0x20
+#define PCI_CB_MEMORY_BASE_1	0x24
+#define PCI_CB_MEMORY_LIMIT_1	0x28
+#define PCI_CB_IO_BASE_0	0x2c
+#define PCI_CB_IO_BASE_0_HI	0x2e
+#define PCI_CB_IO_LIMIT_0	0x30
+#define PCI_CB_IO_LIMIT_0_HI	0x32
+#define PCI_CB_IO_BASE_1	0x34
+#define PCI_CB_IO_BASE_1_HI	0x36
+#define PCI_CB_IO_LIMIT_1	0x38
+#define PCI_CB_IO_LIMIT_1_HI	0x3a
+#define  PCI_CB_IO_RANGE_MASK	~0x03
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_CB_BRIDGE_CONTROL	0x3e
+#define  PCI_CB_BRIDGE_CTL_PARITY	0x01	/* Similar to standard bridge control register */
+#define  PCI_CB_BRIDGE_CTL_SERR		0x02
+#define  PCI_CB_BRIDGE_CTL_ISA		0x04
+#define  PCI_CB_BRIDGE_CTL_VGA		0x08
+#define  PCI_CB_BRIDGE_CTL_MASTER_ABORT	0x20
+#define  PCI_CB_BRIDGE_CTL_CB_RESET	0x40	/* CardBus reset */
+#define  PCI_CB_BRIDGE_CTL_16BIT_INT	0x80	/* Enable interrupt for 16-bit cards */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100	/* Prefetch enable for both memory regions */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define  PCI_CB_BRIDGE_CTL_POST_WRITES	0x400
+#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
+#define PCI_CB_SUBSYSTEM_ID	0x42
+#define PCI_CB_LEGACY_MODE_BASE	0x44	/* 16-bit PC Card legacy mode base address (ExCa) */
+/* 0x48-0x7f reserved */
+
+/* Device classes and subclasses */
+
+#define PCI_CLASS_NOT_DEFINED		0x0000
+#define PCI_CLASS_NOT_DEFINED_VGA	0x0001
+
+#define PCI_BASE_CLASS_STORAGE		0x01
+#define PCI_CLASS_STORAGE_SCSI		0x0100
+#define PCI_CLASS_STORAGE_IDE		0x0101
+#define PCI_CLASS_STORAGE_FLOPPY	0x0102
+#define PCI_CLASS_STORAGE_IPI		0x0103
+#define PCI_CLASS_STORAGE_RAID		0x0104
+#define PCI_CLASS_STORAGE_OTHER		0x0180
+
+#define PCI_BASE_CLASS_NETWORK		0x02
+#define PCI_CLASS_NETWORK_ETHERNET	0x0200
+#define PCI_CLASS_NETWORK_TOKEN_RING	0x0201
+#define PCI_CLASS_NETWORK_FDDI		0x0202
+#define PCI_CLASS_NETWORK_ATM		0x0203
+#define PCI_CLASS_NETWORK_OTHER		0x0280
+
+#define PCI_BASE_CLASS_DISPLAY		0x03
+#define PCI_CLASS_DISPLAY_VGA		0x0300
+#define PCI_CLASS_DISPLAY_XGA		0x0301
+#define PCI_CLASS_DISPLAY_OTHER		0x0380
+
+#define PCI_BASE_CLASS_MULTIMEDIA	0x04
+#define PCI_CLASS_MULTIMEDIA_VIDEO	0x0400
+#define PCI_CLASS_MULTIMEDIA_AUDIO	0x0401
+#define PCI_CLASS_MULTIMEDIA_OTHER	0x0480
+
+#define PCI_BASE_CLASS_MEMORY		0x05
+#define  PCI_CLASS_MEMORY_RAM		0x0500
+#define  PCI_CLASS_MEMORY_FLASH		0x0501
+#define  PCI_CLASS_MEMORY_OTHER		0x0580
+
+#define PCI_BASE_CLASS_BRIDGE		0x06
+#define  PCI_CLASS_BRIDGE_HOST		0x0600
+#define  PCI_CLASS_BRIDGE_ISA		0x0601
+#define  PCI_CLASS_BRIDGE_EISA		0x0602
+#define  PCI_CLASS_BRIDGE_MC		0x0603
+#define  PCI_CLASS_BRIDGE_PCI		0x0604
+#define  PCI_CLASS_BRIDGE_PCMCIA	0x0605
+#define  PCI_CLASS_BRIDGE_NUBUS		0x0606
+#define  PCI_CLASS_BRIDGE_CARDBUS	0x0607
+#define  PCI_CLASS_BRIDGE_OTHER		0x0680
+
+#define PCI_BASE_CLASS_COMMUNICATION	0x07
+#define PCI_CLASS_COMMUNICATION_SERIAL	0x0700
+#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
+#define PCI_CLASS_COMMUNICATION_OTHER	0x0780
+
+#define PCI_BASE_CLASS_SYSTEM		0x08
+#define PCI_CLASS_SYSTEM_PIC		0x0800
+#define PCI_CLASS_SYSTEM_DMA		0x0801
+#define PCI_CLASS_SYSTEM_TIMER		0x0802
+#define PCI_CLASS_SYSTEM_RTC		0x0803
+#define PCI_CLASS_SYSTEM_OTHER		0x0880
+
+#define PCI_BASE_CLASS_INPUT		0x09
+#define PCI_CLASS_INPUT_KEYBOARD	0x0900
+#define PCI_CLASS_INPUT_PEN		0x0901
+#define PCI_CLASS_INPUT_MOUSE		0x0902
+#define PCI_CLASS_INPUT_OTHER		0x0980
+
+#define PCI_BASE_CLASS_DOCKING		0x0a
+#define PCI_CLASS_DOCKING_GENERIC	0x0a00
+#define PCI_CLASS_DOCKING_OTHER		0x0a01
+
+#define PCI_BASE_CLASS_PROCESSOR	0x0b
+#define PCI_CLASS_PROCESSOR_386		0x0b00
+#define PCI_CLASS_PROCESSOR_486		0x0b01
+#define PCI_CLASS_PROCESSOR_PENTIUM	0x0b02
+#define PCI_CLASS_PROCESSOR_ALPHA	0x0b10
+#define PCI_CLASS_PROCESSOR_POWERPC	0x0b20
+#define PCI_CLASS_PROCESSOR_CO		0x0b40
+
+#define PCI_BASE_CLASS_SERIAL		0x0c
+#define PCI_CLASS_SERIAL_FIREWIRE	0x0c00
+#define PCI_CLASS_SERIAL_ACCESS		0x0c01
+#define PCI_CLASS_SERIAL_SSA		0x0c02
+#define PCI_CLASS_SERIAL_USB		0x0c03
+#define PCI_CLASS_SERIAL_FIBER		0x0c04
+
+#define PCI_CLASS_OTHERS		0xff
+
+/*
+ * Vendor and card ID's: sort these numerically according to vendor
+ * (and according to card ID within vendor). Send all updates to
+ * <linux-pcisupport@cck.uni-kl.de>.
+ */
+#define PCI_VENDOR_ID_COMPAQ		0x0e11
+#define PCI_DEVICE_ID_COMPAQ_1280	0x3033
+#define PCI_DEVICE_ID_COMPAQ_TRIFLEX	0x4000
+#define PCI_DEVICE_ID_COMPAQ_SMART2P	0xae10
+#define PCI_DEVICE_ID_COMPAQ_NETEL100	0xae32
+#define PCI_DEVICE_ID_COMPAQ_NETEL10	0xae34
+#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I	0xae35
+#define PCI_DEVICE_ID_COMPAQ_NETEL100D	0xae40
+#define PCI_DEVICE_ID_COMPAQ_NETEL100PI	0xae43
+#define PCI_DEVICE_ID_COMPAQ_NETEL100I	0xb011
+#define PCI_DEVICE_ID_COMPAQ_THUNDER	0xf130
+#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B	0xf150
+
+#define PCI_VENDOR_ID_NCR		0x1000
+#define PCI_DEVICE_ID_NCR_53C810	0x0001
+#define PCI_DEVICE_ID_NCR_53C820	0x0002
+#define PCI_DEVICE_ID_NCR_53C825	0x0003
+#define PCI_DEVICE_ID_NCR_53C815	0x0004
+#define PCI_DEVICE_ID_NCR_53C860	0x0006
+#define PCI_DEVICE_ID_NCR_53C896	0x000b
+#define PCI_DEVICE_ID_NCR_53C895	0x000c
+#define PCI_DEVICE_ID_NCR_53C885	0x000d
+#define PCI_DEVICE_ID_NCR_53C875	0x000f
+#define PCI_DEVICE_ID_NCR_53C875J	0x008f
+
+#define PCI_VENDOR_ID_ATI		0x1002
+#define PCI_DEVICE_ID_ATI_68800		0x4158
+#define PCI_DEVICE_ID_ATI_215CT222	0x4354
+#define PCI_DEVICE_ID_ATI_210888CX	0x4358
+#define PCI_DEVICE_ID_ATI_215GB		0x4742
+#define PCI_DEVICE_ID_ATI_215GD		0x4744
+#define PCI_DEVICE_ID_ATI_215GI		0x4749
+#define PCI_DEVICE_ID_ATI_215GP		0x4750
+#define PCI_DEVICE_ID_ATI_215GQ		0x4751
+#define PCI_DEVICE_ID_ATI_215GT		0x4754
+#define PCI_DEVICE_ID_ATI_215GTB	0x4755
+#define PCI_DEVICE_ID_ATI_210888GX	0x4758
+#define PCI_DEVICE_ID_ATI_215LG		0x4c47
+#define PCI_DEVICE_ID_ATI_264LT		0x4c54
+#define PCI_DEVICE_ID_ATI_264VT		0x5654
+
+#define PCI_VENDOR_ID_VLSI		0x1004
+#define PCI_DEVICE_ID_VLSI_82C592	0x0005
+#define PCI_DEVICE_ID_VLSI_82C593	0x0006
+#define PCI_DEVICE_ID_VLSI_82C594	0x0007
+#define PCI_DEVICE_ID_VLSI_82C597	0x0009
+#define PCI_DEVICE_ID_VLSI_82C541	0x000c
+#define PCI_DEVICE_ID_VLSI_82C543	0x000d
+#define PCI_DEVICE_ID_VLSI_82C532	0x0101
+#define PCI_DEVICE_ID_VLSI_82C534	0x0102
+#define PCI_DEVICE_ID_VLSI_82C535	0x0104
+#define PCI_DEVICE_ID_VLSI_82C147	0x0105
+#define PCI_DEVICE_ID_VLSI_VAS96011	0x0702
+
+#define PCI_VENDOR_ID_ADL		0x1005
+#define PCI_DEVICE_ID_ADL_2301		0x2301
+
+#define PCI_VENDOR_ID_NS		0x100b
+#define PCI_DEVICE_ID_NS_87415		0x0002
+#define PCI_DEVICE_ID_NS_87410		0xd001
+
+#define PCI_VENDOR_ID_TSENG		0x100c
+#define PCI_DEVICE_ID_TSENG_W32P_2	0x3202
+#define PCI_DEVICE_ID_TSENG_W32P_b	0x3205
+#define PCI_DEVICE_ID_TSENG_W32P_c	0x3206
+#define PCI_DEVICE_ID_TSENG_W32P_d	0x3207
+#define PCI_DEVICE_ID_TSENG_ET6000	0x3208
+
+#define PCI_VENDOR_ID_WEITEK		0x100e
+#define PCI_DEVICE_ID_WEITEK_P9000	0x9001
+#define PCI_DEVICE_ID_WEITEK_P9100	0x9100
+
+#define PCI_VENDOR_ID_DEC		0x1011
+#define PCI_DEVICE_ID_DEC_BRD		0x0001
+#define PCI_DEVICE_ID_DEC_TULIP		0x0002
+#define PCI_DEVICE_ID_DEC_TGA		0x0004
+#define PCI_DEVICE_ID_DEC_TULIP_FAST	0x0009
+#define PCI_DEVICE_ID_DEC_TGA2		0x000D
+#define PCI_DEVICE_ID_DEC_FDDI		0x000F
+#define PCI_DEVICE_ID_DEC_TULIP_PLUS	0x0014
+#define PCI_DEVICE_ID_DEC_21142		0x0019
+#define PCI_DEVICE_ID_DEC_21052		0x0021
+#define PCI_DEVICE_ID_DEC_21150		0x0022
+#define PCI_DEVICE_ID_DEC_21152		0x0024
+
+#define PCI_VENDOR_ID_CIRRUS		0x1013
+#define PCI_DEVICE_ID_CIRRUS_7548	0x0038
+#define PCI_DEVICE_ID_CIRRUS_5430	0x00a0
+#define PCI_DEVICE_ID_CIRRUS_5434_4	0x00a4
+#define PCI_DEVICE_ID_CIRRUS_5434_8	0x00a8
+#define PCI_DEVICE_ID_CIRRUS_5436	0x00ac
+#define PCI_DEVICE_ID_CIRRUS_5446	0x00b8
+#define PCI_DEVICE_ID_CIRRUS_5480	0x00bc
+#define PCI_DEVICE_ID_CIRRUS_5464	0x00d4
+#define PCI_DEVICE_ID_CIRRUS_5465	0x00d6
+#define PCI_DEVICE_ID_CIRRUS_6729	0x1100
+#define PCI_DEVICE_ID_CIRRUS_6832	0x1110
+#define PCI_DEVICE_ID_CIRRUS_7542	0x1200
+#define PCI_DEVICE_ID_CIRRUS_7543	0x1202
+#define PCI_DEVICE_ID_CIRRUS_7541	0x1204
+
+#define PCI_VENDOR_ID_IBM		0x1014
+#define PCI_DEVICE_ID_IBM_FIRE_CORAL	0x000a
+#define PCI_DEVICE_ID_IBM_TR		0x0018
+#define PCI_DEVICE_ID_IBM_82G2675	0x001d
+#define PCI_DEVICE_ID_IBM_MCA		0x0020
+#define PCI_DEVICE_ID_IBM_82351		0x0022
+#define PCI_DEVICE_ID_IBM_SERVERAID	0x002e
+#define PCI_DEVICE_ID_IBM_TR_WAKE	0x003e
+#define PCI_DEVICE_ID_IBM_MPIC		0x0046
+#define PCI_DEVICE_ID_IBM_3780IDSP	0x007d
+#define PCI_DEVICE_ID_IBM_MPIC_2	0xffff
+
+#define PCI_VENDOR_ID_WD		0x101c
+#define PCI_DEVICE_ID_WD_7197		0x3296
+
+#define PCI_VENDOR_ID_AMD		0x1022
+#define PCI_DEVICE_ID_AMD_LANCE		0x2000
+#define PCI_DEVICE_ID_AMD_SCSI		0x2020
+
+#define PCI_VENDOR_ID_TRIDENT		0x1023
+#define PCI_DEVICE_ID_TRIDENT_9397	0x9397
+#define PCI_DEVICE_ID_TRIDENT_9420	0x9420
+#define PCI_DEVICE_ID_TRIDENT_9440	0x9440
+#define PCI_DEVICE_ID_TRIDENT_9660	0x9660
+#define PCI_DEVICE_ID_TRIDENT_9750	0x9750
+
+#define PCI_VENDOR_ID_AI		0x1025
+#define PCI_DEVICE_ID_AI_M1435		0x1435
+
+#define PCI_VENDOR_ID_MATROX		0x102B
+#define PCI_DEVICE_ID_MATROX_MGA_2	0x0518
+#define PCI_DEVICE_ID_MATROX_MIL	0x0519
+#define PCI_DEVICE_ID_MATROX_MYS	0x051A
+#define PCI_DEVICE_ID_MATROX_MIL_2	0x051b
+#define PCI_DEVICE_ID_MATROX_MIL_2_AGP	0x051f
+#define PCI_DEVICE_ID_MATROX_MGA_IMP	0x0d10
+
+#define PCI_VENDOR_ID_CT		0x102c
+#define PCI_DEVICE_ID_CT_65545		0x00d8
+#define PCI_DEVICE_ID_CT_65548		0x00dc
+#define PCI_DEVICE_ID_CT_65550		0x00e0
+#define PCI_DEVICE_ID_CT_65554		0x00e4
+#define PCI_DEVICE_ID_CT_65555		0x00e5
+
+#define PCI_VENDOR_ID_MIRO		0x1031
+#define PCI_DEVICE_ID_MIRO_36050	0x5601
+
+#define PCI_VENDOR_ID_NEC		0x1033
+#define PCI_DEVICE_ID_NEC_PCX2		0x0046
+
+#define PCI_VENDOR_ID_FD		0x1036
+#define PCI_DEVICE_ID_FD_36C70		0x0000
+
+#define PCI_VENDOR_ID_SI		0x1039
+#define PCI_DEVICE_ID_SI_5591_AGP	0x0001
+#define PCI_DEVICE_ID_SI_6202		0x0002
+#define PCI_DEVICE_ID_SI_503		0x0008
+#define PCI_DEVICE_ID_SI_ACPI		0x0009
+#define PCI_DEVICE_ID_SI_5597_VGA	0x0200
+#define PCI_DEVICE_ID_SI_6205		0x0205
+#define PCI_DEVICE_ID_SI_501		0x0406
+#define PCI_DEVICE_ID_SI_496		0x0496
+#define PCI_DEVICE_ID_SI_601		0x0601
+#define PCI_DEVICE_ID_SI_5107		0x5107
+#define PCI_DEVICE_ID_SI_5511		0x5511
+#define PCI_DEVICE_ID_SI_5513		0x5513
+#define PCI_DEVICE_ID_SI_5571		0x5571
+#define PCI_DEVICE_ID_SI_5591		0x5591
+#define PCI_DEVICE_ID_SI_5597		0x5597
+#define PCI_DEVICE_ID_SI_7001		0x7001
+
+#define PCI_VENDOR_ID_HP		0x103c
+#define PCI_DEVICE_ID_HP_J2585A		0x1030
+#define PCI_DEVICE_ID_HP_J2585B		0x1031
+
+#define PCI_VENDOR_ID_PCTECH		0x1042
+#define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
+#define PCI_DEVICE_ID_PCTECH_RZ1001	0x1001
+#define PCI_DEVICE_ID_PCTECH_SAMURAI_0	0x3000
+#define PCI_DEVICE_ID_PCTECH_SAMURAI_1	0x3010
+#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
+
+#define PCI_VENDOR_ID_DPT               0x1044   
+#define PCI_DEVICE_ID_DPT               0xa400  
+
+#define PCI_VENDOR_ID_OPTI		0x1045
+#define PCI_DEVICE_ID_OPTI_92C178	0xc178
+#define PCI_DEVICE_ID_OPTI_82C557	0xc557
+#define PCI_DEVICE_ID_OPTI_82C558	0xc558
+#define PCI_DEVICE_ID_OPTI_82C621	0xc621
+#define PCI_DEVICE_ID_OPTI_82C700	0xc700
+#define PCI_DEVICE_ID_OPTI_82C701	0xc701
+#define PCI_DEVICE_ID_OPTI_82C814	0xc814
+#define PCI_DEVICE_ID_OPTI_82C822	0xc822
+#define PCI_DEVICE_ID_OPTI_82C825	0xd568
+
+#define PCI_VENDOR_ID_SGS		0x104a
+#define PCI_DEVICE_ID_SGS_2000		0x0008
+#define PCI_DEVICE_ID_SGS_1764		0x0009
+
+#define PCI_VENDOR_ID_BUSLOGIC		      0x104B
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER    0x1040
+#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT     0x8130
+
+#define PCI_VENDOR_ID_TI		0x104c
+#define PCI_DEVICE_ID_TI_TVP4010	0x3d04
+#define PCI_DEVICE_ID_TI_TVP4020	0x3d07
+#define PCI_DEVICE_ID_TI_PCI1130	0xac12
+#define PCI_DEVICE_ID_TI_PCI1031	0xac13
+#define PCI_DEVICE_ID_TI_PCI1131	0xac15
+#define PCI_DEVICE_ID_TI_PCI1250	0xac16
+#define PCI_DEVICE_ID_TI_PCI1220	0xac17
+
+#define PCI_VENDOR_ID_OAK		0x104e
+#define PCI_DEVICE_ID_OAK_OTI107	0x0107
+
+/* Winbond have two vendor IDs! See 0x10ad as well */
+#define PCI_VENDOR_ID_WINBOND2		0x1050
+#define PCI_DEVICE_ID_WINBOND2_89C940	0x0940
+
+#define PCI_VENDOR_ID_MOTOROLA		0x1057
+#define PCI_DEVICE_ID_MOTOROLA_MPC105	0x0001
+#define PCI_DEVICE_ID_MOTOROLA_MPC106	0x0002
+#define PCI_DEVICE_ID_MOTOROLA_RAVEN	0x4801
+
+#define PCI_VENDOR_ID_PROMISE		0x105a
+#define PCI_DEVICE_ID_PROMISE_20246	0x4d33
+#define PCI_DEVICE_ID_PROMISE_5300	0x5300
+
+#define PCI_VENDOR_ID_N9		0x105d
+#define PCI_DEVICE_ID_N9_I128		0x2309
+#define PCI_DEVICE_ID_N9_I128_2		0x2339
+#define PCI_DEVICE_ID_N9_I128_T2R	0x493d
+
+#define PCI_VENDOR_ID_UMC		0x1060
+#define PCI_DEVICE_ID_UMC_UM8673F	0x0101
+#define PCI_DEVICE_ID_UMC_UM8891A	0x0891
+#define PCI_DEVICE_ID_UMC_UM8886BF	0x673a
+#define PCI_DEVICE_ID_UMC_UM8886A	0x886a
+#define PCI_DEVICE_ID_UMC_UM8881F	0x8881
+#define PCI_DEVICE_ID_UMC_UM8886F	0x8886
+#define PCI_DEVICE_ID_UMC_UM9017F	0x9017
+#define PCI_DEVICE_ID_UMC_UM8886N	0xe886
+#define PCI_DEVICE_ID_UMC_UM8891N	0xe891
+
+#define PCI_VENDOR_ID_X			0x1061
+#define PCI_DEVICE_ID_X_AGX016		0x0001
+
+#define PCI_VENDOR_ID_PICOP		0x1066
+#define PCI_DEVICE_ID_PICOP_PT86C52X	0x0001
+#define PCI_DEVICE_ID_PICOP_PT80C524	0x8002
+
+#define PCI_VENDOR_ID_APPLE		0x106b
+#define PCI_DEVICE_ID_APPLE_BANDIT	0x0001
+#define PCI_DEVICE_ID_APPLE_GC		0x0002
+#define PCI_DEVICE_ID_APPLE_HYDRA	0x000e
+
+#define PCI_VENDOR_ID_NEXGEN		0x1074
+#define PCI_DEVICE_ID_NEXGEN_82C501	0x4e78
+
+#define PCI_VENDOR_ID_QLOGIC		0x1077
+#define PCI_DEVICE_ID_QLOGIC_ISP1020	0x1020
+#define PCI_DEVICE_ID_QLOGIC_ISP1022	0x1022
+
+#define PCI_VENDOR_ID_CYRIX		0x1078
+#define PCI_DEVICE_ID_CYRIX_5510	0x0000
+#define PCI_DEVICE_ID_CYRIX_PCI_MASTER	0x0001
+#define PCI_DEVICE_ID_CYRIX_5520	0x0002
+#define PCI_DEVICE_ID_CYRIX_5530_LEGACY	0x0100
+#define PCI_DEVICE_ID_CYRIX_5530_SMI	0x0101
+#define PCI_DEVICE_ID_CYRIX_5530_IDE	0x0102
+#define PCI_DEVICE_ID_CYRIX_5530_AUDIO	0x0103
+#define PCI_DEVICE_ID_CYRIX_5530_VIDEO	0x0104
+
+#define PCI_VENDOR_ID_LEADTEK		0x107d
+#define PCI_DEVICE_ID_LEADTEK_805	0x0000
+
+#define PCI_VENDOR_ID_CONTAQ		0x1080
+#define PCI_DEVICE_ID_CONTAQ_82C599	0x0600
+#define PCI_DEVICE_ID_CONTAQ_82C693	0xc693
+
+#define PCI_VENDOR_ID_FOREX		0x1083
+
+#define PCI_VENDOR_ID_OLICOM		0x108d
+#define PCI_DEVICE_ID_OLICOM_OC3136	0x0001
+#define PCI_DEVICE_ID_OLICOM_OC2315	0x0011
+#define PCI_DEVICE_ID_OLICOM_OC2325	0x0012
+#define PCI_DEVICE_ID_OLICOM_OC2183	0x0013
+#define PCI_DEVICE_ID_OLICOM_OC2326	0x0014
+#define PCI_DEVICE_ID_OLICOM_OC6151	0x0021
+
+#define PCI_VENDOR_ID_SUN		0x108e
+#define PCI_DEVICE_ID_SUN_EBUS		0x1000
+#define PCI_DEVICE_ID_SUN_HAPPYMEAL	0x1001
+#define PCI_DEVICE_ID_SUN_SIMBA		0x5000
+#define PCI_DEVICE_ID_SUN_PBM		0x8000
+#define PCI_DEVICE_ID_SUN_SABRE		0xa000
+
+#define PCI_VENDOR_ID_CMD		0x1095
+#define PCI_DEVICE_ID_CMD_640		0x0640
+#define PCI_DEVICE_ID_CMD_643		0x0643
+#define PCI_DEVICE_ID_CMD_646		0x0646
+#define PCI_DEVICE_ID_CMD_647		0x0647
+#define PCI_DEVICE_ID_CMD_670		0x0670
+
+#define PCI_VENDOR_ID_VISION		0x1098
+#define PCI_DEVICE_ID_VISION_QD8500	0x0001
+#define PCI_DEVICE_ID_VISION_QD8580	0x0002
+
+#define PCI_VENDOR_ID_BROOKTREE		0x109e
+#define PCI_DEVICE_ID_BROOKTREE_848	0x0350
+#define PCI_DEVICE_ID_BROOKTREE_849A	0x0351
+#define PCI_DEVICE_ID_BROOKTREE_8474	0x8474
+
+#define PCI_VENDOR_ID_SIERRA		0x10a8
+#define PCI_DEVICE_ID_SIERRA_STB	0x0000
+
+#define PCI_VENDOR_ID_ACC		0x10aa
+#define PCI_DEVICE_ID_ACC_2056		0x0000
+
+#define PCI_VENDOR_ID_WINBOND		0x10ad
+#define PCI_DEVICE_ID_WINBOND_83769	0x0001
+#define PCI_DEVICE_ID_WINBOND_82C105	0x0105
+#define PCI_DEVICE_ID_WINBOND_83C553	0x0565
+
+#define PCI_VENDOR_ID_DATABOOK		0x10b3
+#define PCI_DEVICE_ID_DATABOOK_87144	0xb106
+
+#define PCI_VENDOR_ID_PLX		0x10b5
+#define PCI_DEVICE_ID_PLX_9050		0x9050
+#define PCI_DEVICE_ID_PLX_9060		0x9060
+#define PCI_DEVICE_ID_PLX_9060ES	0x906E
+#define PCI_DEVICE_ID_PLX_9060SD	0x906D
+#define PCI_DEVICE_ID_PLX_9080		0x9080
+
+#define PCI_VENDOR_ID_MADGE		0x10b6
+#define PCI_DEVICE_ID_MADGE_MK2		0x0002
+#define PCI_DEVICE_ID_MADGE_C155S	0x1001
+
+#define PCI_VENDOR_ID_3COM		0x10b7
+#define PCI_DEVICE_ID_3COM_3C339	0x3390
+#define PCI_DEVICE_ID_3COM_3C590	0x5900
+#define PCI_DEVICE_ID_3COM_3C595TX	0x5950
+#define PCI_DEVICE_ID_3COM_3C595T4	0x5951
+#define PCI_DEVICE_ID_3COM_3C595MII	0x5952
+#define PCI_DEVICE_ID_3COM_3C900TPO	0x9000
+#define PCI_DEVICE_ID_3COM_3C900COMBO	0x9001
+#define PCI_DEVICE_ID_3COM_3C905TX	0x9050
+#define PCI_DEVICE_ID_3COM_3C905T4	0x9051
+#define PCI_DEVICE_ID_3COM_3C905B_TX	0x9055
+
+#define PCI_VENDOR_ID_SMC		0x10b8
+#define PCI_DEVICE_ID_SMC_EPIC100	0x0005
+
+#define PCI_VENDOR_ID_AL		0x10b9
+#define PCI_DEVICE_ID_AL_M1445		0x1445
+#define PCI_DEVICE_ID_AL_M1449		0x1449
+#define PCI_DEVICE_ID_AL_M1451		0x1451
+#define PCI_DEVICE_ID_AL_M1461		0x1461
+#define PCI_DEVICE_ID_AL_M1489		0x1489
+#define PCI_DEVICE_ID_AL_M1511		0x1511
+#define PCI_DEVICE_ID_AL_M1513		0x1513
+#define PCI_DEVICE_ID_AL_M1521		0x1521
+#define PCI_DEVICE_ID_AL_M1523		0x1523
+#define PCI_DEVICE_ID_AL_M1531		0x1531
+#define PCI_DEVICE_ID_AL_M1533		0x1533
+#define PCI_DEVICE_ID_AL_M3307		0x3307
+#define PCI_DEVICE_ID_AL_M4803		0x5215
+#define PCI_DEVICE_ID_AL_M5219		0x5219
+#define PCI_DEVICE_ID_AL_M5229		0x5229
+#define PCI_DEVICE_ID_AL_M5237		0x5237
+#define PCI_DEVICE_ID_AL_M7101		0x7101
+
+#define PCI_VENDOR_ID_MITSUBISHI	0x10ba
+
+#define PCI_VENDOR_ID_SURECOM		0x10bd
+#define PCI_DEVICE_ID_SURECOM_NE34	0x0e34
+
+#define PCI_VENDOR_ID_NEOMAGIC          0x10c8
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
+
+#define PCI_VENDOR_ID_ASP		0x10cd
+#define PCI_DEVICE_ID_ASP_ABP940	0x1200
+#define PCI_DEVICE_ID_ASP_ABP940U	0x1300
+#define PCI_DEVICE_ID_ASP_ABP940UW	0x2300
+
+#define PCI_VENDOR_ID_MACRONIX		0x10d9
+#define PCI_DEVICE_ID_MACRONIX_MX98713	0x0512
+#define PCI_DEVICE_ID_MACRONIX_MX987x5	0x0531
+
+#define PCI_VENDOR_ID_CERN		0x10dc
+#define PCI_DEVICE_ID_CERN_SPSB_PMC	0x0001
+#define PCI_DEVICE_ID_CERN_SPSB_PCI	0x0002
+#define PCI_DEVICE_ID_CERN_HIPPI_DST	0x0021
+#define PCI_DEVICE_ID_CERN_HIPPI_SRC	0x0022
+
+#define PCI_VENDOR_ID_NVIDIA		0x10de
+
+#define PCI_VENDOR_ID_IMS		0x10e0
+#define PCI_DEVICE_ID_IMS_8849		0x8849
+
+#define PCI_VENDOR_ID_TEKRAM2		0x10e1
+#define PCI_DEVICE_ID_TEKRAM2_690c	0x690c
+
+#define PCI_VENDOR_ID_TUNDRA		0x10e3
+#define PCI_DEVICE_ID_TUNDRA_CA91C042	0x0000
+
+#define PCI_VENDOR_ID_AMCC		0x10e8
+#define PCI_DEVICE_ID_AMCC_MYRINET	0x8043
+#define PCI_DEVICE_ID_AMCC_PARASTATION	0x8062
+#define PCI_DEVICE_ID_AMCC_S5933	0x807d
+#define PCI_DEVICE_ID_AMCC_S5933_HEPC3	0x809c
+
+#define PCI_VENDOR_ID_INTERG		0x10ea
+#define PCI_DEVICE_ID_INTERG_1680	0x1680
+#define PCI_DEVICE_ID_INTERG_1682	0x1682
+
+#define PCI_VENDOR_ID_REALTEK		0x10ec
+#define PCI_DEVICE_ID_REALTEK_8029	0x8029
+#define PCI_DEVICE_ID_REALTEK_8129	0x8129
+#define PCI_DEVICE_ID_REALTEK_8139	0x8139
+
+#define PCI_VENDOR_ID_TRUEVISION	0x10fa
+#define PCI_DEVICE_ID_TRUEVISION_T1000	0x000c
+
+#define PCI_VENDOR_ID_INIT		0x1101
+#define PCI_DEVICE_ID_INIT_320P		0x9100
+#define PCI_DEVICE_ID_INIT_360P		0x9500
+
+#define PCI_VENDOR_ID_TTI		0x1103
+#define PCI_DEVICE_ID_TTI_HPT343	0x0003
+
+#define PCI_VENDOR_ID_VIA		0x1106
+#define PCI_DEVICE_ID_VIA_82C505	0x0505
+#define PCI_DEVICE_ID_VIA_82C561	0x0561
+#define PCI_DEVICE_ID_VIA_82C586_1	0x0571
+#define PCI_DEVICE_ID_VIA_82C576	0x0576
+#define PCI_DEVICE_ID_VIA_82C585	0x0585
+#define PCI_DEVICE_ID_VIA_82C586_0	0x0586
+#define PCI_DEVICE_ID_VIA_82C595	0x0595
+#define PCI_DEVICE_ID_VIA_82C597_0	0x0597
+#define PCI_DEVICE_ID_VIA_82C926	0x0926
+#define PCI_DEVICE_ID_VIA_82C416	0x1571
+#define PCI_DEVICE_ID_VIA_82C595_97	0x1595
+#define PCI_DEVICE_ID_VIA_82C586_2	0x3038
+#define PCI_DEVICE_ID_VIA_82C586_3	0x3040
+#define PCI_DEVICE_ID_VIA_86C100A	0x6100
+#define PCI_DEVICE_ID_VIA_82C597_1	0x8597
+
+#define PCI_VENDOR_ID_VORTEX		0x1119
+#define PCI_DEVICE_ID_VORTEX_GDT60x0	0x0000
+#define PCI_DEVICE_ID_VORTEX_GDT6000B	0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT6x10	0x0002
+#define PCI_DEVICE_ID_VORTEX_GDT6x20	0x0003
+#define PCI_DEVICE_ID_VORTEX_GDT6530	0x0004
+#define PCI_DEVICE_ID_VORTEX_GDT6550	0x0005
+#define PCI_DEVICE_ID_VORTEX_GDT6x17	0x0006
+#define PCI_DEVICE_ID_VORTEX_GDT6x27	0x0007
+#define PCI_DEVICE_ID_VORTEX_GDT6537	0x0008
+#define PCI_DEVICE_ID_VORTEX_GDT6557	0x0009
+#define PCI_DEVICE_ID_VORTEX_GDT6x15	0x000a
+#define PCI_DEVICE_ID_VORTEX_GDT6x25	0x000b
+#define PCI_DEVICE_ID_VORTEX_GDT6535	0x000c
+#define PCI_DEVICE_ID_VORTEX_GDT6555	0x000d
+#define PCI_DEVICE_ID_VORTEX_GDT6x17RP	0x0100
+#define PCI_DEVICE_ID_VORTEX_GDT6x27RP	0x0101
+#define PCI_DEVICE_ID_VORTEX_GDT6537RP	0x0102
+#define PCI_DEVICE_ID_VORTEX_GDT6557RP	0x0103
+#define PCI_DEVICE_ID_VORTEX_GDT6x11RP	0x0104
+#define PCI_DEVICE_ID_VORTEX_GDT6x21RP	0x0105
+#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1	0x0110
+#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1	0x0111
+#define PCI_DEVICE_ID_VORTEX_GDT6537RP1	0x0112
+#define PCI_DEVICE_ID_VORTEX_GDT6557RP1	0x0113
+#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1	0x0114
+#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1	0x0115
+#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2	0x0120
+#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2	0x0121
+#define PCI_DEVICE_ID_VORTEX_GDT6537RP2	0x0122
+#define PCI_DEVICE_ID_VORTEX_GDT6557RP2	0x0123
+#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2	0x0124
+#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2	0x0125
+
+#define PCI_VENDOR_ID_EF		0x111a
+#define PCI_DEVICE_ID_EF_ATM_FPGA	0x0000
+#define PCI_DEVICE_ID_EF_ATM_ASIC	0x0002
+
+#define PCI_VENDOR_ID_FORE		0x1127
+#define PCI_DEVICE_ID_FORE_PCA200PC	0x0210
+#define PCI_DEVICE_ID_FORE_PCA200E	0x0300
+
+#define PCI_VENDOR_ID_IMAGINGTECH	0x112f
+#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI	0x0000
+
+#define PCI_VENDOR_ID_PHILIPS		0x1131
+#define PCI_DEVICE_ID_PHILIPS_SAA7145	0x7145
+#define PCI_DEVICE_ID_PHILIPS_SAA7146	0x7146
+
+#define PCI_VENDOR_ID_CYCLONE		0x113c
+#define PCI_DEVICE_ID_CYCLONE_SDK	0x0001
+
+#define PCI_VENDOR_ID_ALLIANCE		0x1142
+#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO	0x3210
+#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO	0x6422
+#define PCI_DEVICE_ID_ALLIANCE_AT24	0x6424
+#define PCI_DEVICE_ID_ALLIANCE_AT3D	0x643d
+
+#define PCI_VENDOR_ID_SK		0x1148
+#define PCI_DEVICE_ID_SK_FP		0x4000
+#define PCI_DEVICE_ID_SK_TR		0x4200
+#define PCI_DEVICE_ID_SK_GE		0x4300
+
+#define PCI_VENDOR_ID_VMIC		0x114a
+#define PCI_DEVICE_ID_VMIC_VME		0x7587
+
+#define PCI_VENDOR_ID_DIGI		0x114f
+#define PCI_DEVICE_ID_DIGI_EPC		0x0002
+#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH	0x0003
+#define PCI_DEVICE_ID_DIGI_XEM		0x0004
+#define PCI_DEVICE_ID_DIGI_XR		0x0005
+#define PCI_DEVICE_ID_DIGI_CX		0x0006
+#define PCI_DEVICE_ID_DIGI_XRJ		0x0009
+#define PCI_DEVICE_ID_DIGI_EPCJ		0x000a
+#define PCI_DEVICE_ID_DIGI_XR_920	0x0027
+
+#define PCI_VENDOR_ID_MUTECH		0x1159
+#define PCI_DEVICE_ID_MUTECH_MV1000	0x0001
+
+#define PCI_VENDOR_ID_RENDITION		0x1163
+#define PCI_DEVICE_ID_RENDITION_VERITE	0x0001
+#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000
+
+#define PCI_VENDOR_ID_TOSHIBA		0x1179
+#define PCI_DEVICE_ID_TOSHIBA_601	0x0601
+#define PCI_DEVICE_ID_TOSHIBA_TOPIC95	0x060a
+#define PCI_DEVICE_ID_TOSHIBA_TOPIC97	0x060f
+
+#define PCI_VENDOR_ID_RICOH		0x1180
+#define PCI_DEVICE_ID_RICOH_RL5C465	0x0465
+#define PCI_DEVICE_ID_RICOH_RL5C466	0x0466
+#define PCI_DEVICE_ID_RICOH_RL5C475	0x0475
+#define PCI_DEVICE_ID_RICOH_RL5C478	0x0478
+
+#define PCI_VENDOR_ID_ARTOP		0x1191
+#define PCI_DEVICE_ID_ARTOP_ATP8400	0x0004
+#define PCI_DEVICE_ID_ARTOP_ATP850UF	0x0005
+
+#define PCI_VENDOR_ID_ZEITNET		0x1193
+#define PCI_DEVICE_ID_ZEITNET_1221	0x0001
+#define PCI_DEVICE_ID_ZEITNET_1225	0x0002
+
+#define PCI_VENDOR_ID_OMEGA		0x119b
+#define PCI_DEVICE_ID_OMEGA_82C092G	0x1221
+
+#define PCI_VENDOR_ID_LITEON		0x11ad
+#define PCI_DEVICE_ID_LITEON_LNE100TX	0x0002
+
+#define PCI_VENDOR_ID_NP		0x11bc
+#define PCI_DEVICE_ID_NP_PCI_FDDI	0x0001
+
+#define PCI_VENDOR_ID_ATT		0x11c1
+#define PCI_DEVICE_ID_ATT_L56XMF	0x0440
+
+#define PCI_VENDOR_ID_SPECIALIX		0x11cb
+#define PCI_DEVICE_ID_SPECIALIX_IO8	0x2000
+#define PCI_DEVICE_ID_SPECIALIX_XIO	0x4000
+#define PCI_DEVICE_ID_SPECIALIX_RIO	0x8000
+
+#define PCI_VENDOR_ID_AURAVISION	0x11d1
+#define PCI_DEVICE_ID_AURAVISION_VXP524	0x01f7
+
+#define PCI_VENDOR_ID_IKON		0x11d5
+#define PCI_DEVICE_ID_IKON_10115	0x0115
+#define PCI_DEVICE_ID_IKON_10117	0x0117
+
+#define PCI_VENDOR_ID_ZORAN		0x11de
+#define PCI_DEVICE_ID_ZORAN_36057	0x6057
+#define PCI_DEVICE_ID_ZORAN_36120	0x6120
+
+#define PCI_VENDOR_ID_KINETIC		0x11f4
+#define PCI_DEVICE_ID_KINETIC_2915	0x2915
+
+#define PCI_VENDOR_ID_COMPEX		0x11f6
+#define PCI_DEVICE_ID_COMPEX_ENET100VG4	0x0112
+#define PCI_DEVICE_ID_COMPEX_RL2000	0x1401
+
+#define PCI_VENDOR_ID_RP               0x11fe
+#define PCI_DEVICE_ID_RP32INTF         0x0001
+#define PCI_DEVICE_ID_RP8INTF          0x0002
+#define PCI_DEVICE_ID_RP16INTF         0x0003
+#define PCI_DEVICE_ID_RP4QUAD	       0x0004
+#define PCI_DEVICE_ID_RP8OCTA          0x0005
+#define PCI_DEVICE_ID_RP8J	       0x0006
+#define PCI_DEVICE_ID_RPP4	       0x000A
+#define PCI_DEVICE_ID_RPP8	       0x000B
+#define PCI_DEVICE_ID_RP8M	       0x000C
+
+#define PCI_VENDOR_ID_CYCLADES		0x120e
+#define PCI_DEVICE_ID_CYCLOM_Y_Lo	0x0100
+#define PCI_DEVICE_ID_CYCLOM_Y_Hi	0x0101
+#define PCI_DEVICE_ID_CYCLOM_Z_Lo	0x0200
+#define PCI_DEVICE_ID_CYCLOM_Z_Hi	0x0201
+
+#define PCI_VENDOR_ID_ESSENTIAL		0x120f
+#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER	0x0001
+
+#define PCI_VENDOR_ID_O2		0x1217
+#define PCI_DEVICE_ID_O2_6729		0x6729
+#define PCI_DEVICE_ID_O2_6730		0x673a
+#define PCI_DEVICE_ID_O2_6832		0x6832
+#define PCI_DEVICE_ID_O2_6836		0x6836
+
+#define PCI_VENDOR_ID_3DFX		0x121a
+#define PCI_DEVICE_ID_3DFX_VOODOO	0x0001
+#define PCI_DEVICE_ID_3DFX_VOODOO2	0x0002
+
+#define PCI_VENDOR_ID_SIGMADES		0x1236
+#define PCI_DEVICE_ID_SIGMADES_6425	0x6401
+
+#define PCI_VENDOR_ID_CCUBE		0x123f
+
+#define PCI_VENDOR_ID_DIPIX		0x1246
+
+#define PCI_VENDOR_ID_STALLION		0x124d
+#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
+#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
+#define PCI_DEVICE_ID_STALLION_EIOPCI	0x0003
+
+#define PCI_VENDOR_ID_OPTIBASE		0x1255
+#define PCI_DEVICE_ID_OPTIBASE_FORGE	0x1110
+#define PCI_DEVICE_ID_OPTIBASE_FUSION	0x1210
+#define PCI_DEVICE_ID_OPTIBASE_VPLEX	0x2110
+#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC	0x2120
+#define PCI_DEVICE_ID_OPTIBASE_VQUEST	0x2130
+
+#define PCI_VENDOR_ID_SATSAGEM		0x1267
+#define PCI_DEVICE_ID_SATSAGEM_PCR2101	0x5352
+#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
+
+#define PCI_VENDOR_ID_HUGHES		0x1273
+#define PCI_DEVICE_ID_HUGHES_DIRECPC	0x0002
+
+#define PCI_VENDOR_ID_ENSONIQ		0x1274
+#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI	0x5000
+
+#define PCI_VENDOR_ID_ALTEON		0x12ae
+#define PCI_DEVICE_ID_ALTEON_ACENIC	0x0001
+
+#define PCI_VENDOR_ID_PICTUREL		0x12c5
+#define PCI_DEVICE_ID_PICTUREL_PCIVST	0x0081
+
+#define PCI_VENDOR_ID_NVIDIA_SGS	0x12d2
+#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
+
+#define PCI_VENDOR_ID_CBOARDS		0x1307
+#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
+
+#define PCI_VENDOR_ID_SYMPHONY		0x1c1c
+#define PCI_DEVICE_ID_SYMPHONY_101	0x0001
+
+#define PCI_VENDOR_ID_TEKRAM		0x1de1
+#define PCI_DEVICE_ID_TEKRAM_DC290	0xdc29
+
+#define PCI_VENDOR_ID_3DLABS		0x3d3d
+#define PCI_DEVICE_ID_3DLABS_300SX	0x0001
+#define PCI_DEVICE_ID_3DLABS_500TX	0x0002
+#define PCI_DEVICE_ID_3DLABS_DELTA	0x0003
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA	0x0004
+#define PCI_DEVICE_ID_3DLABS_MX		0x0006
+
+#define PCI_VENDOR_ID_AVANCE		0x4005
+#define PCI_DEVICE_ID_AVANCE_ALG2064	0x2064
+#define PCI_DEVICE_ID_AVANCE_2302	0x2302
+
+#define PCI_VENDOR_ID_NETVIN		0x4a14
+#define PCI_DEVICE_ID_NETVIN_NV5000SC	0x5000
+
+#define PCI_VENDOR_ID_S3		0x5333
+#define PCI_DEVICE_ID_S3_PLATO_PXS	0x0551
+#define PCI_DEVICE_ID_S3_ViRGE		0x5631
+#define PCI_DEVICE_ID_S3_TRIO		0x8811
+#define PCI_DEVICE_ID_S3_AURORA64VP	0x8812
+#define PCI_DEVICE_ID_S3_TRIO64UVP	0x8814
+#define PCI_DEVICE_ID_S3_ViRGE_VX	0x883d
+#define PCI_DEVICE_ID_S3_868		0x8880
+#define PCI_DEVICE_ID_S3_928		0x88b0
+#define PCI_DEVICE_ID_S3_864_1		0x88c0
+#define PCI_DEVICE_ID_S3_864_2		0x88c1
+#define PCI_DEVICE_ID_S3_964_1		0x88d0
+#define PCI_DEVICE_ID_S3_964_2		0x88d1
+#define PCI_DEVICE_ID_S3_968		0x88f0
+#define PCI_DEVICE_ID_S3_TRIO64V2	0x8901
+#define PCI_DEVICE_ID_S3_PLATO_PXG	0x8902
+#define PCI_DEVICE_ID_S3_ViRGE_DXGX	0x8a01
+#define PCI_DEVICE_ID_S3_ViRGE_GX2	0x8a10
+#define PCI_DEVICE_ID_S3_ViRGE_MX	0x8c01
+#define PCI_DEVICE_ID_S3_ViRGE_MXP	0x8c02
+#define PCI_DEVICE_ID_S3_ViRGE_MXPMV	0x8c03
+#define PCI_DEVICE_ID_S3_SONICVIBES	0xca00
+
+#define PCI_VENDOR_ID_INTEL		0x8086
+#define PCI_DEVICE_ID_INTEL_82375	0x0482
+#define PCI_DEVICE_ID_INTEL_82424	0x0483
+#define PCI_DEVICE_ID_INTEL_82378	0x0484
+#define PCI_DEVICE_ID_INTEL_82430	0x0486
+#define PCI_DEVICE_ID_INTEL_82434	0x04a3
+#define PCI_DEVICE_ID_INTEL_82092AA_0	0x1221
+#define PCI_DEVICE_ID_INTEL_82092AA_1	0x1222
+#define PCI_DEVICE_ID_INTEL_7116	0x1223
+#define PCI_DEVICE_ID_INTEL_82596	0x1226
+#define PCI_DEVICE_ID_INTEL_82865	0x1227
+#define PCI_DEVICE_ID_INTEL_82557	0x1229
+#define PCI_DEVICE_ID_INTEL_82437	0x122d
+#define PCI_DEVICE_ID_INTEL_82371FB_0	0x122e
+#define PCI_DEVICE_ID_INTEL_82371FB_1	0x1230
+#define PCI_DEVICE_ID_INTEL_82371MX	0x1234
+#define PCI_DEVICE_ID_INTEL_82437MX	0x1235
+#define PCI_DEVICE_ID_INTEL_82441	0x1237
+#define PCI_DEVICE_ID_INTEL_82380FB	0x124b
+#define PCI_DEVICE_ID_INTEL_82439	0x1250
+#define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
+#define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010
+#define PCI_DEVICE_ID_INTEL_82371SB_2	0x7020
+#define PCI_DEVICE_ID_INTEL_82437VX	0x7030
+#define PCI_DEVICE_ID_INTEL_82439TX	0x7100
+#define PCI_DEVICE_ID_INTEL_82371AB_0	0x7110
+#define PCI_DEVICE_ID_INTEL_82371AB	0x7111
+#define PCI_DEVICE_ID_INTEL_82371AB_2	0x7112
+#define PCI_DEVICE_ID_INTEL_82371AB_3	0x7113
+#define PCI_DEVICE_ID_INTEL_82443LX_0	0x7180
+#define PCI_DEVICE_ID_INTEL_82443LX_1	0x7181
+#define PCI_DEVICE_ID_INTEL_82443BX_0	0x7190
+#define PCI_DEVICE_ID_INTEL_82443BX_1	0x7191
+#define PCI_DEVICE_ID_INTEL_82443BX_2	0x7192
+#define PCI_DEVICE_ID_INTEL_P6		0x84c4
+#define PCI_DEVICE_ID_INTEL_82450GX	0x84c5
+
+#define PCI_VENDOR_ID_KTI		0x8e2e
+#define PCI_DEVICE_ID_KTI_ET32P2	0x3000
+
+#define PCI_VENDOR_ID_ADAPTEC		0x9004
+#define PCI_DEVICE_ID_ADAPTEC_7810	0x1078
+#define PCI_DEVICE_ID_ADAPTEC_7850	0x5078
+#define PCI_DEVICE_ID_ADAPTEC_7855	0x5578
+#define PCI_DEVICE_ID_ADAPTEC_5800	0x5800
+#define PCI_DEVICE_ID_ADAPTEC_1480A	0x6075
+#define PCI_DEVICE_ID_ADAPTEC_7860	0x6078
+#define PCI_DEVICE_ID_ADAPTEC_7861	0x6178
+#define PCI_DEVICE_ID_ADAPTEC_7870	0x7078
+#define PCI_DEVICE_ID_ADAPTEC_7871	0x7178
+#define PCI_DEVICE_ID_ADAPTEC_7872	0x7278
+#define PCI_DEVICE_ID_ADAPTEC_7873	0x7378
+#define PCI_DEVICE_ID_ADAPTEC_7874	0x7478
+#define PCI_DEVICE_ID_ADAPTEC_7895	0x7895
+#define PCI_DEVICE_ID_ADAPTEC_7880	0x8078
+#define PCI_DEVICE_ID_ADAPTEC_7881	0x8178
+#define PCI_DEVICE_ID_ADAPTEC_7882	0x8278
+#define PCI_DEVICE_ID_ADAPTEC_7883	0x8378
+#define PCI_DEVICE_ID_ADAPTEC_7884	0x8478
+#define PCI_DEVICE_ID_ADAPTEC_1030	0x8b78
+
+#define PCI_VENDOR_ID_ADAPTEC2		0x9005
+#define PCI_DEVICE_ID_ADAPTEC2_2940U2	0x0010
+#define PCI_DEVICE_ID_ADAPTEC2_7890	0x001f
+#define PCI_DEVICE_ID_ADAPTEC2_3940U2	0x0050
+#define PCI_DEVICE_ID_ADAPTEC2_7896	0x005f
+
+#define PCI_VENDOR_ID_ATRONICS		0x907f
+#define PCI_DEVICE_ID_ATRONICS_2015	0x2015
+
+#define PCI_VENDOR_ID_HOLTEK		0x9412
+#define PCI_DEVICE_ID_HOLTEK_6565	0x6565
+
+#define PCI_VENDOR_ID_TIGERJET		0xe159
+#define PCI_DEVICE_ID_TIGERJET_300	0x0001
+
+#define PCI_VENDOR_ID_ARK		0xedd8
+#define PCI_DEVICE_ID_ARK_STING		0xa091
+#define PCI_DEVICE_ID_ARK_STINGARK	0xa099
+#define PCI_DEVICE_ID_ARK_2000MT	0xa0a1
+
+/*
+ * The PCI interface treats multi-function devices as independent
+ * devices.  The slot/function address of each device is encoded
+ * in a single byte as follows:
+ *
+ *	7:3 = slot
+ *	2:0 = function
+ */
+#define PCI_DEVFN(slot,func)	((((slot) & 0x1f) << 3) | ((func) & 0x07))
+#define PCI_SLOT(devfn)		(((devfn) >> 3) & 0x1f)
+#define PCI_FUNC(devfn)		((devfn) & 0x07)
+
+/*
+ * Error values that may be returned by the PCI bios.
+ */
+#define PCIBIOS_SUCCESSFUL		0x00
+#define PCIBIOS_FUNC_NOT_SUPPORTED	0x81
+#define PCIBIOS_BAD_VENDOR_ID		0x83
+#define PCIBIOS_DEVICE_NOT_FOUND	0x86
+#define PCIBIOS_BAD_REGISTER_NUMBER	0x87
+#define PCIBIOS_SET_FAILED		0x88
+#define PCIBIOS_BUFFER_TOO_SMALL	0x89
+
+#define PCI_MAX_DEVICES			16
+#define PCI_MAX_FUNCTIONS		8
+
+typedef struct  {
+	int (*read_config_byte)(unsigned char, unsigned char,  unsigned char,
+			       unsigned char, unsigned char *);
+	int (*read_config_word)(unsigned char, unsigned char,  unsigned char,
+			       unsigned char, unsigned short *);
+	int (*read_config_dword)(unsigned char, unsigned char,  unsigned char,
+			       unsigned char, unsigned int *);
+	int (*write_config_byte)(unsigned char, unsigned char,  unsigned char,
+			       unsigned char, unsigned char);
+	int (*write_config_word)(unsigned char, unsigned char,  unsigned char,
+			       unsigned char, unsigned short);
+	int (*write_config_dword)(unsigned char, unsigned char,  unsigned char,
+			       unsigned char, unsigned int);
+}pci_config_access_functions;
+
+typedef struct {
+  volatile unsigned char*	pci_config_addr;
+  volatile unsigned char*	pci_config_data;
+  pci_config_access_functions*	pci_functions;
+} pci_config;
+
+extern pci_config pci;
+
+extern inline int
+pci_read_config_byte(unsigned char bus, unsigned char slot, unsigned char function, 
+			 unsigned char where, unsigned char * val) {
+	return pci.pci_functions->read_config_byte(bus, slot, function, where, val);
+}
+
+extern inline int
+pci_read_config_word(unsigned char bus, unsigned char slot, unsigned char function, 
+			 unsigned char where, unsigned short * val) {
+	return pci.pci_functions->read_config_word(bus, slot, function, where, val);
+}
+
+extern inline int
+pci_read_config_dword(unsigned char bus, unsigned char slot, unsigned char function, 
+			 unsigned char where, unsigned int * val) {
+	return pci.pci_functions->read_config_dword(bus, slot, function, where, val);
+}
+
+extern inline int
+pci_write_config_byte(unsigned char bus, unsigned char slot, unsigned char function, 
+			 unsigned char where, unsigned char val) {
+	return pci.pci_functions->write_config_byte(bus, slot, function, where, val);
+}
+
+extern inline int
+pci_write_config_word(unsigned char bus, unsigned char slot, unsigned char function, 
+			 unsigned char where, unsigned short val) {
+	return pci.pci_functions->write_config_word(bus, slot, function, where, val);
+}
+
+extern inline int
+pci_write_config_dword(unsigned char bus, unsigned char slot, unsigned char function, 
+			 unsigned char where, unsigned int val) {
+	return pci.pci_functions->write_config_dword(bus, slot, function, where, val);
+}
+
+/*
+ * Return the number of PCI busses in the system
+ */
+extern unsigned char BusCountPCI();
+extern void InitializePCI();
+
+#endif /* RTEMS_PCI_H */
