Introduced device IDs; removed comment lines from 8139too; removed
authorFlorian Pose <fp@igh-essen.com>
Fri, 16 Feb 2007 17:13:39 +0000
changeset 573 cdee4ea90ce9
parent 572 aef7ea866a41
child 574 609e58ece96a
Introduced device IDs; removed comment lines from 8139too; removed
ec_eoeif_count parameter.
NEWS
devices/8139too-2.6.13-ethercat.c
devices/8139too-2.6.17-ethercat.c
devices/8139too-2.6.18-ethercat.c
devices/8139too-2.6.19-ethercat.c
devices/ecdev.h
master/device.h
master/master.c
master/master.h
master/module.c
script/init.d/ethercat
script/sysconfig/ethercat
--- a/NEWS	Fri Feb 16 13:30:46 2007 +0000
+++ b/NEWS	Fri Feb 16 17:13:39 2007 +0000
@@ -4,6 +4,24 @@
 
 -------------------------------------------------------------------------------
 
+Changes in version 1.3.0:
+
+* Added Intel e100 ethernet driver.
+* Removed "ec_eoeif_count" master module parameter.
+* Introduced "device IDs" to tell a master to wait for certain ethernet
+  devices.
+* Added "main" and "backup" parameters to master module. To hand over
+  device ID lists.
+* Changed format of sysconfig file and accordingly adjusted functionality
+  of the init script to handle device IDs.
+* Device interface changes:
+  - Replaced ecdev_register() and ecdev_unregister() with ecdev_offer() and
+    ecdev_withdraw(), respectively. The device modules now offer all their
+    devices to the master, which decides, which ones to register.
+* Removed EtherCAT line comments from 8139too drivers.
+
+-------------------------------------------------------------------------------
+
 Changes in version 1.2.0:
 
 * Serveral fixes of bugs and stability issues. Master should now run fine
--- a/devices/8139too-2.6.13-ethercat.c	Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.13-ethercat.c	Fri Feb 16 17:13:39 2007 +0000
@@ -153,8 +153,6 @@
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #include "../globals.h"
 #include "ecdev.h"
 
@@ -162,8 +160,6 @@
                             " EtherCAT-capable Fast Ethernet driver " \
                             DRV_VERSION ", master " EC_MASTER_VERSION
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #define PFX DRV_NAME ": "
 
 /* Default Message level */
@@ -215,15 +211,6 @@
 /* bitmapped message enable number */
 static int debug = -1;
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /*
  * Receive ring size 
  * Warning: 64K ring has hardware issues and may lock up.
@@ -338,13 +325,9 @@
 	{0,}
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 /* prevent driver from being loaded automatically */
 //MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static struct {
 	const char str[ETH_GSTRING_LEN];
 } ethtool_stats_keys[] = {
@@ -664,17 +647,15 @@
 	struct mii_if_info mii;
 	unsigned int regs_len;
 	unsigned long fifo_copy_timeout;
+    
+	ec_device_t *ecdev;
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
 MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(EC_MASTER_VERSION);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
@@ -684,19 +665,8 @@
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
-                 "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
-                 "Index of the EtherCAT master to register the device.");
-
 void ec_poll(struct net_device *);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
 static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1046,15 +1016,6 @@
 	assert (dev != NULL);
 	tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (board_idx == ec_device_index) {
-		rtl_ec_net_dev = dev;
-		strcpy(dev->name, "ec0");
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	ioaddr = tp->mmio_addr;
 	assert (ioaddr != NULL);
 
@@ -1106,17 +1067,20 @@
 	tp->mii.reg_num_mask = 0x1f;
 
 	/* dev is fully set up and ready to use now */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+    
+	// offer device to EtherCAT master module
+	if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+				ec_poll, THIS_MODULE)) {
+		printk(KERN_ERR PFX "Failed to offer device.\n");
+		goto err_out;
+	}
+
+	if (!tp->ecdev) {
 		DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
 		i = register_netdev (dev);
 		if (i) goto err_out;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_drvdata (pdev, dev);
 
 	printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1189,6 +1153,11 @@
 	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
 		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
 
+	if (tp->ecdev && ecdev_open(tp->ecdev)) {
+		ecdev_withdraw(tp->ecdev);
+		goto err_out;
+	}
+
 	return 0;
 
 err_out:
@@ -1201,17 +1170,18 @@
 static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	assert (dev != NULL);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		ecdev_close(tp->ecdev);
+		ecdev_withdraw(tp->ecdev);
+	}
+	else {
 		unregister_netdev (dev);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	__rtl8139_cleanup_dev (dev);
 	pci_disable_device (pdev);
 }
@@ -1412,30 +1382,19 @@
 	int retval;
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		retval = request_irq(dev->irq, rtl8139_interrupt,
 			SA_SHIRQ, dev->name, dev);
 		if (retval)
 			return retval;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
 					   &tp->tx_bufs_dma);
 	tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
 					   &tp->rx_ring_dma);
 	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
-			free_irq(dev->irq, dev);
-		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+		if (!tp->ecdev) free_irq(dev->irq, dev);
 		if (tp->tx_bufs)
 			pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
 					    tp->tx_bufs, tp->tx_bufs_dma);
@@ -1453,9 +1412,7 @@
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		netif_start_queue (dev);
 
 		if (netif_msg_ifup(tp))
@@ -1468,8 +1425,6 @@
 		rtl8139_start_thread(dev);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return 0;
 }
 
@@ -1478,19 +1433,16 @@
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		void __iomem *ioaddr = tp->mmio_addr;
+		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+		ecdev_link_state(tp->ecdev, state ? 1 : 0);
+	}
+	else {
 		if (tp->phys[0] >= 0) {
 			mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
 		}
-	} else {
-		void __iomem *ioaddr = tp->mmio_addr;
-		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
-		ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 }
 
 /* Start the hardware at open or resume. */
@@ -1555,14 +1507,9 @@
 	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
 		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev)
 		/* Enable all known interrupts by setting the interrupt mask. */
 		RTL_W16 (IntrMask, rtl8139_intr_mask);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 }
 
 
@@ -1821,30 +1768,27 @@
 	if (tmp8 & CmdTxEnb)
 		RTL_W8 (ChipCmd, CmdRxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
-		spin_lock(&tp->rx_lock);
-		/* Disable interrupts by clearing the interrupt mask. */
-		RTL_W16 (IntrMask, 0x0000);
-
-		/* Stop a shared interrupt from scavenging while we are. */
-		spin_lock_irqsave (&tp->lock, flags);
-		rtl8139_tx_clear (tp);
-		spin_unlock_irqrestore (&tp->lock, flags);
-
-		/* ...and finally, reset everything */
-		if (netif_running(dev)) {
-			rtl8139_hw_start (dev);
-			netif_wake_queue (dev);
-		}
-		spin_unlock(&tp->rx_lock);
-	} else {
-		rtl8139_tx_clear (tp);
-		rtl8139_hw_start (dev);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+    if (tp->ecdev) {
+        rtl8139_tx_clear (tp);
+        rtl8139_hw_start (dev);
+    }
+    else {
+        spin_lock(&tp->rx_lock);
+        /* Disable interrupts by clearing the interrupt mask. */
+        RTL_W16 (IntrMask, 0x0000);
+
+        /* Stop a shared interrupt from scavenging while we are. */
+        spin_lock_irqsave (&tp->lock, flags);
+        rtl8139_tx_clear (tp);
+        spin_unlock_irqrestore (&tp->lock, flags);
+
+        /* ...and finally, reset everything */
+        if (netif_running(dev)) {
+            rtl8139_hw_start (dev);
+            netif_wake_queue (dev);
+        }
+        spin_unlock(&tp->rx_lock);
+    }
 }
 
 
@@ -1858,30 +1802,19 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	/* Note: the chip doesn't have auto-pad! */
 	if (likely(len < TX_BUF_SIZE)) {
 		if (len < ETH_ZLEN)
 			memset(tp->tx_buf[entry], 0, ETH_ZLEN);
 		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 	} else {
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 		tp->stats.tx_dropped++;
 		return 0;
 	}
 
-	if (dev != rtl_ec_net_dev) {
-		spin_lock_irq(&tp->lock);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+	if (!tp->ecdev) spin_lock_irq(&tp->lock);
 	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
 		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 
@@ -1890,9 +1823,7 @@
 	tp->cur_tx++;
 	wmb();
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 			netif_stop_queue (dev);
 		spin_unlock_irq(&tp->lock);
@@ -1902,8 +1833,6 @@
 				dev->name, len, entry);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return 0;
 }
 
@@ -1961,10 +1890,8 @@
 		tx_left--;
 	}
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #ifndef RTL8139_NDEBUG
-	if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+	if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
 		printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
 		        dev->name, dirty_tx, tp->cur_tx);
 		dirty_tx += NUM_TX_DESC;
@@ -1975,13 +1902,8 @@
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
 		mb();
-
-		if (dev != rtl_ec_net_dev) {
-			netif_wake_queue (dev);
-		}
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+		if (!tp->ecdev) netif_wake_queue (dev);
+	}
 }
 
 
@@ -2114,15 +2036,9 @@
 		 RTL_R16 (RxBufAddr),
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	while ((dev == rtl_ec_net_dev || netif_running(dev))
+	while ((tp->ecdev || netif_running(dev))
 	       && received < budget
 	       && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		u32 ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
 		unsigned int pkt_size;
@@ -2135,17 +2051,12 @@
 		rx_size = rx_status >> 16;
 		pkt_size = rx_size - 4;
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (!tp->ecdev) {
 			if (netif_msg_rx_status(tp))
 				printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
 				       " cur %4.4x.\n", dev->name, rx_status,
 				       rx_size, cur_rx);
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #if RTL8139_DEBUG > 2
 		{
 			int i;
@@ -2193,9 +2104,14 @@
 			goto out;
 		}
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			ecdev_receive(tp->ecdev,
+					&rx_ring[ring_offset + 4], pkt_size);
+			dev->last_rx = jiffies;
+			tp->stats.rx_bytes += pkt_size;
+			tp->stats.rx_packets++;
+		}
+		else {
 			/* Malloc up new buffer, compatible with net-2e. */
 			/* Omit the four octet CRC from the length. */
 
@@ -2220,20 +2136,11 @@
 			} else {
 				if (net_ratelimit())
 					printk(KERN_WARNING
-					       "%s: Memory squeeze, dropping packet.\n",
-					       dev->name);
+							"%s: Memory squeeze, dropping packet.\n",
+							dev->name);
 				tp->stats.rx_dropped++;
 			}
-		} else {
-			ecdev_receive(rtl_ec_dev,
-			              &rx_ring[ring_offset + 4], pkt_size);
-			dev->last_rx = jiffies;
-			tp->stats.rx_bytes += pkt_size;
-			tp->stats.rx_packets++;
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		received++;
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2339,19 +2246,15 @@
 	return !done;
 }
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 void ec_poll(struct net_device *dev)
 {
     rtl8139_interrupt(0, dev, NULL);
 }
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
-                               struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
+			       struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
 	struct rtl8139_private *tp = netdev_priv(dev);
@@ -2360,20 +2263,17 @@
 	int link_changed = 0; /* avoid bogus "uninit" warning */
 	int handled = 0;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		status = RTL_R16 (IntrStatus);
+	}
+	else {
 		spin_lock (&tp->lock);
 		status = RTL_R16 (IntrStatus);
 
 		/* shared irq? */
 		if (unlikely((status & rtl8139_intr_mask) == 0))
 			goto out;
-	} else {
-		status = RTL_R16 (IntrStatus);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	handled = 1;
 
@@ -2381,9 +2281,7 @@
 	if (unlikely(status == 0xFFFF)) 
 		goto out;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		/* close possible race's with dev_close */
 		if (unlikely(!netif_running(dev))) {
 			RTL_W16 (IntrMask, 0);
@@ -2391,8 +2289,6 @@
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Acknowledge all of the current interrupt sources ASAP, but
 	   an first get an additional status bit from CSCR. */
 	if (unlikely(status & RxUnderrun))
@@ -2404,24 +2300,20 @@
 
 	/* Receive packets are processed by poll routine.
 	   If not running start it now. */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	if (status & RxAckBits){
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			/* EtherCAT device: Just receive all frames */
+			rtl8139_rx(dev, tp, 100); // FIXME
+		}
+		else {
 			/* Mark for polling */
 			if (netif_rx_schedule_prep(dev)) {
 				RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
 				__netif_rx_schedule (dev);
 			}
-		} else {
-			/* EtherCAT device: Just receive all frames */
-			rtl8139_rx(dev, tp, 100); // FIXME
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Check uncommon events with one test. */
 	if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
 		rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2433,14 +2325,7 @@
 			RTL_W16 (IntrStatus, TxErr);
 	}
  out:
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
-		spin_unlock (&tp->lock);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	if (!tp->ecdev) spin_unlock (&tp->lock);
 
 	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
 		 dev->name, RTL_R16 (IntrStatus));
@@ -2467,9 +2352,17 @@
 	int ret = 0;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		/* Stop the chip's Tx and Rx DMA processes. */
+		RTL_W8 (ChipCmd, 0);
+
+		/* Disable interrupts by clearing the interrupt mask. */
+		RTL_W16 (IntrMask, 0);
+
+		/* Update the error counts. */
+		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+		RTL_W32 (RxMissed, 0);
+	} else {
 		netif_stop_queue (dev);
 
 		if (tp->thr_pid >= 0) {
@@ -2503,19 +2396,7 @@
 
 		synchronize_irq (dev->irq);	/* racy, but that's ok here */
 		free_irq (dev->irq, dev);
-	} else {
-		/* Stop the chip's Tx and Rx DMA processes. */
-		RTL_W8 (ChipCmd, 0);
-
-		/* Disable interrupts by clearing the interrupt mask. */
-		RTL_W16 (IntrMask, 0);
-
-		/* Update the error counts. */
-		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
-		RTL_W32 (RxMissed, 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	rtl8139_tx_clear (tp);
 
@@ -2730,13 +2611,9 @@
 	struct rtl8139_private *np = netdev_priv(dev);
 	int rc;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running(dev))
+	if (np->ecdev || !netif_running(dev))
 		return -EINVAL;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	spin_lock_irq(&np->lock);
 	rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
 	spin_unlock_irq(&np->lock);
@@ -2751,17 +2628,13 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || netif_running(dev)) {
+	if (tp->ecdev || netif_running(dev)) {
 		spin_lock_irqsave (&tp->lock, flags);
 		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 		RTL_W32 (RxMissed, 0);
 		spin_unlock_irqrestore (&tp->lock, flags);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return &tp->stats;
 }
 
@@ -2837,13 +2710,9 @@
 
 	pci_save_state (pdev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	netif_device_detach (dev);
 
 	spin_lock_irqsave (&tp->lock, flags);
@@ -2867,16 +2736,11 @@
 static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	pci_restore_state (pdev);
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_power_state (pdev, PCI_D0);
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
@@ -2901,69 +2765,20 @@
 
 static int __init rtl8139_init_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
-	printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
-	if (pci_module_init(&rtl8139_pci_driver) < 0) {
-		printk(KERN_ERR "Failed to init PCI module.\n");
-		goto out_return;
-	}
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Registering EtherCAT device...\n");
-		if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
-			rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
-			printk(KERN_ERR "Failed to register EtherCAT device!\n");
-			goto out_pci;
-		}
-
-		printk(KERN_INFO "Opening EtherCAT device...\n");
-		if (ecdev_open(rtl_ec_dev)) {
-			printk(KERN_ERR "Failed to open EtherCAT device!\n");
-			goto out_unregister;
-		}
-
-		printk(KERN_INFO "EtherCAT device ready.\n");
-	} else {
-		printk(KERN_WARNING "No EtherCAT device registered!\n");
-	}
-
-	return 0;
-
-    out_unregister:
-	printk(KERN_INFO "Unregistering EtherCAT device...\n");
-	ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-	rtl_ec_dev = NULL;
-    out_pci:
-	pci_unregister_driver(&rtl8139_pci_driver);
-    out_return:
-	return -1;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	/* when we're a module, we always print a version message,
+	 * even if no 8139 board is found.
+	 */
+#ifdef MODULE
+	printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+	return pci_module_init (&rtl8139_pci_driver);
 }
 
 
 static void __exit rtl8139_cleanup_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Closing EtherCAT device...\n");
-		ecdev_close(rtl_ec_dev);
-		printk(KERN_INFO "Unregistering EtherCAT device...\n");
-		ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-		rtl_ec_dev = NULL;
-	}
-
-	pci_unregister_driver(&rtl8139_pci_driver);
-
-	printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	pci_unregister_driver (&rtl8139_pci_driver);
 }
 
 
--- a/devices/8139too-2.6.17-ethercat.c	Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.17-ethercat.c	Fri Feb 16 17:13:39 2007 +0000
@@ -153,8 +153,6 @@
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #include "../globals.h"
 #include "ecdev.h"
 
@@ -162,8 +160,6 @@
                             " EtherCAT-capable Fast Ethernet driver " \
                             DRV_VERSION ", master " EC_MASTER_VERSION
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #define PFX DRV_NAME ": "
 
 /* Default Message level */
@@ -215,15 +211,6 @@
 /* bitmapped message enable number */
 static int debug = -1;
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /*
  * Receive ring size 
  * Warning: 64K ring has hardware issues and may lock up.
@@ -338,13 +325,9 @@
 	{0,}
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 /* prevent driver from being loaded automatically */
 //MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static struct {
 	const char str[ETH_GSTRING_LEN];
 } ethtool_stats_keys[] = {
@@ -666,17 +649,15 @@
 	struct mii_if_info mii;
 	unsigned int regs_len;
 	unsigned long fifo_copy_timeout;
+    
+	ec_device_t *ecdev;
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
 MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(EC_MASTER_VERSION);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
@@ -686,19 +667,8 @@
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
-                 "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
-                 "Index of the EtherCAT master to register the device.");
-
 void ec_poll(struct net_device *);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
 static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1050,15 +1020,6 @@
 	assert (dev != NULL);
 	tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (board_idx == ec_device_index) {
-		rtl_ec_net_dev = dev;
-		strcpy(dev->name, "ec0");
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	ioaddr = tp->mmio_addr;
 	assert (ioaddr != NULL);
 
@@ -1110,17 +1071,20 @@
 	tp->mii.reg_num_mask = 0x1f;
 
 	/* dev is fully set up and ready to use now */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+    
+	// offer device to EtherCAT master module
+	if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+				ec_poll, THIS_MODULE)) {
+		printk(KERN_ERR PFX "Failed to offer device.\n");
+		goto err_out;
+	}
+
+	if (!tp->ecdev) {
 		DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
 		i = register_netdev (dev);
 		if (i) goto err_out;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_drvdata (pdev, dev);
 
 	printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1193,6 +1157,11 @@
 	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
 		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
 
+	if (tp->ecdev && ecdev_open(tp->ecdev)) {
+		ecdev_withdraw(tp->ecdev);
+		goto err_out;
+	}
+
 	return 0;
 
 err_out:
@@ -1205,17 +1174,18 @@
 static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	assert (dev != NULL);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		ecdev_close(tp->ecdev);
+		ecdev_withdraw(tp->ecdev);
+	}
+	else {
 		unregister_netdev (dev);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	__rtl8139_cleanup_dev (dev);
 	pci_disable_device (pdev);
 }
@@ -1416,30 +1386,19 @@
 	int retval;
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		retval = request_irq(dev->irq, rtl8139_interrupt,
 			SA_SHIRQ, dev->name, dev);
 		if (retval)
 			return retval;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
 					   &tp->tx_bufs_dma);
 	tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
 					   &tp->rx_ring_dma);
 	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
-			free_irq(dev->irq, dev);
-		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+		if (!tp->ecdev) free_irq(dev->irq, dev);
 		if (tp->tx_bufs)
 			pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
 					    tp->tx_bufs, tp->tx_bufs_dma);
@@ -1457,9 +1416,7 @@
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		netif_start_queue (dev);
 
 		if (netif_msg_ifup(tp))
@@ -1472,8 +1429,6 @@
 		rtl8139_start_thread(tp);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return 0;
 }
 
@@ -1482,19 +1437,16 @@
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		void __iomem *ioaddr = tp->mmio_addr;
+		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+		ecdev_link_state(tp->ecdev, state ? 1 : 0);
+	}
+	else {
 		if (tp->phys[0] >= 0) {
 			mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
 		}
-	} else {
-		void __iomem *ioaddr = tp->mmio_addr;
-		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
-		ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 }
 
 /* Start the hardware at open or resume. */
@@ -1559,14 +1511,9 @@
 	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
 		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev)
 		/* Enable all known interrupts by setting the interrupt mask. */
 		RTL_W16 (IntrMask, rtl8139_intr_mask);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 }
 
 
@@ -1814,9 +1761,11 @@
 	if (tmp8 & CmdTxEnb)
 		RTL_W8 (ChipCmd, CmdRxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		rtl8139_tx_clear (tp);
+		rtl8139_hw_start (dev);
+	}
+	else {
 		spin_lock_bh(&tp->rx_lock);
 		/* Disable interrupts by clearing the interrupt mask. */
 		RTL_W16 (IntrMask, 0x0000);
@@ -1832,27 +1781,19 @@
 			netif_wake_queue (dev);
 		}
 		spin_unlock_bh(&tp->rx_lock);
-	} else {
-		rtl8139_tx_clear (tp);
-		rtl8139_hw_start (dev);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 }
 
 static void rtl8139_tx_timeout (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev && !tp->have_thread) {
+	if (!tp->ecdev && !tp->have_thread) {
 		INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
 		schedule_delayed_work(&tp->thread, next_tick);
 	} else
 		tp->watchdog_fired = 1;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 }
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -1865,30 +1806,19 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	/* Note: the chip doesn't have auto-pad! */
 	if (likely(len < TX_BUF_SIZE)) {
 		if (len < ETH_ZLEN)
 			memset(tp->tx_buf[entry], 0, ETH_ZLEN);
 		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 	} else {
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 		tp->stats.tx_dropped++;
 		return 0;
 	}
 
-	if (dev != rtl_ec_net_dev) {
-		spin_lock_irq(&tp->lock);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+	if (!tp->ecdev) spin_lock_irq(&tp->lock);
 	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
 		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
 
@@ -1897,9 +1827,7 @@
 	tp->cur_tx++;
 	wmb();
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
 			netif_stop_queue (dev);
 		spin_unlock_irq(&tp->lock);
@@ -1909,8 +1837,6 @@
 				dev->name, len, entry);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return 0;
 }
 
