Introduced per-master character devices for XML descriptions.
--- a/master/Makefile Tue Sep 19 13:09:39 2006 +0000
+++ b/master/Makefile Tue Sep 19 13:28:40 2006 +0000
@@ -43,7 +43,7 @@
obj-m := ec_master.o
ec_master-objs := module.o master.o device.o slave.o datagram.o \
- domain.o mailbox.o ethernet.o debug.o fsm.o
+ domain.o mailbox.o ethernet.o debug.o fsm.o xmldev.o
REV := $(shell svnversion $(src) 2>/dev/null || echo "unknown")
--- a/master/master.c Tue Sep 19 13:09:39 2006 +0000
+++ b/master/master.c Tue Sep 19 13:28:40 2006 +0000
@@ -98,7 +98,8 @@
int ec_master_init(ec_master_t *master, /**< EtherCAT master */
unsigned int index, /**< master index */
- unsigned int eoeif_count /**< number of EoE interfaces */
+ unsigned int eoeif_count, /**< number of EoE interfaces */
+ dev_t dev_num /**< number for XML cdev's */
)
{
ec_eoe_t *eoe, *next_eoe;
@@ -133,6 +134,12 @@
goto out_return;
}
+ // init XML character device
+ if (ec_xmldev_init(&master->xmldev, master, dev_num)) {
+ EC_ERR("Failed to init XML character device.\n");
+ goto out_clear_wq;
+ }
+
// create EoE handlers
for (i = 0; i < eoeif_count; i++) {
if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
@@ -168,6 +175,8 @@
ec_eoe_clear(eoe);
kfree(eoe);
}
+ ec_xmldev_clear(&master->xmldev);
+ out_clear_wq:
destroy_workqueue(master->workqueue);
out_return:
return -1;
@@ -191,6 +200,7 @@
ec_master_reset(master);
ec_fsm_clear(&master->fsm);
destroy_workqueue(master->workqueue);
+ ec_xmldev_clear(&master->xmldev);
// clear EoE objects
list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
--- a/master/master.h Tue Sep 19 13:09:39 2006 +0000
+++ b/master/master.h Tue Sep 19 13:28:40 2006 +0000
@@ -47,6 +47,7 @@
#include "device.h"
#include "domain.h"
+#include "xmldev.h"
#include "fsm.h"
/*****************************************************************************/
@@ -98,6 +99,8 @@
ec_device_t *device; /**< EtherCAT device */
+ ec_xmldev_t xmldev; /**< XML character device */
+
ec_fsm_t fsm; /**< master state machine */
ec_master_mode_t mode; /**< master mode */
@@ -136,7 +139,7 @@
/*****************************************************************************/
// master creation and deletion
-int ec_master_init(ec_master_t *, unsigned int, unsigned int);
+int ec_master_init(ec_master_t *, unsigned int, unsigned int, dev_t);
void ec_master_clear(struct kobject *);
void ec_master_reset(ec_master_t *);
--- a/master/module.c Tue Sep 19 13:09:39 2006 +0000
+++ b/master/module.c Tue Sep 19 13:28:40 2006 +0000
@@ -56,6 +56,7 @@
static int ec_master_count = 1; /**< parameter value, number of masters */
static int ec_eoeif_count = 0; /**< parameter value, number of EoE interf. */
static struct list_head ec_masters; /**< list of masters */
+static dev_t device_number;
/*****************************************************************************/
@@ -89,7 +90,12 @@
EC_INFO("Master driver, %s\n", EC_COMPILE_INFO);
if (ec_master_count < 1) {
- EC_ERR("Error - Invalid ec_master_count: %i\n", ec_master_count);
+ EC_ERR("Invalid ec_master_count: %i\n", ec_master_count);
+ 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;
}
@@ -104,7 +110,7 @@
goto out_free;
}
- if (ec_master_init(master, i, ec_eoeif_count))
+ if (ec_master_init(master, i, ec_eoeif_count, device_number))
goto out_free;
if (kobject_add(&master->kobj)) {
@@ -148,6 +154,8 @@
kobject_put(&master->kobj); // free master
}
+ unregister_chrdev_region(device_number, ec_master_count);
+
EC_INFO("Master driver cleaned up.\n");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/master/xmldev.c Tue Sep 19 13:28:40 2006 +0000
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH
+ *
+ * This file is part of the IgH EtherCAT Master.
+ *
+ * The IgH EtherCAT Master is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The IgH EtherCAT Master is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the IgH EtherCAT Master; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * The right to use EtherCAT Technology is granted and comes free of
+ * charge under condition of compatibility of product made by
+ * Licensee. People intending to distribute/sell products based on the
+ * code, have to sign an agreement to guarantee that products using
+ * software based on IgH EtherCAT master stay compatible with the actual
+ * EtherCAT specification (which are released themselves as an open
+ * standard) as the (only) precondition to have the right to use EtherCAT
+ * Technology, IP and trade marks.
+ *
+ *****************************************************************************/
+
+/**
+ \file
+ EtherCAT XML device.
+*/
+
+/*****************************************************************************/
+
+#include <linux/module.h>
+
+#include "master.h"
+#include "xmldev.h"
+
+/*****************************************************************************/
+
+static char *test_str = "hello world!\n";
+
+int ecxmldev_open(struct inode *, struct file *);
+int ecxmldev_release(struct inode *, struct file *);
+ssize_t ecxmldev_read(struct file *, char __user *, size_t, loff_t *);
+ssize_t ecxmldev_write(struct file *, const char __user *, size_t, loff_t *);
+
+/*****************************************************************************/
+
+static struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .open = ecxmldev_open,
+ .release = ecxmldev_release,
+ .read = ecxmldev_read,
+ .write = ecxmldev_write
+};
+
+/*****************************************************************************/
+
+/**
+ XML device constructor.
+ \return 0 in case of success, else < 0
+*/
+
+int ec_xmldev_init(ec_xmldev_t *xmldev, /**< EtherCAT XML device */
+ ec_master_t *master, /**< EtherCAT master */
+ dev_t dev_num /**< device number */
+ )
+{
+ cdev_init(&xmldev->cdev, &fops);
+ xmldev->cdev.owner = THIS_MODULE;
+ if (cdev_add(&xmldev->cdev,
+ MKDEV(MAJOR(dev_num), master->index), 1)) {
+ EC_ERR("Failed to add character device!\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+
+/**
+ XML device destructor.
+*/
+
+void ec_xmldev_clear(ec_xmldev_t *xmldev /**< EtherCAT XML device */)
+{
+ cdev_del(&xmldev->cdev);
+}
+
+/*****************************************************************************/
+
+int ecxmldev_open(struct inode *inode, struct file *filp)
+{
+ ec_xmldev_t *xmldev;
+
+ xmldev = container_of(inode->i_cdev, ec_xmldev_t, cdev);
+ filp->private_data = xmldev;
+
+ EC_DBG("File opened.\n");
+
+ return 0;
+}
+
+/*****************************************************************************/
+
+int ecxmldev_release(struct inode *inode, struct file *filp)
+{
+ EC_DBG("File closed.\n");
+ return 0;
+}
+
+/*****************************************************************************/
+
+ssize_t ecxmldev_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ size_t len = strlen(test_str);
+
+ if (*f_pos >= len) return 0;
+ if (*f_pos + count > len) count = len - *f_pos;
+
+ if (copy_to_user(buf, test_str + *f_pos, count)) return -EFAULT;
+
+ *f_pos += count;
+
+ return count;
+}
+
+/*****************************************************************************/
+
+ssize_t ecxmldev_write(struct file *filp,
+ const char __user *buf,
+ size_t count,
+ loff_t *f_pos)
+{
+ return -EFAULT;
+}
+
+/*****************************************************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/master/xmldev.h Tue Sep 19 13:28:40 2006 +0000
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH
+ *
+ * This file is part of the IgH EtherCAT Master.
+ *
+ * The IgH EtherCAT Master is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The IgH EtherCAT Master is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the IgH EtherCAT Master; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * The right to use EtherCAT Technology is granted and comes free of
+ * charge under condition of compatibility of product made by
+ * Licensee. People intending to distribute/sell products based on the
+ * code, have to sign an agreement to guarantee that products using
+ * software based on IgH EtherCAT master stay compatible with the actual
+ * EtherCAT specification (which are released themselves as an open
+ * standard) as the (only) precondition to have the right to use EtherCAT
+ * Technology, IP and trade marks.
+ *
+ *****************************************************************************/
+
+/**
+ \file
+ EtherCAT XML device.
+*/
+
+/*****************************************************************************/
+
+#ifndef _EC_XMLDEV_H_
+#define _EC_XMLDEV_H_
+
+#include <linux/fs.h>
+#include <linux/cdev.h>
+
+#include "globals.h"
+#include "../include/ecrt.h"
+
+/*****************************************************************************/
+
+/**
+ EtherCAT XML character device.
+*/
+
+typedef struct
+{
+ ec_master_t *master; /**< master owning the device */
+ struct cdev cdev; /**< character device */
+}
+ec_xmldev_t;
+
+/*****************************************************************************/
+
+int ec_xmldev_init(ec_xmldev_t *, ec_master_t *, dev_t);
+void ec_xmldev_clear(ec_xmldev_t *);
+
+/*****************************************************************************/
+
+#endif
--- a/script/ethercat.sh Tue Sep 19 13:09:39 2006 +0000
+++ b/script/ethercat.sh Tue Sep 19 13:28:40 2006 +0000
@@ -49,6 +49,10 @@
#------------------------------------------------------------------------------
+device="ecxml"
+
+#------------------------------------------------------------------------------
+
ETHERCAT_CONFIG=/etc/sysconfig/ethercat
if [ ! -r $ETHERCAT_CONFIG ]; then
@@ -75,7 +79,7 @@
# add bridge, if it does not already exist
if ! /sbin/brctl show | grep -E -q "^$EOE_BRIDGE"; then
- if ! /sbin/brctl addbr $EOE_BRIDGE; then
+ if ! /sbin/brctl addbr $EOE_BRIDGE; then
/bin/false
rc_status -v
rc_exit
@@ -155,7 +159,8 @@
fi
if [ -z "$EOE_INTERFACES" ]; then
- if [ -n "$EOE_DEVICES" ]; then # support legacy sysconfig files
+ # support legacy sysconfig files
+ if [ -n "$EOE_DEVICES" ]; then
EOE_INTERFACES=$EOE_DEVICES
else
EOE_INTERFACES=0
@@ -181,7 +186,16 @@
rc_exit
fi
- # load device module
+ # 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
@@ -190,7 +204,7 @@
rc_exit
fi
- # build EoE bridge
+ # build EoE bridge
build_eoe_bridge
rc_status -v
@@ -199,7 +213,7 @@
stop)
echo -n "Shutting down EtherCAT master "
- # unload modules
+ # unload modules
for mod in ec_8139too ec_master; do
if lsmod | grep "^$mod " > /dev/null; then
if ! rmmod $mod; then
@@ -210,9 +224,12 @@
fi;
done
+ # remove device node
+ rm -f /dev/${device}0
+
sleep 1
- # reload previous modules
+ # reload previous modules
if ! modprobe 8139too; then
echo "Warning: Failed to restore 8139too module."
fi
@@ -235,7 +252,7 @@
lsmod | grep "^ec_8139too " > /dev/null
device_running=$?
- # master module and device module loaded?
+ # master module and device module loaded?
test $master_running -eq 0 -a $device_running -eq 0
rc_status -v