Re-introduced ecdev_open() and ecdev_close(), to avoid a race condition regarding the link state.
--- 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.
--- 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;
}
--- 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;
}
--- 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);
--- 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);