@@ -1968,10 +1894,8 @@
 		tx_left--;
 	}
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #ifndef RTL8139_NDEBUG
-	if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+	if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
 		printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
 		        dev->name, dirty_tx, tp->cur_tx);
 		dirty_tx += NUM_TX_DESC;
@@ -1982,13 +1906,8 @@
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
 		mb();
-
-		if (dev != rtl_ec_net_dev) {
-			netif_wake_queue (dev);
-		}
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+		if (!tp->ecdev) netif_wake_queue (dev);
+	}
 }
 
 
@@ -2121,15 +2040,9 @@
 		 RTL_R16 (RxBufAddr),
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	while ((dev == rtl_ec_net_dev || netif_running(dev))
+	while ((tp->ecdev || netif_running(dev))
 	       && received < budget
 	       && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		u32 ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
 		unsigned int pkt_size;
@@ -2142,17 +2055,12 @@
 		rx_size = rx_status >> 16;
 		pkt_size = rx_size - 4;
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (!tp->ecdev) {
 			if (netif_msg_rx_status(tp))
 				printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
 				       " cur %4.4x.\n", dev->name, rx_status,
 				       rx_size, cur_rx);
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #if RTL8139_DEBUG > 2
 		{
 			int i;
@@ -2200,9 +2108,14 @@
 			goto out;
 		}
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			ecdev_receive(tp->ecdev,
+					&rx_ring[ring_offset + 4], pkt_size);
+			dev->last_rx = jiffies;
+			tp->stats.rx_bytes += pkt_size;
+			tp->stats.rx_packets++;
+		}
+		else {
 			/* Malloc up new buffer, compatible with net-2e. */
 			/* Omit the four octet CRC from the length. */
 
@@ -2227,20 +2140,11 @@
 			} else {
 				if (net_ratelimit())
 					printk(KERN_WARNING
-					       "%s: Memory squeeze, dropping packet.\n",
-					       dev->name);
+							"%s: Memory squeeze, dropping packet.\n",
+							dev->name);
 				tp->stats.rx_dropped++;
 			}
-		} else {
-			ecdev_receive(rtl_ec_dev,
-			              &rx_ring[ring_offset + 4], pkt_size);
-			dev->last_rx = jiffies;
-			tp->stats.rx_bytes += pkt_size;
-			tp->stats.rx_packets++;
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		received++;
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2346,19 +2250,15 @@
 	return !done;
 }
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 void ec_poll(struct net_device *dev)
 {
     rtl8139_interrupt(0, dev, NULL);
 }
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
-                               struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
+			       struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
 	struct rtl8139_private *tp = netdev_priv(dev);
@@ -2367,20 +2267,17 @@
 	int link_changed = 0; /* avoid bogus "uninit" warning */
 	int handled = 0;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		status = RTL_R16 (IntrStatus);
+	}
+	else {
 		spin_lock (&tp->lock);
 		status = RTL_R16 (IntrStatus);
 
 		/* shared irq? */
 		if (unlikely((status & rtl8139_intr_mask) == 0))
 			goto out;
-	} else {
-		status = RTL_R16 (IntrStatus);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	handled = 1;
 
@@ -2388,9 +2285,7 @@
 	if (unlikely(status == 0xFFFF)) 
 		goto out;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		/* close possible race's with dev_close */
 		if (unlikely(!netif_running(dev))) {
 			RTL_W16 (IntrMask, 0);
@@ -2398,8 +2293,6 @@
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Acknowledge all of the current interrupt sources ASAP, but
 	   an first get an additional status bit from CSCR. */
 	if (unlikely(status & RxUnderrun))
@@ -2411,24 +2304,20 @@
 
 	/* Receive packets are processed by poll routine.
 	   If not running start it now. */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	if (status & RxAckBits){
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			/* EtherCAT device: Just receive all frames */
+			rtl8139_rx(dev, tp, 100); // FIXME
+		}
+		else {
 			/* Mark for polling */
 			if (netif_rx_schedule_prep(dev)) {
 				RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
 				__netif_rx_schedule (dev);
 			}
-		} else {
-			/* EtherCAT device: Just receive all frames */
-			rtl8139_rx(dev, tp, 100); // FIXME
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Check uncommon events with one test. */
 	if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
 		rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2440,14 +2329,7 @@
 			RTL_W16 (IntrStatus, TxErr);
 	}
  out:
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
-		spin_unlock (&tp->lock);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	if (!tp->ecdev) spin_unlock (&tp->lock);
 
 	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
 		 dev->name, RTL_R16 (IntrStatus));
@@ -2473,9 +2355,17 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		/* Stop the chip's Tx and Rx DMA processes. */
+		RTL_W8 (ChipCmd, 0);
+
+		/* Disable interrupts by clearing the interrupt mask. */
+		RTL_W16 (IntrMask, 0);
+
+		/* Update the error counts. */
+		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+		RTL_W32 (RxMissed, 0);
+	} else {
 		netif_stop_queue (dev);
 
 		rtl8139_stop_thread(tp);
@@ -2500,19 +2390,7 @@
 
 		synchronize_irq (dev->irq);	/* racy, but that's ok here */
 		free_irq (dev->irq, dev);
-	} else {
-		/* Stop the chip's Tx and Rx DMA processes. */
-		RTL_W8 (ChipCmd, 0);
-
-		/* Disable interrupts by clearing the interrupt mask. */
-		RTL_W16 (IntrMask, 0);
-
-		/* Update the error counts. */
-		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
-		RTL_W32 (RxMissed, 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	rtl8139_tx_clear (tp);
 
@@ -2728,13 +2606,9 @@
 	struct rtl8139_private *np = netdev_priv(dev);
 	int rc;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running(dev))
+	if (np->ecdev || !netif_running(dev))
 		return -EINVAL;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	spin_lock_irq(&np->lock);
 	rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
 	spin_unlock_irq(&np->lock);
@@ -2749,17 +2623,13 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || netif_running(dev)) {
+	if (tp->ecdev || netif_running(dev)) {
 		spin_lock_irqsave (&tp->lock, flags);
 		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 		RTL_W32 (RxMissed, 0);
 		spin_unlock_irqrestore (&tp->lock, flags);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return &tp->stats;
 }
 
@@ -2835,13 +2705,9 @@
 
 	pci_save_state (pdev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	netif_device_detach (dev);
 
 	spin_lock_irqsave (&tp->lock, flags);
@@ -2865,16 +2731,11 @@
 static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	pci_restore_state (pdev);
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_power_state (pdev, PCI_D0);
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
@@ -2899,69 +2760,20 @@
 
 static int __init rtl8139_init_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
-	printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
-	if (pci_module_init(&rtl8139_pci_driver) < 0) {
-		printk(KERN_ERR "Failed to init PCI module.\n");
-		goto out_return;
-	}
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Registering EtherCAT device...\n");
-		if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
-			rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
-			printk(KERN_ERR "Failed to register EtherCAT device!\n");
-			goto out_pci;
-		}
-
-		printk(KERN_INFO "Opening EtherCAT device...\n");
-		if (ecdev_open(rtl_ec_dev)) {
-			printk(KERN_ERR "Failed to open EtherCAT device!\n");
-			goto out_unregister;
-		}
-
-		printk(KERN_INFO "EtherCAT device ready.\n");
-	} else {
-		printk(KERN_WARNING "No EtherCAT device registered!\n");
-	}
-
-	return 0;
-
-    out_unregister:
-	printk(KERN_INFO "Unregistering EtherCAT device...\n");
-	ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-	rtl_ec_dev = NULL;
-    out_pci:
-	pci_unregister_driver(&rtl8139_pci_driver);
-    out_return:
-	return -1;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	/* when we're a module, we always print a version message,
+	 * even if no 8139 board is found.
+	 */
+#ifdef MODULE
+	printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+	return pci_module_init (&rtl8139_pci_driver);
 }
 
 
 static void __exit rtl8139_cleanup_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Closing EtherCAT device...\n");
-		ecdev_close(rtl_ec_dev);
-		printk(KERN_INFO "Unregistering EtherCAT device...\n");
-		ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-		rtl_ec_dev = NULL;
-	}
-
-	pci_unregister_driver(&rtl8139_pci_driver);
-
-	printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	pci_unregister_driver (&rtl8139_pci_driver);
 }
 
 
--- a/devices/8139too-2.6.18-ethercat.c	Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.18-ethercat.c	Fri Feb 16 17:13:39 2007 +0000
@@ -152,8 +152,6 @@
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #include "../globals.h"
 #include "ecdev.h"
 
@@ -161,8 +159,6 @@
                             " EtherCAT-capable Fast Ethernet driver " \
                             DRV_VERSION ", master " EC_MASTER_VERSION
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #define PFX DRV_NAME ": "
 
 /* Default Message level */
@@ -214,15 +210,6 @@
 /* bitmapped message enable number */
 static int debug = -1;
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /*
  * Receive ring size
  * Warning: 64K ring has hardware issues and may lock up.
@@ -337,13 +324,9 @@
 	{0,}
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 /* prevent driver from being loaded automatically */
 //MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static struct {
 	const char str[ETH_GSTRING_LEN];
 } ethtool_stats_keys[] = {
@@ -665,17 +648,15 @@
 	struct mii_if_info mii;
 	unsigned int regs_len;
 	unsigned long fifo_copy_timeout;
+    
+	ec_device_t *ecdev;
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
 MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(EC_MASTER_VERSION);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
@@ -685,19 +666,8 @@
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
-                 "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
-                 "Index of the EtherCAT master to register the device.");
-
 void ec_poll(struct net_device *);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
 static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1051,15 +1021,6 @@
 	assert (dev != NULL);
 	tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (board_idx == ec_device_index) {
-		rtl_ec_net_dev = dev;
-		strcpy(dev->name, "ec0");
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	ioaddr = tp->mmio_addr;
 	assert (ioaddr != NULL);
 
@@ -1111,17 +1072,20 @@
 	tp->mii.reg_num_mask = 0x1f;
 
 	/* dev is fully set up and ready to use now */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+    
+	// offer device to EtherCAT master module
+	if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+				ec_poll, THIS_MODULE)) {
+		printk(KERN_ERR PFX "Failed to offer device.\n");
+		goto err_out;
+	}
+
+	if (!tp->ecdev) {
 		DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
 		i = register_netdev (dev);
 		if (i) goto err_out;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_drvdata (pdev, dev);
 
 	printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1194,6 +1158,11 @@
 	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
 		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
 
+	if (tp->ecdev && ecdev_open(tp->ecdev)) {
+		ecdev_withdraw(tp->ecdev);
+		goto err_out;
+	}
+
 	return 0;
 
 err_out:
@@ -1206,17 +1175,18 @@
 static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	assert (dev != NULL);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		ecdev_close(tp->ecdev);
+		ecdev_withdraw(tp->ecdev);
+	}
+	else {
 		unregister_netdev (dev);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	__rtl8139_cleanup_dev (dev);
 	pci_disable_device (pdev);
 }
@@ -1417,29 +1387,19 @@
 	int retval;
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		retval = request_irq(dev->irq, rtl8139_interrupt,
 			IRQF_SHARED, dev->name, dev);
 		if (retval)
 			return retval;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
 					   &tp->tx_bufs_dma);
 	tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
 					   &tp->rx_ring_dma);
 	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
-			free_irq(dev->irq, dev);
-		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+		if (!tp->ecdev) free_irq(dev->irq, dev);
 
 		if (tp->tx_bufs)
 			pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
