Introduced per-master character devices for XML descriptions.
This commit is contained in:
parent
66cacc2158
commit
e594f09d72
|
|
@ -43,7 +43,7 @@ ifneq ($(KERNELRELEASE),)
|
|||
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")
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ static struct kobj_type ktype_ec_master = {
|
|||
|
||||
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 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
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 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
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 @@ void ec_master_clear(struct kobject *kobj /**< kobject of the master */)
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include "device.h"
|
||||
#include "domain.h"
|
||||
#include "xmldev.h"
|
||||
#include "fsm.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -98,6 +99,8 @@ struct ec_master
|
|||
|
||||
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 @@ struct ec_master
|
|||
/*****************************************************************************/
|
||||
|
||||
// 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 *);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ void __exit ec_cleanup_module(void);
|
|||
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 @@ int __init ec_init_module(void)
|
|||
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 @@ int __init ec_init_module(void)
|
|||
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 @@ void __exit ec_cleanup_module(void)
|
|||
kobject_put(&master->kobj); // free master
|
||||
}
|
||||
|
||||
unregister_chrdev_region(device_number, ec_master_count);
|
||||
|
||||
EC_INFO("Master driver cleaned up.\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -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
|
||||
|
|
@ -49,6 +49,10 @@
|
|||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
device="ecxml"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ETHERCAT_CONFIG=/etc/sysconfig/ethercat
|
||||
|
||||
if [ ! -r $ETHERCAT_CONFIG ]; then
|
||||
|
|
@ -75,7 +79,7 @@ build_eoe_bridge()
|
|||
|
||||
# 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 @@ case "$1" in
|
|||
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 @@ case "$1" in
|
|||
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 @@ case "$1" in
|
|||
rc_exit
|
||||
fi
|
||||
|
||||
# build EoE bridge
|
||||
# build EoE bridge
|
||||
build_eoe_bridge
|
||||
|
||||
rc_status -v
|
||||
|
|
@ -199,7 +213,7 @@ case "$1" in
|
|||
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 @@ case "$1" in
|
|||
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 @@ case "$1" in
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue