# HG changeset patch # User Florian Pose # Date 1158672520 0 # Node ID 29af81543ce19e6c501960e72fed96c449e855db # Parent a7a8ed41b50aec0c7a5815489ddd480e2a856893 Introduced per-master character devices for XML descriptions. diff -r a7a8ed41b50a -r 29af81543ce1 master/Makefile --- 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") diff -r a7a8ed41b50a -r 29af81543ce1 master/master.c --- 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) { diff -r a7a8ed41b50a -r 29af81543ce1 master/master.h --- 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 *); diff -r a7a8ed41b50a -r 29af81543ce1 master/module.c --- 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"); } diff -r a7a8ed41b50a -r 29af81543ce1 master/xmldev.c --- /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 + +#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; +} + +/*****************************************************************************/ diff -r a7a8ed41b50a -r 29af81543ce1 master/xmldev.h --- /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 +#include + +#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 diff -r a7a8ed41b50a -r 29af81543ce1 script/ethercat.sh --- 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