@@ -1458,9 +1418,7 @@
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		netif_start_queue (dev);
 
 		if (netif_msg_ifup(tp))
@@ -1472,8 +1430,6 @@
 		rtl8139_start_thread(tp);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return 0;
 }
 
@@ -1482,19 +1438,16 @@
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		void __iomem *ioaddr = tp->mmio_addr;
+		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+		ecdev_link_state(tp->ecdev, state ? 1 : 0);
+	}
+	else {
 		if (tp->phys[0] >= 0) {
 			mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
 		}
-	} else {
-		void __iomem *ioaddr = tp->mmio_addr;
-		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
-		ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 }
 
 /* Start the hardware at open or resume. */
@@ -1559,14 +1512,9 @@
 	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
 		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev)
 		/* Enable all known interrupts by setting the interrupt mask. */
 		RTL_W16 (IntrMask, rtl8139_intr_mask);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 }
 
 
@@ -1814,9 +1762,11 @@
 	if (tmp8 & CmdTxEnb)
 		RTL_W8 (ChipCmd, CmdRxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		rtl8139_tx_clear (tp);
+		rtl8139_hw_start (dev);
+	}
+	else {
 		spin_lock_bh(&tp->rx_lock);
 		/* Disable interrupts by clearing the interrupt mask. */
 		RTL_W16 (IntrMask, 0x0000);
@@ -1832,27 +1782,19 @@
 			netif_wake_queue (dev);
 		}
 		spin_unlock_bh(&tp->rx_lock);
-	} else {
-		rtl8139_tx_clear (tp);
-		rtl8139_hw_start (dev);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 }
 
 static void rtl8139_tx_timeout (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev && !tp->have_thread) {
+	if (!tp->ecdev && !tp->have_thread) {
 		INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
 		schedule_delayed_work(&tp->thread, next_tick);
 	} else
 		tp->watchdog_fired = 1;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 }
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -1866,27 +1808,28 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	/* Note: the chip doesn't have auto-pad! */
 	if (likely(len < TX_BUF_SIZE)) {
 		if (len < ETH_ZLEN)
 			memset(tp->tx_buf[entry], 0, ETH_ZLEN);
 		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 	} else {
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 		tp->stats.tx_dropped++;
 		return 0;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
+				tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
+
+		dev->trans_start = jiffies;
+
+		tp->cur_tx++;
+		wmb();
+	}
+	else {
 		spin_lock_irqsave(&tp->lock, flags);
 
 		RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
@@ -1905,17 +1848,6 @@
 			printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
 					dev->name, len, entry);
 	}
-	else {
-		RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
-				tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
-
-		dev->trans_start = jiffies;
-
-		tp->cur_tx++;
-		wmb();
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 
 	return 0;
 }
@@ -1974,10 +1906,8 @@
 		tx_left--;
 	}
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #ifndef RTL8139_NDEBUG
-	if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+	if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
 		printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
 		        dev->name, dirty_tx, tp->cur_tx);
 		dirty_tx += NUM_TX_DESC;
@@ -1988,13 +1918,8 @@
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
 		mb();
-
-		if (dev != rtl_ec_net_dev) {
-			netif_wake_queue (dev);
-		}
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+		if (!tp->ecdev) netif_wake_queue (dev);
+	}
 }
 
 
@@ -2127,14 +2052,9 @@
 		 RTL_R16 (RxBufAddr),
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	while ((dev == rtl_ec_net_dev || netif_running(dev))
+	while ((tp->ecdev || netif_running(dev))
 			&& received < budget
 			&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		u32 ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
 		unsigned int pkt_size;
@@ -2147,17 +2067,12 @@
 		rx_size = rx_status >> 16;
 		pkt_size = rx_size - 4;
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (!tp->ecdev) {
 			if (netif_msg_rx_status(tp))
 				printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
 				       " cur %4.4x.\n", dev->name, rx_status,
 				       rx_size, cur_rx);
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #if RTL8139_DEBUG > 2
 		{
 			int i;
@@ -2205,9 +2120,14 @@
 			goto out;
 		}
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			ecdev_receive(tp->ecdev,
+					&rx_ring[ring_offset + 4], pkt_size);
+			dev->last_rx = jiffies;
+			tp->stats.rx_bytes += pkt_size;
+			tp->stats.rx_packets++;
+		}
+		else {
 			/* Malloc up new buffer, compatible with net-2e. */
 			/* Omit the four octet CRC from the length. */
 
@@ -2232,20 +2152,11 @@
 			} else {
 				if (net_ratelimit())
 					printk(KERN_WARNING
-					       "%s: Memory squeeze, dropping packet.\n",
-					       dev->name);
+							"%s: Memory squeeze, dropping packet.\n",
+							dev->name);
 				tp->stats.rx_dropped++;
 			}
-		} else {
-			ecdev_receive(rtl_ec_dev,
-			              &rx_ring[ring_offset + 4], pkt_size);
-			dev->last_rx = jiffies;
-			tp->stats.rx_bytes += pkt_size;
-			tp->stats.rx_packets++;
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		received++;
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2351,19 +2262,15 @@
 	return !done;
 }
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 void ec_poll(struct net_device *dev)
 {
     rtl8139_interrupt(0, dev, NULL);
 }
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
-                               struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
+			       struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
 	struct rtl8139_private *tp = netdev_priv(dev);
@@ -2372,20 +2279,17 @@
 	int link_changed = 0; /* avoid bogus "uninit" warning */
 	int handled = 0;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		status = RTL_R16 (IntrStatus);
+	}
+	else {
 		spin_lock (&tp->lock);
 		status = RTL_R16 (IntrStatus);
 
 		/* shared irq? */
 		if (unlikely((status & rtl8139_intr_mask) == 0))
 			goto out;
-	} else {
-		status = RTL_R16 (IntrStatus);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	handled = 1;
 
@@ -2393,9 +2297,7 @@
 	if (unlikely(status == 0xFFFF))
 		goto out;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		/* close possible race's with dev_close */
 		if (unlikely(!netif_running(dev))) {
 			RTL_W16 (IntrMask, 0);
@@ -2403,8 +2305,6 @@
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Acknowledge all of the current interrupt sources ASAP, but
 	   an first get an additional status bit from CSCR. */
 	if (unlikely(status & RxUnderrun))
@@ -2416,24 +2316,20 @@
 
 	/* Receive packets are processed by poll routine.
 	   If not running start it now. */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	if (status & RxAckBits){
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			/* EtherCAT device: Just receive all frames */
+			rtl8139_rx(dev, tp, 100); // FIXME
+		}
+		else {
 			/* Mark for polling */
 			if (netif_rx_schedule_prep(dev)) {
 				RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
 				__netif_rx_schedule (dev);
 			}
-		} else {
-			/* EtherCAT device: Just receive all frames */
-			rtl8139_rx(dev, tp, 100); // FIXME
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Check uncommon events with one test. */
 	if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
 		rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2445,14 +2341,7 @@
 			RTL_W16 (IntrStatus, TxErr);
 	}
  out:
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
-		spin_unlock (&tp->lock);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	if (!tp->ecdev) spin_unlock (&tp->lock);
 
 	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
 		 dev->name, RTL_R16 (IntrStatus));
@@ -2478,9 +2367,17 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		/* Stop the chip's Tx and Rx DMA processes. */
+		RTL_W8 (ChipCmd, 0);
+
+		/* Disable interrupts by clearing the interrupt mask. */
+		RTL_W16 (IntrMask, 0);
+
+		/* Update the error counts. */
+		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+		RTL_W32 (RxMissed, 0);
+	} else {
 		netif_stop_queue (dev);
 
 		rtl8139_stop_thread(tp);
@@ -2505,19 +2402,7 @@
 
 		synchronize_irq (dev->irq);	/* racy, but that's ok here */
 		free_irq (dev->irq, dev);
-	} else {
-		/* Stop the chip's Tx and Rx DMA processes. */
-		RTL_W8 (ChipCmd, 0);
-
-		/* Disable interrupts by clearing the interrupt mask. */
-		RTL_W16 (IntrMask, 0);
-
-		/* Update the error counts. */
-		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
-		RTL_W32 (RxMissed, 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	rtl8139_tx_clear (tp);
 
@@ -2733,13 +2618,9 @@
 	struct rtl8139_private *np = netdev_priv(dev);
 	int rc;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running(dev))
+	if (np->ecdev || !netif_running(dev))
 		return -EINVAL;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	spin_lock_irq(&np->lock);
 	rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
 	spin_unlock_irq(&np->lock);
@@ -2754,17 +2635,13 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || netif_running(dev)) {
+	if (tp->ecdev || netif_running(dev)) {
 		spin_lock_irqsave (&tp->lock, flags);
 		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 		RTL_W32 (RxMissed, 0);
 		spin_unlock_irqrestore (&tp->lock, flags);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return &tp->stats;
 }
 
@@ -2840,13 +2717,9 @@
 
 	pci_save_state (pdev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	netif_device_detach (dev);
 
 	spin_lock_irqsave (&tp->lock, flags);
@@ -2870,16 +2743,11 @@
 static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	pci_restore_state (pdev);
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_power_state (pdev, PCI_D0);
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
@@ -2904,69 +2772,20 @@
 
 static int __init rtl8139_init_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
-	printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
-	if (pci_module_init(&rtl8139_pci_driver) < 0) {
-		printk(KERN_ERR "Failed to init PCI module.\n");
-		goto out_return;
-	}
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Registering EtherCAT device...\n");
-		if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
-			rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
-			printk(KERN_ERR "Failed to register EtherCAT device!\n");
-			goto out_pci;
-		}
-
-		printk(KERN_INFO "Opening EtherCAT device...\n");
-		if (ecdev_open(rtl_ec_dev)) {
-			printk(KERN_ERR "Failed to open EtherCAT device!\n");
-			goto out_unregister;
-		}
-
-		printk(KERN_INFO "EtherCAT device ready.\n");
-	} else {
-		printk(KERN_WARNING "No EtherCAT device registered!\n");
-	}
-
-	return 0;
-
-    out_unregister:
-	printk(KERN_INFO "Unregistering EtherCAT device...\n");
-	ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-	rtl_ec_dev = NULL;
-    out_pci:
-	pci_unregister_driver(&rtl8139_pci_driver);
-    out_return:
-	return -1;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	/* when we're a module, we always print a version message,
+	 * even if no 8139 board is found.
+	 */
+#ifdef MODULE
+	printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+	return pci_module_init (&rtl8139_pci_driver);
 }
 
 
 static void __exit rtl8139_cleanup_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Closing EtherCAT device...\n");
-		ecdev_close(rtl_ec_dev);
-		printk(KERN_INFO "Unregistering EtherCAT device...\n");
-		ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-		rtl_ec_dev = NULL;
-	}
-
-	pci_unregister_driver(&rtl8139_pci_driver);
-
-	printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	pci_unregister_driver (&rtl8139_pci_driver);
 }
 
 
--- a/devices/8139too-2.6.19-ethercat.c	Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.19-ethercat.c	Fri Feb 16 17:13:39 2007 +0000
@@ -152,8 +152,6 @@
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #include "../globals.h"
 #include "ecdev.h"
 
@@ -161,8 +159,6 @@
                             " EtherCAT-capable Fast Ethernet driver " \
                             DRV_VERSION ", master " EC_MASTER_VERSION
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #define PFX DRV_NAME ": "
 
 /* Default Message level */
@@ -214,15 +210,6 @@
 /* bitmapped message enable number */
 static int debug = -1;
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /*
  * Receive ring size
  * Warning: 64K ring has hardware issues and may lock up.
@@ -337,13 +324,9 @@
 	{0,}
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 /* prevent driver from being loaded automatically */
 //MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static struct {
 	const char str[ETH_GSTRING_LEN];
 } ethtool_stats_keys[] = {
@@ -665,17 +648,15 @@
 	struct mii_if_info mii;
 	unsigned int regs_len;
 	unsigned long fifo_copy_timeout;
+    
+	ec_device_t *ecdev;
 };
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
 MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(EC_MASTER_VERSION);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
@@ -685,19 +666,8 @@
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
-                 "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
-                 "Index of the EtherCAT master to register the device.");
-
 void ec_poll(struct net_device *);
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
 static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1050,15 +1020,6 @@
 	assert (dev != NULL);
 	tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (board_idx == ec_device_index) {
-		rtl_ec_net_dev = dev;
-		strcpy(dev->name, "ec0");
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	ioaddr = tp->mmio_addr;
 	assert (ioaddr != NULL);
 
@@ -1110,17 +1071,20 @@
 	tp->mii.reg_num_mask = 0x1f;
 
 	/* dev is fully set up and ready to use now */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+    
+	// offer device to EtherCAT master module
+	if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+				ec_poll, THIS_MODULE)) {
+		printk(KERN_ERR PFX "Failed to offer device.\n");
+		goto err_out;
+	}
+
+	if (!tp->ecdev) {
 		DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
 		i = register_netdev (dev);
 		if (i) goto err_out;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_drvdata (pdev, dev);
 
 	printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1193,6 +1157,11 @@
 	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
 		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
 
+	if (tp->ecdev && ecdev_open(tp->ecdev)) {
+		ecdev_withdraw(tp->ecdev);
+		goto err_out;
+	}
+
 	return 0;
 
 err_out:
@@ -1205,17 +1174,18 @@
 static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	assert (dev != NULL);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		ecdev_close(tp->ecdev);
+		ecdev_withdraw(tp->ecdev);
+	}
+	else {
 		unregister_netdev (dev);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	__rtl8139_cleanup_dev (dev);
 	pci_disable_device (pdev);
 }
@@ -1416,29 +1386,19 @@
 	int retval;
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		retval = request_irq(dev->irq, rtl8139_interrupt,
 			IRQF_SHARED, dev->name, dev);
 		if (retval)
 			return retval;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
 					   &tp->tx_bufs_dma);
 	tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
 					   &tp->rx_ring_dma);
 	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
-			free_irq(dev->irq, dev);
-		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+		if (!tp->ecdev) free_irq(dev->irq, dev);
 
 		if (tp->tx_bufs)
 			pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
@@ -1457,9 +1417,7 @@
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		netif_start_queue (dev);
 
 		if (netif_msg_ifup(tp))
@@ -1471,8 +1429,6 @@
 		rtl8139_start_thread(tp);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return 0;
 }
 
@@ -1481,19 +1437,16 @@
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		void __iomem *ioaddr = tp->mmio_addr;
+		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+		ecdev_link_state(tp->ecdev, state ? 1 : 0);
+	}
+	else {
 		if (tp->phys[0] >= 0) {
 			mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
 		}
-	} else {
-		void __iomem *ioaddr = tp->mmio_addr;
-		uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
-		ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 }
 
 /* Start the hardware at open or resume. */
@@ -1558,14 +1511,9 @@
 	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
 		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev)
 		/* Enable all known interrupts by setting the interrupt mask. */
 		RTL_W16 (IntrMask, rtl8139_intr_mask);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 }
 
 
@@ -1813,9 +1761,11 @@
 	if (tmp8 & CmdTxEnb)
 		RTL_W8 (ChipCmd, CmdRxEnb);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		rtl8139_tx_clear (tp);
+		rtl8139_hw_start (dev);
+	}
+	else {
 		spin_lock_bh(&tp->rx_lock);
 		/* Disable interrupts by clearing the interrupt mask. */
 		RTL_W16 (IntrMask, 0x0000);
@@ -1831,27 +1781,19 @@
 			netif_wake_queue (dev);
 		}
 		spin_unlock_bh(&tp->rx_lock);
-	} else {
-		rtl8139_tx_clear (tp);
-		rtl8139_hw_start (dev);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 }
 
 static void rtl8139_tx_timeout (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev && !tp->have_thread) {
+	if (!tp->ecdev && !tp->have_thread) {
 		INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
 		schedule_delayed_work(&tp->thread, next_tick);
 	} else
 		tp->watchdog_fired = 1;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 }
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -1865,27 +1807,28 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = tp->cur_tx % NUM_TX_DESC;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	/* Note: the chip doesn't have auto-pad! */
 	if (likely(len < TX_BUF_SIZE)) {
 		if (len < ETH_ZLEN)
 			memset(tp->tx_buf[entry], 0, ETH_ZLEN);
 		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 	} else {
-		if (dev != rtl_ec_net_dev) {
-			dev_kfree_skb(skb);
-		}
+		if (!tp->ecdev) dev_kfree_skb(skb);
 		tp->stats.tx_dropped++;
 		return 0;
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
+				tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
+
+		dev->trans_start = jiffies;
+
+		tp->cur_tx++;
+		wmb();
+	}
+	else {
 		spin_lock_irqsave(&tp->lock, flags);
 
 		RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
@@ -1904,17 +1847,6 @@
 			printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
 					dev->name, len, entry);
 	}
-	else {
-		RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
-				tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
-
-		dev->trans_start = jiffies;
-
-		tp->cur_tx++;
-		wmb();
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 
 	return 0;
 }
@@ -1973,10 +1905,8 @@
 		tx_left--;
 	}
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 #ifndef RTL8139_NDEBUG
-	if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+	if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
 		printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
 		        dev->name, dirty_tx, tp->cur_tx);
 		dirty_tx += NUM_TX_DESC;
@@ -1987,13 +1917,8 @@
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
 		mb();
-
-		if (dev != rtl_ec_net_dev) {
-			netif_wake_queue (dev);
-		}
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+		if (!tp->ecdev) netif_wake_queue (dev);
+	}
 }
 
 
@@ -2126,14 +2051,9 @@
 		 RTL_R16 (RxBufAddr),
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	while ((dev == rtl_ec_net_dev || netif_running(dev))
+	while ((tp->ecdev || netif_running(dev))
 			&& received < budget
 			&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		u32 ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
 		unsigned int pkt_size;
@@ -2146,17 +2066,12 @@
 		rx_size = rx_status >> 16;
 		pkt_size = rx_size - 4;
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (!tp->ecdev) {
 			if (netif_msg_rx_status(tp))
 				printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
 				       " cur %4.4x.\n", dev->name, rx_status,
 				       rx_size, cur_rx);
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 #if RTL8139_DEBUG > 2
 		{
 			int i;
@@ -2204,9 +2119,14 @@
 			goto out;
 		}
 
-		/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			ecdev_receive(tp->ecdev,
+					&rx_ring[ring_offset + 4], pkt_size);
+			dev->last_rx = jiffies;
+			tp->stats.rx_bytes += pkt_size;
+			tp->stats.rx_packets++;
+		}
+		else {
 			/* Malloc up new buffer, compatible with net-2e. */
 			/* Omit the four octet CRC from the length. */
 
@@ -2231,20 +2151,11 @@
 			} else {
 				if (net_ratelimit())
 					printk(KERN_WARNING
-					       "%s: Memory squeeze, dropping packet.\n",
-					       dev->name);
+							"%s: Memory squeeze, dropping packet.\n",
+							dev->name);
 				tp->stats.rx_dropped++;
 			}
-		} else {
-			ecdev_receive(rtl_ec_dev,
-			              &rx_ring[ring_offset + 4], pkt_size);
-			dev->last_rx = jiffies;
-			tp->stats.rx_bytes += pkt_size;
-			tp->stats.rx_packets++;
 		}
-
-		/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 		received++;
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2350,15 +2261,11 @@
 	return !done;
 }
 
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 void ec_poll(struct net_device *dev)
 {
     rtl8139_interrupt(0, dev);
 }
 
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
 static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
@@ -2370,20 +2277,17 @@
 	int link_changed = 0; /* avoid bogus "uninit" warning */
 	int handled = 0;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		status = RTL_R16 (IntrStatus);
+	}
+	else {
 		spin_lock (&tp->lock);
 		status = RTL_R16 (IntrStatus);
 
 		/* shared irq? */
 		if (unlikely((status & rtl8139_intr_mask) == 0))
 			goto out;
-	} else {
-		status = RTL_R16 (IntrStatus);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	handled = 1;
 
@@ -2391,9 +2295,7 @@
 	if (unlikely(status == 0xFFFF))
 		goto out;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (!tp->ecdev) {
 		/* close possible race's with dev_close */
 		if (unlikely(!netif_running(dev))) {
 			RTL_W16 (IntrMask, 0);
@@ -2401,8 +2303,6 @@
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Acknowledge all of the current interrupt sources ASAP, but
 	   an first get an additional status bit from CSCR. */
 	if (unlikely(status & RxUnderrun))
@@ -2414,24 +2314,20 @@
 
 	/* Receive packets are processed by poll routine.
 	   If not running start it now. */
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
 	if (status & RxAckBits){
-		if (dev != rtl_ec_net_dev) {
+		if (tp->ecdev) {
+			/* EtherCAT device: Just receive all frames */
+			rtl8139_rx(dev, tp, 100); // FIXME
+		}
+		else {
 			/* Mark for polling */
 			if (netif_rx_schedule_prep(dev)) {
 				RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
 				__netif_rx_schedule (dev);
 			}
-		} else {
-			/* EtherCAT device: Just receive all frames */
-			rtl8139_rx(dev, tp, 100); // FIXME
 		}
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	/* Check uncommon events with one test. */
 	if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
 		rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2443,14 +2339,7 @@
 			RTL_W16 (IntrStatus, TxErr);
 	}
  out:
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
-		spin_unlock (&tp->lock);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	if (!tp->ecdev) spin_unlock (&tp->lock);
 
 	DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
 		 dev->name, RTL_R16 (IntrStatus));
@@ -2476,9 +2365,17 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev != rtl_ec_net_dev) {
+	if (tp->ecdev) {
+		/* Stop the chip's Tx and Rx DMA processes. */
+		RTL_W8 (ChipCmd, 0);
+
+		/* Disable interrupts by clearing the interrupt mask. */
+		RTL_W16 (IntrMask, 0);
+
+		/* Update the error counts. */
+		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+		RTL_W32 (RxMissed, 0);
+	} else {
 		netif_stop_queue (dev);
 
 		rtl8139_stop_thread(tp);
@@ -2503,19 +2400,7 @@
 
 		synchronize_irq (dev->irq);	/* racy, but that's ok here */
 		free_irq (dev->irq, dev);
-	} else {
-		/* Stop the chip's Tx and Rx DMA processes. */
-		RTL_W8 (ChipCmd, 0);
-
-		/* Disable interrupts by clearing the interrupt mask. */
-		RTL_W16 (IntrMask, 0);
-
-		/* Update the error counts. */
-		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
-		RTL_W32 (RxMissed, 0);
-	}
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	}
 
 	rtl8139_tx_clear (tp);
 
@@ -2731,13 +2616,9 @@
 	struct rtl8139_private *np = netdev_priv(dev);
 	int rc;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running(dev))
+	if (np->ecdev || !netif_running(dev))
 		return -EINVAL;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	spin_lock_irq(&np->lock);
 	rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
 	spin_unlock_irq(&np->lock);
@@ -2752,17 +2633,13 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || netif_running(dev)) {
+	if (tp->ecdev || netif_running(dev)) {
 		spin_lock_irqsave (&tp->lock, flags);
 		tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 		RTL_W32 (RxMissed, 0);
 		spin_unlock_irqrestore (&tp->lock, flags);
 	}
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	return &tp->stats;
 }
 
