Prepared Free-Run mode
This commit is contained in:
parent
be21ebac29
commit
7818664587
|
|
@ -199,15 +199,10 @@ static int debug = -1;
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
// Uncomment for debugging
|
||||
//#define EC_DEBUG
|
||||
|
||||
// Device index for EtherCAT device selection
|
||||
static int ec_device_index = -1;
|
||||
static int ec_device_master_index = 0;
|
||||
|
||||
static ec_device_t *rtl_ec_dev;
|
||||
int rtl_ec_dev_registered = 0;
|
||||
struct net_device *rtl_ec_net_dev = NULL;
|
||||
|
||||
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
||||
|
|
@ -1025,13 +1020,9 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (board_idx == ec_device_index)
|
||||
{
|
||||
printk(KERN_INFO "Registering EtherCAT device...\n");
|
||||
rtl_ec_dev = ecdev_register(ec_device_master_index, dev,
|
||||
rtl8139_interrupt, THIS_MODULE);
|
||||
|
||||
if (rtl_ec_dev) strcpy(dev->name, "ec0");
|
||||
if (board_idx == ec_device_index) {
|
||||
rtl_ec_net_dev = dev;
|
||||
strcpy(dev->name, "ec0");
|
||||
}
|
||||
|
||||
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
|
@ -1092,7 +1083,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
|||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
/* EtherCAT-Karten nicht beim Stack anmelden. */
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
DPRINTK("About to register device named %s (%p)...\n", dev->name, dev);
|
||||
i = register_netdev (dev);
|
||||
|
|
@ -1190,7 +1181,7 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
unregister_netdev (dev);
|
||||
}
|
||||
|
|
@ -1403,7 +1394,7 @@ static int rtl8139_open (struct net_device *dev)
|
|||
printk(KERN_DEBUG "%s: open\n", dev->name);
|
||||
#endif
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
retval = request_irq(dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
|
||||
if (retval)
|
||||
|
|
@ -1420,7 +1411,7 @@ static int rtl8139_open (struct net_device *dev)
|
|||
{
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
free_irq(dev->irq, dev);
|
||||
}
|
||||
|
|
@ -1445,7 +1436,7 @@ static int rtl8139_open (struct net_device *dev)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
netif_start_queue (dev);
|
||||
|
||||
|
|
@ -1471,7 +1462,7 @@ static void rtl_check_media (struct net_device *dev, unsigned int init_media)
|
|||
{
|
||||
struct rtl8139_private *tp = netdev_priv(dev);
|
||||
|
||||
if (ecdev_is_ec(rtl_ec_dev, dev)) {
|
||||
if (dev == rtl_ec_net_dev) {
|
||||
void __iomem *ioaddr = tp->mmio_addr;
|
||||
uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
|
||||
ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
|
||||
|
|
@ -1545,7 +1536,7 @@ static void rtl8139_hw_start (struct net_device *dev)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
/* Enable all known interrupts by setting the interrupt mask. */
|
||||
RTL_W16 (IntrMask, rtl8139_intr_mask);
|
||||
|
|
@ -1814,7 +1805,7 @@ static void rtl8139_tx_timeout (struct net_device *dev)
|
|||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
spin_lock(&tp->rx_lock);
|
||||
|
||||
|
|
@ -1864,16 +1855,16 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
memset(tp->tx_buf[entry], 0, ETH_ZLEN);
|
||||
|
||||
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb);
|
||||
if (dev != rtl_ec_net_dev) dev_kfree_skb(skb);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev)) dev_kfree_skb(skb);
|
||||
if (dev != rtl_ec_net_dev) dev_kfree_skb(skb);
|
||||
tp->stats.tx_dropped++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
spin_lock_irq(&tp->lock);
|
||||
}
|
||||
|
|
@ -1890,7 +1881,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
|
||||
netif_stop_queue (dev);
|
||||
|
|
@ -1965,7 +1956,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
|
|||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
#ifndef RTL8139_NDEBUG
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev) && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
|
||||
if (dev != rtl_ec_net_dev && 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;
|
||||
|
|
@ -1981,7 +1972,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
netif_wake_queue (dev);
|
||||
}
|
||||
|
|
@ -2120,7 +2111,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
|||
RTL_R16 (RxBufAddr),
|
||||
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
|
||||
|
||||
while ((ecdev_is_ec(rtl_ec_dev, dev) || netif_running(dev))
|
||||
while ((dev == rtl_ec_net_dev || netif_running(dev))
|
||||
&& received < budget
|
||||
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
|
||||
u32 ring_offset = cur_rx % RX_BUF_LEN;
|
||||
|
|
@ -2137,7 +2128,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev) && netif_msg_rx_status(tp))
|
||||
if (dev != rtl_ec_net_dev && 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);
|
||||
|
|
@ -2193,7 +2184,7 @@ no_early_rx:
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
/* Malloc up new buffer, compatible with net-2e. */
|
||||
/* Omit the four octet CRC from the length. */
|
||||
|
|
@ -2356,7 +2347,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev == rtl_ec_net_dev)
|
||||
{
|
||||
status = RTL_R16 (IntrStatus);
|
||||
}
|
||||
|
|
@ -2380,7 +2371,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
/* close possible race's with dev_close */
|
||||
if (unlikely(!netif_running(dev))) {
|
||||
|
|
@ -2408,7 +2399,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
|
|||
|
||||
if (status & RxAckBits)
|
||||
{
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
/* Polling vormerken */
|
||||
if (netif_rx_schedule_prep(dev)) {
|
||||
|
|
@ -2438,7 +2429,7 @@ irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
|
|||
out:
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
spin_unlock (&tp->lock);
|
||||
}
|
||||
|
|
@ -2472,7 +2463,7 @@ static int rtl8139_close (struct net_device *dev)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (!ecdev_is_ec(rtl_ec_dev, dev))
|
||||
if (dev != rtl_ec_net_dev)
|
||||
{
|
||||
netif_stop_queue(dev);
|
||||
if (tp->thr_pid >= 0) {
|
||||
|
|
@ -2737,7 +2728,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (ecdev_is_ec(rtl_ec_dev, dev) || !netif_running(dev))
|
||||
if (dev == rtl_ec_net_dev || !netif_running(dev))
|
||||
return -EINVAL;
|
||||
|
||||
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
|
@ -2758,7 +2749,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (ecdev_is_ec(rtl_ec_dev, dev) || netif_running(dev))
|
||||
if (dev == rtl_ec_net_dev || netif_running(dev))
|
||||
{
|
||||
spin_lock_irqsave (&tp->lock, flags);
|
||||
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
|
||||
|
|
@ -2845,7 +2836,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (ecdev_is_ec(rtl_ec_dev, dev) || !netif_running (dev))
|
||||
if (dev == rtl_ec_net_dev || !netif_running (dev))
|
||||
return 0;
|
||||
|
||||
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
|
@ -2878,7 +2869,7 @@ static int rtl8139_resume (struct pci_dev *pdev)
|
|||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
if (ecdev_is_ec(rtl_ec_dev, dev) || !netif_running (dev))
|
||||
if (dev == rtl_ec_net_dev || !netif_running (dev))
|
||||
return 0;
|
||||
|
||||
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
|
@ -2907,38 +2898,42 @@ static struct pci_driver rtl8139_pci_driver = {
|
|||
|
||||
static int __init rtl8139_init_module (void)
|
||||
{
|
||||
/* 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
|
||||
|
||||
/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||||
|
||||
printk(KERN_INFO "Initializing RTL8139-EtherCAT module. %s\n", COMPILE_INFO);
|
||||
printk(KERN_INFO "EtherCAT device index is %i.\n", ec_device_index);
|
||||
printk(KERN_INFO RTL8139_DRIVER_NAME " " COMPILE_INFO "\n");
|
||||
printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
|
||||
|
||||
if (pci_module_init(&rtl8139_pci_driver) < 0)
|
||||
{
|
||||
printk(KERN_ERR "Could not init PCI module.\n");
|
||||
goto out_ec_dev;
|
||||
if (pci_module_init(&rtl8139_pci_driver) < 0) {
|
||||
printk(KERN_ERR "Failed to init PCI module.\n");
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
if (!rtl_ec_dev)
|
||||
{
|
||||
printk(KERN_WARNING "NO EtherCAT device registered!\n");
|
||||
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, rtl8139_interrupt,
|
||||
THIS_MODULE))) {
|
||||
printk(KERN_ERR "Failed to register EtherCAT device!\n");
|
||||
goto out_pci;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Starting EtherCAT device...\n");
|
||||
if (ecdev_start(ec_device_master_index)) {
|
||||
printk(KERN_ERR "Failed to start EtherCAT device!\n");
|
||||
goto out_unregister;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printk(KERN_WARNING "NO EtherCAT device registered!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_ec_dev:
|
||||
if (rtl_ec_dev) {
|
||||
printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
|
||||
ecdev_unregister(ec_device_master_index, rtl_ec_dev);
|
||||
rtl_ec_dev = NULL;
|
||||
}
|
||||
|
||||
out_unregister:
|
||||
ecdev_unregister(ec_device_master_index, rtl_ec_dev);
|
||||
out_pci:
|
||||
pci_unregister_driver(&rtl8139_pci_driver);
|
||||
out_return:
|
||||
return -1;
|
||||
|
||||
/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
|
@ -2951,14 +2946,16 @@ static void __exit rtl8139_cleanup_module (void)
|
|||
|
||||
printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
|
||||
|
||||
pci_unregister_driver(&rtl8139_pci_driver);
|
||||
|
||||
if (rtl_ec_dev) {
|
||||
printk(KERN_INFO "Unregistering RTL8139-EtherCAT device...\n");
|
||||
ecdev_unregister(ec_device_master_index, rtl_ec_dev);
|
||||
rtl_ec_dev = NULL;
|
||||
if (rtl_ec_net_dev) {
|
||||
printk(KERN_INFO "Stopping device...\n");
|
||||
ecdev_stop(ec_device_master_index);
|
||||
printk(KERN_INFO "Unregistering 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 <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||||
|
|
|
|||
|
|
@ -17,9 +17,8 @@ obj-m := ec_8139too.o
|
|||
|
||||
ec_8139too-objs := 8139too.o
|
||||
|
||||
REV = `svnversion $(src)`
|
||||
DATE = `date`
|
||||
|
||||
REV := $(shell svnversion $(src))
|
||||
DATE := $(shell date)
|
||||
EXTRA_CFLAGS = -DEC_REV="$(REV)" -DEC_USER="$(USER)" -DEC_DATE="$(DATE)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@ ec_device_t *ecdev_register(unsigned int master_index,
|
|||
struct module *module);
|
||||
void ecdev_unregister(unsigned int master_index, ec_device_t *device);
|
||||
|
||||
int ecdev_start(unsigned int master_index);
|
||||
void ecdev_stop(unsigned int master_index);
|
||||
|
||||
/*****************************************************************************/
|
||||
// Device methods
|
||||
|
||||
int ecdev_is_ec(const ec_device_t *device, const struct net_device *net_dev);
|
||||
void ecdev_receive(ec_device_t *device, const void *data, size_t size);
|
||||
void ecdev_link_state(ec_device_t *device, uint8_t newstate);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ else
|
|||
KERNEL := $(shell uname -r)
|
||||
endif
|
||||
|
||||
KERNELDIR = /lib/modules/$(KERNEL)/build
|
||||
KERNELDIR := /lib/modules/$(KERNEL)/build
|
||||
|
||||
modules:
|
||||
$(MAKE) -C $(KERNELDIR) M=`pwd`
|
||||
|
|
|
|||
|
|
@ -196,21 +196,6 @@ void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Ger
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
Prüft, ob das Net-Device \a dev zum registrierten EtherCAT-Gerät gehört.
|
||||
|
||||
\return 0 wenn nein, nicht-null wenn ja.
|
||||
*/
|
||||
|
||||
inline int ecdev_is_ec(const ec_device_t *device, /**< EtherCAT-Gerät */
|
||||
const struct net_device *dev /**< Net-Device */
|
||||
)
|
||||
{
|
||||
return device && device->dev == dev;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Nimmt einen Empfangenen Rahmen entgegen.
|
||||
|
||||
|
|
@ -240,6 +225,11 @@ void ecdev_link_state(ec_device_t *device, /**< EtherCAT-Ger
|
|||
uint8_t state /**< Verbindungszustand */
|
||||
)
|
||||
{
|
||||
if (unlikely(!device)) {
|
||||
EC_WARN("ecdev_link_state: no device!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (likely(state != device->link_state)) {
|
||||
device->link_state = state;
|
||||
EC_INFO("Link state changed to %s.\n", (state ? "UP" : "DOWN"));
|
||||
|
|
@ -248,7 +238,6 @@ void ecdev_link_state(ec_device_t *device, /**< EtherCAT-Ger
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
EXPORT_SYMBOL(ecdev_is_ec);
|
||||
EXPORT_SYMBOL(ecdev_receive);
|
||||
EXPORT_SYMBOL(ecdev_link_state);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,14 +25,17 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void ec_master_freerun(unsigned long);
|
||||
ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
EC_SYSFS_READ_ATTR(slave_count);
|
||||
EC_SYSFS_READ_ATTR(mode);
|
||||
|
||||
static struct attribute *ec_def_attrs[] = {
|
||||
&attr_slave_count,
|
||||
&attr_mode,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -78,6 +81,11 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT-Master */
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Init freerun timer
|
||||
init_timer(&master->freerun_timer);
|
||||
master->freerun_timer.function = ec_master_freerun;
|
||||
master->freerun_timer.data = (unsigned long) master;
|
||||
|
||||
ec_command_init(&master->simple_command);
|
||||
ec_command_init(&master->watch_command);
|
||||
|
||||
|
|
@ -100,6 +108,8 @@ void ec_master_clear(struct kobject *kobj /**< KObject des Masters */)
|
|||
|
||||
EC_INFO("Clearing master %i...\n", master->index);
|
||||
|
||||
del_timer_sync(&master->freerun_timer);
|
||||
|
||||
ec_master_reset(master);
|
||||
|
||||
if (master->device) {
|
||||
|
|
@ -131,6 +141,8 @@ void ec_master_reset(ec_master_t *master
|
|||
ec_domain_t *domain, *next_d;
|
||||
ec_eoe_t *eoe, *next_eoe;
|
||||
|
||||
ec_master_freerun_stop(master);
|
||||
|
||||
// Alle Slaves entfernen
|
||||
list_for_each_entry_safe(slave, next_s, &master->slaves, list) {
|
||||
list_del(&slave->list);
|
||||
|
|
@ -172,6 +184,8 @@ void ec_master_reset(ec_master_t *master
|
|||
master->stats.unmatched = 0;
|
||||
master->stats.eoe_errors = 0;
|
||||
master->stats.t_last = 0;
|
||||
|
||||
master->mode = EC_MASTER_MODE_IDLE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -605,6 +619,61 @@ void ec_master_output_stats(ec_master_t *master /**< EtherCAT-Master */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Starts Free-Run mode.
|
||||
*/
|
||||
|
||||
void ec_master_freerun_start(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
if (master->mode == EC_MASTER_MODE_FREERUN) return;
|
||||
|
||||
if (master->mode == EC_MASTER_MODE_RUNNING) {
|
||||
EC_ERR("ec_master_freerun_start: Master already running!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
EC_INFO("Starting Free-Run mode.\n");
|
||||
|
||||
master->mode = EC_MASTER_MODE_FREERUN;
|
||||
|
||||
master->freerun_timer.expires = jiffies + 10;
|
||||
add_timer(&master->freerun_timer);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Stops Free-Run mode.
|
||||
*/
|
||||
|
||||
void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
if (master->mode != EC_MASTER_MODE_FREERUN) return;
|
||||
|
||||
EC_INFO("Stopping Free-Run mode.\n");
|
||||
|
||||
del_timer_sync(&master->freerun_timer);
|
||||
master->mode = EC_MASTER_MODE_IDLE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Free-Run mode function.
|
||||
*/
|
||||
|
||||
void ec_master_freerun(unsigned long data)
|
||||
{
|
||||
ec_master_t *master = (ec_master_t *) data;
|
||||
|
||||
// nop
|
||||
|
||||
master->freerun_timer.expires += HZ;
|
||||
add_timer(&master->freerun_timer);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Wandelt eine ASCII-kodierte Bus-Adresse in einen Slave-Zeiger.
|
||||
|
||||
|
|
@ -795,6 +864,16 @@ ssize_t ec_show_master_attribute(struct kobject *kobj, /**< KObject */
|
|||
if (attr == &attr_slave_count) {
|
||||
return sprintf(buffer, "%i\n", master->slave_count);
|
||||
}
|
||||
else if (attr == &attr_mode) {
|
||||
switch (master->mode) {
|
||||
case EC_MASTER_MODE_IDLE:
|
||||
return sprintf(buffer, "IDLE\n");
|
||||
case EC_MASTER_MODE_FREERUN:
|
||||
return sprintf(buffer, "FREERUN\n");
|
||||
case EC_MASTER_MODE_RUNNING:
|
||||
return sprintf(buffer, "RUNNING\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,27 @@
|
|||
|
||||
#include <linux/list.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#include "device.h"
|
||||
#include "domain.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
EtherCAT master mode.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EC_MASTER_MODE_IDLE,
|
||||
EC_MASTER_MODE_FREERUN,
|
||||
EC_MASTER_MODE_RUNNING
|
||||
}
|
||||
ec_master_mode_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
EtherCAT-Rahmen-Statistiken.
|
||||
*/
|
||||
|
|
@ -63,6 +78,8 @@ struct ec_master
|
|||
unsigned int timeout; /**< Timeout für synchronen Datenaustausch */
|
||||
struct list_head eoe_slaves; /**< Ethernet over EtherCAT Slaves */
|
||||
unsigned int reserved; /**< Master durch Echtzeitprozess reserviert */
|
||||
struct timer_list freerun_timer; /**< Timer fuer Free-Run-Modus. */
|
||||
ec_master_mode_t mode; /**< Modus des Masters */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -72,6 +89,10 @@ int ec_master_init(ec_master_t *, unsigned int);
|
|||
void ec_master_clear(struct kobject *);
|
||||
void ec_master_reset(ec_master_t *);
|
||||
|
||||
// Free-Run
|
||||
void ec_master_freerun_start(ec_master_t *);
|
||||
void ec_master_freerun_stop(ec_master_t *);
|
||||
|
||||
// IO
|
||||
void ec_master_receive(ec_master_t *, const uint8_t *, size_t);
|
||||
void ec_master_queue_command(ec_master_t *, ec_command_t *);
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ ec_device_t *ecdev_register(unsigned int master_index,
|
|||
|
||||
if (!net_dev) {
|
||||
EC_WARN("Device is NULL!\n");
|
||||
return NULL;
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
if (!(master = ec_find_master(master_index))) return NULL;
|
||||
|
|
@ -189,23 +189,30 @@ ec_device_t *ecdev_register(unsigned int master_index,
|
|||
// critical section start
|
||||
if (master->device) {
|
||||
EC_ERR("Master %i already has a device!\n", master_index);
|
||||
return NULL;
|
||||
// critical section leave
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
if (!(master->device =
|
||||
(ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate device!\n");
|
||||
return NULL;
|
||||
// critical section leave
|
||||
goto out_return;
|
||||
}
|
||||
// critical section end
|
||||
|
||||
if (ec_device_init(master->device, master, net_dev, isr, module)) {
|
||||
kfree(master->device);
|
||||
master->device = NULL;
|
||||
return NULL;
|
||||
EC_ERR("Failed to init device!\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
return master->device;
|
||||
|
||||
out_free:
|
||||
kfree(master->device);
|
||||
master->device = NULL;
|
||||
out_return:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -222,11 +229,6 @@ void ecdev_unregister(unsigned int master_index,
|
|||
{
|
||||
ec_master_t *master;
|
||||
|
||||
if (master_index >= ec_master_count) {
|
||||
EC_WARN("Master %i does not exist!\n", master_index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(master = ec_find_master(master_index))) return;
|
||||
|
||||
if (!master->device || master->device != device) {
|
||||
|
|
@ -239,6 +241,47 @@ void ecdev_unregister(unsigned int master_index,
|
|||
master->device = NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Starts the master.
|
||||
*/
|
||||
|
||||
int ecdev_start(unsigned int master_index
|
||||
/**< Index des EtherCAT-Masters */
|
||||
)
|
||||
{
|
||||
ec_master_t *master;
|
||||
if (!(master = ec_find_master(master_index))) return -1;
|
||||
|
||||
if (ec_device_open(master->device)) {
|
||||
EC_ERR("Failed to open device!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ec_master_freerun_start(master);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Stops the master.
|
||||
*/
|
||||
|
||||
void ecdev_stop(unsigned int master_index
|
||||
/**< Index des EtherCAT-Masters */
|
||||
)
|
||||
{
|
||||
ec_master_t *master;
|
||||
if (!(master = ec_find_master(master_index))) return;
|
||||
|
||||
ec_master_freerun_stop(master);
|
||||
|
||||
if (ec_device_close(master->device))
|
||||
EC_WARN("Failed to close device!\n");
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Echtzeitschnittstelle
|
||||
|
|
@ -261,50 +304,46 @@ ec_master_t *ecrt_request_master(unsigned int master_index
|
|||
|
||||
EC_INFO("Requesting master %i...\n", master_index);
|
||||
|
||||
if (!(master = ec_find_master(master_index))) goto req_return;
|
||||
if (!(master = ec_find_master(master_index))) goto out_return;
|
||||
|
||||
// begin critical section
|
||||
if (master->reserved) {
|
||||
EC_ERR("Master %i is already in use!\n", master_index);
|
||||
goto req_return;
|
||||
goto out_return;
|
||||
}
|
||||
master->reserved = 1;
|
||||
// end critical section
|
||||
|
||||
if (!master->device) {
|
||||
EC_ERR("Master %i has no assigned device!\n", master_index);
|
||||
goto req_release;
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
if (!try_module_get(master->device->module)) {
|
||||
EC_ERR("Failed to reserve device module!\n");
|
||||
goto req_release;
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
if (ec_device_open(master->device)) {
|
||||
EC_ERR("Failed to open device!\n");
|
||||
goto req_module_put;
|
||||
}
|
||||
ec_master_freerun_stop(master);
|
||||
ec_master_reset(master);
|
||||
master->mode = EC_MASTER_MODE_RUNNING;
|
||||
|
||||
if (!master->device->link_state) EC_WARN("Link is DOWN.\n");
|
||||
|
||||
if (ec_master_bus_scan(master)) {
|
||||
EC_ERR("Bus scan failed!\n");
|
||||
goto req_close;
|
||||
goto out_module_put;
|
||||
}
|
||||
|
||||
EC_INFO("Master %i is ready.\n", master_index);
|
||||
return master;
|
||||
|
||||
req_close:
|
||||
if (ec_device_close(master->device))
|
||||
EC_WARN("Warning - Failed to close device!\n");
|
||||
req_module_put:
|
||||
out_module_put:
|
||||
module_put(master->device->module);
|
||||
ec_master_reset(master);
|
||||
req_release:
|
||||
out_release:
|
||||
master->reserved = 0;
|
||||
req_return:
|
||||
out_return:
|
||||
EC_ERR("Failed requesting master %i.\n", master_index);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -326,8 +365,8 @@ void ecrt_release_master(ec_master_t *master /**< EtherCAT-Master */)
|
|||
|
||||
ec_master_reset(master);
|
||||
|
||||
if (ec_device_close(master->device))
|
||||
EC_WARN("Warning - Failed to close device!\n");
|
||||
master->mode = EC_MASTER_MODE_IDLE;
|
||||
ec_master_freerun_start(master);
|
||||
|
||||
module_put(master->device->module);
|
||||
master->reserved = 0;
|
||||
|
|
@ -389,6 +428,8 @@ module_exit(ec_cleanup_module);
|
|||
|
||||
EXPORT_SYMBOL(ecdev_register);
|
||||
EXPORT_SYMBOL(ecdev_unregister);
|
||||
EXPORT_SYMBOL(ecdev_start);
|
||||
EXPORT_SYMBOL(ecdev_stop);
|
||||
EXPORT_SYMBOL(ecrt_request_master);
|
||||
EXPORT_SYMBOL(ecrt_release_master);
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ int __init init_rt_module(void)
|
|||
}
|
||||
ecrt_master_print(master, 2);
|
||||
#else
|
||||
ecrt_master_print(master, 1);
|
||||
ecrt_master_print(master, 0);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
|
|
|
|||
Loading…
Reference in New Issue