[etherlab-dev] Generic driver for kernel 2.6.16
Oliver Schweikert
oliver.schweikert at horiba.com
Thu Nov 18 13:53:20 CET 2010
Hello,
I wanted to test the ethercat master with a unsupported hardware and software combination:
Broadcom controller, bnx2 driver with SLES10, kernel 2.6.16.
To use the generic driver I had to make some modifications, which are appended to this message.
It is not heavy tested and not even gracefull, but principally it works.
It compiles with a 2.6.32 kernel, too.
Maybe it is useful for anybody else...
BTW: I had to bring up the used ethernet interface, manually. Is there a way to do this automatically
in the generic driver?
Regards,
Oliver
--
Oliver Schweikert
Software Development
HORIBA Europe Automation Division GmbH
Zabergäustr. 3
73765 Neuhausen (Germany)
Tel: +49 7158-933-413
Fax: +49 7158-933-613
Email: oliver.schweikert at horiba.com
Geschäftsführer: Thomas E. Ehmann, Yuichi Muroga, Takashi Nagano
Amtsgericht Stuttgart, HRB 213200
diff -r e9f722488fcd devices/generic.c
--- a/devices/generic.c Mon Oct 25 17:06:45 2010 +0200
+++ b/devices/generic.c Thu Nov 18 13:35:37 2010 +0100
@@ -64,6 +64,53 @@
MODULE_VERSION(EC_MASTER_VERSION);
/** \endcond */
+/** Don't know when kernel_bind and for_each_netdev were introduced,
+ * but they're contained in 2.6.25 and are missing in 2.6.17
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
+
+#include <linux/notifier.h>
+#define kernel_bind(sock, addr, addrlen) \
+ sock->ops->bind(sock, addr, addrlen)
+
+/** Emulation of the for_each_netdev macro.
+ * Register for net device events, which will result in a reply of
+ * all recent events of all devices. Store all devices in a list, so
+ * we can loop over all in the for_each_netdev macro.
+ */
+#define MAX_NETDEVICES (1<<8)
+struct net_device * all_netdevices[MAX_NETDEVICES+1];
+
+static int add_netdev(struct notifier_block *self, unsigned long event, void *dev) {
+ static int idx = 0;
+ static int overflow = 0;
+ if(event == NETDEV_REGISTER && overflow == 0) {
+ if(idx == MAX_NETDEVICES) {
+ printk("Maximum number of devices exceeded!");
+ overflow = 1;
+ }
+ else {
+ all_netdevices[idx++] = (struct net_device*)dev;
+ }
+ }
+ return 0;
+}
+
+#define for_each_netdev(net, d) \
+ struct net_device ** ptr; \
+ do { \
+ struct notifier_block nb = { notifier_call : add_netdev, next: 0, priority: 0 }; \
+ int err;\
+ memset(all_netdevices, 0 , sizeof(all_netdevices)); \
+ if((err = register_netdevice_notifier(&nb)) != 0) \
+ printk("Could not get list of net devices: register_netdevice_notifier returned %d\n", err); \
+ else { /* here, we know all net devices */ \
+ unregister_netdevice_notifier(&nb);\
+ } \
+ } while(0); \
+ for(ptr = &all_netdevices[0]; (d = *ptr) != 0; ptr++)
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
struct list_head generic_devices;
diff -r e9f722488fcd master/cdev.c
--- a/master/cdev.c Mon Oct 25 17:06:45 2010 +0200
+++ b/master/cdev.c Thu Nov 18 13:35:37 2010 +0100
@@ -3863,8 +3863,7 @@
return NOPAGE_SIGBUS;
page = vmalloc_to_page(priv->process_data + offset);
-
- EC_MASTER_DBG(master, "Nopage fault vma, address = %#lx,"
+ EC_MASTER_DBG(priv->cdev->master, 1, "Nopage fault vma, address = %#lx,"
" offset = %#lx, page = %p\n", address, offset, page);
get_page(page);
diff -r e9f722488fcd master/ethernet.h
--- a/master/ethernet.h Mon Oct 25 17:06:45 2010 +0200
+++ b/master/ethernet.h Thu Nov 18 13:35:37 2010 +0100
@@ -39,7 +39,12 @@
#include <linux/list.h>
#include <linux/netdevice.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif
#include "globals.h"
#include "slave.h"
diff -r e9f722488fcd master/slave.h
--- a/master/slave.h Mon Oct 25 17:06:45 2010 +0200
+++ b/master/slave.h Thu Nov 18 13:35:37 2010 +0100
@@ -39,6 +39,7 @@
#include <linux/list.h>
#include <linux/kobject.h>
+#include <linux/wait.h>
#include "globals.h"
#include "datagram.h"
More information about the etherlab-dev
mailing list