@@ -2835,13 +2712,9 @@
 
 	pci_save_state (pdev);
 
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
 
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	netif_device_detach (dev);
 
 	spin_lock_irqsave (&tp->lock, flags);
@@ -2865,16 +2738,11 @@
 static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	pci_restore_state (pdev);
-
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	if (dev == rtl_ec_net_dev || !netif_running (dev))
+	if (tp->ecdev || !netif_running (dev))
 		return 0;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
 	pci_set_power_state (pdev, PCI_D0);
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
@@ -2899,69 +2767,20 @@
 
 static int __init rtl8139_init_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
-	printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
-	if (pci_register_driver(&rtl8139_pci_driver) < 0) {
-		printk(KERN_ERR "Failed to init PCI module.\n");
-		goto out_return;
-	}
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Registering EtherCAT device...\n");
-		if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
-			rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
-			printk(KERN_ERR "Failed to register EtherCAT device!\n");
-			goto out_pci;
-		}
-
-		printk(KERN_INFO "Opening EtherCAT device...\n");
-		if (ecdev_open(rtl_ec_dev)) {
-			printk(KERN_ERR "Failed to open EtherCAT device!\n");
-			goto out_unregister;
-		}
-
-		printk(KERN_INFO "EtherCAT device ready.\n");
-	} else {
-		printk(KERN_WARNING "No EtherCAT device registered!\n");
-	}
-
-	return 0;
-
-    out_unregister:
-	printk(KERN_INFO "Unregistering EtherCAT device...\n");
-	ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-	rtl_ec_dev = NULL;
-    out_pci:
-	pci_unregister_driver(&rtl8139_pci_driver);
-    out_return:
-	return -1;
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	/* when we're a module, we always print a version message,
+	 * even if no 8139 board is found.
+	 */
+#ifdef MODULE
+	printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+	return pci_register_driver(&rtl8139_pci_driver);
 }
 
 
 static void __exit rtl8139_cleanup_module (void)
 {
-	/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-	printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
-	if (rtl_ec_net_dev) {
-		printk(KERN_INFO "Closing EtherCAT device...\n");
-		ecdev_close(rtl_ec_dev);
-		printk(KERN_INFO "Unregistering EtherCAT device...\n");
-		ecdev_unregister(ec_device_master_index, rtl_ec_dev);
-		rtl_ec_dev = NULL;
-	}
-
-	pci_unregister_driver(&rtl8139_pci_driver);
-
-	printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
-	/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+	pci_unregister_driver (&rtl8139_pci_driver);
 }
 
 
--- a/devices/ecdev.h	Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/ecdev.h	Fri Feb 16 17:13:39 2007 +0000
@@ -64,12 +64,12 @@
 typedef void (*ec_pollfunc_t)(struct net_device *);
 
 /*****************************************************************************/
-// Registration functions
+// Offering/withdrawal functions
 
-ec_device_t *ecdev_register(unsigned int master_index,
-                            struct net_device *net_dev, ec_pollfunc_t poll,
-                            struct module *module);
-void ecdev_unregister(unsigned int master_index, ec_device_t *device);
+int ecdev_offer(struct net_device *net_dev, ec_device_t **,
+        const char *driver_name, unsigned int board_index,
+        ec_pollfunc_t poll, struct module *module);
+void ecdev_withdraw(ec_device_t *device);
 
 /*****************************************************************************/
 // Device methods
--- a/master/device.h	Fri Feb 16 13:30:46 2007 +0000
+++ b/master/device.h	Fri Feb 16 17:13:39 2007 +0000
@@ -53,6 +53,21 @@
 
 /*****************************************************************************/
 
+typedef enum {
+    ec_device_id_empty,
+    ec_device_id_mac
+}
+ec_device_id_type_t;
+
+typedef struct {
+    struct list_head list;
+    ec_device_id_type_t type;
+    unsigned char octets[ETH_ALEN];
+}
+ec_device_id_t;
+
+/*****************************************************************************/
+
 /**
    EtherCAT device.
    An EtherCAT device is a network interface card, that is owned by an
--- a/master/master.c	Fri Feb 16 13:30:46 2007 +0000
+++ b/master/master.c	Fri Feb 16 17:13:39 2007 +0000
@@ -102,18 +102,20 @@
 
 int ec_master_init(ec_master_t *master, /**< EtherCAT master */
                    unsigned int index, /**< master index */
