# HG changeset patch # User Florian Pose # Date 1165577996 0 # Node ID 04552130dd54486474db2ff3346186328e43127a # Parent b2aee224195229e58d57245e35125b37764dbea7 Re-introduced ecdev_open() and ecdev_close(), to avoid a race condition regarding the link state. diff -r b2aee2241952 -r 04552130dd54 NEWS --- a/NEWS Fri Nov 24 11:09:36 2006 +0000 +++ b/NEWS Fri Dec 08 11:39:56 2006 +0000 @@ -13,8 +13,8 @@ ecrt_master_release(). * Removed ecrt_master_prepare(). Its functionality was moved into ecrt_master_activate(). -* Removed ecdev_start() and ecdev_stop(). Their functionality was moved into - ecdev_register() and ecdev_unregister, respectively. +* Renamed ecdev_start() and ecdev_stop() to ecdev_open() and ecdev_close(). + These two functions now take a pointer to ec_device_t as their arguments. * The data_ptr parameter of ecrt_domain_register_pdo(), ecrt_domain_register_pdo_list() and ecrt_domain_register_pdo_range() may not be NULL any more. diff -r b2aee2241952 -r 04552130dd54 devices/8139too-2.6.13-ethercat.c --- a/devices/8139too-2.6.13-ethercat.c Fri Nov 24 11:09:36 2006 +0000 +++ b/devices/8139too-2.6.13-ethercat.c Fri Dec 08 11:39:56 2006 +0000 @@ -2907,12 +2907,24 @@ printk(KERN_ERR "Failed to register EtherCAT device!\n"); goto out_pci; } + + printk(KERN_INFO "Opening EtherCAT device...\n"); + if (ecdev_open(rtl_ec_dev)) { + printk(KERN_ERR "Failed to open EtherCAT device!\n"); + goto out_unregister; + } + + printk(KERN_INFO "EtherCAT device ready.\n"); } else { printk(KERN_WARNING "No EtherCAT device registered!\n"); } return 0; + out_unregister: + printk(KERN_INFO "Unregistering EtherCAT device...\n"); + ecdev_unregister(ec_device_master_index, rtl_ec_dev); + rtl_ec_dev = NULL; out_pci: pci_unregister_driver(&rtl8139_pci_driver); out_return: @@ -2929,7 +2941,9 @@ printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n"); if (rtl_ec_net_dev) { - printk(KERN_INFO "Unregistering device...\n"); + printk(KERN_INFO "Closing EtherCAT device...\n"); + ecdev_close(rtl_ec_dev); + printk(KERN_INFO "Unregistering EtherCAT device...\n"); ecdev_unregister(ec_device_master_index, rtl_ec_dev); rtl_ec_dev = NULL; } diff -r b2aee2241952 -r 04552130dd54 devices/8139too-2.6.17-ethercat.c --- a/devices/8139too-2.6.17-ethercat.c Fri Nov 24 11:09:36 2006 +0000 +++ b/devices/8139too-2.6.17-ethercat.c Fri Dec 08 11:39:56 2006 +0000 @@ -2905,12 +2905,24 @@ printk(KERN_ERR "Failed to register EtherCAT device!\n"); goto out_pci; } + + printk(KERN_INFO "Opening EtherCAT device...\n"); + if (ecdev_open(rtl_ec_dev)) { + printk(KERN_ERR "Failed to open EtherCAT device!\n"); + goto out_unregister; + } + + printk(KERN_INFO "EtherCAT device ready.\n"); } else { printk(KERN_WARNING "No EtherCAT device registered!\n"); } return 0; + out_unregister: + printk(KERN_INFO "Unregistering EtherCAT device...\n"); + ecdev_unregister(ec_device_master_index, rtl_ec_dev); + rtl_ec_dev = NULL; out_pci: pci_unregister_driver(&rtl8139_pci_driver); out_return: @@ -2927,7 +2939,9 @@ printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n"); if (rtl_ec_net_dev) { - printk(KERN_INFO "Unregistering device...\n"); + printk(KERN_INFO "Closing EtherCAT device...\n"); + ecdev_close(rtl_ec_dev); + printk(KERN_INFO "Unregistering EtherCAT device...\n"); ecdev_unregister(ec_device_master_index, rtl_ec_dev); rtl_ec_dev = NULL; } diff -r b2aee2241952 -r 04552130dd54 devices/ecdev.h --- a/devices/ecdev.h Fri Nov 24 11:09:36 2006 +0000 +++ b/devices/ecdev.h Fri Dec 08 11:39:56 2006 +0000 @@ -74,6 +74,8 @@ /*****************************************************************************/ // Device methods +int ecdev_open(ec_device_t *device); +int ecdev_close(ec_device_t *device); void ecdev_receive(ec_device_t *device, const void *data, size_t size); void ecdev_link_state(ec_device_t *device, uint8_t newstate); diff -r b2aee2241952 -r 04552130dd54 master/module.c --- a/master/module.c Fri Nov 24 11:09:36 2006 +0000 +++ b/master/module.c Fri Dec 08 11:39:56 2006 +0000 @@ -311,19 +311,9 @@ goto out_free; } - if (ec_device_open(master->device)) { - EC_ERR("Failed to open device!\n"); - goto out_clear; - } - up(&master->device_sem); - - ec_master_enter_idle_mode(master); - return master->device; - out_clear: - ec_device_clear(master->device); out_free: kfree(master->device); master->device = NULL; @@ -352,11 +342,6 @@ if (!(master = ec_find_master(master_index))) return; - ec_master_leave_idle_mode(master); - - if (ec_device_close(master->device)) - EC_WARN("Failed to close device!\n"); - down(&master->device_sem); if (!master->device || master->device != device) { @@ -372,6 +357,41 @@ up(&master->device_sem); } +/*****************************************************************************/ + +/** + Opens the network device and makes the master enter IDLE mode. + \return 0 on success, else < 0 + \ingroup DeviceInterface +*/ + +int ecdev_open(ec_device_t *device /**< EtherCAT device */) +{ + if (ec_device_open(device)) { + EC_ERR("Failed to open device!\n"); + return -1; + } + + ec_master_enter_idle_mode(device->master); + return 0; +} + +/*****************************************************************************/ + +/** + Makes the master leave IDLE mode and closes the network device. + \return 0 on success, else < 0 + \ingroup DeviceInterface +*/ + +void ecdev_close(ec_device_t *device /**< EtherCAT device */) +{ + ec_master_leave_idle_mode(device->master); + + if (ec_device_close(device)) + EC_WARN("Failed to close device!\n"); +} + /****************************************************************************** * Realtime interface *****************************************************************************/ @@ -465,6 +485,8 @@ EXPORT_SYMBOL(ecdev_register); EXPORT_SYMBOL(ecdev_unregister); +EXPORT_SYMBOL(ecdev_open); +EXPORT_SYMBOL(ecdev_close); EXPORT_SYMBOL(ecrt_request_master); EXPORT_SYMBOL(ecrt_release_master);