+                   const ec_device_id_t *main_id, /**< ID of main device */
+                   const ec_device_id_t *backup_id, /**< ID of main device */
                    unsigned int eoeif_count /**< number of EoE interfaces */
                    )
 {
     ec_eoe_t *eoe, *next_eoe;
     unsigned int i;
 
-    EC_INFO("Initializing master %i.\n", index);
-
     atomic_set(&master->available, 1);
     master->index = index;
 
     master->device = NULL;
+    master->main_device_id = main_id;
+    master->backup_device_id = backup_id;
     init_MUTEX(&master->device_sem);
 
     master->mode = EC_MASTER_MODE_ORPHANED;
--- a/master/master.h	Fri Feb 16 13:30:46 2007 +0000
+++ b/master/master.h	Fri Feb 16 17:13:39 2007 +0000
@@ -99,6 +99,8 @@
     struct kobject kobj; /**< kobject */
 
     ec_device_t *device; /**< EtherCAT device */
+    const ec_device_id_t *main_device_id; /**< ID of main device */
+    const ec_device_id_t *backup_device_id; /**< ID of backup device */
     struct semaphore device_sem; /**< device semaphore */
 
     ec_fsm_master_t fsm; /**< master state machine */
@@ -147,7 +149,8 @@
 /*****************************************************************************/
 
 // master creation/deletion
-int ec_master_init(ec_master_t *, unsigned int, unsigned int);
+int ec_master_init(ec_master_t *, unsigned int,
+        const ec_device_id_t *, const ec_device_id_t *, unsigned int);
 void ec_master_destroy(ec_master_t *);
 
 // mode transitions
--- a/master/module.c	Fri Feb 16 13:30:46 2007 +0000
+++ b/master/module.c	Fri Feb 16 17:13:39 2007 +0000
@@ -54,8 +54,12 @@
 
 /*****************************************************************************/
 
-static int ec_master_count = 1; /**< parameter value, number of masters */
-static struct list_head ec_masters; /**< list of masters */
+static char *main; /**< main devices parameter */
+static char *backup; /**< backup devices parameter */
+
+static LIST_HEAD(main_device_ids); /**< list of main device IDs */
+static LIST_HEAD(backup_device_ids); /**< list of main device IDs */
+static LIST_HEAD(masters); /**< list of masters */
 static dev_t device_number; /**< XML character device number */
 ec_xmldev_t xmldev; /**< XML character device */
 
@@ -65,18 +69,171 @@
 
 /** \cond */
 
-module_param(ec_master_count, int, S_IRUGO);
-
 MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
 MODULE_DESCRIPTION("EtherCAT master driver module");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(EC_MASTER_VERSION);
-MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize");
+
+module_param(main, charp, S_IRUGO);
+MODULE_PARM_DESC(main, "main device IDs");
+module_param(backup, charp, S_IRUGO);
+MODULE_PARM_DESC(backup, "backup device IDs");
 
 /** \endcond */
 
 /*****************************************************************************/
 
+void clear_device_ids(struct list_head *device_ids)
+{
+    ec_device_id_t *dev_id, *next_dev_id;
+    
+    list_for_each_entry_safe(dev_id, next_dev_id, device_ids, list) {
+        list_del(&dev_id->list);
+        kfree(dev_id);
+    }
+}
+
+/*****************************************************************************/
+
+static int parse_device_id_mac(ec_device_id_t *dev_id,
+        const char *src, const char **remainder)
+{
+    unsigned int i, value;
+    char *rem;
+
+    for (i = 0; i < ETH_ALEN; i++) {
+        value = simple_strtoul(src, &rem, 16);
+        if (rem != src + 2
+                || value > 0xFF
+                || (i < ETH_ALEN - 1 && *rem != ':')) {
+            return -1;
+        }
+        dev_id->octets[i] = value;
+        if (i < ETH_ALEN - 1)
+            src = rem + 1;
+    }
+
+    dev_id->type = ec_device_id_mac;
+    *remainder = rem;
+    return 0;
+}
+
+/*****************************************************************************/
+
+static int parse_device_ids(struct list_head *device_ids, const char *src)
+{
+    const char *rem;
+    ec_device_id_t *dev_id;
+    unsigned int index = 0;
+
+    while (*src) {
+        // allocate new device ID
+        if (!(dev_id = kmalloc(sizeof(ec_device_id_t), GFP_KERNEL))) {
+            EC_ERR("Out of memory!\n");
+            goto out_free;
+        }
+        
+        if (*src == ';') { // empty device ID
+            dev_id->type = ec_device_id_empty;
+        }
+        else if (*src == 'M') {
+            src++;
+            if (parse_device_id_mac(dev_id, src, &rem)) {
+                EC_ERR("Device ID %u: Invalid MAC syntax!\n", index);
+                kfree(dev_id);
+                goto out_free;
+            }
+            src = rem;
+        }
+        else {
+            EC_ERR("Device ID %u: Unknown format \'%c\'!\n", index, *src);
+            kfree(dev_id);
+            goto out_free;
+        }
+        
+        list_add_tail(&dev_id->list, device_ids); 
+        if (*src) {
+            if (*src != ';') {
+                EC_ERR("Invalid delimiter '%c' after device ID %i!\n",
+                        *src, index);
+                goto out_free;
+            }
+            src++; // skip delimiter
+        }
+        index++;
+    }
+
+    return 0;
+
+out_free:
+    clear_device_ids(device_ids);
+    return -1;
+}
+
+/*****************************************************************************/
+
+static int create_device_ids(void)
+{
+    ec_device_id_t *id;
+    unsigned int main_count = 0, backup_count = 0;
+    
+    if (parse_device_ids(&main_device_ids, main))
+        return -1;
+
+    if (parse_device_ids(&backup_device_ids, main))
+        return -1;
+
+    // count main device IDs and check for empty ones
+    list_for_each_entry(id, &main_device_ids, list) {
+        if (id->type == ec_device_id_empty) {
+            EC_ERR("Main device IDs may not be empty!\n");
+            return -1;
+        }
+        main_count++;
+    }
+
+    // count backup device IDs
+    list_for_each_entry(id, &backup_device_ids, list) {
+        backup_count++;
+    }
+
+    // fill up backup device IDs
+    while (backup_count < main_count) {
+        if (!(id = kmalloc(sizeof(ec_device_id_t), GFP_KERNEL))) {
+            EC_ERR("Out of memory!\n");
+            return -1;
+        }
+        
+        id->type = ec_device_id_empty;
+        list_add_tail(&id->list, &backup_device_ids);
+        backup_count++;
+    }
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+static int device_id_check(const ec_device_id_t *dev_id,
+        const struct net_device *dev, const char *driver_name,
+        unsigned int device_index)
+{
+    unsigned int i;
+    
+    switch (dev_id->type) {
+        case ec_device_id_mac:
+            for (i = 0; i < ETH_ALEN; i++)
+                if (dev->dev_addr[i] != dev_id->octets[i])
+                    return 0;
+            return 1;
+        default:
+            return 0;
+    }
+}
+                
+
+/*****************************************************************************/
+
 /**
    Module initialization.
    Initializes \a ec_master_count masters.
@@ -85,48 +242,68 @@
 
 int __init ec_init_module(void)
 {
-    unsigned int i;
     ec_master_t *master, *next;
+    ec_device_id_t *main_dev_id, *backup_dev_id;
+    unsigned int master_index = 0;
 
     EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
 
-    if (ec_master_count < 1) {
-        EC_ERR("Invalid ec_master_count: %i\n", ec_master_count);
+    if (alloc_chrdev_region(&device_number, 0, 1, "EtherCAT")) {
+        EC_ERR("Failed to obtain device number!\n");
         goto out_return;
     }
 
-    if (alloc_chrdev_region(&device_number, 0, ec_master_count, "EtherCAT")) {
-        EC_ERR("Failed to allocate device number!\n");
-        goto out_return;
-    }
-
-    EC_INFO("Initializing %i EtherCAT master(s)...\n", ec_master_count);
-
-    INIT_LIST_HEAD(&ec_masters);
-
-    for (i = 0; i < ec_master_count; i++) {
-        if (!(master =
-              (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
-            EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i);
-            goto out_free;
-        }
-
-        if (ec_master_init(master, i, 0))
-            goto out_free;
-
-        list_add_tail(&master->list, &ec_masters);
-    }
-
-    EC_INFO("Master driver initialized.\n");
+    if (create_device_ids())
+        goto out_free_ids;
+    
+    if (!list_empty(&main_device_ids)) {
+        main_dev_id =
+            list_entry(main_device_ids.next, ec_device_id_t, list);
+        backup_dev_id =
+            list_entry(backup_device_ids.next, ec_device_id_t, list);
+        
+        while (1) {
+            if (!(master = (ec_master_t *)
+                        kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
+                EC_ERR("Failed to allocate memory for EtherCAT master %i.\n",
+                        master_index);
+                goto out_free_masters;
+            }
+
+            if (ec_master_init(master, master_index,
+                        main_dev_id, backup_dev_id, 0))
+                goto out_free_masters;
+
+            list_add_tail(&master->list, &masters);
+            master_index++;
+
+            // last device IDs?
+            if (main_dev_id->list.next == &main_device_ids)
+                break;
+            
+            // next device IDs
+            main_dev_id =
+                list_entry(main_dev_id->list.next, ec_device_id_t, list);
+            backup_dev_id =
+                list_entry(backup_dev_id->list.next, ec_device_id_t, list);
+        }
+    }
+    
+    EC_INFO("%u master%s waiting for devices.\n",
+            master_index, (master_index == 1 ? "" : "s"));
     return 0;
 
- out_free:
-    list_for_each_entry_safe(master, next, &ec_masters, list) {
+out_free_masters:
+    list_for_each_entry_safe(master, next, &masters, list) {
         list_del(&master->list);
         kobject_del(&master->kobj);
         kobject_put(&master->kobj);
     }
- out_return:
+out_free_ids:
+    clear_device_ids(&main_device_ids);
+    clear_device_ids(&backup_device_ids);
+    unregister_chrdev_region(device_number, 1);
+out_return:
     return -1;
 }
 
@@ -143,12 +320,12 @@
 
     EC_INFO("Cleaning up master driver...\n");
 
-    list_for_each_entry_safe(master, next, &ec_masters, list) {
+    list_for_each_entry_safe(master, next, &masters, list) {
         list_del(&master->list);
         ec_master_destroy(master);
     }
 
-    unregister_chrdev_region(device_number, ec_master_count);
+    unregister_chrdev_region(device_number, 1);
 
     EC_INFO("Master driver cleaned up.\n");
 }
@@ -164,7 +341,7 @@
 {
     ec_master_t *master;
 
-    list_for_each_entry(master, &ec_masters, list) {
+    list_for_each_entry(master, &masters, list) {
         if (master->index == master_index) return master;
     }
 
@@ -270,48 +447,71 @@
  *****************************************************************************/
 
 /**
-   Connects an EtherCAT device to a certain master.
-   The master will use the device for sending and receiving frames. It is
-   required that no other instance (for example the kernel IP stack) uses
-   the device.
+   Offers an EtherCAT device to a certain master.
+   The master decides, if it wants to use the device for EtherCAT operation,
+   or not. It is important, that the offered net_device is not used by
+   the kernel IP stack. If the master, accepted the offer, the address of
+   the newly created EtherCAT device is written to the ecdev pointer, else
+   the pointer is written to zero.
    \return 0 on success, else < 0
    \ingroup DeviceInterface
 */
 
-ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
-                            struct net_device *net_dev, /**< net_device of
-                                                           the device */
-                            ec_pollfunc_t poll, /**< device poll function */
-                            struct module *module /**< pointer to the module */
-                            )
+int ecdev_offer(struct net_device *net_dev, /**< net_device to offer */
+        ec_device_t **ecdev, /**< pointer to store a device on success */
+        const char *driver_name, /**< name of the network driver */
+        unsigned int device_index, /**< index of the supported device */
+        ec_pollfunc_t poll, /**< device poll function */
+        struct module *module /**< pointer to the module */
+        )
 {
     ec_master_t *master;
-
-    if (!(master = ec_find_master(master_index))) return NULL;
-
-    if (down_interruptible(&master->device_sem)) {
-        EC_ERR("Interrupted while waiting for device!\n");
-        goto out_return;
-    }
-
-    if (master->device) {
-        EC_ERR("Master %i already has a device!\n", master_index);
-        goto out_up;
-    }
-
-    if (!(master->device =
-          (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
-        EC_ERR("Failed to allocate device!\n");
-        goto out_up;
-    }
-
-    if (ec_device_init(master->device, master, net_dev, poll, module)) {
-        EC_ERR("Failed to init device!\n");
-        goto out_free;
-    }
-
-    up(&master->device_sem);
-    return master->device;
+    unsigned int i;
+
+    list_for_each_entry(master, &masters, list) {
+        if (down_interruptible(&master->device_sem)) {
+            EC_ERR("Interrupted while waiting for device semaphore!\n");
+            goto out_return;
+        }
+
+        if (device_id_check(master->main_device_id, net_dev,
+                    driver_name, device_index)) {
+
+            EC_INFO("Accepting device %s:%u (", driver_name, device_index);
+            for (i = 0; i < ETH_ALEN; i++) {
+                printk("%02X", net_dev->dev_addr[i]);
+                if (i < ETH_ALEN - 1) printk(":");
+            }
+            printk(") for master %u.\n", master->index);
+
+            if (master->device) {
+                EC_ERR("Master already has a device.\n");
+                goto out_up;
+            }
+            
+            if (!(master->device = (ec_device_t *)
+                        kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
+                EC_ERR("Failed to allocate device!\n");
+                goto out_up;
+            }
+
+            if (ec_device_init(master->device, master,
+                        net_dev, poll, module)) {
+                EC_ERR("Failed to init device!\n");
+                goto out_free;
+            }
+
+            up(&master->device_sem);
+            sprintf(net_dev->name, "ec%u", master->index);
+            *ecdev = master->device; // offer accepted
+            return 0; // no error
+        }
+
+        up(&master->device_sem);
+    }
+
+    *ecdev = NULL; // offer declined
+    return 0; // no error
 
  out_free:
     kfree(master->device);
@@ -319,13 +519,13 @@
  out_up:
     up(&master->device_sem);
  out_return:
-    return NULL;
-}
-
-/*****************************************************************************/
-
-/**
-   Disconnect an EtherCAT device from the master.
+    return 1;
+}
+
+/*****************************************************************************/
+
+/**
+   Withdraws an EtherCAT device from the master.
    The device is disconnected from the master and all device ressources
    are freed.
    \attention Before calling this function, the ecdev_stop() function has
@@ -333,26 +533,24 @@
    \ingroup DeviceInterface
 */
 
-void ecdev_unregister(unsigned int master_index, /**< master index */
-                      ec_device_t *device /**< EtherCAT device */
-                      )
-{
-    ec_master_t *master;
-
-    if (!(master = ec_find_master(master_index))) return;
+void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
+{
+    ec_master_t *master = device->master;
+    unsigned int i;
 
     down(&master->device_sem);
-
-    if (!master->device || master->device != device) {
-        up(&master->device_sem);
-        EC_WARN("Unable to unregister device!\n");
-        return;
-    }
-
+    
+    EC_INFO("Master %u releasing device ", master->index);
+    for (i = 0; i < ETH_ALEN; i++) {
+        printk("%02X", device->dev->dev_addr[i]);
+        if (i < ETH_ALEN - 1) printk(":");
+    }
+    printk(".\n");
+    
     ec_device_clear(master->device);
     kfree(master->device);
     master->device = NULL;
-
+    
     up(&master->device_sem);
 }
 
@@ -505,8 +703,8 @@
 module_init(ec_init_module);
 module_exit(ec_cleanup_module);
 
-EXPORT_SYMBOL(ecdev_register);
-EXPORT_SYMBOL(ecdev_unregister);
+EXPORT_SYMBOL(ecdev_offer);
+EXPORT_SYMBOL(ecdev_withdraw);
 EXPORT_SYMBOL(ecdev_open);
 EXPORT_SYMBOL(ecdev_close);
 EXPORT_SYMBOL(ecrt_request_master);
--- a/script/init.d/ethercat	Fri Feb 16 13:30:46 2007 +0000
+++ b/script/init.d/ethercat	Fri Feb 16 17:13:39 2007 +0000
@@ -49,100 +49,39 @@
 
 #------------------------------------------------------------------------------
 
-device="ecxml"
-
-IFCONFIG=ifconfig
-BRCTL=brctl
-ROUTE=route
+XMLDEVICE='ecxml'
 
 #------------------------------------------------------------------------------
 
 ETHERCAT_CONFIG=/etc/sysconfig/ethercat
 
-if [ ! -r $ETHERCAT_CONFIG ]; then
-    echo "$ETHERCAT_CONFIG not existing";
-    if [ "$1" = "stop" ]; then
+if [ ! -r ${ETHERCAT_CONFIG} ]; then
+    echo "${ETHERCAT_CONFIG} not existing";
+    if [ "${1}" = "stop" ]; then
 	exit 0
     else
 	exit 6
     fi
 fi
 
-. $ETHERCAT_CONFIG
-
-#------------------------------------------------------------------------------
-
-#
-#  Function for setting up the EoE bridge
-#
-build_eoe_bridge()
+. ${ETHERCAT_CONFIG}
+
+#------------------------------------------------------------------------------
+
+function make_device_id()
 {
-    if [ -z "$EOE_BRIDGE" ]; then return; fi
-
-    EOEIF=`$IFCONFIG -a | grep -o -E "^eoe[0-9]+ "`
-
-    # add bridge, if it does not already exist
-    if ! $BRCTL show | grep -E -q "^$EOE_BRIDGE"; then
-        if ! $BRCTL addbr $EOE_BRIDGE; then
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-    fi
-
-    # check if specified interfaces are bridged
-    for interf in $EOEIF $EOE_EXTRA_INTERFACES; do
-	# interface is already part of the bridge (FIXME->show $EOE_BRIDGE)
-	if $BRCTL show | grep -E -q $interf
-	    then continue
-	fi
-	# clear IP address and open interface
-	if ! $IFCONFIG $interf 0.0.0.0 up; then
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-	# add interface to the bridge
-	if ! $BRCTL addif $EOE_BRIDGE $interf; then
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-    done
-
-    # configure IP on bridge
-    if [ -n "$EOE_IP_ADDRESS" -a -n "$EOE_IP_NETMASK" ]; then
-	if ! $IFCONFIG $EOE_BRIDGE $EOE_IP_ADDRESS \
-	    netmask $EOE_IP_NETMASK; then
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-    fi
-
-    # open bridge
-    if ! $IFCONFIG $EOE_BRIDGE up; then
-	/bin/false
-	rc_status -v
-	rc_exit
-    fi
-
-    # install new default gateway
-    if [ -n "$EOE_GATEWAY" ]; then
-	while $ROUTE -n | grep -E -q "^0.0.0.0"; do
-	    if ! $ROUTE del default; then
-		echo "Failed to remove route!" 1>&2
-		/bin/false
-		rc_status -v
-		rc_exit
-	    fi
-	done
-	if ! $ROUTE add default gw $EOE_GATEWAY; then
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-    fi
+    if [ -z "${1}" ]; then
+        DEVICE_ID=";"
+    elif echo ${1} | grep -qE '^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$'; then
+        DEVICE_ID="M${1};"
+    elif echo ${1} | grep -qE '^[^:]+:[0-9]+$'; then
+        DEVICE_ID="D${1};"
+    else
+        echo Invalid device ID syntax in ${ETHERCAT_CONFIG}
+        /bin/false
+        rc_status -v
+        rc_exit
+    fi 
 }
 
 #------------------------------------------------------------------------------
@@ -150,127 +89,119 @@
 . /etc/rc.status
 rc_reset
 
-case "$1" in
-
-    start)
-	echo -n "Starting EtherCAT master "
-
-	if [ -z "$DEVICE_INDEX" ]; then
-	    echo "ERROR: DEVICE_INDEX not set!"
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-
-	if [ -z "$EOE_INTERFACES" ]; then
-            # support legacy sysconfig files
-	    if [ -n "$EOE_DEVICES" ]; then
-		EOE_INTERFACES=$EOE_DEVICES
-	    else
-		EOE_INTERFACES=0
-	    fi
-	fi
-
-        # unload conflicting modules at first
-	for mod in 8139too; do
-	    if lsmod | grep "^$mod " > /dev/null; then
-		if ! rmmod $mod; then
-		    /bin/false
-		    rc_status -v
-		    rc_exit
-		fi
-	    fi
-	done
-
-        # load master module
-	if ! modprobe ec_master ec_eoeif_count=$EOE_INTERFACES; then
-	    modprobe 8139too
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-
-	# remove stale device node
-	rm -f /dev/${device}0
-
-	# get dynamic major number
-	major=$(awk "\$2==\"EtherCAT\" {print \$1}" /proc/devices)
-
-	# create character device
-	mknod /dev/${device}0 c $major 0
-
-	# load device module
-	if ! modprobe ec_8139too ec_device_index=$DEVICE_INDEX; then
-	    rmmod ec_master
-	    modprobe 8139too
-	    /bin/false
-	    rc_status -v
-	    rc_exit
-	fi
-
-	# build EoE bridge
-	build_eoe_bridge
-
-	rc_status -v
-	;;
-
-    stop)
-	echo -n "Shutting down EtherCAT master "
-
-	# unload modules
-	for mod in ec_8139too ec_master; do
-	    if lsmod | grep "^$mod " > /dev/null; then
-		if ! rmmod $mod; then
-		    /bin/false
-		    rc_status -v
-		    rc_exit
-		fi;
-	    fi;
-	done
-
-	# remove device node
-	rm -f /dev/${device}0
-
-	sleep 1
-
-	# reload previous modules
-	if ! modprobe 8139too; then
-	    echo "Warning: Failed to restore 8139too module."
-	fi
-
-	rc_status -v
-	;;
-
-    restart)
-	$0 stop || exit 1
-	sleep 1
-	$0 start
-	rc_status
-	;;
-
-    status)
-	echo -n "Checking for EtherCAT "
-
-	lsmod | grep "^ec_master " > /dev/null
-	master_running=$?
-	lsmod | grep "^ec_8139too " > /dev/null
-	device_running=$?
-
-	# master module and device module loaded?
-	test $master_running -eq 0 -a $device_running -eq 0
-
-	rc_status -v
-	;;
-
-    bridge)
-	echo -n "Building EoE bridge "
-	build_eoe_bridge
-	rc_status -v
-	;;
-
-    *)
-	echo "USAGE: $0 {start|stop|restart|status|bridge}"
-	;;
+case "${1}" in
+
+start)
+    echo -n "Starting EtherCAT master "
+
+    # construct DEVICES and BACKUPS from configuration variables
+    DEVICES=""
+    BACKUPS=""
+    MASTER_INDEX=0
+    while true; do
+        DEVICE=$(eval echo "\${MASTER${MASTER_INDEX}_DEVICE}")
+        BACKUP=$(eval echo "\${MASTER${MASTER_INDEX}_BACKUP}")
+        if [ -z "${DEVICE}" ]; then break; fi
+
+        make_device_id ${DEVICE}
+        DEVICES=${DEVICES}${DEVICE_ID}
+        make_device_id ${BACKUP}
+        BACKUPS=${BACKUPS}${DEVICE_ID}
+
+        MASTER_INDEX=$(expr ${MASTER_INDEX} + 1)
+    done
+
+    # unload conflicting modules at first
+    for MODULE in 8139too; do
+        if lsmod | grep "^${MODULE} " > /dev/null; then
+            if ! rmmod ${MODULE}; then
+                /bin/false
+                rc_status -v
+                rc_exit
+            fi
+        fi
+    done
+
+    # load master module
+    if ! modprobe ec_master main=${DEVICES} backup=${BACKUPS}; then
+        modprobe 8139too
+        /bin/false
+        rc_status -v
+        rc_exit
+    fi
+
+    # remove stale device node
+    rm -f /dev/${XMLDEVICE}0
+
+    # get dynamic major number
+    MAJOR=$(awk "\$2==\"EtherCAT\" {print \$1}" /proc/devices)
+
+    # create character device
+    mknod /dev/${XMLDEVICE}0 c ${MAJOR} 0
+
+    # load device module
+    if ! modprobe ec_8139too; then
+        rmmod ec_master
+        modprobe 8139too
+        /bin/false
+        rc_status -v
+        rc_exit
+    fi
+
+    rc_status -v
+    ;;
+
+stop)
+    echo -n "Shutting down EtherCAT master "
+
+    # unload modules
+    for mod in ec_8139too ec_master; do
+        if lsmod | grep "^$mod " > /dev/null; then
+            if ! rmmod $mod; then
+                /bin/false
+                rc_status -v
+                rc_exit
+            fi;
+        fi;
+    done
+
+    # remove device node
+    rm -f /dev/${XMLDEVICE}0
+
+    sleep 1
+
+    # reload previous modules
+    if ! modprobe 8139too; then
+        echo "Warning: Failed to restore 8139too module."
+    fi
+
+    rc_status -v
+    ;;
+
+restart)
+    $0 stop || exit 1
+    sleep 1
+    $0 start
+    rc_status
+    ;;
+
+status)
+    echo -n "Checking for EtherCAT "
+
+    lsmod | grep "^ec_master " > /dev/null
+    master_running=$?
+    lsmod | grep "^ec_8139too " > /dev/null
+    device_running=$?
+
+    # master module and device module loaded?
+    test $master_running -eq 0 -a $device_running -eq 0
+
+    rc_status -v
+    ;;
+
+*)
+    echo "USAGE: $0 {start|stop|restart|status}"
+    ;;
 
 esac
 
--- a/script/sysconfig/ethercat	Fri Feb 16 13:30:46 2007 +0000
+++ b/script/sysconfig/ethercat	Fri Feb 16 17:13:39 2007 +0000
@@ -1,58 +1,32 @@
 #------------------------------------------------------------------------------
 #
-#  EtherCAT sysconfig file
+#  EtherCAT master sysconfig file
 #
 #  $Id$
 #
 #------------------------------------------------------------------------------
 
 #
-#  PCI index of the (RTL8139-)EtherCAT device
-#  Setting this is mandatory for the EtherCAT init script!
+# Master device and backup-device settings.
 #
-#DEVICE_INDEX=99
-
+# The MASTERX_DEVICE variable specifies the ethernet device for master 'X',
+# while the MASTERX_BACKUP variable specifies the backup ethernet device for
+# redundancy purposes.
 #
-#  Number of Ethernet-over-EtherCAT interfaces every master shall create
-#  on startup. Default is 0.
+# There are three formats for specifying ethernet devices:
+# 1) MAC address (example: "00:00:08:44:55:66"). Specify the MAC address of
+#    the ethernet card to use.
+# 2) PCI bus address (example: "01:1c.0"). Specify the PCU bis address of the
+#    ethernet card to use.
+# 3) Driver and device index (example: "8139too:0"). Currently there are two
+#    drivers available: "8139too" and "e100". The device index is the index
+#    into driver-supported PCI cards.
 #
-#EOE_INTERFACES=0
-
+# The MASTERX_DEVICE variables also determine, how many masters will be
+# created: A non-empty variable MASTER0_DEVICE will create one master, adding
+# a non-empty variable MASTER1_DEVICE will create a second master, and so on.
 #
-#  Bridge all EoE interfaces after master startup
-#  This variable shall contain the name of the EoE bridge to set up.
-#  If the variable is empty or undefined, no EoE bridge will be built.
-#
-#EOE_BRIDGE=eoebr0
-
-#
-#  IP address of the EoE bridge
-#  Set both EOE_IP_ADDRESS and EOE_IP_NETMASK to let the local host communicate
-#  with devices on the EoE bridge.
-#
-#EOE_IP_ADDRESS=192.168.X.X
-
-#
-#  IP netmask of the EoE bridge
-#  See EOE_IP_ADDRESS.
-#
-#EOE_IP_NETMASK=255.255.255.0
-
-#
-#  Renew default gateway after bridge installation.
-#  Set this to the new default gateway, if the default route shall
-#  be renewed after the bridge has been installed.
-#
-#EOE_GATEWAY=192.168.X.X
-
-#
-#  List of extra interfaces to include in the EoE bridge.
-#  Set this to interconnect the EoE bridge with other local interfaces.
-#  If EOE_BRIDGE is empty or undefined, setting this variable has no effect.
-#  Important: The IP address of these interfaces will be cleared. Set
-#  EOE_IP_ADDRESS and EOE_IP_NETMASK accordingly to enable IP traffic to
-#  extra interfaces.
-#
-#EOE_EXTRA_INTERFACES=eth0
+MASTER0_DEVICE=
+MASTER0_BACKUP=
 
 #------------------------------------------------------------------------------